Compare commits
	
		
			490 Commits
		
	
	
		
			wip/fmuell
			...
			wip/nielsd
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 952672ca62 | ||
|   | 4e84b46c9b | ||
|   | b4797956c7 | ||
|   | c1c45f95af | ||
|   | ac09e0110a | ||
|   | 0e37cd2ec9 | ||
|   | 76dc77f617 | ||
|   | cb4c0d32c0 | ||
|   | 3d4ba028c4 | ||
|   | 5481c1899f | ||
|   | 2fd120162f | ||
|   | 523ba5a719 | ||
|   | 07d25cd69d | ||
|   | 520cea9394 | ||
|   | 58c4212cfa | ||
|   | 7059e31f6a | ||
|   | a9234f7631 | ||
|   | 1e5a8b0cd7 | ||
|   | 5ef343f245 | ||
|   | 22e33b4c47 | ||
|   | 5ace4682bf | ||
|   | 14d9839ed3 | ||
|   | 3b6fae582b | ||
|   | 3cbdf4f9a5 | ||
|   | d8825e0d12 | ||
|   | 3c5fea59df | ||
|   | 443c8347ea | ||
|   | ee3f52c097 | ||
|   | 4b01bb6f99 | ||
|   | 27ef8154dc | ||
|   | 0a7e717e0e | ||
|   | 2d2824b947 | ||
|   | 40c2a403ac | ||
|   | 238b87d386 | ||
|   | 8c01d341c7 | ||
|   | 866629b3d3 | ||
|   | 2b3ab3ecec | ||
|   | 759120b95f | ||
|   | de0e21612c | ||
|   | 83e83444db | ||
|   | 5060aee7b2 | ||
|   | 12bace2721 | ||
|   | 2c45b5416e | ||
|   | 96c2473317 | ||
|   | 6359d6ef30 | ||
|   | 2f6323afc2 | ||
|   | d25bcbc3a7 | ||
|   | dd5d7d3b70 | ||
|   | 771b1a0788 | ||
|   | 5a9d094f3e | ||
|   | 9ca8433170 | ||
|   | 0ada312748 | ||
|   | 88697add1b | ||
|   | 4730b7a094 | ||
|   | aa3e64aec3 | ||
|   | af26e2b212 | ||
|   | 8167f20972 | ||
|   | bd4aac8f49 | ||
|   | 785dd5c5f7 | ||
|   | 71e469a59c | ||
|   | 6d4b9d29b8 | ||
|   | 33f5bb39cd | ||
|   | a1c3900630 | ||
|   | cdaf164c01 | ||
|   | 2bd80579ed | ||
|   | 54039c3552 | ||
|   | b197a1affb | ||
|   | 51655be6a3 | ||
|   | 9697c209c0 | ||
|   | 6ecb0a4546 | ||
|   | 30861d4800 | ||
|   | a23391ea28 | ||
|   | 58e0b80cac | ||
|   | 41dd744b74 | ||
|   | bdf66d7b62 | ||
|   | 4258ae3ec2 | ||
|   | 9b379c49ba | ||
|   | 7e70dd8453 | ||
|   | 2e209a82f9 | ||
|   | ab0ecc469f | ||
|   | 7d75ddf635 | ||
|   | 271e43a1ed | ||
|   | 2702a82896 | ||
|   | 8ad33d8752 | ||
|   | d84bbb8770 | ||
|   | c0c2edf2e1 | ||
|   | de0c3251dd | ||
|   | 0afd600ea4 | ||
|   | 598407b14a | ||
|   | d9bfa16f05 | ||
|   | 03117d65b2 | ||
|   | 5520bb3890 | ||
|   | 4e6b2eb72a | ||
|   | 2e5295b3a9 | ||
|   | 3121c9aa29 | ||
|   | 1ebbd7c768 | ||
|   | 8572bb97c7 | ||
|   | d5ebd8c816 | ||
|   | ed999ce926 | ||
|   | 50b7739076 | ||
|   | 94995e9c1e | ||
|   | fb04dafb0b | ||
|   | d57234bec9 | ||
|   | 38da54fb02 | ||
|   | bbd3275dad | ||
|   | 3a3f9aa008 | ||
|   | 3c54e863e6 | ||
|   | a63ba61194 | ||
|   | ab9710ee7b | ||
|   | 43cef45229 | ||
|   | 8db4f3c67f | ||
|   | 594a070029 | ||
|   | c2e04e3cfa | ||
|   | 293f50e8e5 | ||
|   | df7fea3407 | ||
|   | 563412698a | ||
|   | 2b30146c6c | ||
|   | 0f531d8c44 | ||
|   | 218c87994b | ||
|   | f74c07b9ac | ||
|   | 59edea4bb4 | ||
|   | 4d4d5a0b16 | ||
|   | 03c4930883 | ||
|   | 9593e20425 | ||
|   | 2b1d6e607f | ||
|   | 1dff32e48a | ||
|   | 1e3a174de9 | ||
|   | 7bb84dae80 | ||
|   | 44fcb9e9af | ||
|   | 2d30e310bc | ||
|   | be2d630348 | ||
|   | bea6045aae | ||
|   | ad491e7922 | ||
|   | fedb8e706a | ||
|   | 1be933bc49 | ||
|   | 526bb72f3d | ||
|   | 49c95cff6c | ||
|   | 56a361650c | ||
|   | d4763b157d | ||
|   | d2dc072ba9 | ||
|   | ffaca00594 | ||
|   | 9090b7dc3d | ||
|   | a540fe4130 | ||
|   | 5be61bbb68 | ||
|   | 8e51fee5c1 | ||
|   | 9d6fcfdc85 | ||
|   | 5f5a3b78a5 | ||
|   | 4e5ca6d376 | ||
|   | 2fab75f448 | ||
|   | 22883f2fa2 | ||
|   | 5d9f80bc73 | ||
|   | f7d117488b | ||
|   | 244a329ee7 | ||
|   | 044572cb60 | ||
|   | 746875258d | ||
|   | 4892a87dfe | ||
|   | 8b9c8ddb1e | ||
|   | eb9000576c | ||
|   | 862aaf341e | ||
|   | a5c75ff58b | ||
|   | 4541fb9819 | ||
|   | 9f8edd980c | ||
|   | e5b9043435 | ||
|   | c0012c2ea4 | ||
|   | b77e4975f0 | ||
|   | e83f2344f6 | ||
|   | de6512be1a | ||
|   | 0b72ff1896 | ||
|   | fea0192772 | ||
|   | f81ac498fb | ||
|   | 5357e0a18c | ||
|   | d7632bbd3d | ||
|   | 1b5e91e4b3 | ||
|   | 727195c767 | ||
|   | 9158f55360 | ||
|   | 8146e9d527 | ||
|   | 4247251020 | ||
|   | 7eee0e0ed6 | ||
|   | 4f0851ca77 | ||
|   | 911ae49767 | ||
|   | 5af81d4057 | ||
|   | c435889baa | ||
|   | 49f79d9d5d | ||
|   | 1767cd0f6c | ||
|   | 3e0915521a | ||
|   | a298943fac | ||
|   | df9ddf96a5 | ||
|   | 4fa5d701d5 | ||
|   | b05683d586 | ||
|   | 2f3f3fbcdb | ||
|   | 611605a67f | ||
|   | 0427a782be | ||
|   | 32baff5906 | ||
|   | 0089143d06 | ||
|   | 05e55cee23 | ||
|   | 31e7f0340f | ||
|   | 6e317a54fd | ||
|   | 9c1f62c38c | ||
|   | 1341d5557f | ||
|   | b7d79a5f06 | ||
|   | 62233a4db4 | ||
|   | 4a7e2ddff5 | ||
|   | fb737ebde0 | ||
|   | bf77cb44e7 | ||
|   | c72e2bb4a9 | ||
|   | 68c182b1df | ||
|   | 348d303794 | ||
|   | ede0fd8660 | ||
|   | 187c2193e8 | ||
|   | 706bdd8059 | ||
|   | 436861edc8 | ||
|   | 9729a2e772 | ||
|   | 6b924c00c5 | ||
|   | b90f4d29a4 | ||
|   | 47915f8c11 | ||
|   | 5dfdeaa4ea | ||
|   | 98a2a81f2a | ||
|   | c4850027bc | ||
|   | d4202e7f38 | ||
|   | 4f65283f31 | ||
|   | d86d3bbe54 | ||
|   | 6f794738e8 | ||
|   | ef7a93bb07 | ||
|   | 5197a992a6 | ||
|   | 49d8540f6d | ||
|   | 6e1a1f1a57 | ||
|   | c73428247c | ||
|   | fc2caf5794 | ||
|   | b117826ada | ||
|   | 26b44b48ab | ||
|   | 6349f0feb1 | ||
|   | 2ae17cfb50 | ||
|   | 4785093a5c | ||
|   | 859aef78c4 | ||
|   | 20730a5465 | ||
|   | fc5f687afc | ||
|   | 53e56f2395 | ||
|   | da314aff79 | ||
|   | fe89f7c5ac | ||
|   | 8b3be5e063 | ||
|   | 58dc538510 | ||
|   | 6cbef9355d | ||
|   | 22eac5c508 | ||
|   | a2860e9c73 | ||
|   | 1c5258ab68 | ||
|   | 8641eaa538 | ||
|   | 88436383c0 | ||
|   | affdcdcb0e | ||
|   | 06174be777 | ||
|   | fde8401124 | ||
|   | 70ac33d58c | ||
|   | 5a897407d9 | ||
|   | 1b3c26364b | ||
|   | ae07aa7864 | ||
|   | fb80831269 | ||
|   | 561cecf383 | ||
|   | 60ccdc2deb | ||
|   | d7d996b1d3 | ||
|   | 32b8bc39ac | ||
|   | 9dc99ad611 | ||
|   | 628cb4d553 | ||
|   | ad80bce78d | ||
|   | 1c9d821aa2 | ||
|   | 510b060947 | ||
|   | 26e33ff093 | ||
|   | 5f2bd70690 | ||
|   | 6dfa550663 | ||
|   | 252e2420ad | ||
|   | 572d54981e | ||
|   | 61471f9fb4 | ||
|   | 4d0a742d64 | ||
|   | 5f4e0e5ff8 | ||
|   | a4c159ecad | ||
|   | b1f893e998 | ||
|   | 789dc165af | ||
|   | 115eda9650 | ||
|   | d027e35cef | ||
|   | b3e178af9d | ||
|   | 559ec8750a | ||
|   | 02c3980b83 | ||
|   | 6f027ee7dc | ||
|   | 6d6c2e5b99 | ||
|   | 4a4f752459 | ||
|   | 8f1fff1374 | ||
|   | deead2af97 | ||
|   | 9e881ab637 | ||
|   | b6ec02cef2 | ||
|   | 26e3ccda49 | ||
|   | 2bda79cb3a | ||
|   | 19c60ff5c5 | ||
|   | e3c5c9a2e7 | ||
|   | 2c17c186b8 | ||
|   | ef1697d00d | ||
|   | 40e7638a4b | ||
|   | aaf69b2898 | ||
|   | 0464361ca5 | ||
|   | 420697693b | ||
|   | 37f53a42da | ||
|   | 5617ffc79c | ||
|   | ca4d86e9e5 | ||
|   | 0141fef561 | ||
|   | 5d4a804c90 | ||
|   | 6bc3300e5a | ||
|   | 15f69bdc3b | ||
|   | 0bcf76970a | ||
|   | 03c4628cad | ||
|   | 9f4ae9618a | ||
|   | 3590af15bb | ||
|   | c5de7fd20e | ||
|   | 7127fb1fa1 | ||
|   | 7cf11abefc | ||
|   | d78b416e1a | ||
|   | f5144ec899 | ||
|   | 08d1ebe7ee | ||
|   | a665801e9f | ||
|   | 112e3b110b | ||
|   | 94a674c008 | ||
|   | 72be8eeb31 | ||
|   | ad8690bb2e | ||
|   | 76cb08a72a | ||
|   | 2d4989e937 | ||
|   | f248b91f82 | ||
|   | d671eb1969 | ||
|   | 70f4906ca5 | ||
|   | ffb9aa1ace | ||
|   | 823fd855cf | ||
|   | f5ee225362 | ||
|   | ff1ea4b1c9 | ||
|   | 779b5afa51 | ||
|   | 6d870f6ae4 | ||
|   | d3926cbca9 | ||
|   | a308804679 | ||
|   | a4e4da705a | ||
|   | 7a494ec027 | ||
|   | d53ebb101a | ||
|   | f3168d22a6 | ||
|   | be06101e9a | ||
|   | 6e4178981a | ||
|   | b85ea59cda | ||
|   | bbd68626cc | ||
|   | 8490173879 | ||
|   | baed9518c2 | ||
|   | 27d0d9f2b3 | ||
|   | 382282b931 | ||
|   | 23d233857e | ||
|   | 9620bd0f22 | ||
|   | ecfe56ca63 | ||
|   | eabb02d3da | ||
|   | da3953a388 | ||
|   | 2d26dbc96f | ||
|   | 7073471302 | ||
|   | 81f0e7de9e | ||
|   | 33e05f5912 | ||
|   | c1d3e304cb | ||
|   | 1b169655ac | ||
|   | 67393e09c3 | ||
|   | 1ec8d2c531 | ||
|   | a111bfb90a | ||
|   | 7dd326f090 | ||
|   | 24a26e025b | ||
|   | 1eb7ba0506 | ||
|   | d17d99bd6d | ||
|   | fd50b9a45e | ||
|   | a1534dab02 | ||
|   | 7484458b7c | ||
|   | 5ca039c1db | ||
|   | 2294ae0c46 | ||
|   | 4d2b2a12ea | ||
|   | c6d57059ff | ||
|   | 5f13cf767e | ||
|   | 93425b0500 | ||
|   | a87ab6d0fc | ||
|   | 1c117c469a | ||
|   | 8003f8b803 | ||
|   | 7df93458d7 | ||
|   | 753618a19f | ||
|   | e355756758 | ||
|   | 62a3b9e6a3 | ||
|   | dc79393b27 | ||
|   | c334aa2a4c | ||
|   | 9f61a4f5fd | ||
|   | 15d0050994 | ||
|   | 1846f337d8 | ||
|   | a9e63039ce | ||
|   | 7edd5f27d1 | ||
|   | 9b47195974 | ||
|   | 4ef8041be0 | ||
|   | f0a7395b30 | ||
|   | c1a6effea0 | ||
|   | f78efc46e7 | ||
|   | 42ae052da7 | ||
|   | fab390826e | ||
|   | 2a9923628b | ||
|   | 291aa0b053 | ||
|   | 83eb75ad7a | ||
|   | bb215966e5 | ||
|   | 545d49c70d | ||
|   | ace44af815 | ||
|   | 699e97559d | ||
|   | 4aecf4c973 | ||
|   | b092c5f37d | ||
|   | aca8aec94b | ||
|   | 9cfb51c106 | ||
|   | e2352f5126 | ||
|   | 40e624444c | ||
|   | 3cf67b1236 | ||
|   | 5dedb97fcc | ||
|   | 4590094605 | ||
|   | 15e7625c80 | ||
|   | cdd2803498 | ||
|   | 43fb2b38b1 | ||
|   | 95224bd006 | ||
|   | 446183adee | ||
|   | 345a8fe748 | ||
|   | d8593c5b4a | ||
|   | f89d721c12 | ||
|   | af34b7c25e | ||
|   | b108aa1ace | ||
|   | 5dbf09c008 | ||
|   | 680dc18c6b | ||
|   | 73413ac6c0 | ||
|   | f61c8e5e1d | ||
|   | 36713db990 | ||
|   | 6bb7d4002f | ||
|   | aa28d487d3 | ||
|   | a7d974481c | ||
|   | 3730314dd5 | ||
|   | 6b0c8c9fe0 | ||
|   | 28a56d24ad | ||
|   | 5e6629e1a7 | ||
|   | a00b967df0 | ||
|   | 193e4ae31e | ||
|   | 409a27c3b8 | ||
|   | ba97e8da7a | ||
|   | c47e672eea | ||
|   | 43a19739ab | ||
|   | 36f9147b21 | ||
|   | 8647922df9 | ||
|   | df3068d9ca | ||
|   | 036e67049b | ||
|   | f02033acb7 | ||
|   | 91d73d65c3 | ||
|   | 81c4c23016 | ||
|   | fef2bac8ab | ||
|   | c59c5eb893 | ||
|   | a977c1388a | ||
|   | 0f799ae313 | ||
|   | 23c3f3fdea | ||
|   | 82c7090e9e | ||
|   | 0fdfebdb67 | ||
|   | 208c551787 | ||
|   | b10606e884 | ||
|   | f4a64f77f2 | ||
|   | e92477a752 | ||
|   | 37e0a73c8f | ||
|   | 4f76e05058 | ||
|   | 3134222d27 | ||
|   | a9ed128dce | ||
|   | c264cc4131 | ||
|   | a7943ff934 | ||
|   | c353914dd0 | ||
|   | 91319e3963 | ||
|   | dc4ff941bd | ||
|   | b597d5faf0 | ||
|   | f6da36ad3a | ||
|   | 5f4e2749a2 | ||
|   | 69b1fb699f | ||
|   | 259f90bbf6 | ||
|   | 8665045326 | ||
|   | a7bb8ee639 | ||
|   | 8f732e4f45 | ||
|   | 95a31b0c31 | ||
|   | 36b9f45368 | ||
|   | 46575804cc | ||
|   | 86a00b6872 | ||
|   | 23d6d13d80 | ||
|   | 09addfc87c | ||
|   | a2f27a9409 | ||
|   | 412003efbf | ||
|   | 582b3aacf4 | ||
|   | 1af0b54c1e | ||
|   | 74ba2e6634 | ||
|   | 78608a5080 | ||
|   | 7a86637f8d | ||
|   | c2961f2152 | ||
|   | 6845c6f958 | ||
|   | 794a056819 | ||
|   | 69ad75cf48 | ||
|   | 3db52155dd | ||
|   | 38805ae662 | 
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						| @@ -80,3 +80,4 @@ tests/run-test.sh | ||||
| *~ | ||||
| *.patch | ||||
| *.sw? | ||||
| .vscode | ||||
|   | ||||
							
								
								
									
										88
									
								
								.gitlab-ci.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,88 @@ | ||||
| stages: | ||||
|  - review | ||||
|  - source_check | ||||
|  - build | ||||
|  - test | ||||
|  | ||||
| variables: | ||||
|     JS_LOG: "js-report.txt" | ||||
|     POT_LOG: "pot-update.txt" | ||||
|  | ||||
| .only_default: &only_default | ||||
|     only: | ||||
|         - branches | ||||
|         - tags | ||||
|         - merge_requests | ||||
|  | ||||
| check_commit_log: | ||||
|     image: registry.gitlab.gnome.org/gnome/mutter/master:v2 | ||||
|     stage: review | ||||
|     variables: | ||||
|         GIT_DEPTH: "100" | ||||
|     script: | ||||
|         - ./.gitlab-ci/check-commit-log.sh | ||||
|     only: | ||||
|         - merge_requests | ||||
|  | ||||
| js_check: | ||||
|     image: registry.gitlab.gnome.org/gnome/gnome-shell/extension-ci:v1 | ||||
|     stage: source_check | ||||
|     script: | ||||
|         - find js -name '*.js' -exec js60 -c -s '{}' ';' 2>&1 | tee $JS_LOG | ||||
|         - (! grep -q . $JS_LOG) | ||||
|     <<: *only_default | ||||
|     only: | ||||
|         changes: | ||||
|             - js/**/* | ||||
|     artifacts: | ||||
|         paths: | ||||
|             - ${JS_LOG} | ||||
|         when: on_failure | ||||
|  | ||||
| build: | ||||
|     image: registry.gitlab.gnome.org/gnome/mutter/master:v2 | ||||
|     stage: build | ||||
|     before_script: | ||||
|         - .gitlab-ci/checkout-mutter.sh | ||||
|         - meson mutter mutter/build --prefix=/usr -Dtests=false | ||||
|         - ninja -C mutter/build install | ||||
|     script: | ||||
|         - meson . build -Dbuiltype=debugoptimized | ||||
|         - ninja -C build | ||||
|         - ninja -C build install | ||||
|     <<: *only_default | ||||
|     artifacts: | ||||
|         expire_in: 1 day | ||||
|         paths: | ||||
|             - mutter | ||||
|             - build | ||||
|  | ||||
| test: | ||||
|     image: registry.gitlab.gnome.org/gnome/mutter/master:v2 | ||||
|     stage: test | ||||
|     before_script: | ||||
|         - ninja -C mutter/build install | ||||
|     script: | ||||
|         - xvfb-run meson test -C build --no-rebuild | ||||
|     <<: *only_default | ||||
|     artifacts: | ||||
|         expire_in: 1 day | ||||
|         paths: | ||||
|             - build/meson-logs/testlog.txt | ||||
|         when: on_failure | ||||
|  | ||||
| test-pot: | ||||
|     image: registry.gitlab.gnome.org/gnome/mutter/master:v2 | ||||
|     stage: test | ||||
|     before_script: | ||||
|         - ninja -C mutter/build install | ||||
|     script: | ||||
|         # Check that pot files are generated correctly: | ||||
|         # https://savannah.gnu.org/bugs/?50920#comment5 | ||||
|         - ninja -C build gnome-shell-pot 2>&1 | awk ' | ||||
|             BEGIN { start=0; } | ||||
|             start==1 { print $0; } | ||||
|             /gnome-shell-pot/ { start=1; } | ||||
|           ' | tee $POT_LOG | ||||
|         - (! grep -q . $POT_LOG) | ||||
|     <<: *only_default | ||||
							
								
								
									
										18
									
								
								.gitlab-ci/Dockerfile.extension-ci
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,18 @@ | ||||
| FROM registry.fedoraproject.org/fedora:latest | ||||
|  | ||||
| RUN dnf -y update && dnf -y upgrade && \ | ||||
|     dnf install -y 'dnf-command(copr)' && \ | ||||
|  | ||||
|     # For syntax checks with `find . -name '*.js' -exec js60 -c -s '{}' ';'` | ||||
|     dnf install -y findutils mozjs60-devel && \ | ||||
|  | ||||
|     # For static analysis with eslint | ||||
|     dnf install -y nodejs && \ | ||||
|     npm install -g eslint && \ | ||||
|  | ||||
|     # Shameless plug for my own tooling; useful for generating zip | ||||
|     dnf copr enable -y fmuellner/gnome-shell-ci && \ | ||||
|     dnf install -y gnome-extensions-tool meson && \ | ||||
|  | ||||
|     dnf clean all && \ | ||||
|     rm -rf /var/cache/dnf | ||||
							
								
								
									
										31
									
								
								.gitlab-ci/check-commit-log.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						| @@ -0,0 +1,31 @@ | ||||
| #!/usr/bin/env bash | ||||
|  | ||||
| if [ -z "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then | ||||
|   echo Cannot review non-merge request | ||||
|   exit 1 | ||||
| fi | ||||
|  | ||||
| git fetch $CI_MERGE_REQUEST_PROJECT_URL.git $CI_MERGE_REQUEST_TARGET_BRANCH_NAME | ||||
|  | ||||
| branch_point=$(git merge-base HEAD FETCH_HEAD) | ||||
|  | ||||
| commits=$(git log --format='format:%H' $branch_point..$CI_COMMIT_SHA) | ||||
|  | ||||
| if [ -z "$commits" ]; then | ||||
|   echo Commit range empty | ||||
|   exit 1 | ||||
| fi | ||||
|  | ||||
| function commit_message_has_url() { | ||||
|   commit=$1 | ||||
|   commit_message=$(git show -s --format='format:%b' $commit) | ||||
|   echo "$commit_message" | grep -qe "\($CI_MERGE_REQUEST_PROJECT_URL/\(issues\|merge_requests\)/[0-9]\+\|https://bugzilla.gnome.org/show_bug.cgi?id=[0-9]\+\)" | ||||
|   return $? | ||||
| } | ||||
|  | ||||
| for commit in $commits; do | ||||
|   if ! commit_message_has_url $commit; then | ||||
|     echo "Missing merge request or issue URL on commit $(echo $commit | cut -c -8)" | ||||
|     exit 1 | ||||
|   fi | ||||
| done | ||||
							
								
								
									
										35
									
								
								.gitlab-ci/checkout-mutter.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						| @@ -0,0 +1,35 @@ | ||||
| #!/usr/bin/bash | ||||
|  | ||||
| shell_branch=$(git describe --contains --all HEAD) | ||||
| mutter_target= | ||||
|  | ||||
| git clone https://gitlab.gnome.org/GNOME/mutter.git | ||||
|  | ||||
| if [ $? -ne 0 ]; then | ||||
|   echo Checkout failed | ||||
|   exit 1 | ||||
| fi | ||||
|  | ||||
| cd mutter | ||||
|  | ||||
| if [ "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then | ||||
|   merge_request_remote=${CI_MERGE_REQUEST_SOURCE_PROJECT_URL//gnome-shell/mutter} | ||||
|   merge_request_branch=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME | ||||
|  | ||||
|   echo Looking for $merge_request_branch on remote ... | ||||
|   if git fetch -q $merge_request_remote $merge_request_branch 2>/dev/null; then | ||||
|     mutter_target=FETCH_HEAD | ||||
|   else | ||||
|     mutter_target=origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME | ||||
|     echo Using $mutter_target instead | ||||
|   fi | ||||
| fi | ||||
|  | ||||
| if [ -z "$mutter_target" ]; then | ||||
|   mutter_target=$(git branch -r -l origin/$shell_branch) | ||||
|   mutter_target=${mutter_target:-$(git branch -r -l ${shell_branch#remotes/})} | ||||
|   mutter_target=${mutter_target:-origin/master} | ||||
|   echo Using $mutter_target instead | ||||
| fi | ||||
|  | ||||
| git checkout -q $mutter_target | ||||
							
								
								
									
										31
									
								
								.project
									
									
									
									
									
								
							
							
						
						| @@ -1,31 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <projectDescription> | ||||
| 	<name>gnome-shell</name> | ||||
| 	<comment></comment> | ||||
| 	<projects> | ||||
| 	</projects> | ||||
| 	<buildSpec> | ||||
| 		<buildCommand> | ||||
| 			<name>org.eclipse.wst.jsdt.core.javascriptValidator</name> | ||||
| 			<arguments> | ||||
| 			</arguments> | ||||
| 		</buildCommand> | ||||
| 		<buildCommand> | ||||
| 			<name>org.eclipse.linuxtools.cdt.autotools.genmakebuilder</name> | ||||
| 			<arguments> | ||||
| 			</arguments> | ||||
| 		</buildCommand> | ||||
| 		<buildCommand> | ||||
| 			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name> | ||||
| 			<arguments> | ||||
| 			</arguments> | ||||
| 		</buildCommand> | ||||
| 	</buildSpec> | ||||
| 	<natures> | ||||
| 		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature> | ||||
| 		<nature>org.eclipse.linuxtools.cdt.autotools.autotoolsNature</nature> | ||||
| 		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature> | ||||
| 		<nature>org.eclipse.cdt.core.cnature</nature> | ||||
| 		<nature>org.eclipse.wst.jsdt.core.jsNature</nature> | ||||
| 	</natures> | ||||
| </projectDescription> | ||||
| @@ -1,148 +0,0 @@ | ||||
| #Fri Nov 28 14:33:30 EST 2008 | ||||
| eclipse.preferences.version=1 | ||||
| org.eclipse.cdt.core.formatter.alignment_for_arguments_in_method_invocation=16 | ||||
| org.eclipse.cdt.core.formatter.alignment_for_base_clause_in_type_declaration=80 | ||||
| org.eclipse.cdt.core.formatter.alignment_for_compact_if=0 | ||||
| org.eclipse.cdt.core.formatter.alignment_for_conditional_expression=80 | ||||
| org.eclipse.cdt.core.formatter.alignment_for_declarator_list=16 | ||||
| org.eclipse.cdt.core.formatter.alignment_for_enumerator_list=48 | ||||
| org.eclipse.cdt.core.formatter.alignment_for_expression_list=0 | ||||
| org.eclipse.cdt.core.formatter.alignment_for_expressions_in_array_initializer=16 | ||||
| org.eclipse.cdt.core.formatter.alignment_for_parameters_in_method_declaration=16 | ||||
| org.eclipse.cdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 | ||||
| org.eclipse.cdt.core.formatter.brace_position_for_array_initializer=next_line_shifted | ||||
| org.eclipse.cdt.core.formatter.brace_position_for_block=next_line_shifted | ||||
| org.eclipse.cdt.core.formatter.brace_position_for_block_in_case=next_line_shifted | ||||
| org.eclipse.cdt.core.formatter.brace_position_for_method_declaration=next_line | ||||
| org.eclipse.cdt.core.formatter.brace_position_for_namespace_declaration=next_line | ||||
| org.eclipse.cdt.core.formatter.brace_position_for_switch=next_line_shifted | ||||
| org.eclipse.cdt.core.formatter.brace_position_for_type_declaration=next_line | ||||
| org.eclipse.cdt.core.formatter.compact_else_if=true | ||||
| org.eclipse.cdt.core.formatter.continuation_indentation=2 | ||||
| org.eclipse.cdt.core.formatter.continuation_indentation_for_array_initializer=2 | ||||
| org.eclipse.cdt.core.formatter.format_guardian_clause_on_one_line=false | ||||
| org.eclipse.cdt.core.formatter.indent_access_specifier_compare_to_type_header=false | ||||
| org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_access_specifier=true | ||||
| org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_namespace_header=true | ||||
| org.eclipse.cdt.core.formatter.indent_breaks_compare_to_cases=true | ||||
| org.eclipse.cdt.core.formatter.indent_declaration_compare_to_template_header=true | ||||
| org.eclipse.cdt.core.formatter.indent_empty_lines=false | ||||
| org.eclipse.cdt.core.formatter.indent_statements_compare_to_block=true | ||||
| org.eclipse.cdt.core.formatter.indent_statements_compare_to_body=true | ||||
| org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_cases=true | ||||
| org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_switch=false | ||||
| org.eclipse.cdt.core.formatter.indentation.size=8 | ||||
| org.eclipse.cdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_new_line_after_template_declaration=insert | ||||
| org.eclipse.cdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert | ||||
| org.eclipse.cdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_new_line_before_else_in_if_statement=insert | ||||
| org.eclipse.cdt.core.formatter.insert_new_line_before_identifier_in_function_declaration=insert | ||||
| org.eclipse.cdt.core.formatter.insert_new_line_before_while_in_do_statement=insert | ||||
| org.eclipse.cdt.core.formatter.insert_new_line_in_empty_block=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_assignment_operator=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_binary_operator=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_arguments=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_parameters=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_closing_brace_in_block=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_closing_paren_in_cast=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_colon_in_base_clause=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_colon_in_case=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_colon_in_conditional=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_comma_in_array_initializer=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_comma_in_base_types=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_comma_in_declarator_list=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_comma_in_expression_list=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_arguments=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_parameters=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_opening_angle_bracket_in_template_arguments=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_opening_angle_bracket_in_template_parameters=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_opening_bracket=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_postfix_operator=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_prefix_operator=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_question_in_conditional=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_semicolon_in_for=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_after_unary_operator=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_assignment_operator=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_binary_operator=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_arguments=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_parameters=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_closing_bracket=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_colon_in_base_clause=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_colon_in_case=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_colon_in_conditional=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_colon_in_default=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_comma_in_base_types=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_comma_in_declarator_list=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_comma_in_expression_list=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_comma_in_template_arguments=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_comma_in_template_parameters=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_opening_angle_bracket_in_template_arguments=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_opening_angle_bracket_in_template_parameters=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_block=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_namespace_declaration=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_switch=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_opening_bracket=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_catch=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_for=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_if=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_switch=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_while=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_postfix_operator=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_prefix_operator=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_question_in_conditional=insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_semicolon=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_semicolon_in_for=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_before_unary_operator=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_between_empty_brackets=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert | ||||
| org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert | ||||
| org.eclipse.cdt.core.formatter.keep_else_statement_on_same_line=false | ||||
| org.eclipse.cdt.core.formatter.keep_empty_array_initializer_on_one_line=false | ||||
| org.eclipse.cdt.core.formatter.keep_imple_if_on_one_line=false | ||||
| org.eclipse.cdt.core.formatter.keep_then_statement_on_same_line=false | ||||
| org.eclipse.cdt.core.formatter.lineSplit=80 | ||||
| org.eclipse.cdt.core.formatter.number_of_empty_lines_to_preserve=1 | ||||
| org.eclipse.cdt.core.formatter.put_empty_statement_on_new_line=true | ||||
| org.eclipse.cdt.core.formatter.tabulation.char=space | ||||
| org.eclipse.cdt.core.formatter.tabulation.size=2 | ||||
| org.eclipse.cdt.core.formatter.use_tabs_only_for_leading_indentations=false | ||||
| @@ -1,4 +0,0 @@ | ||||
| #Fri Nov 28 14:33:30 EST 2008 | ||||
| eclipse.preferences.version=1 | ||||
| formatter_profile=org.eclipse.cdt.ui.default.gnu_profile | ||||
| formatter_settings_version=1 | ||||
| @@ -1,315 +0,0 @@ | ||||
| #Fri Nov 28 14:43:43 EST 2008 | ||||
| eclipse.preferences.version=1 | ||||
| org.eclipse.wst.jsdt.core.codeComplete.argumentPrefixes= | ||||
| org.eclipse.wst.jsdt.core.codeComplete.argumentSuffixes= | ||||
| org.eclipse.wst.jsdt.core.codeComplete.fieldPrefixes= | ||||
| org.eclipse.wst.jsdt.core.codeComplete.fieldSuffixes= | ||||
| org.eclipse.wst.jsdt.core.codeComplete.localPrefixes= | ||||
| org.eclipse.wst.jsdt.core.codeComplete.localSuffixes= | ||||
| org.eclipse.wst.jsdt.core.codeComplete.staticFieldPrefixes= | ||||
| org.eclipse.wst.jsdt.core.codeComplete.staticFieldSuffixes= | ||||
| org.eclipse.wst.jsdt.core.compiler.codegen.inlineJsrBytecode=disabled | ||||
| org.eclipse.wst.jsdt.core.compiler.codegen.targetPlatform=1.2 | ||||
| org.eclipse.wst.jsdt.core.compiler.codegen.unusedLocal=preserve | ||||
| org.eclipse.wst.jsdt.core.compiler.compliance=1.4 | ||||
| org.eclipse.wst.jsdt.core.compiler.debug.lineNumber=generate | ||||
| org.eclipse.wst.jsdt.core.compiler.debug.localVariable=generate | ||||
| org.eclipse.wst.jsdt.core.compiler.debug.sourceFile=generate | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.assertIdentifier=warning | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.deprecation=warning | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.deprecationInDeprecatedCode=disabled | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.discouragedReference=warning | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.emptyStatement=ignore | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.enumIdentifier=warning | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.fallthroughCase=ignore | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.fieldHiding=ignore | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.forbiddenReference=ignore | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.hiddenCatchBlock=warning | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.indirectStaticAccess=ignore | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.localVariableHiding=ignore | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.looseVarDecleration=warning | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.missingDeprecatedAnnotation=ignore | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.noEffectAssignment=warning | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.nonExternalizedStringLiteral=ignore | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.nullReference=ignore | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.optionalSemicolon=warning | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.parameterAssignment=ignore | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.potentialNullReference=ignore | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.redundantNullCheck=ignore | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.undefinedField=warning | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.undocumentedEmptyBlock=ignore | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.unnecessaryElse=ignore | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.unresolvedFieldReference=ignore | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.unresolvedMethodReference=ignore | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.unresolvedTypeReference=ignore | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.unusedLabel=warning | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.unusedLocal=warning | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.unusedParameter=ignore | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled | ||||
| org.eclipse.wst.jsdt.core.compiler.problem.unusedPrivateMember=warning | ||||
| org.eclipse.wst.jsdt.core.compiler.source=1.3 | ||||
| org.eclipse.wst.jsdt.core.formatter.align_type_members_on_columns=false | ||||
| org.eclipse.wst.jsdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 | ||||
| org.eclipse.wst.jsdt.core.formatter.alignment_for_arguments_in_enum_constant=16 | ||||
| org.eclipse.wst.jsdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 | ||||
| org.eclipse.wst.jsdt.core.formatter.alignment_for_arguments_in_method_invocation=16 | ||||
| org.eclipse.wst.jsdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 | ||||
| org.eclipse.wst.jsdt.core.formatter.alignment_for_assignment=0 | ||||
| org.eclipse.wst.jsdt.core.formatter.alignment_for_binary_expression=16 | ||||
| org.eclipse.wst.jsdt.core.formatter.alignment_for_compact_if=16 | ||||
| org.eclipse.wst.jsdt.core.formatter.alignment_for_conditional_expression=80 | ||||
| org.eclipse.wst.jsdt.core.formatter.alignment_for_enum_constants=0 | ||||
| org.eclipse.wst.jsdt.core.formatter.alignment_for_expressions_in_array_initializer=16 | ||||
| org.eclipse.wst.jsdt.core.formatter.alignment_for_multiple_fields=16 | ||||
| org.eclipse.wst.jsdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 | ||||
| org.eclipse.wst.jsdt.core.formatter.alignment_for_parameters_in_method_declaration=16 | ||||
| org.eclipse.wst.jsdt.core.formatter.alignment_for_selector_in_method_invocation=16 | ||||
| org.eclipse.wst.jsdt.core.formatter.alignment_for_superclass_in_type_declaration=16 | ||||
| org.eclipse.wst.jsdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 | ||||
| org.eclipse.wst.jsdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 | ||||
| org.eclipse.wst.jsdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 | ||||
| org.eclipse.wst.jsdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 | ||||
| org.eclipse.wst.jsdt.core.formatter.blank_lines_after_imports=1 | ||||
| org.eclipse.wst.jsdt.core.formatter.blank_lines_after_package=1 | ||||
| org.eclipse.wst.jsdt.core.formatter.blank_lines_before_field=0 | ||||
| org.eclipse.wst.jsdt.core.formatter.blank_lines_before_first_class_body_declaration=0 | ||||
| org.eclipse.wst.jsdt.core.formatter.blank_lines_before_imports=1 | ||||
| org.eclipse.wst.jsdt.core.formatter.blank_lines_before_member_type=1 | ||||
| org.eclipse.wst.jsdt.core.formatter.blank_lines_before_method=1 | ||||
| org.eclipse.wst.jsdt.core.formatter.blank_lines_before_new_chunk=1 | ||||
| org.eclipse.wst.jsdt.core.formatter.blank_lines_before_package=0 | ||||
| org.eclipse.wst.jsdt.core.formatter.blank_lines_between_import_groups=1 | ||||
| org.eclipse.wst.jsdt.core.formatter.blank_lines_between_type_declarations=0 | ||||
| org.eclipse.wst.jsdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line | ||||
| org.eclipse.wst.jsdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line | ||||
| org.eclipse.wst.jsdt.core.formatter.brace_position_for_array_initializer=end_of_line | ||||
| org.eclipse.wst.jsdt.core.formatter.brace_position_for_block=end_of_line | ||||
| org.eclipse.wst.jsdt.core.formatter.brace_position_for_block_in_case=end_of_line | ||||
| org.eclipse.wst.jsdt.core.formatter.brace_position_for_constructor_declaration=end_of_line | ||||
| org.eclipse.wst.jsdt.core.formatter.brace_position_for_enum_constant=end_of_line | ||||
| org.eclipse.wst.jsdt.core.formatter.brace_position_for_enum_declaration=end_of_line | ||||
| org.eclipse.wst.jsdt.core.formatter.brace_position_for_method_declaration=end_of_line | ||||
| org.eclipse.wst.jsdt.core.formatter.brace_position_for_objlit_initializer=end_of_line | ||||
| org.eclipse.wst.jsdt.core.formatter.brace_position_for_switch=end_of_line | ||||
| org.eclipse.wst.jsdt.core.formatter.brace_position_for_type_declaration=end_of_line | ||||
| org.eclipse.wst.jsdt.core.formatter.comment.clear_blank_lines_in_block_comment=false | ||||
| org.eclipse.wst.jsdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false | ||||
| org.eclipse.wst.jsdt.core.formatter.comment.format_block_comments=true | ||||
| org.eclipse.wst.jsdt.core.formatter.comment.format_header=false | ||||
| org.eclipse.wst.jsdt.core.formatter.comment.format_html=true | ||||
| org.eclipse.wst.jsdt.core.formatter.comment.format_javadoc_comments=true | ||||
| org.eclipse.wst.jsdt.core.formatter.comment.format_line_comments=true | ||||
| org.eclipse.wst.jsdt.core.formatter.comment.format_source_code=true | ||||
| org.eclipse.wst.jsdt.core.formatter.comment.indent_parameter_description=true | ||||
| org.eclipse.wst.jsdt.core.formatter.comment.indent_root_tags=true | ||||
| org.eclipse.wst.jsdt.core.formatter.comment.insert_new_line_before_root_tags=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.comment.insert_new_line_for_parameter=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.comment.line_length=80 | ||||
| org.eclipse.wst.jsdt.core.formatter.compact_else_if=true | ||||
| org.eclipse.wst.jsdt.core.formatter.continuation_indentation=2 | ||||
| org.eclipse.wst.jsdt.core.formatter.continuation_indentation_for_array_initializer=2 | ||||
| org.eclipse.wst.jsdt.core.formatter.continuation_indentation_for_objlit_initializer=1 | ||||
| org.eclipse.wst.jsdt.core.formatter.format_guardian_clause_on_one_line=false | ||||
| org.eclipse.wst.jsdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true | ||||
| org.eclipse.wst.jsdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true | ||||
| org.eclipse.wst.jsdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true | ||||
| org.eclipse.wst.jsdt.core.formatter.indent_body_declarations_compare_to_type_header=true | ||||
| org.eclipse.wst.jsdt.core.formatter.indent_breaks_compare_to_cases=true | ||||
| org.eclipse.wst.jsdt.core.formatter.indent_empty_lines=false | ||||
| org.eclipse.wst.jsdt.core.formatter.indent_statements_compare_to_block=true | ||||
| org.eclipse.wst.jsdt.core.formatter.indent_statements_compare_to_body=true | ||||
| org.eclipse.wst.jsdt.core.formatter.indent_switchstatements_compare_to_cases=true | ||||
| org.eclipse.wst.jsdt.core.formatter.indent_switchstatements_compare_to_switch=false | ||||
| org.eclipse.wst.jsdt.core.formatter.indentation.size=4 | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_new_line_after_annotation=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_new_line_after_comma_in_objlit_initializer=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_new_line_after_opening_brace_in_objlit_initializer=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_new_line_before_closing_brace_in_objlit_initializer=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_block=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_enum_constant=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_method_body=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_type_declaration=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_and_in_type_parameter=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_assignment_operator=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_at_in_annotation=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_binary_operator=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_closing_brace_in_block=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_closing_paren_in_cast=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_colon_in_assert=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_colon_in_case=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_colon_in_conditional=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_colon_in_for=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_annotation=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_array_initializer=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_for_increments=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_for_inits=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_type_arguments=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_type_parameters=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_ellipsis=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_postfix_operator=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_prefix_operator=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_question_in_conditional=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_question_in_wildcard=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_semicolon_in_for=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_after_unary_operator=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_and_in_type_parameter=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_assignment_operator=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_binary_operator=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_colon_in_assert=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_colon_in_case=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_colon_in_conditional=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_colon_in_default=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_colon_in_for=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_annotation=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_ellipsis=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_block=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_switch=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_catch=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_for=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_if=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_switch=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_while=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_postfix_operator=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_prefix_operator=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_question_in_conditional=insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_question_in_wildcard=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_semicolon=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_semicolon_in_for=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_before_unary_operator=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert | ||||
| org.eclipse.wst.jsdt.core.formatter.keep_else_statement_on_same_line=false | ||||
| org.eclipse.wst.jsdt.core.formatter.keep_empty_array_initializer_on_one_line=false | ||||
| org.eclipse.wst.jsdt.core.formatter.keep_empty_objlit_initializer_on_one_line=false | ||||
| org.eclipse.wst.jsdt.core.formatter.keep_imple_if_on_one_line=false | ||||
| org.eclipse.wst.jsdt.core.formatter.keep_then_statement_on_same_line=false | ||||
| org.eclipse.wst.jsdt.core.formatter.lineSplit=80 | ||||
| org.eclipse.wst.jsdt.core.formatter.never_indent_block_comments_on_first_column=false | ||||
| org.eclipse.wst.jsdt.core.formatter.never_indent_line_comments_on_first_column=false | ||||
| org.eclipse.wst.jsdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 | ||||
| org.eclipse.wst.jsdt.core.formatter.number_of_empty_lines_to_preserve=1 | ||||
| org.eclipse.wst.jsdt.core.formatter.put_empty_statement_on_new_line=true | ||||
| org.eclipse.wst.jsdt.core.formatter.tabulation.char=space | ||||
| org.eclipse.wst.jsdt.core.formatter.tabulation.size=4 | ||||
| org.eclipse.wst.jsdt.core.formatter.use_tabs_only_for_leading_indentations=false | ||||
| org.eclipse.wst.jsdt.core.formatter.wrap_before_binary_operator=true | ||||
| @@ -1,10 +0,0 @@ | ||||
| #Fri Nov 28 14:39:12 EST 2008 | ||||
| eclipse.preferences.version=1 | ||||
| formatter_profile=_gjs | ||||
| formatter_settings_version=11 | ||||
| org.eclipse.wst.jsdt.ui.exception.name=e | ||||
| org.eclipse.wst.jsdt.ui.gettersetter.use.is=true | ||||
| org.eclipse.wst.jsdt.ui.javadoc=false | ||||
| org.eclipse.wst.jsdt.ui.keywordthis=false | ||||
| org.eclipse.wst.jsdt.ui.overrideannotation=true | ||||
| org.eclipse.wst.jsdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates/> | ||||
| @@ -1 +0,0 @@ | ||||
| org.eclipse.wst.jsdt.launching.baseBrowserLibrary | ||||
| @@ -1 +0,0 @@ | ||||
| Window | ||||
							
								
								
									
										10
									
								
								HACKING.md
									
									
									
									
									
								
							
							
						
						| @@ -80,9 +80,7 @@ e.g. `imports.ui.popupMenu`. | ||||
| Each import block should be sorted alphabetically. Don't import modules you | ||||
| don't use. | ||||
| ```javascript | ||||
|     const GLib = imports.gi.GLib; | ||||
|     const Gio = imports.gi.Gio; | ||||
|     const St = imports.gi.St; | ||||
|     const { GLib, Gio, St } = imports.gi; | ||||
|  | ||||
|     const Main = imports.ui.main; | ||||
|     const Params = imports.misc.params; | ||||
| @@ -158,15 +156,15 @@ you to inherit from a type to use it, you can do so: | ||||
|     var MyClutterActor = GObject.registerClass( | ||||
|     class MyClutterActor extends Clutter.Actor { | ||||
|  | ||||
|         vfunc_get_preferred_width(actor, forHeight) { | ||||
|         vfunc_get_preferred_width(forHeight) { | ||||
|              return [100, 100]; | ||||
|         } | ||||
|  | ||||
|         vfunc_get_preferred_height(actor, forWidth) { | ||||
|         vfunc_get_preferred_height(forWidth) { | ||||
|              return [100, 100]; | ||||
|         } | ||||
|  | ||||
|         vfunc_paint(actor) { | ||||
|         vfunc_paint() { | ||||
|              let alloc = this.get_allocation_box(); | ||||
|              Cogl.set_source_color4ub(255, 0, 0, 255); | ||||
|              Cogl.rectangle(alloc.x1, alloc.y1, | ||||
|   | ||||
							
								
								
									
										172
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						| @@ -1,3 +1,175 @@ | ||||
| 3.33.2 | ||||
| ====== | ||||
| * Fix keeping actors visible in scrollviews [Marco; #1061] | ||||
| * Move some chrome above popup windows [Jonas D.; !358] | ||||
| * Include 'sandboxed-app-id' in winodw introspection info [Florian; #1289] | ||||
| * Port to libecal-2.0 [Milan; !501] | ||||
| * Support TCRYPT in mount password dialog [segfault; !126] | ||||
| * Misc. bug fixes and cleanups [Florian, Marco, Veerasamy; !517, #745, !499, | ||||
|   !510, !515, !546, !549] | ||||
|  | ||||
| Contributors: | ||||
|   Cosimo Cecchi, Milan Crha, Jonas Dreßler, Florian Müllner, segfault, | ||||
|   Veerasamy Sevagen, Marco Trevisan (Treviño) | ||||
|  | ||||
| Translators: | ||||
|   Daniel Mustieles [es] | ||||
|  | ||||
| 3.33.1 | ||||
| ====== | ||||
| * Refine the app menu [Florian; #968] | ||||
| * Refine window preview style [Feichtmeier; !461] | ||||
| * Only emit ::style-changed on actual changes [Carlos; #1153] | ||||
| * Disable emoji on-screen keyboard support on X11 [Florian; #1172] | ||||
| * Fix tablet button mapping overlay [Carlos; #1220] | ||||
| * Don't crash for world clock locations with no timezone [Florian; #1062] | ||||
| * Don't leak old on-screen keyboard layout groups [Carlos; mutter#556] | ||||
| * Fix ellipsization in dialog subtitles/bodies [Marco; !531] | ||||
| * Fix glitch of fullscreen window in workspace switch animation [Jonas D.; !322] | ||||
| * Fix distortion of some image contents [Florian; !525] | ||||
| * Allow dragging unfocused tiled/maximized windows from top bar [Dylan; #679290] | ||||
| * Handle network interface name changes [Fabrice; !534] | ||||
| * Avoid unnecessary style changes when computing :first/:last-child | ||||
|   [Florian; !529] | ||||
| * Misc. bug fixes and cleanups [Florian, Marco, Robert, Georges, Carlos, Simon, | ||||
|   Jonas D.; !487, !441, !502, !503, !504, !506, #822, !551, !512, !509, !511, | ||||
|   #1054, !524, #1065, !331, !540] | ||||
|  | ||||
| Contributors: | ||||
|   Fabrice Bellet, Jonas Dreßler, Feichtmeier, Carlos Garnacho, Robert Mader, | ||||
|   Dylan McCall, Simon McVittie, Florian Müllner, Georges Basile Stavracas Neto, | ||||
|   Marco Trevisan (Treviño) | ||||
|  | ||||
| Translators: | ||||
|   Daniel Mustieles [es], Kukuh Syafaat [id], Fabio Tomat [fur], | ||||
|   Carmen Bianca BAKKER [eo], Dingzhong Chen [zh_CN], Tim Sabsch [de] | ||||
|  | ||||
| 3.32.1 | ||||
| ====== | ||||
| * Fix avatar scaling on login screen [Florian; #1024] | ||||
| * Fix distortion of desktop zoom [Florian; #646] | ||||
| * Fix mouse cursor visibility when using desktop zoom [Florian, Marco; #1020] | ||||
| * Fix screen dimming after wake-up on lock screen [Xiaoguang; #900] | ||||
| * Fix Alt+Esc switcher [Florian; #1064] | ||||
| * Respect struts for popover placement [Andrea; #1102] | ||||
| * Fix app icons updates after theme changes [Florian; #1117] | ||||
| * Fix desktop zoom after resolution changes [Marco; #1120] | ||||
| * Implement stick-to-finger workspace switch overview gestures [Florian; #516] | ||||
| * Make World Clocks offsets relative to local time [Florian; #1157] | ||||
| * Fix top app icon disappearing from dash [Florian; #1053] | ||||
| * Update switch style to match new Adwaita [Jakub; !496] | ||||
| * Ensure CSS units are pixel-aligned when scaling is used [Carlos; #91] | ||||
| * Misc. bug fixes and cleanups [Florian, Jakub, Robert, Alex, Carlos, Phil, | ||||
|   Marco, Benjamin, AsciiWolf, Ray, verdre; !444, #1016, #1018, !449, #1036, | ||||
|   !455, #1094, !440, #1023, #624, #1017, !476, !473, !480, #1130, !485, !481, | ||||
|   !490, !489, #1151, !435, #1160, !482, #1150, #1166, !384] | ||||
|  | ||||
| Contributors: | ||||
|   AsciiWolf, Andrea Azzarone, Benjamin Berg, Carlos Garnacho, Victor Ibragimov, | ||||
|   Robert Mader, Alex Monday, Florian Müllner, Jakub Steiner, Ray Strode, | ||||
|   Marco Trevisan (Treviño), verdre, Xiaoguang Wang, Phil Wyett | ||||
|  | ||||
| Translators: | ||||
|   Victor Ibragimov [tg, af, et, ja], Bruce Cowan [en_GB], Piotr Drąg [tg], | ||||
|   Charles Monzat [fr], Khaled Hosny [ar], Goran Vidović [hr], | ||||
|   Cheng-Chia Tseng [zh_TW], Carmen Bianca BAKKER [eo], Daniel Mustieles [es], | ||||
|   Dušan Kazik [sk] | ||||
|  | ||||
| 3.32.0 | ||||
| ====== | ||||
| * Fix sizing issues in on-screen-keyboard emoji panel [Carlos; !439] | ||||
| * Fix test linker failure on Debian/Ubuntu [Iain; !442] | ||||
| * Avoid assertion when sizing fallback app icons from CSS [Florian; #1027] | ||||
| * Fix mis-sized menu arrows after texture cache changes [Florian; !452] | ||||
|  | ||||
| Contributors: | ||||
|   Carlos Garnacho, Iain Lane, Florian Müllner | ||||
|  | ||||
| Translators: | ||||
|   Gábor Kelemen [hu], Victor Ibragimov [tg], Ryuta Fujii [ja], Piotr Drąg [af, | ||||
|   tg], Mart Raudsepp [et] | ||||
|  | ||||
| 3.31.92 | ||||
| ======= | ||||
| * Fix visual glitch in submenus [Alex; #987] | ||||
| * Support fractional scaling [Jonas, Marco; #765011, !5] | ||||
| * Only consider visible children for :first-child/:last-child [Florian; !312] | ||||
| * Hide trailing separator in search results [verdre; !311] | ||||
| * Remember choice in inhibit-shortcuts dialogue [Olivier; !382] | ||||
| * Don't toggle on-screen keyboard on every focus change [Carlos; !397] | ||||
| * Fix legacy tray icons not responding to events on wayland [Florian; #191] | ||||
| * Fix generating French OSK layout [Florian; #997] | ||||
| * Use borderless round user images [Florian; #811] | ||||
| * Misc. bug fixes and cleanups [Andrea, Robert, Florian, Marco, Niels, | ||||
|   Benjamin; !414, !417, !420, #996, !408, !422, !425, #1006, !427, !315, | ||||
|   #989, !430, !431, !432, #1015, !429, !423, !419, !434] | ||||
|  | ||||
| Contributors: | ||||
|   Jonas Ådahl, Alan, Andrea Azzarone, Benjamin Berg, Olivier Fourdan, | ||||
|   Carlos Garnacho, Niels De Graef, Robert Mader, Alex Monday, Florian Müllner, | ||||
|   Marco Trevisan (Treviño), verdre | ||||
|  | ||||
| Translators: | ||||
|   Carmen Bianca BAKKER [eo], Asier Sarasua Garmendia [eu], Stas Solovey [ru], | ||||
|   Changwoo Ryu [ko], Julien Humbert [fr], Milo Casagrande [it], | ||||
|   Марко Костић [sr], Ask Hjorth Larsen [da], Kukuh Syafaat [id], | ||||
|   Daniel Șerbănescu [ro], Bernd Homuth [de], Trần Ngọc Quân [vi], | ||||
|   Nathan Follens [nl], Rūdolfs Mazurs [lv], Aurimas Černius [lt] | ||||
|  | ||||
| 3.31.91 | ||||
| ======= | ||||
| * Don't close on-screen-keyboard's language menu on hover [Florian; #171] | ||||
| * Don't let unfullscreen gesture interfere with top bar taps [Jonas D.; #552] | ||||
| * Always use symbolic user icon in system menu [Florian; #957] | ||||
| * Add flags parameter in GrabAccelerators API [Andrea; #68] | ||||
| * Misc. bug fixes and cleanups [Florian, Jonas A.; !399, !398, !400, !402, | ||||
|   !407, !410, !411] | ||||
|  | ||||
| Contributors: | ||||
|   Jonas Ådahl, Andrea Azzarone, Arnaud Bonatti, Jonas Dreßler, Florian Müllner | ||||
|  | ||||
| Translators: | ||||
|   Jordi Mas [ca], Ryuta Fujii [ja], Marek Cernocky [cs], Fran Dieguez [gl], | ||||
|   Jiri Grönroos [fi], Serdar Sağlam [tr], Anders Jonsson [sv], | ||||
|   Matej Urbančič [sl], Gun Chleoc [gd], Kukuh Syafaat [id], | ||||
|   Baurzhan Muftakhidinov [kk], Alan Mortensen [da], Rafael Fontenelle [pt_BR], | ||||
|   Sveinn í Felli [is] | ||||
|  | ||||
| 3.31.90 | ||||
| ======= | ||||
| * Fix input methods after ibus restarts [Takao; #295] | ||||
| * Refresh world clocks and weather sections [Florian; #262] | ||||
| * Port to ES6 classes (update your extensions!) [Florian; !361] | ||||
| * networkAgent: Advise users when WPS support is available [Lubomir; !329] | ||||
| * Performance improvements [Carlos; #832, #815] | ||||
| * Fix drag-and-drop with wacom pens [Carlos; #540] | ||||
| * Fix CAPS LOCK indication on wayland [Carlos; #762881] | ||||
| * Show details of non-sensitive notifications on lock screen [Philip; #726] | ||||
| * Refine extension-prefs' error UI [Florian; !193] | ||||
| * Add switch-to-application-n keybindings [Florian; #648000] | ||||
| * Remove top bar translucency [Florian; #408] | ||||
| * Support emojis and keypads in on-screen keyboard [Carlos; #675] | ||||
| * Don't allow popups to re-enable keyboard shortcuts on lock screen | ||||
|   (CVE-2019-3820) [Florian, Ray; #851] | ||||
| * Replace app menu [Florian; #624] | ||||
| * Include commonly copied+pasted extension helpers [Florian; !150] | ||||
| * Misc. bug fixes and cleanups [Florian, Daniel, Philip, Sergio, Pascal, | ||||
|   Georges, verdre, Carlos, Christopher; #780, #909, !316, !308, !309, #915, | ||||
|   !350, !362, !357, !365, !366, !283, !367, #942, !371, !373, !374, !343, | ||||
|   !375, !292, !317, !377, !379, !346, !383, #953, !388] | ||||
|  | ||||
| Contributors: | ||||
|   Sergio Costas, Christopher Davis, Bilal Elmoussaoui, Takao Fujiwara, | ||||
|   Carlos Garnacho, Niels De Graef, Christian Kellner, Ignat Loskutov, | ||||
|   Florian Müllner, Georges Basile Stavracas Neto, Pascal Nowack, Lubomir Rintel, | ||||
|   Jakub Steiner, Ray Strode, verdre, Daniel van Vugt, Philip Withnall | ||||
|  | ||||
| Translators: | ||||
|   Daniel Mustieles [es], Carmen Bianca BAKKER [eo], Charles Monzat [fr], | ||||
|   Pieter Schalk Schoeman [af], Jordi Mas [ca], Matej Urbančič [sl], | ||||
|   Fran Dieguez [gl], Balázs Úr [hu], A S Alam [pa], Fabio Tomat [fur], | ||||
|   Aurimas Černius [lt], Piotr Drąg [pl], Marek Cernocky [cs], Ryuta Fujii [ja] | ||||
|  | ||||
| 3.31.4 | ||||
| ====== | ||||
| * Improve icon grid performance [Daniel; #174] | ||||
|   | ||||
| @@ -11,6 +11,14 @@ see the [project wiki][project-wiki]. | ||||
|  | ||||
| Bugs should be reported to the GNOME [bug tracking system][bug-tracker]. | ||||
|  | ||||
| ## Contributing | ||||
|  | ||||
| To contribute, open merge requests at https://gitlab.gnome.org/GNOME/gnome-shell. | ||||
|  | ||||
| Commit messages should follow the [GNOME commit message | ||||
| guidelines](https://wiki.gnome.org/Git/CommitMessages). We require an URL | ||||
| to either an issue or a merge request in each commit. | ||||
|  | ||||
| ## License | ||||
| GNOME Shell is distributed under the terms of the GNU General Public License, | ||||
| version 2 or later. See the [COPYING][license] file for details. | ||||
|   | ||||
							
								
								
									
										40
									
								
								README.mdwn
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,40 @@ | ||||
| cldr2json | ||||
| ========= | ||||
|  | ||||
| This script converts Unicode CLDR android keyboard layouts to JSON usable by | ||||
| GNOME Shell. | ||||
|  | ||||
| CLDR keyboard layouts can be found at | ||||
| <http://www.unicode.org/Public/cldr/latest/keyboards.zip> | ||||
|  | ||||
|  | ||||
| Usage | ||||
| ===== | ||||
|  | ||||
|     ./cldr2json <input file or directory> <output directory> | ||||
|  | ||||
| example: | ||||
|  | ||||
|     ./cldr2json cldr/keyboards/android/ json_layouts/ | ||||
|  | ||||
|  | ||||
| Keyboard layout mapping | ||||
| ======================= | ||||
|  | ||||
| Unicode CLDR layout identifiers are language codes, while XKB layout | ||||
| identifiers are... something else. The mapping between the two currently uses | ||||
| heuristic based on the layout descriptions, in this order: | ||||
|  | ||||
| - if the CLDR layout description matches an XKB layout description, chose its | ||||
|   XKB identifier | ||||
| - if one word of the CLDR layout description matches an XKB layout | ||||
|   description, chose its XKB identifier | ||||
| - if the CLDR layout description matches one word of an XKB layout description, | ||||
|   chose its XKB identifier | ||||
|  | ||||
| That doesn't always work. For instance it fails for "en" language, that should | ||||
| match "us" XKB identifier. For such cases, there is a mapping in | ||||
| LOCALE_TO_XKB_OVERRIDES at the top of the script. If you discover a weird | ||||
| mapping of if you get a "failed to find XKB mapping for <locale>" warning then | ||||
| please consider adding an override there. | ||||
|  | ||||
							
								
								
									
										208
									
								
								cldr2json.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						| @@ -0,0 +1,208 @@ | ||||
| #!/usr/bin/python3 | ||||
| # | ||||
| # Copyright 2015  Daiki Ueno <dueno@src.gnome.org> | ||||
| #           2016  Parag Nemade <pnemade@redhat.com> | ||||
| #           2017  Alan <alan@boum.org> | ||||
| # | ||||
| # This program is free software; you can redistribute it and/or modify | ||||
| # it under the terms of the GNU Lesser General Public License as | ||||
| # published by the Free Software Foundation; either version 2 of the | ||||
| # License, or (at your option) any later version. | ||||
| # | ||||
| # This program is distributed in the hope that it will be useful, but | ||||
| # WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
| # Lesser General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU Lesser General Public | ||||
| # License along with this program; if not, see | ||||
| # <http://www.gnu.org/licenses/>. | ||||
|  | ||||
| import glob | ||||
| import json | ||||
| import locale | ||||
| import logging | ||||
| import os | ||||
| import re | ||||
| import sys | ||||
| import xml.etree.ElementTree | ||||
|  | ||||
| import gi | ||||
| gi.require_version('GnomeDesktop', '3.0')   # NOQA: E402 | ||||
| from gi.repository import GnomeDesktop | ||||
|  | ||||
| ESCAPE_PATTERN = re.compile(r'\\u\{([0-9A-Fa-f]+?)\}') | ||||
| ISO_PATTERN = re.compile(r'[A-E]([0-9]+)') | ||||
|  | ||||
| LOCALE_TO_XKB_OVERRIDES = { | ||||
|     'af':    'za', | ||||
|     'en':    'us', | ||||
|     'en-GB': 'uk', | ||||
|     'es-US': 'latam', | ||||
|     'fr-CA': 'ca', | ||||
|     'hi':    'in+bolnagri', | ||||
|     'ky':    'kg', | ||||
|     'nl-BE': 'be', | ||||
|     'zu':    None | ||||
| } | ||||
|  | ||||
|  | ||||
| def parse_single_key(value): | ||||
|     def unescape(m): | ||||
|         return chr(int(m.group(1), 16)) | ||||
|     value = ESCAPE_PATTERN.sub(unescape, value) | ||||
|     return value | ||||
|  | ||||
|  | ||||
| def parse_rows(keymap): | ||||
|     unsorted_rows = {} | ||||
|     for _map in keymap.iter('map'): | ||||
|         value = _map.get('to') | ||||
|         key = [parse_single_key(value)] | ||||
|         iso = _map.get('iso') | ||||
|         if not ISO_PATTERN.match(iso): | ||||
|             sys.stderr.write('invalid ISO key name: %s\n' % iso) | ||||
|             continue | ||||
|         if not iso[0] in unsorted_rows: | ||||
|             unsorted_rows[iso[0]] = [] | ||||
|         unsorted_rows[iso[0]].append((int(iso[1:]), key)) | ||||
|         # add subkeys | ||||
|         longPress = _map.get('longPress') | ||||
|         if longPress: | ||||
|             for value in longPress.split(' '): | ||||
|                 subkey = parse_single_key(value) | ||||
|                 key.append(subkey) | ||||
|  | ||||
|     rows = [] | ||||
|     for k, v in sorted(list(unsorted_rows.items()), | ||||
|                        key=lambda x: x[0], | ||||
|                        reverse=True): | ||||
|         row = [] | ||||
|         for key in sorted(v, key=lambda x: x): | ||||
|             row.append(key[1]) | ||||
|         rows.append(row) | ||||
|  | ||||
|     return rows | ||||
|  | ||||
|  | ||||
| def convert_xml(tree): | ||||
|     root = {} | ||||
|     for xml_keyboard in tree.iter("keyboard"): | ||||
|         locale_full = xml_keyboard.get("locale") | ||||
|         locale, sep, end = locale_full.partition("-t-") | ||||
|     root["locale"] = locale | ||||
|     for xml_name in tree.iter("name"): | ||||
|         name = xml_name.get("value") | ||||
|     root["name"] = name | ||||
|     root["levels"] = [] | ||||
|     # parse levels | ||||
|     for index, keymap in enumerate(tree.iter('keyMap')): | ||||
|         # FIXME: heuristics here | ||||
|         modifiers = keymap.get('modifiers') | ||||
|         if not modifiers: | ||||
|             mode = 'default' | ||||
|             modifiers = '' | ||||
|         elif 'shift' in modifiers.split(' '): | ||||
|             mode = 'latched' | ||||
|             modifiers = 'shift' | ||||
|         else: | ||||
|             mode = 'locked' | ||||
|         level = {} | ||||
|         level["level"] = modifiers | ||||
|         level["mode"] = mode | ||||
|         level["rows"] = parse_rows(keymap) | ||||
|         root["levels"].append(level) | ||||
|     return root | ||||
|  | ||||
|  | ||||
| def locale_to_xkb(locale, name): | ||||
|     if locale in sorted(LOCALE_TO_XKB_OVERRIDES.keys()): | ||||
|         xkb = LOCALE_TO_XKB_OVERRIDES[locale] | ||||
|         logging.debug("override for %s → %s", | ||||
|                       locale, xkb) | ||||
|         if xkb: | ||||
|             return xkb | ||||
|         else: | ||||
|             raise KeyError("layout %s explicitely disabled in overrides" | ||||
|                            % locale) | ||||
|     xkb_names = sorted(name_to_xkb.keys()) | ||||
|     if name in xkb_names: | ||||
|         return name_to_xkb[name] | ||||
|     else: | ||||
|         logging.debug("name %s failed" % name) | ||||
|     for sub_name in name.split(' '): | ||||
|         if sub_name in xkb_names: | ||||
|             xkb = name_to_xkb[sub_name] | ||||
|             logging.debug("dumb mapping failed but match with locale word: " | ||||
|                           "%s (%s) → %s (%s)", | ||||
|                           locale, name, xkb, sub_name) | ||||
|             return xkb | ||||
|         else: | ||||
|             logging.debug("sub_name failed") | ||||
|     for xkb_name in xkb_names: | ||||
|         for xkb_sub_name in xkb_name.split(' '): | ||||
|             if xkb_sub_name.strip('()') == name: | ||||
|                 xkb = name_to_xkb[xkb_name] | ||||
|                 logging.debug("dumb mapping failed but match with xkb word: " | ||||
|                               "%s (%s) → %s (%s)", | ||||
|                               locale, name, xkb, xkb_name) | ||||
|                 return xkb | ||||
|     raise KeyError("failed to find XKB mapping for %s" % locale) | ||||
|  | ||||
|  | ||||
| def convert_file(source_file, destination_path): | ||||
|     logging.info("Parsing %s", source_file) | ||||
|  | ||||
|     itree = xml.etree.ElementTree.ElementTree() | ||||
|     itree.parse(source_file) | ||||
|  | ||||
|     root = convert_xml(itree) | ||||
|  | ||||
|     try: | ||||
|         xkb_name = locale_to_xkb(root["locale"], root["name"]) | ||||
|     except KeyError as e: | ||||
|         logging.warn(e) | ||||
|         return False | ||||
|     destination_file = os.path.join(destination_path, xkb_name + ".json") | ||||
|  | ||||
|     with open(destination_file, 'w', encoding="utf-8") as dest_fd: | ||||
|         json.dump(root, dest_fd, ensure_ascii=False, indent=2, sort_keys=True) | ||||
|  | ||||
|     logging.debug("written %s", destination_file) | ||||
|  | ||||
|  | ||||
| def load_xkb_mappings(): | ||||
|     xkb = GnomeDesktop.XkbInfo() | ||||
|     layouts = xkb.get_all_layouts() | ||||
|     name_to_xkb = {} | ||||
|  | ||||
|     for layout in layouts: | ||||
|         name = xkb.get_layout_info(layout).display_name | ||||
|         name_to_xkb[name] = layout | ||||
|  | ||||
|     return name_to_xkb | ||||
|  | ||||
|  | ||||
| locale.setlocale(locale.LC_ALL, "C") | ||||
| name_to_xkb = load_xkb_mappings() | ||||
|  | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     if "DEBUG" in os.environ: | ||||
|         logging.basicConfig(level=logging.DEBUG) | ||||
|  | ||||
|     if len(sys.argv) < 2: | ||||
|         print("supply a CLDR keyboard file") | ||||
|         sys.exit(1) | ||||
|  | ||||
|     if len(sys.argv) < 3: | ||||
|         print("supply an output directory") | ||||
|         sys.exit(1) | ||||
|  | ||||
|     source = sys.argv[1] | ||||
|     destination = sys.argv[2] | ||||
|     if os.path.isfile(source): | ||||
|         convert_file(source, destination) | ||||
|     elif os.path.isdir(source): | ||||
|         for path in glob.glob(source + "/*-t-k0-android.xml"): | ||||
|             convert_file(path, destination) | ||||
							
								
								
									
										12
									
								
								data/dbus-interfaces/org.gnome.Shell.CalendarServer.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,12 @@ | ||||
| <node> | ||||
|   <interface name="org.gnome.Shell.CalendarServer"> | ||||
|     <method name="GetEvents"> | ||||
|       <arg type="x" direction="in" /> | ||||
|       <arg type="x" direction="in" /> | ||||
|       <arg type="b" direction="in" /> | ||||
|       <arg type="a(sssbxxa{sv})" direction="out" /> | ||||
|     </method> | ||||
|     <property name="HasCalendars" type="b" access="read" /> | ||||
|     <signal name="Changed" /> | ||||
|   </interface> | ||||
| </node> | ||||
| @@ -9,9 +9,6 @@ | ||||
|     <method name="ShowOSD"> | ||||
|       <arg type="a{sv}" direction="in" name="params"/> | ||||
|     </method> | ||||
|     <method name="ShowMonitorLabels"> | ||||
|       <arg type="a{uv}" direction="in" name="params"/> | ||||
|     </method> | ||||
|     <method name="ShowMonitorLabels2"> | ||||
|       <arg type="a{sv}" direction="in" name="params"/> | ||||
|     </method> | ||||
| @@ -22,17 +19,22 @@ | ||||
|     <method name="ShowApplications"/> | ||||
|     <method name="GrabAccelerator"> | ||||
|       <arg type="s" direction="in" name="accelerator"/> | ||||
|       <arg type="u" direction="in" name="flags"/> | ||||
|       <arg type="u" direction="in" name="modeFlags"/> | ||||
|       <arg type="u" direction="in" name="grabFlags"/> | ||||
|       <arg type="u" direction="out" name="action"/> | ||||
|     </method> | ||||
|     <method name="GrabAccelerators"> | ||||
|       <arg type="a(su)" direction="in" name="accelerators"/> | ||||
|       <arg type="a(suu)" direction="in" name="accelerators"/> | ||||
|       <arg type="au" direction="out" name="actions"/> | ||||
|     </method> | ||||
|     <method name="UngrabAccelerator"> | ||||
|       <arg type="u" direction="in" name="action"/> | ||||
|       <arg type="b" direction="out" name="success"/> | ||||
|     </method> | ||||
|     <method name="UngrabAccelerators"> | ||||
|       <arg type="au" direction="in" name="action"/> | ||||
|       <arg type="b" direction="out" name="success"/> | ||||
|     </method> | ||||
|     <signal name="AcceleratorActivated"> | ||||
|       <arg name="action" type="u"/> | ||||
|       <arg name="parameters" type="a{sv}"/> | ||||
|   | ||||
							
								
								
									
										15740
									
								
								data/emoji.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -39,6 +39,7 @@ | ||||
|     <file preprocess="xml-stripblanks">org.gnome.SettingsDaemon.Rfkill.xml</file> | ||||
|     <file preprocess="xml-stripblanks">org.gnome.SettingsDaemon.Wacom.xml</file> | ||||
|     <file preprocess="xml-stripblanks">org.gnome.Shell.AudioDeviceSelection.xml</file> | ||||
|     <file preprocess="xml-stripblanks">org.gnome.Shell.CalendarServer.xml</file> | ||||
|     <file preprocess="xml-stripblanks">org.gnome.Shell.Extensions.xml</file> | ||||
|     <file preprocess="xml-stripblanks">org.gnome.Shell.Introspect.xml</file> | ||||
|     <file preprocess="xml-stripblanks">org.gnome.Shell.HotplugSniffer.xml</file> | ||||
|   | ||||
| @@ -6,6 +6,7 @@ | ||||
|     <file>be.json</file> | ||||
|     <file>bg.json</file> | ||||
|     <file>by.json</file> | ||||
|     <file>ca.json</file> | ||||
|     <file>cz.json</file> | ||||
|     <file>de.json</file> | ||||
|     <file>dk.json</file> | ||||
| @@ -54,5 +55,6 @@ | ||||
|     <file>us.json</file> | ||||
|     <file>vn.json</file> | ||||
|     <file>za.json</file> | ||||
|     <file>emoji.json</file> | ||||
|   </gresource> | ||||
| </gresources> | ||||
|   | ||||
| @@ -20,11 +20,13 @@ | ||||
|     <file>no-notifications.svg</file> | ||||
|     <file>noise-texture.png</file> | ||||
|     <file>pad-osd.css</file> | ||||
|     <file alias="icons/pointer-double-click-symbolic.svg">pointer-double-click-symbolic.svg</file> | ||||
|     <file alias="icons/pointer-drag-symbolic.svg">pointer-drag-symbolic.svg</file> | ||||
|     <file alias="icons/pointer-primary-click-symbolic.svg">pointer-primary-click-symbolic.svg</file> | ||||
|     <file alias="icons/pointer-secondary-click-symbolic.svg">pointer-secondary-click-symbolic.svg</file> | ||||
|     <file>process-working.svg</file> | ||||
|     <file>toggle-off-us.svg</file> | ||||
|     <file>toggle-off-intl.svg</file> | ||||
|     <file>toggle-off-hc.svg</file> | ||||
|     <file>toggle-on-us.svg</file> | ||||
|     <file>toggle-on-intl.svg</file> | ||||
|     <file>toggle-on-hc.svg</file> | ||||
|   </gresource> | ||||
|   | ||||
| @@ -145,6 +145,42 @@ | ||||
|       <summary>Keybinding that pauses and resumes all running tweens, for debugging purposes</summary> | ||||
|       <description></description> | ||||
|     </key> | ||||
|     <key name="switch-to-application-1" type="as"> | ||||
|       <default>["<Super>1"]</default> | ||||
|       <summary>Switch to application 1</summary> | ||||
|     </key> | ||||
|     <key name="switch-to-application-2" type="as"> | ||||
|       <default>["<Super>2"]</default> | ||||
|       <summary>Switch to application 2</summary> | ||||
|     </key> | ||||
|     <key name="switch-to-application-3" type="as"> | ||||
|       <default>["<Super>3"]</default> | ||||
|       <summary>Switch to application 3</summary> | ||||
|     </key> | ||||
|     <key name="switch-to-application-4" type="as"> | ||||
|       <default>["<Super>4"]</default> | ||||
|       <summary>Switch to application 4</summary> | ||||
|     </key> | ||||
|     <key name="switch-to-application-5" type="as"> | ||||
|       <default>["<Super>5"]</default> | ||||
|       <summary>Switch to application 5</summary> | ||||
|     </key> | ||||
|     <key name="switch-to-application-6" type="as"> | ||||
|       <default>["<Super>6"]</default> | ||||
|       <summary>Switch to application 6</summary> | ||||
|     </key> | ||||
|     <key name="switch-to-application-7" type="as"> | ||||
|       <default>["<Super>7"]</default> | ||||
|       <summary>Switch to application 7</summary> | ||||
|     </key> | ||||
|     <key name="switch-to-application-8" type="as"> | ||||
|       <default>["<Super>8"]</default> | ||||
|       <summary>Switch to application 8</summary> | ||||
|     </key> | ||||
|     <key name="switch-to-application-9" type="as"> | ||||
|       <default>["<Super>9"]</default> | ||||
|       <summary>Switch to application 9</summary> | ||||
|     </key> | ||||
|   </schema> | ||||
|  | ||||
|   <schema id="org.gnome.shell.keyboard" path="/org/gnome/shell/keyboard/" | ||||
|   | ||||
							
								
								
									
										599
									
								
								data/osk-layouts/ca.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,599 @@ | ||||
| { | ||||
|   "levels": [ | ||||
|     { | ||||
|       "level": "", | ||||
|       "mode": "default", | ||||
|       "rows": [ | ||||
|         [ | ||||
|           [ | ||||
|             "q" | ||||
|           ], | ||||
|           [ | ||||
|             "w" | ||||
|           ], | ||||
|           [ | ||||
|             "e", | ||||
|             "é", | ||||
|             "è", | ||||
|             "ê", | ||||
|             "ë", | ||||
|             "%", | ||||
|             "ę", | ||||
|             "ė", | ||||
|             "ē" | ||||
|           ], | ||||
|           [ | ||||
|             "r" | ||||
|           ], | ||||
|           [ | ||||
|             "t" | ||||
|           ], | ||||
|           [ | ||||
|             "y", | ||||
|             "%", | ||||
|             "ÿ" | ||||
|           ], | ||||
|           [ | ||||
|             "u", | ||||
|             "ù", | ||||
|             "û", | ||||
|             "%", | ||||
|             "ü", | ||||
|             "ú", | ||||
|             "ū" | ||||
|           ], | ||||
|           [ | ||||
|             "i", | ||||
|             "î", | ||||
|             "%", | ||||
|             "ï", | ||||
|             "ì", | ||||
|             "í", | ||||
|             "į", | ||||
|             "ī" | ||||
|           ], | ||||
|           [ | ||||
|             "o", | ||||
|             "ô", | ||||
|             "œ", | ||||
|             "%", | ||||
|             "ö", | ||||
|             "ò", | ||||
|             "ó", | ||||
|             "õ", | ||||
|             "ø", | ||||
|             "ō", | ||||
|             "º" | ||||
|           ], | ||||
|           [ | ||||
|             "p" | ||||
|           ] | ||||
|         ], | ||||
|         [ | ||||
|           [ | ||||
|             "a", | ||||
|             "à", | ||||
|             "â", | ||||
|             "%", | ||||
|             "æ", | ||||
|             "á", | ||||
|             "ä", | ||||
|             "ã", | ||||
|             "å", | ||||
|             "ā", | ||||
|             "ª" | ||||
|           ], | ||||
|           [ | ||||
|             "s" | ||||
|           ], | ||||
|           [ | ||||
|             "d" | ||||
|           ], | ||||
|           [ | ||||
|             "f" | ||||
|           ], | ||||
|           [ | ||||
|             "g" | ||||
|           ], | ||||
|           [ | ||||
|             "h" | ||||
|           ], | ||||
|           [ | ||||
|             "j" | ||||
|           ], | ||||
|           [ | ||||
|             "k" | ||||
|           ], | ||||
|           [ | ||||
|             "l" | ||||
|           ] | ||||
|         ], | ||||
|         [ | ||||
|           [ | ||||
|             "z" | ||||
|           ], | ||||
|           [ | ||||
|             "x" | ||||
|           ], | ||||
|           [ | ||||
|             "c", | ||||
|             "ç", | ||||
|             "ć", | ||||
|             "č" | ||||
|           ], | ||||
|           [ | ||||
|             "v" | ||||
|           ], | ||||
|           [ | ||||
|             "b" | ||||
|           ], | ||||
|           [ | ||||
|             "n" | ||||
|           ], | ||||
|           [ | ||||
|             "m" | ||||
|           ] | ||||
|         ], | ||||
|         [ | ||||
|           [ | ||||
|             "," | ||||
|           ], | ||||
|           [ | ||||
|             " " | ||||
|           ], | ||||
|           [ | ||||
|             ".", | ||||
|             "#", | ||||
|             "!", | ||||
|             ",", | ||||
|             "?", | ||||
|             "-", | ||||
|             ":", | ||||
|             "'", | ||||
|             "@" | ||||
|           ] | ||||
|         ] | ||||
|       ] | ||||
|     }, | ||||
|     { | ||||
|       "level": "shift", | ||||
|       "mode": "latched", | ||||
|       "rows": [ | ||||
|         [ | ||||
|           [ | ||||
|             "Q" | ||||
|           ], | ||||
|           [ | ||||
|             "W" | ||||
|           ], | ||||
|           [ | ||||
|             "E", | ||||
|             "É", | ||||
|             "È", | ||||
|             "Ê", | ||||
|             "Ë", | ||||
|             "%", | ||||
|             "Ę", | ||||
|             "Ė", | ||||
|             "Ē" | ||||
|           ], | ||||
|           [ | ||||
|             "R" | ||||
|           ], | ||||
|           [ | ||||
|             "T" | ||||
|           ], | ||||
|           [ | ||||
|             "Y", | ||||
|             "%", | ||||
|             "Ÿ" | ||||
|           ], | ||||
|           [ | ||||
|             "U", | ||||
|             "Ù", | ||||
|             "Û", | ||||
|             "%", | ||||
|             "Ü", | ||||
|             "Ú", | ||||
|             "Ū" | ||||
|           ], | ||||
|           [ | ||||
|             "I", | ||||
|             "Î", | ||||
|             "%", | ||||
|             "Ï", | ||||
|             "Ì", | ||||
|             "Í", | ||||
|             "Į", | ||||
|             "Ī" | ||||
|           ], | ||||
|           [ | ||||
|             "O", | ||||
|             "Ô", | ||||
|             "Œ", | ||||
|             "%", | ||||
|             "Ö", | ||||
|             "Ò", | ||||
|             "Ó", | ||||
|             "Õ", | ||||
|             "Ø", | ||||
|             "Ō", | ||||
|             "º" | ||||
|           ], | ||||
|           [ | ||||
|             "P" | ||||
|           ] | ||||
|         ], | ||||
|         [ | ||||
|           [ | ||||
|             "A", | ||||
|             "À", | ||||
|             "Â", | ||||
|             "%", | ||||
|             "Æ", | ||||
|             "Á", | ||||
|             "Ä", | ||||
|             "Ã", | ||||
|             "Å", | ||||
|             "Ā", | ||||
|             "ª" | ||||
|           ], | ||||
|           [ | ||||
|             "S" | ||||
|           ], | ||||
|           [ | ||||
|             "D" | ||||
|           ], | ||||
|           [ | ||||
|             "F" | ||||
|           ], | ||||
|           [ | ||||
|             "G" | ||||
|           ], | ||||
|           [ | ||||
|             "H" | ||||
|           ], | ||||
|           [ | ||||
|             "J" | ||||
|           ], | ||||
|           [ | ||||
|             "K" | ||||
|           ], | ||||
|           [ | ||||
|             "L" | ||||
|           ] | ||||
|         ], | ||||
|         [ | ||||
|           [ | ||||
|             "Z" | ||||
|           ], | ||||
|           [ | ||||
|             "X" | ||||
|           ], | ||||
|           [ | ||||
|             "C", | ||||
|             "Ç", | ||||
|             "Ć", | ||||
|             "Č" | ||||
|           ], | ||||
|           [ | ||||
|             "V" | ||||
|           ], | ||||
|           [ | ||||
|             "B" | ||||
|           ], | ||||
|           [ | ||||
|             "N" | ||||
|           ], | ||||
|           [ | ||||
|             "M" | ||||
|           ] | ||||
|         ], | ||||
|         [ | ||||
|           [ | ||||
|             "," | ||||
|           ], | ||||
|           [ | ||||
|             " " | ||||
|           ], | ||||
|           [ | ||||
|             ".", | ||||
|             "#", | ||||
|             "!", | ||||
|             ",", | ||||
|             "?", | ||||
|             "-", | ||||
|             ":", | ||||
|             "'", | ||||
|             "@" | ||||
|           ] | ||||
|         ] | ||||
|       ] | ||||
|     }, | ||||
|     { | ||||
|       "level": "opt", | ||||
|       "mode": "locked", | ||||
|       "rows": [ | ||||
|         [ | ||||
|           [ | ||||
|             "1", | ||||
|             "¹", | ||||
|             "½", | ||||
|             "⅓", | ||||
|             "¼", | ||||
|             "⅛" | ||||
|           ], | ||||
|           [ | ||||
|             "2", | ||||
|             "²", | ||||
|             "⅔" | ||||
|           ], | ||||
|           [ | ||||
|             "3", | ||||
|             "³", | ||||
|             "¾", | ||||
|             "⅜" | ||||
|           ], | ||||
|           [ | ||||
|             "4", | ||||
|             "⁴" | ||||
|           ], | ||||
|           [ | ||||
|             "5", | ||||
|             "⅝" | ||||
|           ], | ||||
|           [ | ||||
|             "6" | ||||
|           ], | ||||
|           [ | ||||
|             "7", | ||||
|             "⅞" | ||||
|           ], | ||||
|           [ | ||||
|             "8" | ||||
|           ], | ||||
|           [ | ||||
|             "9" | ||||
|           ], | ||||
|           [ | ||||
|             "0", | ||||
|             "ⁿ", | ||||
|             "∅" | ||||
|           ] | ||||
|         ], | ||||
|         [ | ||||
|           [ | ||||
|             "@" | ||||
|           ], | ||||
|           [ | ||||
|             "#" | ||||
|           ], | ||||
|           [ | ||||
|             "$", | ||||
|             "¢", | ||||
|             "£", | ||||
|             "€", | ||||
|             "¥", | ||||
|             "₱" | ||||
|           ], | ||||
|           [ | ||||
|             "%", | ||||
|             "‰" | ||||
|           ], | ||||
|           [ | ||||
|             "&" | ||||
|           ], | ||||
|           [ | ||||
|             "-", | ||||
|             "_", | ||||
|             "–", | ||||
|             "—", | ||||
|             "·" | ||||
|           ], | ||||
|           [ | ||||
|             "+", | ||||
|             "±" | ||||
|           ], | ||||
|           [ | ||||
|             "(", | ||||
|             "<", | ||||
|             "{", | ||||
|             "[" | ||||
|           ], | ||||
|           [ | ||||
|             ")", | ||||
|             ">", | ||||
|             "}", | ||||
|             "]" | ||||
|           ] | ||||
|         ], | ||||
|         [ | ||||
|           [ | ||||
|             "*", | ||||
|             "†", | ||||
|             "‡", | ||||
|             "★" | ||||
|           ], | ||||
|           [ | ||||
|             "\"", | ||||
|             "“", | ||||
|             "”", | ||||
|             "«", | ||||
|             "»" | ||||
|           ], | ||||
|           [ | ||||
|             "'", | ||||
|             "‘", | ||||
|             "’", | ||||
|             "‹", | ||||
|             "›" | ||||
|           ], | ||||
|           [ | ||||
|             ":" | ||||
|           ], | ||||
|           [ | ||||
|             ";" | ||||
|           ], | ||||
|           [ | ||||
|             "!", | ||||
|             "¡" | ||||
|           ], | ||||
|           [ | ||||
|             "?", | ||||
|             "¿" | ||||
|           ] | ||||
|         ], | ||||
|         [ | ||||
|           [ | ||||
|             "_" | ||||
|           ], | ||||
|           [ | ||||
|             "/" | ||||
|           ], | ||||
|           [ | ||||
|             " " | ||||
|           ], | ||||
|           [ | ||||
|             "," | ||||
|           ], | ||||
|           [ | ||||
|             ".", | ||||
|             "…" | ||||
|           ] | ||||
|         ] | ||||
|       ] | ||||
|     }, | ||||
|     { | ||||
|       "level": "opt+shift", | ||||
|       "mode": "locked", | ||||
|       "rows": [ | ||||
|         [ | ||||
|           [ | ||||
|             "~" | ||||
|           ], | ||||
|           [ | ||||
|             "`" | ||||
|           ], | ||||
|           [ | ||||
|             "|" | ||||
|           ], | ||||
|           [ | ||||
|             "•", | ||||
|             "♪", | ||||
|             "♥", | ||||
|             "♠", | ||||
|             "♦", | ||||
|             "♣" | ||||
|           ], | ||||
|           [ | ||||
|             "√" | ||||
|           ], | ||||
|           [ | ||||
|             "Π", | ||||
|             "π" | ||||
|           ], | ||||
|           [ | ||||
|             "÷" | ||||
|           ], | ||||
|           [ | ||||
|             "×" | ||||
|           ], | ||||
|           [ | ||||
|             "¶", | ||||
|             "§" | ||||
|           ], | ||||
|           [ | ||||
|             "∆" | ||||
|           ] | ||||
|         ], | ||||
|         [ | ||||
|           [ | ||||
|             "£" | ||||
|           ], | ||||
|           [ | ||||
|             "¢" | ||||
|           ], | ||||
|           [ | ||||
|             "€" | ||||
|           ], | ||||
|           [ | ||||
|             "¥" | ||||
|           ], | ||||
|           [ | ||||
|             "^", | ||||
|             "↑", | ||||
|             "↓", | ||||
|             "←", | ||||
|             "→" | ||||
|           ], | ||||
|           [ | ||||
|             "°", | ||||
|             "′", | ||||
|             "″" | ||||
|           ], | ||||
|           [ | ||||
|             "=", | ||||
|             "≠", | ||||
|             "≈", | ||||
|             "∞" | ||||
|           ], | ||||
|           [ | ||||
|             "{" | ||||
|           ], | ||||
|           [ | ||||
|             "}" | ||||
|           ] | ||||
|         ], | ||||
|         [ | ||||
|           [ | ||||
|             "\\" | ||||
|           ], | ||||
|           [ | ||||
|             "©" | ||||
|           ], | ||||
|           [ | ||||
|             "®" | ||||
|           ], | ||||
|           [ | ||||
|             "™" | ||||
|           ], | ||||
|           [ | ||||
|             "℅" | ||||
|           ], | ||||
|           [ | ||||
|             "[" | ||||
|           ], | ||||
|           [ | ||||
|             "]" | ||||
|           ] | ||||
|         ], | ||||
|         [ | ||||
|           [ | ||||
|             "<", | ||||
|             "‹", | ||||
|             "≤", | ||||
|             "«" | ||||
|           ], | ||||
|           [ | ||||
|             ">", | ||||
|             "›", | ||||
|             "≥", | ||||
|             "»" | ||||
|           ], | ||||
|           [ | ||||
|             " " | ||||
|           ], | ||||
|           [ | ||||
|             "," | ||||
|           ], | ||||
|           [ | ||||
|             ".", | ||||
|             "…" | ||||
|           ] | ||||
|         ] | ||||
|       ] | ||||
|     } | ||||
|   ], | ||||
|   "locale": "fr-CA", | ||||
|   "name": "French Canada" | ||||
| } | ||||
| @@ -6,10 +6,20 @@ | ||||
|       "rows": [ | ||||
|         [ | ||||
|           [ | ||||
|             "q" | ||||
|             "a", | ||||
|             "à", | ||||
|             "â", | ||||
|             "%", | ||||
|             "æ", | ||||
|             "á", | ||||
|             "ä", | ||||
|             "ã", | ||||
|             "å", | ||||
|             "ā", | ||||
|             "ª" | ||||
|           ], | ||||
|           [ | ||||
|             "w" | ||||
|             "z" | ||||
|           ], | ||||
|           [ | ||||
|             "e", | ||||
| @@ -71,17 +81,7 @@ | ||||
|         ], | ||||
|         [ | ||||
|           [ | ||||
|             "a", | ||||
|             "à", | ||||
|             "â", | ||||
|             "%", | ||||
|             "æ", | ||||
|             "á", | ||||
|             "ä", | ||||
|             "ã", | ||||
|             "å", | ||||
|             "ā", | ||||
|             "ª" | ||||
|             "q" | ||||
|           ], | ||||
|           [ | ||||
|             "s" | ||||
| @@ -106,11 +106,14 @@ | ||||
|           ], | ||||
|           [ | ||||
|             "l" | ||||
|           ], | ||||
|           [ | ||||
|             "m" | ||||
|           ] | ||||
|         ], | ||||
|         [ | ||||
|           [ | ||||
|             "z" | ||||
|             "w" | ||||
|           ], | ||||
|           [ | ||||
|             "x" | ||||
| @@ -131,7 +134,11 @@ | ||||
|             "n" | ||||
|           ], | ||||
|           [ | ||||
|             "m" | ||||
|             "'", | ||||
|             "‘", | ||||
|             "’", | ||||
|             "‹", | ||||
|             "›" | ||||
|           ] | ||||
|         ], | ||||
|         [ | ||||
| @@ -161,10 +168,20 @@ | ||||
|       "rows": [ | ||||
|         [ | ||||
|           [ | ||||
|             "Q" | ||||
|             "A", | ||||
|             "À", | ||||
|             "Â", | ||||
|             "%", | ||||
|             "Æ", | ||||
|             "Á", | ||||
|             "Ä", | ||||
|             "Ã", | ||||
|             "Å", | ||||
|             "Ā", | ||||
|             "ª" | ||||
|           ], | ||||
|           [ | ||||
|             "W" | ||||
|             "Z" | ||||
|           ], | ||||
|           [ | ||||
|             "E", | ||||
| @@ -226,17 +243,7 @@ | ||||
|         ], | ||||
|         [ | ||||
|           [ | ||||
|             "A", | ||||
|             "À", | ||||
|             "Â", | ||||
|             "%", | ||||
|             "Æ", | ||||
|             "Á", | ||||
|             "Ä", | ||||
|             "Ã", | ||||
|             "Å", | ||||
|             "Ā", | ||||
|             "ª" | ||||
|             "Q" | ||||
|           ], | ||||
|           [ | ||||
|             "S" | ||||
| @@ -261,11 +268,14 @@ | ||||
|           ], | ||||
|           [ | ||||
|             "L" | ||||
|           ], | ||||
|           [ | ||||
|             "M" | ||||
|           ] | ||||
|         ], | ||||
|         [ | ||||
|           [ | ||||
|             "Z" | ||||
|             "W" | ||||
|           ], | ||||
|           [ | ||||
|             "X" | ||||
| @@ -286,7 +296,11 @@ | ||||
|             "N" | ||||
|           ], | ||||
|           [ | ||||
|             "M" | ||||
|             "'", | ||||
|             "‘", | ||||
|             "’", | ||||
|             "‹", | ||||
|             "›" | ||||
|           ] | ||||
|         ], | ||||
|         [ | ||||
| @@ -369,10 +383,10 @@ | ||||
|             "#" | ||||
|           ], | ||||
|           [ | ||||
|             "$", | ||||
|             "€", | ||||
|             "¢", | ||||
|             "£", | ||||
|             "€", | ||||
|             "$", | ||||
|             "¥", | ||||
|             "₱" | ||||
|           ], | ||||
| @@ -511,13 +525,14 @@ | ||||
|             "£" | ||||
|           ], | ||||
|           [ | ||||
|             "¥" | ||||
|           ], | ||||
|           [ | ||||
|             "$", | ||||
|             "¢" | ||||
|           ], | ||||
|           [ | ||||
|             "€" | ||||
|           ], | ||||
|           [ | ||||
|             "¥" | ||||
|             "¢" | ||||
|           ], | ||||
|           [ | ||||
|             "^", | ||||
| @@ -594,6 +609,6 @@ | ||||
|       ] | ||||
|     } | ||||
|   ], | ||||
|   "locale": "fr-CA", | ||||
|   "name": "French Canada" | ||||
|   "locale": "fr", | ||||
|   "name": "French" | ||||
| } | ||||
| @@ -2,26 +2,23 @@ | ||||
| // it gets @if ed depending on $variant | ||||
|  | ||||
|  | ||||
| $base_color: if($variant =='light', #ffffff, #292929); | ||||
| $bg_color: if($variant =='light', #ededed, #393f3f); | ||||
| $fg_color: if($variant =='light', #2e3436, #eeeeec); | ||||
| $base_color: if($variant == 'light', #ffffff, lighten(desaturate(#241f31, 20%), 2%)); | ||||
| $bg_color: if($variant == 'light', #f6f5f4, desaturate(#3d3846, 10%)); | ||||
| $fg_color: if($variant == 'light', #2e3436, #eeeeec); | ||||
|  | ||||
| $selected_fg_color: #ffffff; | ||||
| $selected_bg_color: if($variant == 'light', #4a90d9, darken(#4a90d9,20%)); | ||||
| $selected_borders_color: if($variant=='light', darken($selected_bg_color, 30%), | ||||
|                                                darken($selected_bg_color, 20%)); | ||||
| $borders_color: if($variant =='light', darken($bg_color,30%), darken($bg_color,12%)); | ||||
| $borders_edge: if($variant =='light', white, transparentize($fg_color, 0.9)); | ||||
| $link_color: if($variant == 'light', darken($selected_bg_color,10%), | ||||
|                                      lighten($selected_bg_color,20%)); | ||||
| $link_visited_color: if($variant == 'light', darken($selected_bg_color,20%), | ||||
|                                      lighten($selected_bg_color,10%)); | ||||
| $selected_bg_color: if($variant == 'light', #3584e4, darken(#3584e4, 20%)); | ||||
| $selected_borders_color: if($variant== 'light', darken($selected_bg_color, 15%), darken($selected_bg_color, 30%)); | ||||
| $borders_color: if($variant == 'light', darken($bg_color, 18%), darken($bg_color, 10%)); | ||||
| $borders_edge: if($variant == 'light', transparentize(white, 0.2), transparentize($fg_color, 0.93)); | ||||
| $link_color: if($variant == 'light', darken($selected_bg_color, 10%), lighten($selected_bg_color, 20%)); | ||||
| $link_visited_color: if($variant == 'light', darken($selected_bg_color, 20%), lighten($selected_bg_color, 10%)); | ||||
| $top_hilight: $borders_edge; | ||||
|  | ||||
| $warning_color: #f57900; | ||||
| $error_color: #cc0000; | ||||
| $success_color: if($variant =='light', #73d216, darken(#73d216,10%)); | ||||
| $destructive_color: if($variant =='light', #ef2929, darken(#ef2929,10%)); | ||||
| $error_color: #ff8080; | ||||
| $success_color: if($variant == 'light', #33d17a, darken(#33d17a, 10%)); | ||||
| $destructive_color: if($variant == 'light', #e01b24, darken(#e01b24, 10%)); | ||||
|  | ||||
| $osd_fg_color: #eeeeec; | ||||
| $osd_bg_color: #2e3436; | ||||
|   | ||||
| @@ -157,18 +157,13 @@ StScrollBar { | ||||
|  | ||||
| /* Switches */ | ||||
| .toggle-switch { | ||||
|   width: 65px; | ||||
|   width: 46px; | ||||
|   height: 22px; | ||||
|   background-size: contain; | ||||
|   background-image: url("resource:///org/gnome/shell/theme/toggle-off-intl.svg"); | ||||
|   &:checked { background-image: url("resource:///org/gnome/shell/theme/toggle-on-intl.svg"); } | ||||
| } | ||||
|  | ||||
|   @each $v in us, intl { | ||||
|     .toggle-switch-#{$v} { | ||||
|       background-image: url("resource:///org/gnome/shell/theme/toggle-off-#{$v}.svg"); | ||||
|       &:checked { background-image: url("resource:///org/gnome/shell/theme/toggle-on-#{$v}.svg"); } | ||||
|     } | ||||
|   } | ||||
|  | ||||
| /* links */ | ||||
| .shell-link { | ||||
|   color: $link_color; | ||||
| @@ -267,8 +262,7 @@ StScrollBar { | ||||
|   } | ||||
|  | ||||
|   .end-session-dialog-logout-icon { | ||||
|     //border: 2px solid #8b8b8b; | ||||
|     border-radius: 5px; | ||||
|     border-radius: 99px; | ||||
|     width: 48px; | ||||
|     height: 48px; | ||||
|     background-size: contain; | ||||
| @@ -388,12 +382,11 @@ StScrollBar { | ||||
|  | ||||
|   .prompt-dialog-password-box { | ||||
|     spacing: 1em; | ||||
|     padding-bottom: 1em; | ||||
|   } | ||||
|  | ||||
|   .prompt-dialog-error-label { | ||||
|     font-size: 10pt; | ||||
|     color: $error_color; | ||||
|     color: $warning_color; | ||||
|     padding-bottom: 8px; | ||||
|   } | ||||
|  | ||||
| @@ -411,6 +404,23 @@ StScrollBar { | ||||
|     padding-bottom: 8px; | ||||
|   } | ||||
|  | ||||
|   .prompt-dialog-pim-box { | ||||
|     spacing: 1em; | ||||
|   } | ||||
|  | ||||
|   .prompt-dialog-grid { | ||||
|     spacing-rows: 15px; | ||||
|     spacing-columns: 1em; | ||||
|   } | ||||
|  | ||||
|   .prompt-dialog-keyfiles-box { | ||||
|     spacing: 1em; | ||||
|   } | ||||
|  | ||||
|   .prompt-dialog-button.button { | ||||
|     padding: 8px; | ||||
|   } | ||||
|  | ||||
|  | ||||
| /* Polkit Dialog */ | ||||
|  | ||||
| @@ -428,7 +438,7 @@ StScrollBar { | ||||
|   } | ||||
|  | ||||
|   .polkit-dialog-user-icon { | ||||
|     border-radius: 5px; | ||||
|     border-radius: 99px; | ||||
|     background-size: contain; | ||||
|     width: 48px; | ||||
|     height: 48px; | ||||
| @@ -508,6 +518,7 @@ StScrollBar { | ||||
|  | ||||
|   .popup-menu-arrow { } //defined globally in the TOP BAR | ||||
|   .popup-sub-menu { | ||||
|     padding-bottom: 1px; | ||||
|     background-color: darken($bg_color,2%); | ||||
|     box-shadow: inset 0 -1px 0px lighten($borders_color,5%); | ||||
|   } | ||||
| @@ -729,9 +740,7 @@ StScrollBar { | ||||
| /* TOP BAR */ | ||||
|  | ||||
| #panel { | ||||
|   background-color: rgba(0, 0, 0, 0.35); | ||||
|   /* transition from solid to transparent */ | ||||
|   transition-duration: 500ms; | ||||
|   background-color: black; | ||||
|   font-weight: bold; | ||||
|   height: 1.86em; | ||||
|   font-feature-settings: "tnum"; | ||||
| @@ -748,7 +757,7 @@ StScrollBar { | ||||
|  | ||||
|   .panel-corner { | ||||
|     -panel-corner-radius: $panel-corner-radius; | ||||
|     -panel-corner-background-color: rgba(0, 0, 0, 0.35); | ||||
|     -panel-corner-background-color: black; | ||||
|     -panel-corner-border-width: 2px; | ||||
|     -panel-corner-border-color: transparent; | ||||
|  | ||||
| @@ -767,9 +776,7 @@ StScrollBar { | ||||
|     -natural-hpadding: 12px; | ||||
|     -minimum-hpadding: 6px; | ||||
|     font-weight: bold; | ||||
|     color: #eee; | ||||
|     text-shadow: 0px 1px 2px rgba(0, 0, 0, 0.9); | ||||
|     transition-duration: 100ms; | ||||
|     color: #ccc; | ||||
|  | ||||
|     .app-menu-icon { | ||||
|       -st-icon-style: symbolic; | ||||
| @@ -778,21 +785,8 @@ StScrollBar { | ||||
|       //dimensions of the icon are hardcoded | ||||
|     } | ||||
|  | ||||
|     .system-status-icon, | ||||
|     .app-menu-icon > StIcon, | ||||
|     .popup-menu-arrow { | ||||
|       icon-shadow: 0px 1px 2px rgba(0, 0, 0, 0.9); | ||||
|     } | ||||
|  | ||||
|     &:hover { | ||||
|       color: lighten($fg_color, 10%); | ||||
|       text-shadow: 0px 1px 6px rgba(0, 0, 0, 1); | ||||
|  | ||||
|       .system-status-icon, | ||||
|       .app-menu-icon > StIcon, | ||||
|       .popup-menu-arrow { | ||||
|         icon-shadow: 0px 1px 6px rgba(0, 0, 0, 1); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     &:active, &:overview, &:focus, &:checked { | ||||
| @@ -801,8 +795,6 @@ StScrollBar { | ||||
|       background-color: rgba(0, 0, 0, 0.01); | ||||
|       box-shadow: inset 0 -2px 0px lighten($selected_bg_color,5%); | ||||
|       color: lighten($fg_color,10%); | ||||
|  | ||||
|       & > .system-status-icon { icon-shadow: black 0 2px 2px; } | ||||
|     } | ||||
|  | ||||
|     .system-status-icon { icon-size: 1.09em; padding: 0 5px; } | ||||
| @@ -827,31 +819,6 @@ StScrollBar { | ||||
|   .screencast-indicator { color: $warning_color; } | ||||
|  | ||||
|   .remote-access-indicator { color: $warning_color; } | ||||
|  | ||||
|   &.solid { | ||||
|     background-color: black; | ||||
|     /* transition from transparent to solid */ | ||||
|     transition-duration: 300ms; | ||||
|  | ||||
|     .panel-corner { | ||||
|       -panel-corner-background-color: black; | ||||
|     } | ||||
|  | ||||
|     .panel-button { | ||||
|       color: #ccc; | ||||
|       text-shadow: none; | ||||
|  | ||||
|       &:hover, &:active, &:overview, &:focus, &:checked { | ||||
|         color: lighten($fg_color, 10%); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .system-status-icon, | ||||
|     .app-menu-icon > StIcon, | ||||
|     .popup-menu-arrow { | ||||
|       icon-shadow: none; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
|   // calendar popover | ||||
| @@ -922,14 +889,47 @@ StScrollBar { | ||||
|       font-weight: bold; | ||||
|     } | ||||
|  | ||||
|     .world-clocks-grid { | ||||
|     .weather-header.location { | ||||
|       font-weight: normal; | ||||
|       font-size: 0.9em; | ||||
|     } | ||||
|  | ||||
|     .world-clocks-grid, | ||||
|     .weather-grid { | ||||
|       spacing-rows: 0.4em; | ||||
|       spacing-columns: 0.8em; | ||||
|     } | ||||
|  | ||||
|     .weather-box { | ||||
|       spacing: 0.4em; | ||||
|     } | ||||
|  | ||||
|     .world-clocks-city { | ||||
|       font-weight: bold; | ||||
|       font-size: 0.9em; | ||||
|     } | ||||
|  | ||||
|     .world-clocks-time { | ||||
|       color: darken($fg_color,20%); | ||||
|       font-feature-settings: "tnum"; | ||||
|       font-size: 1.2em; | ||||
|     } | ||||
|  | ||||
|     .world-clocks-timezone { | ||||
|       color: darken($fg_color,40%); | ||||
|       font-feature-settings: "tnum"; | ||||
|       font-size: 0.9em; | ||||
|     } | ||||
|  | ||||
|     .weather-forecast-icon { | ||||
|       icon-size: 2.18em; | ||||
|     } | ||||
|  | ||||
|     .weather-forecast-time { | ||||
|       color: darken($fg_color,40%); | ||||
|       font-size: 0.8em; | ||||
|     } | ||||
|  | ||||
|     .calendar-month-label { | ||||
|       color: darken($fg_color,5%); | ||||
|       font-weight: bold; | ||||
| @@ -1042,6 +1042,11 @@ StScrollBar { | ||||
|             -st-icon-style: symbolic; | ||||
|           } | ||||
|  | ||||
|           .message-icon-bin > .fallback-window-icon { | ||||
|             width: 1.09em; | ||||
|             height: 1.09em; | ||||
|           } | ||||
|  | ||||
|           .message-secondary-bin { | ||||
|             padding: 0 0.82em;; | ||||
|           } | ||||
| @@ -1091,11 +1096,7 @@ StScrollBar { | ||||
|  | ||||
|   // a little unstructured mess: | ||||
|  | ||||
|   .system-switch-user-submenu-icon.user-icon { | ||||
|     icon-size: 20px; | ||||
|     padding: 0 2px; | ||||
|   } | ||||
|   .system-switch-user-submenu-icon.default-icon { | ||||
|   .system-switch-user-submenu-icon { | ||||
|     icon-size: 16px; | ||||
|     padding: 0 4px; | ||||
|   } | ||||
| @@ -1107,6 +1108,11 @@ StScrollBar { | ||||
|     .label-shadow { color: transparent; } | ||||
|   } | ||||
|  | ||||
|   .app-menu, | ||||
|   .app-well-menu { | ||||
|     max-width: 27.25em; | ||||
|   } | ||||
|  | ||||
|   .aggregate-menu { | ||||
|     min-width: 21em; | ||||
|     .popup-menu-icon { padding: 0 4px; } | ||||
| @@ -1147,35 +1153,57 @@ StScrollBar { | ||||
|  | ||||
| .ripple-box:rtl { border-radius: 0 0 0 52px; } // just a simple change to the border radius position | ||||
|  | ||||
| // Rubberband for select-area screenshots | ||||
| .select-area-rubberband { | ||||
|   background-color: transparentize($selected_bg_color,0.7); | ||||
|   border: 1px solid $selected_bg_color; | ||||
| } | ||||
|  | ||||
| // Pointer location | ||||
| .ripple-pointer-location { | ||||
|   width: 50px; | ||||
|   height: 50px; | ||||
|   border-radius: 25px 25px 25px 25px; // radius the size of the box give us the curve | ||||
|   background-color: lighten(transparentize($selected_bg_color, 0.7), 30%); | ||||
|   box-shadow: 0 0 2px 2px lighten($selected_bg_color, 20%); | ||||
| } | ||||
|  | ||||
| // not really top bar only | ||||
| .popup-menu-arrow { width: 16px; height: 16px; } | ||||
| .popup-menu-arrow { icon-size: 1.09em; } | ||||
| .popup-menu-icon { icon-size: 1.09em; } | ||||
|  | ||||
| //close buttons | ||||
|  | ||||
| .window-close { | ||||
|   background-color: white; | ||||
|   background-color: $selected_bg_color; | ||||
|   color: white; | ||||
|   border-radius: 24px; | ||||
|   border: 4px solid $selected_bg_color; | ||||
|   box-shadow: inset 0 -4px 0 0 transparentize($selected_bg_color, 0.5); | ||||
|   color: $selected_bg_color; | ||||
|   border: 2px solid $selected_bg_color; | ||||
|   height: 24px; | ||||
|   width: 24px; | ||||
|   -shell-close-overlap: 14px; | ||||
|   -shell-close-overlap: 11px; | ||||
|   box-shadow: -1px 1px 5px 0px transparentize(black, 0.5); | ||||
|  | ||||
|   &:hover { | ||||
|     background-color: $selected_bg_color; | ||||
|     border-color: white; | ||||
|     color: white; | ||||
|     background-color: lighten($selected_bg_color, 5%); | ||||
|     border-color: lighten($selected_bg_color, 5%); | ||||
|   } | ||||
|  | ||||
|   &:active { | ||||
|     background-color: mix(white, $selected_bg_color, 75%); | ||||
|     border-color: $selected_bg_color; | ||||
|     color: $selected_bg_color; | ||||
|     background-color: darken($selected_bg_color, 5%); | ||||
|     border-color: darken($selected_bg_color, 5%); | ||||
|   } | ||||
| } | ||||
|  | ||||
| // Pointer accessibility notifications | ||||
| .pie-timer { | ||||
|   width: 60px; | ||||
|   height: 60px; | ||||
|   -pie-border-width: 3px; | ||||
|   -pie-border-color: $selected_bg_color; | ||||
|   -pie-background-color: lighten(transparentize($selected_bg_color, 0.7), 40%); | ||||
| } | ||||
|  | ||||
| /* NETWORK DIALOGS */ | ||||
|  | ||||
| .nm-dialog { | ||||
| @@ -1237,13 +1265,14 @@ StScrollBar { | ||||
|   } | ||||
|  | ||||
|   .window-clone-border { | ||||
|     border: 4px solid $selected_bg_color; | ||||
|     border-radius: 4px; | ||||
|     $_bg: transparentize(white, 0.65); | ||||
|     border: 5px solid $_bg; | ||||
|     border-radius: 6px; | ||||
|     // For window decorations with round corners we can't match | ||||
|     // the exact shape when the window is scaled. So apply a shadow | ||||
|     // to fix that case | ||||
|     box-shadow: inset 0px 0px 0px 1px $selected_bg_color; | ||||
|   } | ||||
|     box-shadow: inset 0 0 0 1px $_bg; | ||||
| } | ||||
|   .window-caption { | ||||
|     spacing: 25px; | ||||
|     color: $selected_fg_color; | ||||
| @@ -1294,6 +1323,8 @@ StScrollBar { | ||||
|  | ||||
|   .search-section-separator { height: 2px; background-color: rgba(255, 255, 255, 0.2); } | ||||
|  | ||||
|   .search-section:last-child .search-section-separator { background-color: transparent; } | ||||
|  | ||||
|   .list-search-result-content { spacing: 30px; } | ||||
|   .list-search-result-title { color: darken($osd_fg_color,5%); spacing: 12px; } | ||||
|   .list-search-result-description { color: transparentize(darken($osd_fg_color,15%), 0.5); } | ||||
| @@ -1456,13 +1487,13 @@ StScrollBar { | ||||
|       height: 12px; | ||||
|       background-color: transparent; | ||||
|       border: 2px solid rgba(255, 255, 255, 0.4); | ||||
|       border-radius:12px; | ||||
|       border-radius: 12px; | ||||
|     } | ||||
|  | ||||
|     &:hover .page-indicator-icon { border-color: white; } | ||||
|     &:active .page-indicator-icon { border: none; margin: 2px; background-color:#fff; } | ||||
|     &:active .page-indicator-icon { border: none; margin: 2px; background-color: white; } | ||||
|     &:checked .page-indicator-icon, | ||||
|     &:checked:active { background-color: #fff;} | ||||
|     &:checked:active .page-indicator-icon { background-color: white;} | ||||
|   } | ||||
|  | ||||
|   .no-frequent-applications-label { @extend %status_text; } | ||||
| @@ -1646,6 +1677,15 @@ StScrollBar { | ||||
|  | ||||
| #keyboard { | ||||
|     background-color: transparentize($osd_bg_color, 0.3); | ||||
|  | ||||
|     .page-indicator { | ||||
|         padding: 4px 4px; | ||||
|  | ||||
|         .page-indicator-icon { | ||||
|             width: 6px; | ||||
|             height: 6px | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
|   .key-container { | ||||
| @@ -1655,8 +1695,8 @@ StScrollBar { | ||||
|  | ||||
|   .keyboard-key { | ||||
|     background-color: #393f3f; | ||||
|     min-height: 2em; | ||||
|     min-width: 2em; | ||||
|     min-height: 1.2em; | ||||
|     min-width: 1.2em; | ||||
|     font-size: 16pt; | ||||
|     border-radius: 3px; | ||||
|     border: 1px solid #464d4d; | ||||
| @@ -1707,6 +1747,20 @@ StScrollBar { | ||||
|     -boxpointer-gap: 5px; | ||||
|   } | ||||
|  | ||||
| .emoji-page { | ||||
|   .keyboard-key { | ||||
|     background-color: transparent; | ||||
|     border: none; | ||||
|   } | ||||
| } | ||||
|  | ||||
| .emoji-panel { | ||||
|   .keyboard-key:latched { | ||||
|     border-color: #005684; | ||||
|     background-color: #006098; | ||||
|   } | ||||
| } | ||||
|  | ||||
| // IBus Candidate Popup | ||||
|  | ||||
| .candidate-popup-content { | ||||
| @@ -1741,13 +1795,11 @@ StScrollBar { | ||||
|  | ||||
| /* Auth Dialogs & Screen Shield */ | ||||
|  | ||||
| .framed-user-icon { | ||||
| .user-icon { | ||||
|   background-size: contain; | ||||
|   border: 2px solid $osd_fg_color; | ||||
|   color: $osd_fg_color; | ||||
|   border-radius: 3px; | ||||
|   border-radius: 99px; | ||||
|   &:hover { | ||||
|     border-color: lighten($osd_fg_color,30%); | ||||
|     color: lighten($osd_fg_color,30%); | ||||
|   } | ||||
| } | ||||
|   | ||||
							
								
								
									
										28
									
								
								data/theme/pointer-double-click-symbolic.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,28 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="20" | ||||
|    height="20" | ||||
|    id="svg2"> | ||||
|   <g | ||||
|      id="layer1" | ||||
|      style="display:inline"> | ||||
|     <g | ||||
|        id="id1" | ||||
|        transform="translate(-19,-0.75)"> | ||||
|       <path | ||||
|          style="color:#000000;shape-padding:0;clip-rule:nonzero;display:block;overflow:visible;visibility:visible;opacity:1;solid-color:#000000;solid-opacity:1;fill:#464646;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" | ||||
|          d="m 19.855469,0.45507812 c 0,6.69466128 0,13.38932288 0,20.08398388 1.414713,-1.38151 2.829427,-2.763021 4.24414,-4.144531 0.5882,1.18866 1.158389,2.386561 1.758464,3.569127 1.108631,1.640259 4.157538,0.465128 3.89799,-1.495859 0.01057,-0.470226 -0.405577,-0.908445 -0.434651,-1.313638 0.259401,-0.25321 0.518802,-0.50642 0.778203,-0.75963 0.5882,1.18866 1.158389,2.386561 1.758464,3.569127 1.108631,1.640259 4.157538,0.465128 3.89799,-1.495859 -0.192325,-0.904303 -0.717854,-1.698026 -1.068629,-2.548967 -0.238908,-0.512658 -0.477817,-1.025315 -0.716725,-1.537973 1.755859,0 3.511719,0 5.267578,0 C 34.777352,9.738932 30.31641,5.0970051 25.855469,0.45507812 c 0,2.08138018 0,4.16276048 0,6.24414068 -2,-2.0813802 -4,-4.1627605 -6,-6.24414068 z m 1.5,3.72656248 c 2,2.0813801 4,4.1627603 6,6.2441404 0,-2.0813801 0,-4.1627603 0,-6.2441404 2.786458,2.8997395 5.572917,5.7994789 8.359375,8.6992184 -1.366537,0 -2.733073,0 -4.09961,0 0.883468,1.903435 1.781983,3.800273 2.656081,5.707817 0.0065,0.622781 -1.227555,0.980575 -1.325116,0.207118 -0.80433,-1.640251 -1.608661,-3.280501 -2.412991,-4.920752 -1.020182,0.995443 -2.040365,1.990885 -3.060547,2.986328 0.263642,0.608048 0.596803,1.192457 0.814693,1.816134 -0.182662,0.601037 -1.26833,0.8373 -1.365856,0.06795 -0.796094,-1.623456 -1.592189,-3.246912 -2.388284,-4.870368 -1.059245,1.033854 -2.118489,2.067708 -3.177734,3.101562 -4e-6,-4.265002 -7e-6,-8.5300036 -1.1e-5,-12.7950054 z" | ||||
|          id="path5565" /> | ||||
|     </g> | ||||
|     <g | ||||
|        id="id2" | ||||
|        transform="translate(-25,-0.75)" /> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 2.5 KiB | 
							
								
								
									
										20
									
								
								data/theme/pointer-drag-symbolic.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,20 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="20" | ||||
|    height="20" | ||||
|    id="svg2"> | ||||
|   <g | ||||
|      id="g835"> | ||||
|     <path | ||||
|        style="color:#000000;shape-padding:0;clip-rule:nonzero;display:block;overflow:visible;visibility:visible;opacity:1;solid-color:#000000;solid-opacity:1;fill:#464646;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" | ||||
|        d="M 10.705078 1.671875 C 9.8685536 1.7465699 8.886927 1.5353073 8.2578125 2.2480469 C 8.0785627 2.7511513 7.8667422 2.9777446 7.3125 2.8652344 C 6.5186841 2.8141575 5.6105879 2.9190179 5.125 3.6386719 C 4.5700923 4.4696324 4.8113194 5.4949043 4.7578125 6.4316406 L 4.7578125 7.9335938 C 4.2480917 7.6156216 3.6258927 7.8015358 3.0585938 7.7519531 C 2.6157606 7.7312277 2.1774807 7.7771069 1.7402344 7.84375 C 1.7971654 10.529678 1.813967 13.217089 1.8613281 15.902344 C 1.9550191 17.204635 3.0933719 18.307155 4.40625 18.326172 C 5.0391993 18.341272 5.8885801 18.332951 6.6308594 18.337891 C 9.8526764 18.325821 13.076973 18.38774 16.296875 18.28125 C 17.459088 18.161027 18.510143 17.092798 18.367188 15.884766 L 18.367188 6.4042969 C 17.660379 5.4636119 16.551912 4.623434 15.308594 4.8339844 C 15.009045 4.3804158 14.822476 3.3608651 14.082031 3.0351562 C 13.727176 2.744118 13.242443 2.9253873 12.822266 2.8730469 C 12.524824 2.8003648 11.966366 3.0655864 11.953125 2.6210938 C 11.795774 2.0995736 11.23789 1.7125276 10.705078 1.671875 z M 10.599609 3.1757812 C 10.764131 3.4472414 10.782382 3.9294982 10.818359 4.3007812 C 10.824915 4.3076775 10.838155 4.3066925 10.845703 4.3125 C 10.836598 4.3123268 10.827465 4.3126732 10.818359 4.3125 L 11.3125 10.212891 L 11.976562 4.3710938 L 13.322266 4.375 C 13.858345 4.7645492 13.735252 5.5154752 13.876953 6.0976562 C 13.865826 6.1651282 13.88335 6.1937019 13.892578 6.234375 C 13.891928 6.2343667 13.891276 6.2343833 13.890625 6.234375 L 13.902344 6.3203125 L 14.384766 10.185547 L 15.048828 6.265625 C 15.622863 6.228498 16.206517 6.3041365 16.607422 6.7675781 C 17.017062 6.9844433 16.823063 7.4565491 16.867188 7.8261719 L 16.867188 16.167969 C 16.530129 17.131654 15.267211 16.71624 14.492188 16.828125 C 11.121671 16.841205 7.7500508 16.861953 4.3808594 16.814453 C 3.4051926 16.786173 3.2389196 15.744474 3.3398438 14.972656 C 3.3282027 13.065594 3.2950998 11.158732 3.2617188 9.2519531 C 3.5880829 9.2584131 3.9376766 9.2391948 4.25 9.2617188 C 4.7438842 10.17694 4.7346154 11.262903 4.7578125 12.277344 C 5.2504494 12.270544 5.8011939 12.317174 6.2578125 12.277344 C 6.2669593 9.7577406 6.2393741 7.2373172 6.2714844 4.71875 C 6.3763823 4.198849 7.0022289 4.409587 7.3828125 4.3652344 L 8.0585938 4.3652344 L 8.546875 10.212891 L 9.2167969 4.3359375 L 9.2128906 4.3359375 C 9.2438386 3.9531035 9.0622615 3.4401006 9.4609375 3.2167969 L 10.599609 3.1757812 z " | ||||
|        id="path5630" /> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 3.3 KiB | 
							
								
								
									
										26
									
								
								data/theme/pointer-primary-click-symbolic.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,26 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="20" | ||||
|    height="20" | ||||
|    id="svg2" | ||||
|    version="1.1"> | ||||
|   <g | ||||
|      id="layer1" | ||||
|      style="display:inline"> | ||||
|     <g | ||||
|        id="id1" | ||||
|        transform="translate(-22.25,-0.75)"> | ||||
|       <path | ||||
|          style="color:#000000;shape-padding:0;clip-rule:nonzero;display:block;overflow:visible;visibility:visible;opacity:1;solid-color:#000000;solid-opacity:1;fill:#464646;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" | ||||
|          d="m 25.855469,0.45507812 c 0,6.69466128 0,13.38932288 0,20.08398388 1.414713,-1.380859 2.829427,-2.761719 4.24414,-4.142578 0.612408,1.215372 1.173049,2.460221 1.819709,3.656095 1.141947,1.476279 3.975266,0.389006 3.846009,-1.473608 -0.09413,-0.822519 -0.594755,-1.521423 -0.899969,-2.277599 -0.298869,-0.640171 -0.597739,-1.280342 -0.896608,-1.920513 1.75651,0 3.513021,0 5.269531,0 C 34.777344,9.738932 30.316406,5.0970051 25.855469,0.45507812 Z m 1.5,3.72656248 c 2.786458,2.8997395 5.572917,5.7994789 8.359375,8.6992184 -1.367188,0 -2.734375,0 -4.101563,0 0.885072,1.903196 1.781799,3.80152 2.659622,5.707744 0.0349,0.566084 -1.149057,0.988823 -1.282093,0.297971 -0.818567,-1.671162 -1.637133,-3.342323 -2.455699,-5.013485 -1.059896,1.034505 -2.119791,2.06901 -3.179687,3.103515 1.5e-5,-4.264988 3e-5,-8.5299756 4.5e-5,-12.7949634 z" | ||||
|          id="path5565" /> | ||||
|     </g> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 1.9 KiB | 
							
								
								
									
										26
									
								
								data/theme/pointer-secondary-click-symbolic.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,26 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="20" | ||||
|    height="20" | ||||
|    id="svg2"> | ||||
|   <g | ||||
|      id="layer1" | ||||
|      style="display:inline;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none;stroke:#000000;stroke-opacity:1"> | ||||
|     <g | ||||
|        transform="matrix(-1,0,0,1,42,-0.75)" | ||||
|        id="g5847" | ||||
|        style="stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none;stroke:#000000;stroke-opacity:1"> | ||||
|       <path | ||||
|          style="color:#000000;shape-padding:0;clip-rule:nonzero;display:block;overflow:visible;visibility:visible;opacity:1;solid-color:#000000;solid-opacity:1;fill:#464646;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" | ||||
|          d="m 25.855469,0.45507812 c 0,6.69466128 0,13.38932288 0,20.08398388 1.414713,-1.380859 2.829427,-2.761719 4.24414,-4.142578 0.612408,1.215372 1.173049,2.460221 1.819709,3.656095 1.141947,1.476279 3.975266,0.389006 3.846009,-1.473608 -0.09413,-0.822519 -0.594755,-1.521423 -0.899969,-2.277599 -0.298869,-0.640171 -0.597739,-1.280342 -0.896608,-1.920513 1.75651,0 3.513021,0 5.269531,0 C 34.777344,9.738932 30.316406,5.0970051 25.855469,0.45507812 Z m 1.5,3.72656248 c 2.786458,2.8997395 5.572917,5.7994789 8.359375,8.6992184 -1.367188,0 -2.734375,0 -4.101563,0 0.885072,1.903196 1.781799,3.80152 2.659622,5.707744 0.0349,0.566084 -1.149057,0.988823 -1.282093,0.297971 -0.818567,-1.671162 -1.637133,-3.342323 -2.455699,-5.013485 -1.059896,1.034505 -2.119791,2.06901 -3.179687,3.103515 1.5e-5,-4.264988 3e-5,-8.5299756 4.5e-5,-12.7949634 z" | ||||
|          id="path5851" /> | ||||
|     </g> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 2.0 KiB | 
| @@ -10,124 +10,62 @@ | ||||
|    xmlns:xlink="http://www.w3.org/1999/xlink" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="65" | ||||
|    width="46" | ||||
|    height="22" | ||||
|    id="svg2857" | ||||
|    viewBox="0 0 46 22" | ||||
|    version="1.1" | ||||
|    inkscape:version="0.48.5 r10040" | ||||
|    sodipodi:docname="toggle-off-us.svg"> | ||||
|    id="svg2751" | ||||
|    inkscape:version="0.92.4 5da689c313, 2019-01-14" | ||||
|    sodipodi:docname="toggle-off-intl.svg"> | ||||
|   <defs | ||||
|      id="defs2859"> | ||||
|     <inkscape:perspective | ||||
|        sodipodi:type="inkscape:persp3d" | ||||
|        inkscape:vp_x="0 : 526.18109 : 1" | ||||
|        inkscape:vp_y="0 : 1000 : 0" | ||||
|        inkscape:vp_z="744.09448 : 526.18109 : 1" | ||||
|        inkscape:persp3d-origin="372.04724 : 350.78739 : 1" | ||||
|        id="perspective2865" /> | ||||
|     <inkscape:perspective | ||||
|        id="perspective2843" | ||||
|        inkscape:persp3d-origin="0.5 : 0.33333333 : 1" | ||||
|        inkscape:vp_z="1 : 0.5 : 1" | ||||
|        inkscape:vp_y="0 : 1000 : 0" | ||||
|        inkscape:vp_x="0 : 0.5 : 1" | ||||
|        sodipodi:type="inkscape:persp3d" /> | ||||
|      id="defs2745"> | ||||
|     <linearGradient | ||||
|        inkscape:collect="always" | ||||
|        xlink:href="#linearGradient76469-7-7-4" | ||||
|        id="linearGradient38024" | ||||
|        gradientUnits="userSpaceOnUse" | ||||
|        gradientTransform="matrix(1.0215462,0,0,1.0322581,717.22867,428.68472)" | ||||
|        x1="6" | ||||
|        y1="102.95528" | ||||
|        x2="6" | ||||
|        y2="84.505203" /> | ||||
|     <linearGradient | ||||
|        inkscape:collect="always" | ||||
|        id="linearGradient76469-7-7-4"> | ||||
|        id="linearGradient3329"> | ||||
|       <stop | ||||
|          style="stop-color:#2e3232;stop-opacity:1" | ||||
|          style="stop-color:#39393a;stop-opacity:1;" | ||||
|          offset="0" | ||||
|          id="stop76471-7-1-5" /> | ||||
|          id="stop3325" /> | ||||
|       <stop | ||||
|          style="stop-color:#3e4545;stop-opacity:1" | ||||
|          style="stop-color:#302f30;stop-opacity:1" | ||||
|          offset="1" | ||||
|          id="stop76473-9-0-0" /> | ||||
|     </linearGradient> | ||||
|     <inkscape:path-effect | ||||
|        effect="spiro" | ||||
|        id="path-effect77541-4" | ||||
|        is_visible="true" /> | ||||
|     <inkscape:path-effect | ||||
|        effect="spiro" | ||||
|        id="path-effect77541-4-0" | ||||
|        is_visible="true" /> | ||||
|     <linearGradient | ||||
|        inkscape:collect="always" | ||||
|        xlink:href="#linearGradient37802-8" | ||||
|        id="linearGradient12311-3-1-0-5-4" | ||||
|        gradientUnits="userSpaceOnUse" | ||||
|        gradientTransform="matrix(1.5918367,0,0,0.85714285,-256.56122,59.071426)" | ||||
|        x1="610.13782" | ||||
|        y1="501.43866" | ||||
|        x2="610.13782" | ||||
|        y2="492.52756" /> | ||||
|     <linearGradient | ||||
|        id="linearGradient37802-8" | ||||
|        inkscape:collect="always"> | ||||
|       <stop | ||||
|          id="stop37804-1" | ||||
|          offset="0" | ||||
|          style="stop-color:#2c2c2c;stop-opacity:1" /> | ||||
|       <stop | ||||
|          id="stop37806-8" | ||||
|          offset="1" | ||||
|          style="stop-color:#16191a;stop-opacity:1" /> | ||||
|          id="stop3327" /> | ||||
|     </linearGradient> | ||||
|     <linearGradient | ||||
|        y2="492.52756" | ||||
|        x2="610.13782" | ||||
|        y1="501.43866" | ||||
|        x1="610.13782" | ||||
|        gradientTransform="matrix(1.5918367,0,0,0.85714285,-900.56122,-423.92857)" | ||||
|        inkscape:collect="always" | ||||
|        xlink:href="#linearGradient3329" | ||||
|        id="linearGradient3331" | ||||
|        x1="53" | ||||
|        y1="294.42917" | ||||
|        x2="53" | ||||
|        y2="309.80417" | ||||
|        gradientUnits="userSpaceOnUse" | ||||
|        id="linearGradient13602" | ||||
|        xlink:href="#linearGradient37802-8" | ||||
|        inkscape:collect="always" /> | ||||
|        gradientTransform="translate(-42.760724)" /> | ||||
|   </defs> | ||||
|   <sodipodi:namedview | ||||
|      id="base" | ||||
|      pagecolor="#000000" | ||||
|      pagecolor="#535353" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1.0" | ||||
|      inkscape:pageopacity="1" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:zoom="1" | ||||
|      inkscape:cx="-5.0602834" | ||||
|      inkscape:cy="16.473273" | ||||
|      inkscape:cx="-19.436775" | ||||
|      inkscape:cy="-13.499723" | ||||
|      inkscape:document-units="px" | ||||
|      inkscape:current-layer="g37994" | ||||
|      inkscape:current-layer="layer1" | ||||
|      showgrid="false" | ||||
|      inkscape:window-width="2560" | ||||
|      inkscape:window-height="1375" | ||||
|      inkscape:window-x="0" | ||||
|      inkscape:window-y="27" | ||||
|      inkscape:window-maximized="1" | ||||
|      units="px" | ||||
|      inkscape:pagecheckerboard="true" | ||||
|      borderlayer="true" | ||||
|      inkscape:showpageshadow="false" | ||||
|      inkscape:snap-nodes="false" | ||||
|      inkscape:snap-bbox="true" | ||||
|      showborder="false"> | ||||
|     <inkscape:grid | ||||
|        type="xygrid" | ||||
|        id="grid12954" | ||||
|        empspacing="5" | ||||
|        visible="true" | ||||
|        enabled="true" | ||||
|        snapvisiblegridlinesonly="true" /> | ||||
|        id="grid3298" /> | ||||
|   </sodipodi:namedview> | ||||
|   <metadata | ||||
|      id="metadata2862"> | ||||
|      id="metadata2748"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
| @@ -142,68 +80,24 @@ | ||||
|      inkscape:label="Layer 1" | ||||
|      inkscape:groupmode="layer" | ||||
|      id="layer1" | ||||
|      transform="translate(-444.64286,-781.36218)"> | ||||
|     <g | ||||
|        transform="matrix(0.6526046,0,0,0.80554422,99.592644,-636.32172)" | ||||
|        id="g37994"> | ||||
|       <g | ||||
|          id="g37996" | ||||
|          transform="translate(-115,1277)"> | ||||
|         <rect | ||||
|            style="color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964000000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;opacity:0.19591837" | ||||
|            id="rect13475" | ||||
|            width="98" | ||||
|            height="25" | ||||
|            x="644.5" | ||||
|            y="484.61118" | ||||
|            rx="4.7429576" | ||||
|            ry="3.8424656" /> | ||||
|         <rect | ||||
|            ry="3.8424656" | ||||
|            rx="4.7429576" | ||||
|            y="483.5" | ||||
|            x="644.5" | ||||
|            height="25" | ||||
|            width="98" | ||||
|            id="rect38000" | ||||
|            style="color:#000000;fill:url(#linearGradient12311-3-1-0-5-4);fill-opacity:1;fill-rule:nonzero;stroke:#16191a;stroke-width:1.37920942;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" /> | ||||
|       </g> | ||||
|       <g | ||||
|          transform="translate(-49.946213,-1.890275)" | ||||
|          id="g38002"> | ||||
|         <g | ||||
|            transform="translate(-115,1247)" | ||||
|            style="display:inline" | ||||
|            id="g38004"> | ||||
|           <rect | ||||
|              ry="3.7972314" | ||||
|              rx="4.6871223" | ||||
|              y="515.5" | ||||
|              x="694.53046" | ||||
|              height="25" | ||||
|              width="45.969578" | ||||
|              id="rect38006" | ||||
|              style="color:#000000;fill:url(#linearGradient38024);fill-opacity:1;fill-rule:nonzero;stroke:#1f2020;stroke-width:1.37920964;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> | ||||
|           <path | ||||
|              sodipodi:nodetypes="cc" | ||||
|              style="opacity:0.1;color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964px;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||||
|              d="m 699.09675,516.7365 36.86904,0" | ||||
|              id="path38016" | ||||
|              inkscape:path-effect="#path-effect77541-4" | ||||
|              inkscape:original-d="m 699.09675,516.7365 36.86904,0" | ||||
|              inkscape:connector-curvature="0" /> | ||||
|         </g> | ||||
|       </g> | ||||
|       <path | ||||
|          sodipodi:type="arc" | ||||
|          style="color:#000000;fill:none;stroke:#ffffff;stroke-width:2.15627193;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" | ||||
|          id="path13479" | ||||
|          sodipodi:cx="16.4375" | ||||
|          sodipodi:cy="10.8125" | ||||
|          sodipodi:rx="4.3125" | ||||
|          sodipodi:ry="4.3125" | ||||
|          d="m 20.75,10.8125 a 4.3125,4.3125 0 1 1 -8.625,0 4.3125,4.3125 0 1 1 8.625,0 z" | ||||
|          transform="matrix(1.4212691,0,0,1.1514287,577.38488,1761.1138)" /> | ||||
|     </g> | ||||
|      transform="translate(0,-291.17916)"> | ||||
|     <rect | ||||
|        style="opacity:1;vector-effect:none;fill:#323233;fill-opacity:1;stroke:#272728;stroke-width:1.08532763;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" | ||||
|        id="rect3296" | ||||
|        width="44.446434" | ||||
|        height="20.910645" | ||||
|        x="0.625" | ||||
|        y="291.71494" | ||||
|        rx="10.455324" | ||||
|        ry="10.073335" /> | ||||
|     <rect | ||||
|        ry="10.455322" | ||||
|        rx="10.455322" | ||||
|        y="291.71494" | ||||
|        x="0.5428465" | ||||
|        height="20.910645" | ||||
|        width="21.142862" | ||||
|        id="rect3300" | ||||
|        style="opacity:1;vector-effect:none;fill:url(#linearGradient3331);fill-opacity:1;stroke:#151515;stroke-width:1.08532763;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" /> | ||||
|   </g> | ||||
| </svg> | ||||
|   | ||||
| Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 3.3 KiB | 
| @@ -1,255 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:xlink="http://www.w3.org/1999/xlink" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="65" | ||||
|    height="22" | ||||
|    id="svg2857" | ||||
|    version="1.1" | ||||
|    inkscape:version="0.48.5 r10040" | ||||
|    sodipodi:docname="toggle-on-intl.svg"> | ||||
|   <defs | ||||
|      id="defs2859"> | ||||
|     <inkscape:perspective | ||||
|        sodipodi:type="inkscape:persp3d" | ||||
|        inkscape:vp_x="0 : 526.18109 : 1" | ||||
|        inkscape:vp_y="0 : 1000 : 0" | ||||
|        inkscape:vp_z="744.09448 : 526.18109 : 1" | ||||
|        inkscape:persp3d-origin="372.04724 : 350.78739 : 1" | ||||
|        id="perspective2865" /> | ||||
|     <inkscape:perspective | ||||
|        id="perspective2843" | ||||
|        inkscape:persp3d-origin="0.5 : 0.33333333 : 1" | ||||
|        inkscape:vp_z="1 : 0.5 : 1" | ||||
|        inkscape:vp_y="0 : 1000 : 0" | ||||
|        inkscape:vp_x="0 : 0.5 : 1" | ||||
|        sodipodi:type="inkscape:persp3d" /> | ||||
|     <linearGradient | ||||
|        inkscape:collect="always" | ||||
|        xlink:href="#linearGradient76469-7-7-4" | ||||
|        id="linearGradient38024" | ||||
|        gradientUnits="userSpaceOnUse" | ||||
|        gradientTransform="matrix(1.0215462,0,0,1.0322581,717.22867,428.68472)" | ||||
|        x1="6" | ||||
|        y1="102.95528" | ||||
|        x2="6" | ||||
|        y2="84.505203" /> | ||||
|     <linearGradient | ||||
|        inkscape:collect="always" | ||||
|        id="linearGradient76469-7-7-4"> | ||||
|       <stop | ||||
|          style="stop-color:#2e3232;stop-opacity:1" | ||||
|          offset="0" | ||||
|          id="stop76471-7-1-5" /> | ||||
|       <stop | ||||
|          style="stop-color:#3e4545;stop-opacity:1" | ||||
|          offset="1" | ||||
|          id="stop76473-9-0-0" /> | ||||
|     </linearGradient> | ||||
|     <inkscape:path-effect | ||||
|        effect="spiro" | ||||
|        id="path-effect77541-4" | ||||
|        is_visible="true" /> | ||||
|     <linearGradient | ||||
|        inkscape:collect="always" | ||||
|        xlink:href="#linearGradient37802" | ||||
|        id="linearGradient12311-3-1-0-5" | ||||
|        gradientUnits="userSpaceOnUse" | ||||
|        gradientTransform="matrix(1.5918367,0,0,0.85714285,-256.56122,59.071426)" | ||||
|        x1="610.13782" | ||||
|        y1="501.43866" | ||||
|        x2="610.13782" | ||||
|        y2="492.52756" /> | ||||
|     <linearGradient | ||||
|        id="linearGradient37802" | ||||
|        inkscape:collect="always"> | ||||
|       <stop | ||||
|          id="stop37804" | ||||
|          offset="0" | ||||
|          style="stop-color:#2c2c2c;stop-opacity:1" /> | ||||
|       <stop | ||||
|          id="stop37806" | ||||
|          offset="1" | ||||
|          style="stop-color:#16191a;stop-opacity:1" /> | ||||
|     </linearGradient> | ||||
|     <linearGradient | ||||
|        inkscape:collect="always" | ||||
|        xlink:href="#linearGradient76469-7-7-4-3" | ||||
|        id="linearGradient77680" | ||||
|        gradientUnits="userSpaceOnUse" | ||||
|        gradientTransform="matrix(1,0,0,1.0322581,717.71949,428.68472)" | ||||
|        x1="6" | ||||
|        y1="102.95528" | ||||
|        x2="6" | ||||
|        y2="84.505203" /> | ||||
|     <linearGradient | ||||
|        inkscape:collect="always" | ||||
|        id="linearGradient76469-7-7-4-3"> | ||||
|       <stop | ||||
|          style="stop-color:#2e3232;stop-opacity:1" | ||||
|          offset="0" | ||||
|          id="stop76471-7-1-5-7" /> | ||||
|       <stop | ||||
|          style="stop-color:#3e4545;stop-opacity:1" | ||||
|          offset="1" | ||||
|          id="stop76473-9-0-0-9" /> | ||||
|     </linearGradient> | ||||
|     <inkscape:path-effect | ||||
|        effect="spiro" | ||||
|        id="path-effect77541-4-0" | ||||
|        is_visible="true" /> | ||||
|     <linearGradient | ||||
|        inkscape:collect="always" | ||||
|        xlink:href="#linearGradient37802-8" | ||||
|        id="linearGradient12311-3-1-0-5-4" | ||||
|        gradientUnits="userSpaceOnUse" | ||||
|        gradientTransform="matrix(1.5918367,0,0,0.85714285,-256.56122,59.071426)" | ||||
|        x1="610.13782" | ||||
|        y1="501.43866" | ||||
|        x2="610.13782" | ||||
|        y2="492.52756" /> | ||||
|     <linearGradient | ||||
|        id="linearGradient37802-8" | ||||
|        inkscape:collect="always"> | ||||
|       <stop | ||||
|          id="stop37804-1" | ||||
|          offset="0" | ||||
|          style="stop-color:#2c2c2c;stop-opacity:1" /> | ||||
|       <stop | ||||
|          id="stop37806-8" | ||||
|          offset="1" | ||||
|          style="stop-color:#16191a;stop-opacity:1" /> | ||||
|     </linearGradient> | ||||
|     <linearGradient | ||||
|        y2="492.52756" | ||||
|        x2="610.13782" | ||||
|        y1="501.43866" | ||||
|        x1="610.13782" | ||||
|        gradientTransform="matrix(1.5918367,0,0,0.85714285,-900.56122,-423.92857)" | ||||
|        gradientUnits="userSpaceOnUse" | ||||
|        id="linearGradient13602" | ||||
|        xlink:href="#linearGradient37802-8" | ||||
|        inkscape:collect="always" /> | ||||
|   </defs> | ||||
|   <sodipodi:namedview | ||||
|      id="base" | ||||
|      pagecolor="#000000" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1.0" | ||||
|      inkscape:pageopacity="1" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:zoom="1" | ||||
|      inkscape:cx="16.760995" | ||||
|      inkscape:cy="21.955673" | ||||
|      inkscape:document-units="px" | ||||
|      inkscape:current-layer="g37994" | ||||
|      showgrid="false" | ||||
|      inkscape:window-width="2560" | ||||
|      inkscape:window-height="1375" | ||||
|      inkscape:window-x="0" | ||||
|      inkscape:window-y="27" | ||||
|      inkscape:window-maximized="1" | ||||
|      borderlayer="true" | ||||
|      inkscape:showpageshadow="false" | ||||
|      inkscape:snap-nodes="false" | ||||
|      inkscape:snap-bbox="true" | ||||
|      showborder="false"> | ||||
|     <inkscape:grid | ||||
|        type="xygrid" | ||||
|        id="grid12954" | ||||
|        empspacing="5" | ||||
|        visible="true" | ||||
|        enabled="true" | ||||
|        snapvisiblegridlinesonly="true" /> | ||||
|   </sodipodi:namedview> | ||||
|   <metadata | ||||
|      id="metadata2862"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|         <dc:title></dc:title> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <g | ||||
|      inkscape:label="Layer 1" | ||||
|      inkscape:groupmode="layer" | ||||
|      id="layer1" | ||||
|      transform="translate(-444.64286,-781.36218)"> | ||||
|     <g | ||||
|        transform="matrix(0.6526046,0,0,0.80554422,99.592644,-636.32172)" | ||||
|        id="g37994"> | ||||
|       <g | ||||
|          id="g37996" | ||||
|          transform="translate(-115,1277)"> | ||||
|         <rect | ||||
|            style="color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964000000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;opacity:0.19591837" | ||||
|            id="rect13475" | ||||
|            width="98" | ||||
|            height="25" | ||||
|            x="644.5" | ||||
|            y="484.61118" | ||||
|            rx="4.7429576" | ||||
|            ry="3.8424656" /> | ||||
|         <rect | ||||
|            ry="3.8424656" | ||||
|            rx="4.7429576" | ||||
|            y="483.5" | ||||
|            x="644.5" | ||||
|            height="25" | ||||
|            width="98" | ||||
|            id="rect38000" | ||||
|            style="color:#000000;fill:url(#linearGradient12311-3-1-0-5-4);fill-opacity:1;fill-rule:nonzero;stroke:#16191a;stroke-width:1.37920942;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" /> | ||||
|       </g> | ||||
|       <g | ||||
|          transform="translate(-49.946213,-1.890275)" | ||||
|          id="g38002"> | ||||
|         <g | ||||
|            transform="translate(-115,1247)" | ||||
|            style="display:inline" | ||||
|            id="g38004"> | ||||
|           <rect | ||||
|              ry="3.7972314" | ||||
|              rx="4.6871223" | ||||
|              y="515.5" | ||||
|              x="694.53046" | ||||
|              height="25" | ||||
|              width="45.969578" | ||||
|              id="rect38006" | ||||
|              style="color:#000000;fill:url(#linearGradient38024);fill-opacity:1;fill-rule:nonzero;stroke:#1f2020;stroke-width:1.37920964;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> | ||||
|           <path | ||||
|              sodipodi:nodetypes="cc" | ||||
|              style="opacity:0.1;color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964px;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||||
|              d="m 699.09675,516.7365 36.86904,0" | ||||
|              id="path38016" | ||||
|              inkscape:path-effect="#path-effect77541-4" | ||||
|              inkscape:original-d="m 699.09675,516.7365 36.86904,0" | ||||
|              inkscape:connector-curvature="0" /> | ||||
|         </g> | ||||
|       </g> | ||||
|       <text | ||||
|          xml:space="preserve" | ||||
|          style="font-size:13.79166794px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold" | ||||
|          x="520.29974" | ||||
|          y="1997.0011" | ||||
|          id="text75614" | ||||
|          sodipodi:linespacing="125%" | ||||
|          transform="scale(1.1236771,0.88993537)"><tspan | ||||
|            sodipodi:role="line" | ||||
|            id="tspan75616" | ||||
|            x="520.29974" | ||||
|            y="1997.0011">OFF</tspan></text> | ||||
|     </g> | ||||
|   </g> | ||||
| </svg> | ||||
| Before Width: | Height: | Size: 8.8 KiB | 
| @@ -10,117 +10,69 @@ | ||||
|    xmlns:xlink="http://www.w3.org/1999/xlink" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="65" | ||||
|    width="46" | ||||
|    height="22" | ||||
|    id="svg2857" | ||||
|    viewBox="0 0 46 22" | ||||
|    version="1.1" | ||||
|    inkscape:version="0.91 r13725" | ||||
|    id="svg2751" | ||||
|    inkscape:version="0.92.4 5da689c313, 2019-01-14" | ||||
|    sodipodi:docname="toggle-on-intl.svg"> | ||||
|   <defs | ||||
|      id="defs2859"> | ||||
|     <inkscape:perspective | ||||
|        sodipodi:type="inkscape:persp3d" | ||||
|        inkscape:vp_x="0 : 526.18109 : 1" | ||||
|        inkscape:vp_y="0 : 1000 : 0" | ||||
|        inkscape:vp_z="744.09448 : 526.18109 : 1" | ||||
|        inkscape:persp3d-origin="372.04724 : 350.78739 : 1" | ||||
|        id="perspective2865" /> | ||||
|     <inkscape:perspective | ||||
|        id="perspective2843" | ||||
|        inkscape:persp3d-origin="0.5 : 0.33333333 : 1" | ||||
|        inkscape:vp_z="1 : 0.5 : 1" | ||||
|        inkscape:vp_y="0 : 1000 : 0" | ||||
|        inkscape:vp_x="0 : 0.5 : 1" | ||||
|        sodipodi:type="inkscape:persp3d" /> | ||||
|      id="defs2745"> | ||||
|     <linearGradient | ||||
|        inkscape:collect="always" | ||||
|        xlink:href="#linearGradient77461" | ||||
|        id="linearGradient77551" | ||||
|        gradientUnits="userSpaceOnUse" | ||||
|        gradientTransform="matrix(1.3066667,0,0,1,-841.64667,-483)" | ||||
|        x1="1164.7644" | ||||
|        y1="962.93695" | ||||
|        x2="1164.7644" | ||||
|        y2="970.51404" /> | ||||
|     <linearGradient | ||||
|        id="linearGradient77461" | ||||
|        inkscape:collect="always"> | ||||
|        id="linearGradient3329"> | ||||
|       <stop | ||||
|          id="stop77463" | ||||
|          style="stop-color:#39393a;stop-opacity:1;" | ||||
|          offset="0" | ||||
|          style="stop-color:#182f4c;stop-opacity:1" /> | ||||
|          id="stop3325" /> | ||||
|       <stop | ||||
|          id="stop77465" | ||||
|          style="stop-color:#302f30;stop-opacity:1" | ||||
|          offset="1" | ||||
|          style="stop-color:#205b9a;stop-opacity:1" /> | ||||
|          id="stop3327" /> | ||||
|     </linearGradient> | ||||
|     <linearGradient | ||||
|        inkscape:collect="always" | ||||
|        xlink:href="#linearGradient76469-7-7-4" | ||||
|        id="linearGradient38024" | ||||
|        xlink:href="#linearGradient3329" | ||||
|        id="linearGradient3331" | ||||
|        x1="53" | ||||
|        y1="294.42917" | ||||
|        x2="53" | ||||
|        y2="309.80417" | ||||
|        gradientUnits="userSpaceOnUse" | ||||
|        gradientTransform="matrix(1.0215462,0,0,1.0322581,717.22867,428.68472)" | ||||
|        x1="6" | ||||
|        y1="102.95528" | ||||
|        x2="6" | ||||
|        y2="84.505203" /> | ||||
|     <linearGradient | ||||
|        inkscape:collect="always" | ||||
|        id="linearGradient76469-7-7-4"> | ||||
|       <stop | ||||
|          style="stop-color:#2e3232;stop-opacity:1" | ||||
|          offset="0" | ||||
|          id="stop76471-7-1-5" /> | ||||
|       <stop | ||||
|          style="stop-color:#3e4545;stop-opacity:1" | ||||
|          offset="1" | ||||
|          id="stop76473-9-0-0" /> | ||||
|     </linearGradient> | ||||
|     <inkscape:path-effect | ||||
|        effect="spiro" | ||||
|        id="path-effect77541-4" | ||||
|        is_visible="true" /> | ||||
|        gradientTransform="translate(-19)" /> | ||||
|   </defs> | ||||
|   <sodipodi:namedview | ||||
|      id="base" | ||||
|      pagecolor="#000000" | ||||
|      pagecolor="#535353" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1.0" | ||||
|      inkscape:pageopacity="1" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:zoom="1" | ||||
|      inkscape:cx="37.410841" | ||||
|      inkscape:cy="16.009314" | ||||
|      inkscape:cx="13.588971" | ||||
|      inkscape:cy="14.124546" | ||||
|      inkscape:document-units="px" | ||||
|      inkscape:current-layer="g37994" | ||||
|      inkscape:current-layer="layer1" | ||||
|      showgrid="false" | ||||
|      inkscape:window-width="2560" | ||||
|      inkscape:window-height="1376" | ||||
|      inkscape:window-x="0" | ||||
|      inkscape:window-y="27" | ||||
|      inkscape:window-maximized="1" | ||||
|      units="px" | ||||
|      inkscape:pagecheckerboard="true" | ||||
|      borderlayer="true" | ||||
|      inkscape:showpageshadow="false" | ||||
|      inkscape:snap-nodes="false" | ||||
|      inkscape:snap-bbox="true" | ||||
|      showborder="false"> | ||||
|     <inkscape:grid | ||||
|        type="xygrid" | ||||
|        id="grid12954" | ||||
|        empspacing="5" | ||||
|        visible="true" | ||||
|        enabled="true" | ||||
|        snapvisiblegridlinesonly="true" /> | ||||
|        id="grid3298" /> | ||||
|   </sodipodi:namedview> | ||||
|   <metadata | ||||
|      id="metadata2862"> | ||||
|      id="metadata2748"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|         <dc:title /> | ||||
|         <dc:title></dc:title> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
| @@ -128,65 +80,24 @@ | ||||
|      inkscape:label="Layer 1" | ||||
|      inkscape:groupmode="layer" | ||||
|      id="layer1" | ||||
|      transform="translate(-444.64286,-781.36218)"> | ||||
|     <g | ||||
|        transform="matrix(0.6526046,0,0,0.80554422,99.592644,-636.32172)" | ||||
|        id="g37994"> | ||||
|       <g | ||||
|          id="g37996" | ||||
|          transform="translate(-115,1277)"> | ||||
|         <rect | ||||
|            style="color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964000000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;opacity:0.19591837" | ||||
|            id="rect13475" | ||||
|            width="98" | ||||
|            height="25" | ||||
|            x="644.5" | ||||
|            y="484.61118" | ||||
|            rx="4.7429576" | ||||
|            ry="3.8424656" /> | ||||
|         <rect | ||||
|            ry="3.8424656" | ||||
|            rx="4.7429576" | ||||
|            y="483.5" | ||||
|            x="644.5" | ||||
|            height="25" | ||||
|            width="98" | ||||
|            id="rect38000" | ||||
|            style="color:#000000;fill:url(#linearGradient77551);fill-opacity:1;fill-rule:nonzero;stroke:#182f4c;stroke-width:1.37920964;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> | ||||
|       </g> | ||||
|       <g | ||||
|          transform="translate(2.0625,-2)" | ||||
|          id="g38002"> | ||||
|         <g | ||||
|            transform="translate(-115,1247)" | ||||
|            style="display:inline" | ||||
|            id="g38004"> | ||||
|           <rect | ||||
|              ry="3.7972314" | ||||
|              rx="4.6871223" | ||||
|              y="515.5" | ||||
|              x="694.53046" | ||||
|              height="25" | ||||
|              width="45.969578" | ||||
|              id="rect38006" | ||||
|              style="color:#000000;fill:url(#linearGradient38024);fill-opacity:1;fill-rule:nonzero;stroke:#1f2020;stroke-width:1.37920964;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> | ||||
|           <path | ||||
|              sodipodi:nodetypes="cc" | ||||
|              style="opacity:0.1;color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964px;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||||
|              d="m 699.09675,516.7365 36.86904,0" | ||||
|              id="path38016" | ||||
|              inkscape:path-effect="#path-effect77541-4" | ||||
|              inkscape:original-d="m 699.09675,516.7365 36.86904,0" | ||||
|              inkscape:connector-curvature="0" /> | ||||
|         </g> | ||||
|       </g> | ||||
|       <rect | ||||
|          style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999994;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" | ||||
|          id="rect13678" | ||||
|          width="3.0646207" | ||||
|          height="12.414008" | ||||
|          x="554.77728" | ||||
|          y="1767.3566" /> | ||||
|     </g> | ||||
|      transform="translate(0,-291.17916)"> | ||||
|     <rect | ||||
|        style="opacity:1;vector-effect:none;fill:#15539e;fill-opacity:1;stroke:#030e1b;stroke-width:1.08532763;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" | ||||
|        id="rect3296" | ||||
|        width="44.446434" | ||||
|        height="20.910645" | ||||
|        x="0.625" | ||||
|        y="291.71494" | ||||
|        rx="10.455324" | ||||
|        ry="10.073335" /> | ||||
|     <rect | ||||
|        ry="10.455322" | ||||
|        rx="10.455322" | ||||
|        y="291.71494" | ||||
|        x="24.30357" | ||||
|        height="20.910645" | ||||
|        width="21.142862" | ||||
|        id="rect3300" | ||||
|        style="opacity:1;vector-effect:none;fill:url(#linearGradient3331);fill-opacity:1;stroke:#030e1b;stroke-width:1.08532763;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" /> | ||||
|   </g> | ||||
| </svg> | ||||
|   | ||||
| Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 3.3 KiB | 
| @@ -1,207 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:xlink="http://www.w3.org/1999/xlink" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="65" | ||||
|    height="22" | ||||
|    id="svg2857" | ||||
|    version="1.1" | ||||
|    inkscape:version="0.91 r13725" | ||||
|    sodipodi:docname="toggle-on-us.svg"> | ||||
|   <defs | ||||
|      id="defs2859"> | ||||
|     <inkscape:perspective | ||||
|        sodipodi:type="inkscape:persp3d" | ||||
|        inkscape:vp_x="0 : 526.18109 : 1" | ||||
|        inkscape:vp_y="0 : 1000 : 0" | ||||
|        inkscape:vp_z="744.09448 : 526.18109 : 1" | ||||
|        inkscape:persp3d-origin="372.04724 : 350.78739 : 1" | ||||
|        id="perspective2865" /> | ||||
|     <inkscape:perspective | ||||
|        id="perspective2843" | ||||
|        inkscape:persp3d-origin="0.5 : 0.33333333 : 1" | ||||
|        inkscape:vp_z="1 : 0.5 : 1" | ||||
|        inkscape:vp_y="0 : 1000 : 0" | ||||
|        inkscape:vp_x="0 : 0.5 : 1" | ||||
|        sodipodi:type="inkscape:persp3d" /> | ||||
|     <linearGradient | ||||
|        inkscape:collect="always" | ||||
|        xlink:href="#linearGradient76469-7-7-4" | ||||
|        id="linearGradient38024" | ||||
|        gradientUnits="userSpaceOnUse" | ||||
|        gradientTransform="matrix(1.0215462,0,0,1.0322581,717.22867,428.68472)" | ||||
|        x1="6" | ||||
|        y1="102.95528" | ||||
|        x2="6" | ||||
|        y2="84.505203" /> | ||||
|     <linearGradient | ||||
|        inkscape:collect="always" | ||||
|        id="linearGradient76469-7-7-4"> | ||||
|       <stop | ||||
|          style="stop-color:#2e3232;stop-opacity:1" | ||||
|          offset="0" | ||||
|          id="stop76471-7-1-5" /> | ||||
|       <stop | ||||
|          style="stop-color:#3e4545;stop-opacity:1" | ||||
|          offset="1" | ||||
|          id="stop76473-9-0-0" /> | ||||
|     </linearGradient> | ||||
|     <inkscape:path-effect | ||||
|        effect="spiro" | ||||
|        id="path-effect77541-4" | ||||
|        is_visible="true" /> | ||||
|     <linearGradient | ||||
|        id="linearGradient77461-1" | ||||
|        inkscape:collect="always"> | ||||
|       <stop | ||||
|          id="stop77463-1" | ||||
|          offset="0" | ||||
|          style="stop-color:#182f4c;stop-opacity:1" /> | ||||
|       <stop | ||||
|          id="stop77465-4" | ||||
|          offset="1" | ||||
|          style="stop-color:#205b9a;stop-opacity:1" /> | ||||
|     </linearGradient> | ||||
|     <linearGradient | ||||
|        inkscape:collect="always" | ||||
|        xlink:href="#linearGradient77461-1" | ||||
|        id="linearGradient77551-6-5" | ||||
|        gradientUnits="userSpaceOnUse" | ||||
|        gradientTransform="matrix(0.8527367,0,0,0.80554422,-969.41608,-778.00299)" | ||||
|        x1="1164.7644" | ||||
|        y1="962.93695" | ||||
|        x2="1164.7644" | ||||
|        y2="970.51404" /> | ||||
|     <linearGradient | ||||
|        inkscape:collect="always" | ||||
|        xlink:href="#linearGradient77461-1" | ||||
|        id="linearGradient11198" | ||||
|        gradientUnits="userSpaceOnUse" | ||||
|        gradientTransform="matrix(1.3066667,0,0,1,-1066.3709,794.25325)" | ||||
|        x1="1322.5831" | ||||
|        y1="-312.51855" | ||||
|        x2="1322.5831" | ||||
|        y2="-306.53461" /> | ||||
|   </defs> | ||||
|   <sodipodi:namedview | ||||
|      id="base" | ||||
|      pagecolor="#000000" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1.0" | ||||
|      inkscape:pageopacity="1" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:zoom="1" | ||||
|      inkscape:cx="-26.798898" | ||||
|      inkscape:cy="5.3753009" | ||||
|      inkscape:document-units="px" | ||||
|      inkscape:current-layer="g37994" | ||||
|      showgrid="false" | ||||
|      inkscape:window-width="2560" | ||||
|      inkscape:window-height="1376" | ||||
|      inkscape:window-x="0" | ||||
|      inkscape:window-y="27" | ||||
|      inkscape:window-maximized="1" | ||||
|      borderlayer="true" | ||||
|      inkscape:showpageshadow="false" | ||||
|      inkscape:snap-nodes="false" | ||||
|      inkscape:snap-bbox="true" | ||||
|      showborder="false"> | ||||
|     <inkscape:grid | ||||
|        type="xygrid" | ||||
|        id="grid12954" | ||||
|        empspacing="5" | ||||
|        visible="true" | ||||
|        enabled="true" | ||||
|        snapvisiblegridlinesonly="true" /> | ||||
|   </sodipodi:namedview> | ||||
|   <metadata | ||||
|      id="metadata2862"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|         <dc:title /> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <g | ||||
|      inkscape:label="Layer 1" | ||||
|      inkscape:groupmode="layer" | ||||
|      id="layer1" | ||||
|      transform="translate(-444.64286,-781.36218)"> | ||||
|     <g | ||||
|        transform="matrix(0.6526046,0,0,0.80554422,99.592644,-636.32172)" | ||||
|        id="g37994"> | ||||
|       <g | ||||
|          id="g37996" | ||||
|          transform="translate(-115,1277)"> | ||||
|         <rect | ||||
|            style="color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964000000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;opacity:0.19591837" | ||||
|            id="rect13475" | ||||
|            width="98" | ||||
|            height="25" | ||||
|            x="644.5" | ||||
|            y="484.61118" | ||||
|            rx="4.7429576" | ||||
|            ry="3.8424656" /> | ||||
|         <rect | ||||
|            ry="3.8424656" | ||||
|            rx="4.7429576" | ||||
|            y="483.5" | ||||
|            x="644.5" | ||||
|            height="25" | ||||
|            width="98" | ||||
|            id="rect38000" | ||||
|            style="color:#000000;fill:url(#linearGradient11198);fill-opacity:1;fill-rule:nonzero;stroke:#182f4c;stroke-width:1.37920964;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;clip-rule:nonzero;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;filter-blend-mode:normal;filter-gaussianBlur-deviation:0;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto" /> | ||||
|       </g> | ||||
|       <g | ||||
|          transform="translate(2.0625,-2)" | ||||
|          id="g38002"> | ||||
|         <g | ||||
|            transform="translate(-115,1247)" | ||||
|            style="display:inline" | ||||
|            id="g38004"> | ||||
|           <rect | ||||
|              ry="3.7972314" | ||||
|              rx="4.6871223" | ||||
|              y="515.5" | ||||
|              x="694.53046" | ||||
|              height="25" | ||||
|              width="45.969578" | ||||
|              id="rect38006" | ||||
|              style="color:#000000;fill:url(#linearGradient38024);fill-opacity:1;fill-rule:nonzero;stroke:#1f2020;stroke-width:1.37920964;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> | ||||
|           <path | ||||
|              sodipodi:nodetypes="cc" | ||||
|              style="opacity:0.1;color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964px;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||||
|              d="m 699.09675,516.7365 36.86904,0" | ||||
|              id="path38016" | ||||
|              inkscape:path-effect="#path-effect77541-4" | ||||
|              inkscape:original-d="m 699.09675,516.7365 36.86904,0" | ||||
|              inkscape:connector-curvature="0" /> | ||||
|         </g> | ||||
|       </g> | ||||
|       <text | ||||
|          transform="scale(1.1000946,0.90901274)" | ||||
|          sodipodi:linespacing="125%" | ||||
|          id="text38018" | ||||
|          y="1955.5205" | ||||
|          x="495.94223" | ||||
|          style="font-size:13.29953671px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold" | ||||
|          xml:space="preserve"><tspan | ||||
|            y="1955.5205" | ||||
|            x="495.94223" | ||||
|            id="tspan38020" | ||||
|            sodipodi:role="line">ON</tspan></text> | ||||
|     </g> | ||||
|   </g> | ||||
| </svg> | ||||
| Before Width: | Height: | Size: 7.7 KiB | 
| @@ -40,6 +40,7 @@ do | ||||
| done | ||||
|  | ||||
| cat >>$TMP_GRESOURCE_FILE <<EOF | ||||
|     <file>emoji.json</file> | ||||
|   </gresource> | ||||
| </gresources> | ||||
| EOF | ||||
|   | ||||
| @@ -1,10 +1,5 @@ | ||||
| const Gettext = imports.gettext; | ||||
| const GLib = imports.gi.GLib; | ||||
| const GObject = imports.gi.GObject; | ||||
| const Gio = imports.gi.Gio; | ||||
| const Gtk = imports.gi.Gtk; | ||||
| const Gdk = imports.gi.Gdk; | ||||
| const Pango = imports.gi.Pango; | ||||
| const { Gdk, GLib, Gio, GObject, Gtk, Pango } = imports.gi; | ||||
| const Format = imports.format; | ||||
|  | ||||
| const _ = Gettext.gettext; | ||||
| @@ -104,29 +99,111 @@ var Application = class { | ||||
|     } | ||||
|  | ||||
|     _buildErrorUI(extension, exc) { | ||||
|         let box = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL }); | ||||
|         let scroll = new Gtk.ScrolledWindow({ | ||||
|             hscrollbar_policy: Gtk.PolicyType.NEVER, | ||||
|             propagate_natural_height: true | ||||
|         }); | ||||
|  | ||||
|         let box = new Gtk.Box({ | ||||
|             orientation: Gtk.Orientation.VERTICAL, | ||||
|             spacing: 12, | ||||
|             margin: 100, | ||||
|             margin_bottom: 60 | ||||
|         }); | ||||
|         scroll.add(box); | ||||
|  | ||||
|         let label = new Gtk.Label({ | ||||
|             label: _("There was an error loading the preferences dialog for %s:").format(extension.metadata.name) | ||||
|             label: '<span size="x-large">%s</span>'.format(_("Something’s gone wrong")), | ||||
|             use_markup: true | ||||
|         }); | ||||
|         label.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL); | ||||
|         box.add(label); | ||||
|  | ||||
|         label = new Gtk.Label({ | ||||
|             label: _("We’re very sorry, but there’s been a problem: the settings for this extension can’t be displayed. We recommend that you report the issue to the extension authors."), | ||||
|             justify: Gtk.Justification.CENTER, | ||||
|             wrap: true | ||||
|         }); | ||||
|         box.add(label); | ||||
|  | ||||
|         let errortext = ''; | ||||
|         errortext += exc; | ||||
|         errortext += '\n\n'; | ||||
|         errortext += 'Stack trace:\n'; | ||||
|         let expander = new Expander({ | ||||
|             label: _("Technical Details"), | ||||
|             margin_top: 12 | ||||
|         }); | ||||
|         box.add(expander); | ||||
|  | ||||
|         // Indent stack trace. | ||||
|         errortext += exc.stack.split('\n').map(line => '  ' + line).join('\n'); | ||||
|         let errortext = `${exc}\n\nStack trace:\n${ | ||||
|             // Indent stack trace. | ||||
|             exc.stack.split('\n').map(line => `  ${line}`).join('\n') | ||||
|         }`; | ||||
|  | ||||
|         let scroll = new Gtk.ScrolledWindow({ vexpand: true }); | ||||
|         let buffer = new Gtk.TextBuffer({ text: errortext }); | ||||
|         let textview = new Gtk.TextView({ buffer: buffer }); | ||||
|         textview.override_font(Pango.font_description_from_string('monospace')); | ||||
|         scroll.add(textview); | ||||
|         box.add(scroll); | ||||
|         let textview = new Gtk.TextView({ | ||||
|             buffer: buffer, | ||||
|             wrap_mode: Gtk.WrapMode.WORD, | ||||
|             monospace: true, | ||||
|             editable: false, | ||||
|             top_margin: 12, | ||||
|             bottom_margin: 12, | ||||
|             left_margin: 12, | ||||
|             right_margin: 12 | ||||
|         }); | ||||
|  | ||||
|         box.show_all(); | ||||
|         return box; | ||||
|         let toolbar = new Gtk.Toolbar(); | ||||
|         let provider = new Gtk.CssProvider(); | ||||
|         provider.load_from_data(`* { | ||||
|             border: 0 solid @borders; | ||||
|             border-top-width: 1px; | ||||
|         }`); | ||||
|         toolbar.get_style_context().add_provider( | ||||
|             provider, | ||||
|             Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION | ||||
|         ); | ||||
|  | ||||
|         let copyButton = new Gtk.ToolButton({ | ||||
|             icon_name: 'edit-copy-symbolic', | ||||
|             tooltip_text: _("Copy Error") | ||||
|         }); | ||||
|         toolbar.add(copyButton); | ||||
|  | ||||
|         copyButton.connect('clicked', w => { | ||||
|             let clipboard = Gtk.Clipboard.get_default(w.get_display()); | ||||
|             let backticks = '```'; | ||||
|             clipboard.set_text( | ||||
|                 // markdown for pasting in gitlab issues | ||||
|                 `The settings of extension ${extension.uuid} had an error:\n${ | ||||
|                 backticks}\n${exc}\n${backticks}\n\nStack trace:\n${ | ||||
|                 backticks}\n${exc.stack}${backticks}\n`, -1 | ||||
|             ); | ||||
|         }); | ||||
|  | ||||
|         let spacing = new Gtk.SeparatorToolItem({ draw: false }); | ||||
|         toolbar.add(spacing); | ||||
|         toolbar.child_set_property(spacing, "expand", true); | ||||
|  | ||||
|         let urlButton = new Gtk.ToolButton({ | ||||
|             label: _("Homepage"), | ||||
|             tooltip_text: _("Visit extension homepage"), | ||||
|             no_show_all: true, | ||||
|             visible: extension.metadata.url != null | ||||
|         }); | ||||
|         toolbar.add(urlButton); | ||||
|  | ||||
|         urlButton.connect('clicked', w => { | ||||
|             let context = w.get_display().get_app_launch_context(); | ||||
|             Gio.AppInfo.launch_default_for_uri(extension.metadata.url, context); | ||||
|         }); | ||||
|  | ||||
|         let expandedBox = new Gtk.Box({ | ||||
|             orientation: Gtk.Orientation.VERTICAL | ||||
|         }); | ||||
|         expandedBox.add(textview); | ||||
|         expandedBox.add(toolbar); | ||||
|  | ||||
|         expander.add(expandedBox); | ||||
|  | ||||
|         scroll.show_all(); | ||||
|         return scroll; | ||||
|     } | ||||
|  | ||||
|     _buildUI(app) { | ||||
| @@ -147,8 +224,12 @@ var Application = class { | ||||
|                             Gio.SettingsBindFlags.DEFAULT | | ||||
|                             Gio.SettingsBindFlags.INVERT_BOOLEAN); | ||||
|  | ||||
|         this._mainStack = new Gtk.Stack({ | ||||
|             transition_type: Gtk.StackTransitionType.CROSSFADE | ||||
|         }); | ||||
|         this._window.add(this._mainStack); | ||||
|  | ||||
|         let scroll = new Gtk.ScrolledWindow({ hscrollbar_policy: Gtk.PolicyType.NEVER }); | ||||
|         this._window.add(scroll); | ||||
|  | ||||
|         this._extensionSelector = new Gtk.ListBox({ selection_mode: Gtk.SelectionMode.NONE }); | ||||
|         this._extensionSelector.set_sort_func(this._sortList.bind(this)); | ||||
| @@ -156,6 +237,8 @@ var Application = class { | ||||
|  | ||||
|         scroll.add(this._extensionSelector); | ||||
|  | ||||
|         this._mainStack.add_named(scroll, 'listing'); | ||||
|         this._mainStack.add_named(new EmptyPlaceholder(), 'placeholder'); | ||||
|  | ||||
|         this._shellProxy = new GnomeShellProxy(Gio.DBus.session, 'org.gnome.Shell', '/org/gnome/Shell'); | ||||
|         this._shellProxy.connectSignal('ExtensionStatusChanged', (proxy, senderName, [uuid, state, error]) => { | ||||
| @@ -200,6 +283,11 @@ var Application = class { | ||||
|     } | ||||
|  | ||||
|     _extensionsLoaded() { | ||||
|         if (this._extensionSelector.get_children().length > 0) | ||||
|             this._mainStack.visible_child_name = 'listing'; | ||||
|         else | ||||
|             this._mainStack.visible_child_name = 'placeholder'; | ||||
|  | ||||
|         if (this._startupUuid && this._extensionAvailable(this._startupUuid)) | ||||
|             this._selectExtension(this._startupUuid); | ||||
|         this._startupUuid = null; | ||||
| @@ -239,6 +327,171 @@ var Application = class { | ||||
|     } | ||||
| }; | ||||
|  | ||||
| var Expander = GObject.registerClass({ | ||||
|     Properties: { | ||||
|         'label': GObject.ParamSpec.string( | ||||
|             'label', 'label', 'label', | ||||
|             GObject.ParamFlags.READWRITE, | ||||
|             null | ||||
|         ) | ||||
|     } | ||||
| }, class Expander extends Gtk.Box { | ||||
|     _init(params = {}) { | ||||
|         this._labelText = null; | ||||
|  | ||||
|         super._init(Object.assign(params, { | ||||
|             orientation: Gtk.Orientation.VERTICAL, | ||||
|             spacing: 0 | ||||
|         })); | ||||
|  | ||||
|         this._frame = new Gtk.Frame({ | ||||
|             shadow_type: Gtk.ShadowType.IN, | ||||
|             hexpand: true | ||||
|         }); | ||||
|  | ||||
|         let eventBox = new Gtk.EventBox(); | ||||
|         this._frame.add(eventBox); | ||||
|  | ||||
|         let hbox = new Gtk.Box({ | ||||
|             spacing: 6, | ||||
|             margin: 12 | ||||
|         }); | ||||
|         eventBox.add(hbox); | ||||
|  | ||||
|         this._arrow = new Gtk.Image({ | ||||
|             icon_name: 'pan-end-symbolic' | ||||
|         }); | ||||
|         hbox.add(this._arrow); | ||||
|  | ||||
|         this._label = new Gtk.Label({ label: this._labelText }); | ||||
|         hbox.add(this._label); | ||||
|  | ||||
|         this._revealer = new Gtk.Revealer(); | ||||
|  | ||||
|         this._childBin = new Gtk.Frame({ | ||||
|             shadow_type: Gtk.ShadowType.IN | ||||
|         }); | ||||
|         this._revealer.add(this._childBin); | ||||
|  | ||||
|         // Directly chain up to parent for internal children | ||||
|         super.add(this._frame); | ||||
|         super.add(this._revealer); | ||||
|  | ||||
|         let provider = new Gtk.CssProvider(); | ||||
|         provider.load_from_data('* { border-top-width: 0; }'); | ||||
|         this._childBin.get_style_context().add_provider( | ||||
|             provider, | ||||
|             Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION | ||||
|         ); | ||||
|  | ||||
|         this._gesture = new Gtk.GestureMultiPress({ | ||||
|             widget: this._frame, | ||||
|             button: 0, | ||||
|             exclusive: true | ||||
|         }); | ||||
|         this._gesture.connect('released', (gesture, nPress) => { | ||||
|             if (nPress == 1) | ||||
|                 this._revealer.reveal_child = !this._revealer.reveal_child; | ||||
|         }); | ||||
|         this._revealer.connect('notify::reveal-child', () => { | ||||
|             if (this._revealer.reveal_child) | ||||
|                 this._arrow.icon_name = 'pan-down-symbolic'; | ||||
|             else | ||||
|                 this._arrow.icon_name = 'pan-end-symbolic'; | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     get label() { | ||||
|         return this._labelText; | ||||
|     } | ||||
|  | ||||
|     set label(text) { | ||||
|         if (this._labelText == text) | ||||
|             return; | ||||
|  | ||||
|         if (this._label) | ||||
|             this._label.label = text; | ||||
|         this._labelText = text; | ||||
|         this.notify('label'); | ||||
|     } | ||||
|  | ||||
|     add(child) { | ||||
|         // set expanded child | ||||
|         this._childBin.get_children().forEach(c => { | ||||
|             this._childBin.remove(c); | ||||
|         }); | ||||
|  | ||||
|         if (child) | ||||
|             this._childBin.add(child); | ||||
|     } | ||||
| }); | ||||
|  | ||||
| var EmptyPlaceholder = GObject.registerClass( | ||||
| class EmptyPlaceholder extends Gtk.Box { | ||||
|     _init() { | ||||
|         super._init({ | ||||
|             orientation: Gtk.Orientation.VERTICAL, | ||||
|             spacing: 6, | ||||
|             margin: 32 | ||||
|         }); | ||||
|  | ||||
|         let image = new Gtk.Image({ | ||||
|             icon_name: 'application-x-addon-symbolic', | ||||
|             pixel_size: 96, | ||||
|             visible: true, | ||||
|             vexpand: true, | ||||
|             valign: Gtk.Align.END | ||||
|         }); | ||||
|         image.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL); | ||||
|         this.add(image); | ||||
|  | ||||
|         let label = new Gtk.Label({ | ||||
|             label: `<b><span size="x-large">${_("No Extensions Installed" )}</span></b>`, | ||||
|             use_markup: true, | ||||
|             visible: true | ||||
|         }); | ||||
|         label.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL); | ||||
|         this.add(label); | ||||
|  | ||||
|         let appInfo = Gio.DesktopAppInfo.new('org.gnome.Software.desktop'); | ||||
|  | ||||
|         let desc = new Gtk.Label({ | ||||
|             label: _("Extensions can be installed through Software or <a href=\"https://extensions.gnome.org\">extensions.gnome.org</a>."), | ||||
|             use_markup: true, | ||||
|             wrap: true, | ||||
|             justify: Gtk.Justification.CENTER, | ||||
|             visible: true, | ||||
|             max_width_chars: 50, | ||||
|             hexpand: true, | ||||
|             vexpand: (appInfo == null), | ||||
|             halign: Gtk.Align.CENTER, | ||||
|             valign: Gtk.Align.START | ||||
|         }); | ||||
|         this.add(desc); | ||||
|  | ||||
|         if (appInfo) { | ||||
|             let button = new Gtk.Button({ | ||||
|                 label: _("Browse in Software"), | ||||
|                 image: new Gtk.Image({ | ||||
|                     icon_name: "org.gnome.Software-symbolic" | ||||
|                 }), | ||||
|                 always_show_image: true, | ||||
|                 margin_top: 12, | ||||
|                 visible: true, | ||||
|                 halign: Gtk.Align.CENTER, | ||||
|                 valign: Gtk.Align.START, | ||||
|                 vexpand: true | ||||
|             }); | ||||
|             this.add(button); | ||||
|  | ||||
|             button.connect('clicked', w => { | ||||
|                 let context = w.get_display().get_app_launch_context(); | ||||
|                 appInfo.launch([], context); | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
| }); | ||||
|  | ||||
| var DescriptionLabel = GObject.registerClass( | ||||
| class DescriptionLabel extends Gtk.Label { | ||||
|     vfunc_get_preferred_height_for_width(width) { | ||||
| @@ -298,9 +551,9 @@ class ExtensionRow extends Gtk.ListBoxRow { | ||||
|  | ||||
|         let button = new Gtk.Button({ valign: Gtk.Align.CENTER, | ||||
|                                       no_show_all: true }); | ||||
|         button.add(new Gtk.Image({ icon_name: 'emblem-system-symbolic', | ||||
|                                    icon_size: Gtk.IconSize.BUTTON, | ||||
|                                    visible: true })); | ||||
|         button.set_image(new Gtk.Image({ icon_name: 'emblem-system-symbolic', | ||||
|                                          icon_size: Gtk.IconSize.BUTTON, | ||||
|                                          visible: true })); | ||||
|         button.get_style_context().add_class('circular'); | ||||
|         hbox.add(button); | ||||
|  | ||||
|   | ||||
| @@ -1,10 +1,7 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const Gio = imports.gi.Gio; | ||||
| const Pango = imports.gi.Pango; | ||||
| const { Clutter, Pango, Shell, St } = imports.gi; | ||||
| const Signals = imports.signals; | ||||
| const St = imports.gi.St; | ||||
|  | ||||
| const Animation = imports.ui.animation; | ||||
| const Batch = imports.gdm.batch; | ||||
| @@ -96,7 +93,7 @@ var AuthPrompt = class { | ||||
|                          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 }); | ||||
|         ShellEntry.addContextMenu(this._entry, { isPassword: true, actionMode: Shell.ActionMode.NONE }); | ||||
|  | ||||
|         this.actor.add(this._entry, | ||||
|                        { expand: true, | ||||
|   | ||||
| @@ -124,7 +124,7 @@ var Batch = class extends Task { | ||||
|     } | ||||
|  | ||||
|     process() { | ||||
|         throw new Error('Not implemented'); | ||||
|         throw new GObject.NotImplementedError(`process in ${this.constructor.name}`); | ||||
|     } | ||||
|  | ||||
|     runTask() { | ||||
|   | ||||
| @@ -1,8 +1,6 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Gio = imports.gi.Gio; | ||||
| const Shell = imports.gi.Shell; | ||||
| const Signals = imports.signals; | ||||
|  | ||||
| const FprintManagerIface = ` | ||||
| <node> | ||||
|   | ||||
| @@ -16,19 +16,9 @@ | ||||
|  * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| const AccountsService = imports.gi.AccountsService; | ||||
| const Atk = imports.gi.Atk; | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const Gdm = imports.gi.Gdm; | ||||
| const Gio = imports.gi.Gio; | ||||
| const GLib = imports.gi.GLib; | ||||
| const GObject = imports.gi.GObject; | ||||
| const Gtk = imports.gi.Gtk; | ||||
| const Meta = imports.gi.Meta; | ||||
| const Pango = imports.gi.Pango; | ||||
| const Shell = imports.gi.Shell; | ||||
| const { AccountsService, Atk, Clutter, Gdm, Gio, | ||||
|         GLib, GObject, Meta, Pango, Shell, St } = imports.gi; | ||||
| const Signals = imports.signals; | ||||
| const St = imports.gi.St; | ||||
|  | ||||
| const AuthPrompt = imports.gdm.authPrompt; | ||||
| const Batch = imports.gdm.batch; | ||||
| @@ -161,8 +151,8 @@ Signals.addSignalMethods(UserListItem.prototype); | ||||
| var UserList = class { | ||||
|     constructor() { | ||||
|         this.actor = new St.ScrollView({ style_class: 'login-dialog-user-list-view'}); | ||||
|         this.actor.set_policy(Gtk.PolicyType.NEVER, | ||||
|                               Gtk.PolicyType.AUTOMATIC); | ||||
|         this.actor.set_policy(St.PolicyType.NEVER, | ||||
|                               St.PolicyType.AUTOMATIC); | ||||
|  | ||||
|         this._box = new St.BoxLayout({ vertical: true, | ||||
|                                        style_class: 'login-dialog-user-list', | ||||
| @@ -183,7 +173,7 @@ var UserList = class { | ||||
|         if (global.stage.get_key_focus() != this.actor) | ||||
|             return; | ||||
|  | ||||
|         let focusSet = this.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false); | ||||
|         let focusSet = this.actor.navigate_focus(null, St.DirectionType.TAB_FORWARD, false); | ||||
|         if (!focusSet) { | ||||
|             Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => { | ||||
|                 this._moveFocusToItems(); | ||||
| @@ -335,7 +325,8 @@ var SessionMenuButton = class { | ||||
|                  this._button.remove_style_pseudo_class('active'); | ||||
|         }); | ||||
|  | ||||
|         this._manager = new PopupMenu.PopupMenuManager({ actor: this._button }); | ||||
|         this._manager = new PopupMenu.PopupMenuManager(this._button, | ||||
|                                                        { actionMode: Shell.ActionMode.NONE }); | ||||
|         this._manager.addMenu(this._menu); | ||||
|  | ||||
|         this._button.connect('clicked', () => { this._menu.toggle(); }); | ||||
| @@ -473,8 +464,8 @@ var LoginDialog = GObject.registerClass({ | ||||
|  | ||||
|         this._bannerView = new St.ScrollView({ style_class: 'login-dialog-banner-view', | ||||
|                                                opacity: 0, | ||||
|                                                vscrollbar_policy: Gtk.PolicyType.AUTOMATIC, | ||||
|                                                hscrollbar_policy: Gtk.PolicyType.NEVER }); | ||||
|                                                vscrollbar_policy: St.PolicyType.AUTOMATIC, | ||||
|                                                hscrollbar_policy: St.PolicyType.NEVER }); | ||||
|         this.add_child(this._bannerView); | ||||
|  | ||||
|         let bannerBox = new St.BoxLayout({ vertical: true }); | ||||
| @@ -490,6 +481,9 @@ var LoginDialog = GObject.registerClass({ | ||||
|         this._logoBin = new St.Widget({ style_class: 'login-dialog-logo-bin', | ||||
|                                         x_align: Clutter.ActorAlign.CENTER, | ||||
|                                         y_align: Clutter.ActorAlign.END }); | ||||
|         this._logoBin.connect('resource-scale-changed', () => { | ||||
|             this._updateLogoTexture(this._textureCache, this._logoFile); | ||||
|         }); | ||||
|         this.add_child(this._logoBin); | ||||
|         this._updateLogo(); | ||||
|  | ||||
| @@ -658,7 +652,7 @@ var LoginDialog = GObject.registerClass({ | ||||
|                      bannerAllocation.x2 = Math.floor(centerX - centerGap / 2); | ||||
|                      bannerAllocation.x1 = Math.floor(bannerAllocation.x2 - wideBannerWidth); | ||||
|  | ||||
|                      // figure out how tall it would like to be and try to accomodate | ||||
|                      // figure out how tall it would like to be and try to accommodate | ||||
|                      // but don't let it get too close to the logo | ||||
|                      let [wideMinHeight, wideBannerHeight] = this._bannerView.get_preferred_height(wideBannerWidth); | ||||
|  | ||||
| @@ -787,11 +781,12 @@ var LoginDialog = GObject.registerClass({ | ||||
|             return; | ||||
|  | ||||
|         this._logoBin.destroy_all_children(); | ||||
|         if (this._logoFile) { | ||||
|         if (this._logoFile && this._logoBin.resource_scale > 0) { | ||||
|             let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; | ||||
|             this._logoBin.add_child(this._textureCache.load_file_async(this._logoFile, | ||||
|                                                                        -1, _LOGO_ICON_HEIGHT, | ||||
|                                                                        scaleFactor)); | ||||
|                                                                        scaleFactor, | ||||
|                                                                        this._logoBin.resource_scale)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Gio = imports.gi.Gio; | ||||
| const Shell = imports.gi.Shell; | ||||
| const Signals = imports.signals; | ||||
|  | ||||
| const { loadInterfaceXML } = imports.misc.fileUtils; | ||||
|   | ||||
| @@ -1,18 +1,13 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const Gio = imports.gi.Gio; | ||||
| const GLib = imports.gi.GLib; | ||||
| const Mainloop = imports.mainloop; | ||||
| const { Clutter, Gio, GLib } = imports.gi; | ||||
| const Signals = imports.signals; | ||||
| const St = imports.gi.St; | ||||
|  | ||||
| const Batch = imports.gdm.batch; | ||||
| const Fprint = imports.gdm.fingerprint; | ||||
| const OVirt = imports.gdm.oVirt; | ||||
| const Main = imports.ui.main; | ||||
| const Params = imports.misc.params; | ||||
| const ShellEntry = imports.ui.shellEntry; | ||||
| const SmartcardManager = imports.misc.smartcardManager; | ||||
| const Tweener = imports.ui.tweener; | ||||
|  | ||||
|   | ||||
| @@ -64,6 +64,7 @@ | ||||
|     <file>ui/keyboard.js</file> | ||||
|     <file>ui/layout.js</file> | ||||
|     <file>ui/lightbox.js</file> | ||||
|     <file>ui/locatePointer.js</file> | ||||
|     <file>ui/lookingGlass.js</file> | ||||
|     <file>ui/magnifier.js</file> | ||||
|     <file>ui/magnifierDBus.js</file> | ||||
| @@ -78,12 +79,14 @@ | ||||
|     <file>ui/overview.js</file> | ||||
|     <file>ui/overviewControls.js</file> | ||||
|     <file>ui/padOsd.js</file> | ||||
|     <file>ui/pageIndicators.js</file> | ||||
|     <file>ui/panel.js</file> | ||||
|     <file>ui/panelMenu.js</file> | ||||
|     <file>ui/pointerA11yTimeout.js</file> | ||||
|     <file>ui/pointerWatcher.js</file> | ||||
|     <file>ui/popupMenu.js</file> | ||||
|     <file>ui/remoteMenu.js</file> | ||||
|     <file>ui/remoteSearch.js</file> | ||||
|     <file>ui/ripples.js</file> | ||||
|     <file>ui/runDialog.js</file> | ||||
|     <file>ui/screenShield.js</file> | ||||
|     <file>ui/screencast.js</file> | ||||
| @@ -120,6 +123,7 @@ | ||||
|  | ||||
|     <file>ui/status/accessibility.js</file> | ||||
|     <file>ui/status/brightness.js</file> | ||||
|     <file>ui/status/dwellClick.js</file> | ||||
|     <file>ui/status/location.js</file> | ||||
|     <file>ui/status/keyboard.js</file> | ||||
|     <file>ui/status/nightLight.js</file> | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
| // Common utils for the extension system and the extension | ||||
| // preferences tool | ||||
|  | ||||
| const Gettext = imports.gettext; | ||||
| const Signals = imports.signals; | ||||
|  | ||||
| const Gio = imports.gi.Gio; | ||||
| @@ -63,6 +64,66 @@ function getCurrentExtension() { | ||||
|     return null; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * initTranslations: | ||||
|  * @domain: (optional): the gettext domain to use | ||||
|  * | ||||
|  * Initialize Gettext to load translations from extensionsdir/locale. | ||||
|  * If @domain is not provided, it will be taken from metadata['gettext-domain'] | ||||
|  */ | ||||
| function initTranslations(domain) { | ||||
|     let extension = getCurrentExtension(); | ||||
|  | ||||
|     if (!extension) | ||||
|         throw new Error('initTranslations() can only be called from extensions'); | ||||
|  | ||||
|     domain = domain || extension.metadata['gettext-domain']; | ||||
|  | ||||
|     // Expect USER extensions to have a locale/ subfolder, otherwise assume a | ||||
|     // SYSTEM extension that has been installed in the same prefix as the shell | ||||
|     let localeDir = extension.dir.get_child('locale'); | ||||
|     if (localeDir.query_exists(null)) | ||||
|         Gettext.bindtextdomain(domain, localeDir.get_path()); | ||||
|     else | ||||
|         Gettext.bindtextdomain(domain, Config.LOCALEDIR); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * getSettings: | ||||
|  * @schema: (optional): the GSettings schema id | ||||
|  * | ||||
|  * Builds and returns a GSettings schema for @schema, using schema files | ||||
|  * in extensionsdir/schemas. If @schema is omitted, it is taken from | ||||
|  * metadata['settings-schema']. | ||||
|  */ | ||||
| function getSettings(schema) { | ||||
|     let extension = getCurrentExtension(); | ||||
|  | ||||
|     if (!extension) | ||||
|         throw new Error('getSettings() can only be called from extensions'); | ||||
|  | ||||
|     schema = schema || extension.metadata['settings-schema']; | ||||
|  | ||||
|     const GioSSS = Gio.SettingsSchemaSource; | ||||
|  | ||||
|     // Expect USER extensions to have a schemas/ subfolder, otherwise assume a | ||||
|     // SYSTEM extension that has been installed in the same prefix as the shell | ||||
|     let schemaDir = extension.dir.get_child('schemas'); | ||||
|     let schemaSource; | ||||
|     if (schemaDir.query_exists(null)) | ||||
|         schemaSource = GioSSS.new_from_directory(schemaDir.get_path(), | ||||
|                                                  GioSSS.get_default(), | ||||
|                                                  false); | ||||
|     else | ||||
|         schemaSource = GioSSS.get_default(); | ||||
|  | ||||
|     let schemaObj = schemaSource.lookup(schema, true); | ||||
|     if (!schemaObj) | ||||
|         throw new Error(`Schema ${schema} could not be found for extension ${extension.metadata.uuid}. Please check your installation`); | ||||
|  | ||||
|     return new Gio.Settings({ settings_schema: schemaObj }); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * versionCheck: | ||||
|  * @required: an array of versions we're compatible with | ||||
|   | ||||
| @@ -1,9 +1,7 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Gio = imports.gi.Gio; | ||||
| const GLib = imports.gi.GLib; | ||||
| const { Gio, GLib } = imports.gi; | ||||
| const Config = imports.misc.config; | ||||
| const Params = imports.misc.params; | ||||
|  | ||||
| function collectFromDatadirs(subdir, includeUserDir, processFile) { | ||||
|     let dataDirs = GLib.get_system_data_dirs(); | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Gio = imports.gi.Gio; | ||||
| const Signals = imports.signals; | ||||
|  | ||||
| const { loadInterfaceXML } = imports.misc.fileUtils; | ||||
|  | ||||
|   | ||||
| @@ -1,11 +1,9 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Gio = imports.gi.Gio; | ||||
| const GLib = imports.gi.GLib; | ||||
| const { Gio, GLib, IBus } = imports.gi; | ||||
| const Mainloop = imports.mainloop; | ||||
| const Signals = imports.signals; | ||||
|  | ||||
| const IBus = imports.gi.IBus; | ||||
| const IBusCandidatePopup = imports.ui.ibusCandidatePopup; | ||||
|  | ||||
| // Ensure runtime version matches | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const GObject = imports.gi.GObject; | ||||
| const IBus = imports.gi.IBus; | ||||
| const { Clutter, GLib, GObject, IBus } = imports.gi; | ||||
|  | ||||
| const Keyboard = imports.ui.status.keyboard; | ||||
| const Signals = imports.signals; | ||||
|  | ||||
| var HIDE_PANEL_TIME = 50; | ||||
|  | ||||
| var InputMethod = GObject.registerClass( | ||||
| class InputMethod extends Clutter.InputMethod { | ||||
| @@ -15,6 +15,7 @@ class InputMethod extends Clutter.InputMethod { | ||||
|         this._preeditStr = ''; | ||||
|         this._preeditPos = 0; | ||||
|         this._preeditVisible = false; | ||||
|         this._hidePanelId = 0; | ||||
|         this._ibus = IBus.Bus.new_async(); | ||||
|         this._ibus.connect('connected', this._onConnected.bind(this)); | ||||
|         this._ibus.connect('disconnected', this._clear.bind(this)); | ||||
| @@ -138,6 +139,11 @@ class InputMethod extends Clutter.InputMethod { | ||||
|             this._updateCapabilities(); | ||||
|             this._emitRequestSurrounding(); | ||||
|         } | ||||
|  | ||||
|         if (this._hidePanelId) { | ||||
|             GLib.source_remove(this._hidePanelId); | ||||
|             this._hidePanelId = 0; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     vfunc_focus_out() { | ||||
| @@ -152,6 +158,12 @@ class InputMethod extends Clutter.InputMethod { | ||||
|             this.set_preedit_text(null, 0); | ||||
|             this._preeditStr = null; | ||||
|         } | ||||
|  | ||||
|         this._hidePanelId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, HIDE_PANEL_TIME, () => { | ||||
|             this.set_input_panel_state(Clutter.InputPanelState.OFF); | ||||
|             this._hidePanelId = 0; | ||||
|             return GLib.SOURCE_REMOVE; | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     vfunc_reset() { | ||||
|   | ||||
| @@ -1,7 +1,4 @@ | ||||
| const Gio = imports.gi.Gio; | ||||
| const GLib = imports.gi.GLib; | ||||
| const Meta = imports.gi.Meta; | ||||
| const Shell = imports.gi.Shell; | ||||
| const { Gio, GLib, Meta, Shell } = imports.gi; | ||||
|  | ||||
| const INTROSPECT_SCHEMA = 'org.gnome.shell'; | ||||
| const INTROSPECT_KEY = 'introspect'; | ||||
| @@ -45,8 +42,6 @@ var IntrospectService = class { | ||||
|     } | ||||
|  | ||||
|     _isStandaloneApp(app) { | ||||
|         let windows = app.get_windows(); | ||||
|  | ||||
|         return app.get_windows().some(w => w.transient_for == null); | ||||
|     } | ||||
|  | ||||
| @@ -58,6 +53,11 @@ var IntrospectService = class { | ||||
|        return APP_WHITELIST.includes(sender); | ||||
|     } | ||||
|  | ||||
|     _getSandboxedAppId(app) { | ||||
|         let ids = app.get_windows().map(w => w.get_sandboxed_app_id()); | ||||
|         return ids.find(id => id != null); | ||||
|     } | ||||
|  | ||||
|     _syncRunningApplications() { | ||||
|         let tracker = Shell.WindowTracker.get_default(); | ||||
|         let apps = this._appSystem.get_running(); | ||||
| @@ -79,6 +79,10 @@ var IntrospectService = class { | ||||
|                 newActiveApplication = app.get_id(); | ||||
|             } | ||||
|  | ||||
|             let sandboxedAppId = this._getSandboxedAppId(app); | ||||
|             if (sandboxedAppId) | ||||
|                 appInfo['sandboxed-app-id'] = new GLib.Variant('s', sandboxedAppId); | ||||
|  | ||||
|             newRunningApplications[app.get_id()] = appInfo; | ||||
|         } | ||||
|  | ||||
| @@ -140,6 +144,7 @@ var IntrospectService = class { | ||||
|                 let frameRect = window.get_frame_rect(); | ||||
|                 let title = window.get_title(); | ||||
|                 let wmClass = window.get_wm_class(); | ||||
|                 let sandboxedAppId = window.get_sandboxed_app_id(); | ||||
|  | ||||
|                 windowsList[windowId] = { | ||||
|                     'app-id': GLib.Variant.new('s', app.get_id()), | ||||
| @@ -156,6 +161,10 @@ var IntrospectService = class { | ||||
|  | ||||
|                 if (wmClass != null) | ||||
|                     windowsList[windowId]['wm-class'] = GLib.Variant.new('s', wmClass); | ||||
|  | ||||
|                 if (sandboxedAppId != null) | ||||
|                     windowsList[windowId]['sandboxed-app-id'] = | ||||
|                         GLib.Variant.new('s', sandboxedAppId); | ||||
|             } | ||||
|         } | ||||
|         invocation.return_value(new GLib.Variant('(a{ta{sv}})', [windowsList])); | ||||
|   | ||||
| @@ -1,8 +1,6 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const GLib = imports.gi.GLib; | ||||
| const GnomeDesktop = imports.gi.GnomeDesktop; | ||||
| const Meta = imports.gi.Meta; | ||||
| const { GLib, GnomeDesktop, Meta } = imports.gi; | ||||
|  | ||||
| const Main = imports.ui.main; | ||||
|  | ||||
|   | ||||
| @@ -1,9 +1,6 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const GLib = imports.gi.GLib; | ||||
| const Gio = imports.gi.Gio; | ||||
| const Mainloop = imports.mainloop; | ||||
| const Shell = imports.gi.Shell; | ||||
| const { GLib, Gio } = imports.gi; | ||||
| const Signals = imports.signals; | ||||
|  | ||||
| const { loadInterfaceXML } = imports.misc.fileUtils; | ||||
| @@ -51,6 +48,28 @@ function canLock() { | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| function registerSessionWithGDM() { | ||||
|     log("Registering session with GDM"); | ||||
|     Gio.DBus.system.call('org.gnome.DisplayManager', | ||||
|                          '/org/gnome/DisplayManager/Manager', | ||||
|                          'org.gnome.DisplayManager.Manager', | ||||
|                          'RegisterSession', | ||||
|                          GLib.Variant.new('(a{sv})', [{}]), null, | ||||
|                          Gio.DBusCallFlags.NONE, -1, null, | ||||
|         (source, result) => { | ||||
|             try { | ||||
|                 source.call_finish(result); | ||||
|             } catch (e) { | ||||
|                 if (!e.matches(Gio.DBusError, Gio.DBusError.UNKNOWN_METHOD)) | ||||
|                     log(`Error registering session with GDM: ${e.message}`); | ||||
|                 else | ||||
|                     log("Not calling RegisterSession(): method not exported, GDM too old?"); | ||||
|             } | ||||
|         } | ||||
|     ); | ||||
| } | ||||
|  | ||||
| let _loginManager = null; | ||||
|  | ||||
| /** | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Gio = imports.gi.Gio; | ||||
| const NMA = imports.gi.NMA; | ||||
| const { Gio, NMA } = imports.gi; | ||||
| const Signals = imports.signals; | ||||
|  | ||||
| const { loadInterfaceXML } = imports.misc.fileUtils; | ||||
| @@ -72,7 +71,7 @@ function _findProviderForMccMnc(operator_name, operator_code) { | ||||
| // Tries to find the operator name corresponding to the given SID | ||||
| // | ||||
| function _findProviderForSid(sid) { | ||||
|     if (sid == 0) | ||||
|     if (!sid) | ||||
|         return null; | ||||
|  | ||||
|     let mpd = _getMobileProvidersDatabase(); | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Gio = imports.gi.Gio; | ||||
| const GLib = imports.gi.GLib; | ||||
| const { Gio, GLib } = imports.gi; | ||||
| const Params = imports.misc.params; | ||||
| const Signals = imports.signals; | ||||
|  | ||||
| @@ -160,7 +159,7 @@ var ObjectManager = class { | ||||
|         try { | ||||
|             initable.init_finish(result); | ||||
|         } catch(e) { | ||||
|             logError(e, 'could not initialize object manager for object ' + params.name); | ||||
|             logError(e, 'could not initialize object manager for object ' + this._serviceName); | ||||
|  | ||||
|             this._tryToCompleteLoad(); | ||||
|             return; | ||||
| @@ -281,8 +280,8 @@ var ObjectManager = class { | ||||
|             let object = this._objects[objectPaths]; | ||||
|  | ||||
|             let interfaceNames = Object.keys(object); | ||||
|             for (let j = 0; i < interfaceNames.length; i++) { | ||||
|                 let interfaceName = interfaceNames[i]; | ||||
|             for (let j = 0; j < interfaceNames.length; j++) { | ||||
|                 let interfaceName = interfaceNames[j]; | ||||
|                 if (object[interfaceName]) | ||||
|                     proxies.push(object(interfaceName)); | ||||
|             } | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Gio = imports.gi.Gio; | ||||
| const Shell = imports.gi.Shell; | ||||
| const Signals = imports.signals; | ||||
|  | ||||
| const ObjectManager = imports.misc.objectManager; | ||||
|   | ||||
| @@ -1,10 +1,4 @@ | ||||
| const AccountsService = imports.gi.AccountsService; | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const Gdm = imports.gi.Gdm; | ||||
| const Gio = imports.gi.Gio; | ||||
| const GLib = imports.gi.GLib; | ||||
| const Meta = imports.gi.Meta; | ||||
| const GObject = imports.gi.GObject; | ||||
| const { AccountsService, Clutter, Gdm, Gio, GLib, GObject, Meta } = imports.gi; | ||||
|  | ||||
| const GnomeSession = imports.misc.gnomeSession; | ||||
| const LoginManager = imports.misc.loginManager; | ||||
| @@ -94,42 +88,42 @@ const SystemActions = GObject.registerClass({ | ||||
|                             name: C_("search-result", "Power Off"), | ||||
|                             iconName: 'system-shutdown-symbolic', | ||||
|                             // Translators: A list of keywords that match the power-off action, separated by semicolons | ||||
|                             keywords: _("power off;shutdown;reboot;restart").split(';'), | ||||
|                             keywords: _("power off;shutdown;reboot;restart").split(/[; ]/), | ||||
|                             available: false }); | ||||
|         this._actions.set(LOCK_SCREEN_ACTION_ID, | ||||
|                           { // Translators: The name of the lock screen action in search | ||||
|                             name: C_("search-result", "Lock Screen"), | ||||
|                             iconName: 'system-lock-screen-symbolic', | ||||
|                             // Translators: A list of keywords that match the lock screen action, separated by semicolons | ||||
|                             keywords: _("lock screen").split(';'), | ||||
|                             keywords: _("lock screen").split(/[; ]/), | ||||
|                             available: false }); | ||||
|         this._actions.set(LOGOUT_ACTION_ID, | ||||
|                           { // Translators: The name of the logout action in search | ||||
|                             name: C_("search-result", "Log Out"), | ||||
|                             iconName: 'application-exit-symbolic', | ||||
|                             // Translators: A list of keywords that match the logout action, separated by semicolons | ||||
|                             keywords: _("logout;sign off").split(';'), | ||||
|                             keywords: _("logout;log out;sign off").split(/[; ]/), | ||||
|                             available: false }); | ||||
|         this._actions.set(SUSPEND_ACTION_ID, | ||||
|                           { // Translators: The name of the suspend action in search | ||||
|                             name: C_("search-result", "Suspend"), | ||||
|                             iconName: 'media-playback-pause-symbolic', | ||||
|                             // Translators: A list of keywords that match the suspend action, separated by semicolons | ||||
|                             keywords: _("suspend;sleep").split(';'), | ||||
|                             keywords: _("suspend;sleep").split(/[; ]/), | ||||
|                             available: false }); | ||||
|         this._actions.set(SWITCH_USER_ACTION_ID, | ||||
|                           { // Translators: The name of the switch user action in search | ||||
|                             name: C_("search-result", "Switch User"), | ||||
|                             iconName: 'system-switch-user-symbolic', | ||||
|                             // Translators: A list of keywords that match the switch user action, separated by semicolons | ||||
|                             keywords: _("switch user").split(';'), | ||||
|                             keywords: _("switch user").split(/[; ]/), | ||||
|                             available: false }); | ||||
|         this._actions.set(LOCK_ORIENTATION_ACTION_ID, | ||||
|                           { // Translators: The name of the lock orientation action in search | ||||
|                             name: C_("search-result", "Lock Orientation"), | ||||
|                             iconName: '', | ||||
|                             // Translators: A list of keywords that match the lock orientation action, separated by semicolons | ||||
|                             keywords: _("lock orientation;screen;rotation").split(';'), | ||||
|                             keywords: _("lock orientation;screen;rotation").split(/[; ]/), | ||||
|                             available: false }); | ||||
|  | ||||
|         this._loginScreenSettings = new Gio.Settings({ schema_id: LOGIN_SCREEN_SCHEMA }); | ||||
| @@ -268,7 +262,7 @@ const SystemActions = GObject.registerClass({ | ||||
|         let results = []; | ||||
|  | ||||
|         for (let [key, {available, keywords}] of this._actions) | ||||
|             if (available && terms.every(t => keywords.some(k => (k.indexOf(t) >= 0)))) | ||||
|             if (available && terms.every(t => keywords.some(k => k.startsWith(t)))) | ||||
|                 results.push(key); | ||||
|  | ||||
|         return results; | ||||
|   | ||||
| @@ -1,14 +1,9 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const { Clutter, Gio, GLib, GObject, Shell, St } = imports.gi; | ||||
| const Gettext = imports.gettext; | ||||
| const Gio = imports.gi.Gio; | ||||
| const GLib = imports.gi.GLib; | ||||
| const GObject = imports.gi.GObject; | ||||
| const Mainloop = imports.mainloop; | ||||
| const Signals = imports.signals; | ||||
| const Shell = imports.gi.Shell; | ||||
| const St = imports.gi.St; | ||||
|  | ||||
| const Main = imports.ui.main; | ||||
| const Tweener = imports.ui.tweener; | ||||
| @@ -371,7 +366,7 @@ class CloseButton extends St.Button { | ||||
|     } | ||||
|  | ||||
|     _computeBoxPointerOffset() { | ||||
|         if (!this._boxPointer || !this._boxPointer.actor.get_stage()) | ||||
|         if (!this._boxPointer || !this._boxPointer.get_stage()) | ||||
|             return 0; | ||||
|  | ||||
|         let side = this._boxPointer.arrowSide; | ||||
|   | ||||
| @@ -1,9 +1,6 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Geoclue = imports.gi.Geoclue; | ||||
| const Gio = imports.gi.Gio; | ||||
| const GLib = imports.gi.GLib; | ||||
| const GWeather = imports.gi.GWeather; | ||||
| const { Geoclue, Gio, GLib, GWeather } = imports.gi; | ||||
| const Signals = imports.signals; | ||||
|  | ||||
| const PermissionStore = imports.misc.permissionStore; | ||||
| @@ -33,6 +30,14 @@ var WeatherClient = class { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             if (this._permStore.g_name_owner == null) { | ||||
|                 // Failed to auto-start, likely because xdg-desktop-portal | ||||
|                 // isn't installed; don't restrict access to location service | ||||
|                 this._weatherAuthorized = true; | ||||
|                 this._updateAutoLocation(); | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             this._permStore.LookupRemote('gnome', 'geolocation', (res, error) => { | ||||
|                 if (error) | ||||
|                     log('Error looking up permission: ' + error.message); | ||||
| @@ -61,8 +66,8 @@ var WeatherClient = class { | ||||
|             this.emit('changed'); | ||||
|         }); | ||||
|  | ||||
|         this._weatherAppMon = new Util.AppSettingsMonitor('org.gnome.Weather.Application.desktop', | ||||
|                                                           'org.gnome.Weather.Application'); | ||||
|         this._weatherAppMon = new Util.AppSettingsMonitor('org.gnome.Weather.desktop', | ||||
|                                                           'org.gnome.Weather'); | ||||
|         this._weatherAppMon.connect('available-changed', () => { this.emit('changed'); }); | ||||
|         this._weatherAppMon.watchSetting('automatic-location', | ||||
|                                          this._onAutomaticLocationChanged.bind(this)); | ||||
| @@ -234,7 +239,7 @@ var WeatherClient = class { | ||||
|         if (table != 'gnome' || id != 'geolocation') | ||||
|             return; | ||||
|  | ||||
|         let permission = perms['org.gnome.Weather.Application'] || ['NONE']; | ||||
|         let permission = perms['org.gnome.Weather'] || ['NONE']; | ||||
|         let [accuracy] = permission; | ||||
|         this._weatherAuthorized = accuracy != 'NONE'; | ||||
|  | ||||
|   | ||||
| @@ -10,7 +10,7 @@ const Scripting = imports.ui.scripting; | ||||
| // someone should be able to get an idea of how well the shell is performing | ||||
| // on a particular system. | ||||
|  | ||||
| let METRICS = { | ||||
| var METRICS = { | ||||
|     overviewLatencyFirst: | ||||
|     { description: "Time to first frame after triggering overview, first time", | ||||
|       units: "us" }, | ||||
| @@ -65,7 +65,7 @@ let WINDOW_CONFIGS = [ | ||||
|     { width: 640, height: 480, alpha: true,  maximized: false, count: 10, metric: 'overviewFps10Alpha' } | ||||
| ]; | ||||
|  | ||||
| function run() { | ||||
| function *run() { | ||||
|     Scripting.defineScriptEvent("overviewShowStart", "Starting to show the overview"); | ||||
|     Scripting.defineScriptEvent("overviewShowDone", "Overview finished showing"); | ||||
|     Scripting.defineScriptEvent("afterShowHide", "After a show/hide cycle for the overview"); | ||||
|   | ||||
| @@ -1,12 +1,8 @@ | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const Gio = imports.gi.Gio; | ||||
| const Gtk = imports.gi.Gtk; | ||||
| const Meta = imports.gi.Meta; | ||||
| const { Clutter, Gio, Shell } = imports.gi; | ||||
| const Main = imports.ui.main; | ||||
| const Scripting = imports.ui.scripting; | ||||
| const Shell = imports.gi.Shell; | ||||
|  | ||||
| let METRICS = { | ||||
| var METRICS = { | ||||
|     timeToDesktop: | ||||
|     { description: "Time from starting graphical.target to desktop showing", | ||||
|       units: "us" }, | ||||
| @@ -89,7 +85,7 @@ function extractBootTimestamp() { | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| function run() { | ||||
| function *run() { | ||||
|     Scripting.defineScriptEvent("desktopShown", "Finished initial animation"); | ||||
|     Scripting.defineScriptEvent("overviewShowStart", "Starting to show the overview"); | ||||
|     Scripting.defineScriptEvent("overviewShowDone", "Overview finished showing"); | ||||
| @@ -108,7 +104,10 @@ function run() { | ||||
|     yield Scripting.waitLeisure(); | ||||
|     Scripting.scriptEvent('desktopShown'); | ||||
|  | ||||
|     Gtk.Settings.get_default().gtk_enable_animations = false; | ||||
|     let interfaceSettings = new Gio.Settings({ | ||||
|         schema_id: 'org.gnome.desktop.interface' | ||||
|     }); | ||||
|     interfaceSettings.set_boolean('enable-animations', false); | ||||
|  | ||||
|     Scripting.scriptEvent('overviewShowStart'); | ||||
|     Main.overview.show(); | ||||
| @@ -204,7 +203,7 @@ function run() { | ||||
|  | ||||
|     yield Scripting.sleep(1000); | ||||
|  | ||||
|     Gtk.Settings.get_default().gtk_enable_animations = true; | ||||
|     interfaceSettings.set_boolean('enable-animations', true); | ||||
| } | ||||
|  | ||||
| let overviewShowStart; | ||||
|   | ||||
| @@ -1,12 +1,6 @@ | ||||
| const Format = imports.format; | ||||
| const Gettext = imports.gettext; | ||||
| const GLib = imports.gi.GLib; | ||||
| const GObject = imports.gi.GObject; | ||||
| const Gio = imports.gi.Gio; | ||||
| const Gtk = imports.gi.Gtk; | ||||
| const Pango = imports.gi.Pango; | ||||
| const Soup = imports.gi.Soup; | ||||
| const WebKit = imports.gi.WebKit2; | ||||
| const { Gio, GLib, GObject, Gtk, Pango, Soup, WebKit2: WebKit } = imports.gi; | ||||
|  | ||||
| const _ = Gettext.gettext; | ||||
|  | ||||
|   | ||||
| @@ -1,9 +1,4 @@ | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const Gio = imports.gi.Gio; | ||||
| const GLib = imports.gi.GLib; | ||||
| const Pango = imports.gi.Pango; | ||||
| const Shell = imports.gi.Shell; | ||||
| const St = imports.gi.St; | ||||
| const { Clutter, Gio, GLib, GObject, Shell } = imports.gi; | ||||
|  | ||||
| const CheckBox = imports.ui.checkBox; | ||||
| const Dialog = imports.ui.dialog; | ||||
| @@ -20,9 +15,10 @@ var DialogResponse = { | ||||
|     CLOSED: 2 | ||||
| }; | ||||
|  | ||||
| var AccessDialog = class extends ModalDialog.ModalDialog { | ||||
|     constructor(invocation, handle, title, subtitle, body, options) { | ||||
|         super({ styleClass: 'access-dialog' }); | ||||
| var AccessDialog = GObject.registerClass( | ||||
| class AccessDialog extends ModalDialog.ModalDialog { | ||||
|     _init(invocation, handle, title, subtitle, body, options) { | ||||
|         super._init({ styleClass: 'access-dialog' }); | ||||
|  | ||||
|         this._invocation = invocation; | ||||
|         this._handle = handle; | ||||
| @@ -114,7 +110,7 @@ var AccessDialog = class extends ModalDialog.ModalDialog { | ||||
|         }); | ||||
|         this.close(); | ||||
|     } | ||||
| }; | ||||
| }); | ||||
|  | ||||
| var AccessDialogDBus = class { | ||||
|     constructor() { | ||||
|   | ||||
| @@ -1,14 +1,7 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const Gio = imports.gi.Gio; | ||||
| const GLib = imports.gi.GLib; | ||||
| const GObject = imports.gi.GObject; | ||||
| const { Atk, Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi; | ||||
| const Mainloop = imports.mainloop; | ||||
| const Meta = imports.gi.Meta; | ||||
| const Shell = imports.gi.Shell; | ||||
| const St = imports.gi.St; | ||||
| const Atk = imports.gi.Atk; | ||||
|  | ||||
| const Main = imports.ui.main; | ||||
| const SwitcherPopup = imports.ui.switcherPopup; | ||||
| @@ -481,12 +474,10 @@ var CyclerList = GObject.registerClass({ | ||||
|     } | ||||
| }); | ||||
|  | ||||
| var CyclerPopup = GObject.registerClass( | ||||
| class CyclerPopup extends SwitcherPopup.SwitcherPopup { | ||||
| var CyclerPopup = GObject.registerClass({ | ||||
|     GTypeFlags: GObject.TypeFlags.ABSTRACT | ||||
| }, class CyclerPopup extends SwitcherPopup.SwitcherPopup { | ||||
|     _init() { | ||||
|         if (new.target === CyclerPopup) | ||||
|             throw new TypeError('Cannot instantiate abstract class ' + new.target.name); | ||||
|  | ||||
|         super._init(); | ||||
|  | ||||
|         this._items = this._getWindows(); | ||||
| @@ -626,9 +617,8 @@ class WindowSwitcherPopup extends SwitcherPopup.SwitcherPopup { | ||||
| var WindowCyclerPopup = GObject.registerClass( | ||||
| class WindowCyclerPopup extends CyclerPopup { | ||||
|     _init() { | ||||
|         super._init(); | ||||
|  | ||||
|         this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell.window-switcher' }); | ||||
|         super._init(); | ||||
|     } | ||||
|  | ||||
|     _getWindows() { | ||||
|   | ||||
| @@ -1,11 +1,7 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const GLib = imports.gi.GLib; | ||||
| const Gio = imports.gi.Gio; | ||||
| const { GLib, Gio, St } = imports.gi; | ||||
| const Mainloop = imports.mainloop; | ||||
| const St = imports.gi.St; | ||||
| const Signals = imports.signals; | ||||
| const Atk = imports.gi.Atk; | ||||
|  | ||||
| const Tweener = imports.ui.tweener; | ||||
|  | ||||
| @@ -16,7 +12,16 @@ var SPINNER_ANIMATION_DELAY = 1.0; | ||||
| 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', | ||||
|             this._loadFile.bind(this, file, width, height)); | ||||
|  | ||||
|         let themeContext = St.ThemeContext.get_for_stage(global.stage); | ||||
|         this._scaleChangedId = themeContext.connect('notify::scale-factor', | ||||
|             this._loadFile.bind(this, file, width, height)); | ||||
|  | ||||
|         this._speed = speed; | ||||
|  | ||||
|         this._isLoaded = false; | ||||
| @@ -24,10 +29,7 @@ var Animation = class { | ||||
|         this._timeoutId = 0; | ||||
|         this._frame = 0; | ||||
|  | ||||
|         let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; | ||||
|         this._animations = St.TextureCache.get_default().load_sliced_image (file, width, height, scaleFactor, | ||||
|                                                                             this._animationsLoaded.bind(this)); | ||||
|         this.actor.set_child(this._animations); | ||||
|         this._loadFile(file, width, height); | ||||
|     } | ||||
|  | ||||
|     play() { | ||||
| @@ -51,6 +53,23 @@ var Animation = class { | ||||
|         this._isPlaying = false; | ||||
|     } | ||||
|  | ||||
|     _loadFile(file, width, height) { | ||||
|         let [validResourceScale, resourceScale] = this.actor.get_resource_scale(); | ||||
|  | ||||
|         this._isLoaded = false; | ||||
|         this.actor.destroy_all_children(); | ||||
|  | ||||
|         if (!validResourceScale) | ||||
|             return; | ||||
|  | ||||
|         let texture_cache = St.TextureCache.get_default(); | ||||
|         let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; | ||||
|         this._animations = texture_cache.load_sliced_image(file, width, height, | ||||
|                                                            scaleFactor, resourceScale, | ||||
|                                                            this._animationsLoaded.bind(this)); | ||||
|         this.actor.set_child(this._animations); | ||||
|     } | ||||
|  | ||||
|     _showFrame(frame) { | ||||
|         let oldFrameActor = this._animations.get_child_at_index(this._frame); | ||||
|         if (oldFrameActor) | ||||
| @@ -68,15 +87,32 @@ var Animation = class { | ||||
|         return GLib.SOURCE_CONTINUE; | ||||
|     } | ||||
|  | ||||
|     _syncAnimationSize() { | ||||
|         if (!this._isLoaded) | ||||
|             return; | ||||
|  | ||||
|         let [width, height] = this.actor.get_size(); | ||||
|  | ||||
|         for (let i = 0; i < this._animations.get_n_children(); ++i) | ||||
|             this._animations.get_child_at_index(i).set_size(width, height); | ||||
|     } | ||||
|  | ||||
|     _animationsLoaded() { | ||||
|         this._isLoaded = this._animations.get_n_children() > 0; | ||||
|  | ||||
|         this._syncAnimationSize(); | ||||
|  | ||||
|         if (this._isPlaying) | ||||
|             this.play(); | ||||
|     } | ||||
|  | ||||
|     _onDestroy() { | ||||
|         this.stop(); | ||||
|  | ||||
|         let themeContext = St.ThemeContext.get_for_stage(global.stage); | ||||
|         if (this._scaleChangedId) | ||||
|             themeContext.disconnect(this._scaleChangedId); | ||||
|         this._scaleChangedId = 0; | ||||
|     } | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -1,16 +1,8 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const Gio = imports.gi.Gio; | ||||
| const GLib = imports.gi.GLib; | ||||
| const GObject = imports.gi.GObject; | ||||
| const Gtk = imports.gi.Gtk; | ||||
| const Shell = imports.gi.Shell; | ||||
| const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi; | ||||
| const Signals = imports.signals; | ||||
| const Meta = imports.gi.Meta; | ||||
| const St = imports.gi.St; | ||||
| const Mainloop = imports.mainloop; | ||||
| const Atk = imports.gi.Atk; | ||||
|  | ||||
| const AppFavorites = imports.ui.appFavorites; | ||||
| const BoxPointer = imports.ui.boxpointer; | ||||
| @@ -18,13 +10,10 @@ const DND = imports.ui.dnd; | ||||
| const GrabHelper = imports.ui.grabHelper; | ||||
| const IconGrid = imports.ui.iconGrid; | ||||
| const Main = imports.ui.main; | ||||
| const Overview = imports.ui.overview; | ||||
| const OverviewControls = imports.ui.overviewControls; | ||||
| const PageIndicators = imports.ui.pageIndicators; | ||||
| const PopupMenu = imports.ui.popupMenu; | ||||
| const Tweener = imports.ui.tweener; | ||||
| const Workspace = imports.ui.workspace; | ||||
| const Search = imports.ui.search; | ||||
| const System = imports.ui.status.system; | ||||
| const Params = imports.misc.params; | ||||
| const Util = imports.misc.util; | ||||
| const SystemActions = imports.misc.systemActions; | ||||
| @@ -109,8 +98,8 @@ function clamp(value, min, max) { | ||||
|  | ||||
| class BaseAppView { | ||||
|     constructor(params, gridParams) { | ||||
|         if (new.target === BaseAppView) | ||||
|             throw new TypeError('Cannot instantiate abstract class ' + new.target.name); | ||||
|         if (this.constructor === BaseAppView) | ||||
|             throw new TypeError(`Cannot instantiate abstract class ${this.constructor.name}`); | ||||
|  | ||||
|         gridParams = Params.parse(gridParams, { xAlign: St.Align.MIDDLE, | ||||
|                                                 columnLimit: MAX_COLUMNS, | ||||
| @@ -175,7 +164,7 @@ class BaseAppView { | ||||
|  | ||||
|     _selectAppInternal(id) { | ||||
|         if (this._items[id]) | ||||
|             this._items[id].actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false); | ||||
|             this._items[id].actor.navigate_focus(null, St.DirectionType.TAB_FORWARD, false); | ||||
|         else | ||||
|             log('No such application ' + id); | ||||
|     } | ||||
| @@ -246,116 +235,6 @@ class BaseAppView { | ||||
| }; | ||||
| Signals.addSignalMethods(BaseAppView.prototype); | ||||
|  | ||||
| var PageIndicatorsActor = GObject.registerClass( | ||||
| class PageIndicatorsActor extends St.BoxLayout { | ||||
|     _init() { | ||||
|         super._init({ style_class: 'page-indicators', | ||||
|                       vertical: true, | ||||
|                       x_expand: true, y_expand: true, | ||||
|                       x_align: Clutter.ActorAlign.END, | ||||
|                       y_align: Clutter.ActorAlign.CENTER, | ||||
|                       reactive: true, | ||||
|                       clip_to_allocation: true }); | ||||
|     } | ||||
|  | ||||
|     vfunc_get_preferred_height(forWidth) { | ||||
|         // We want to request the natural height of all our children as our | ||||
|         // natural height, so we chain up to St.BoxLayout, but we only request 0 | ||||
|         // as minimum height, since it's not that important if some indicators | ||||
|         // are not shown | ||||
|         let [, natHeight] = super.vfunc_get_preferred_height(forWidth); | ||||
|         return [0, natHeight]; | ||||
|     } | ||||
| }); | ||||
|  | ||||
| class PageIndicators { | ||||
|     constructor() { | ||||
|         this.actor = new PageIndicatorsActor(); | ||||
|         this._nPages = 0; | ||||
|         this._currentPage = undefined; | ||||
|  | ||||
|         this.actor.connect('notify::mapped', () => { | ||||
|             this.animateIndicators(IconGrid.AnimationDirection.IN); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     setNPages(nPages) { | ||||
|         if (this._nPages == nPages) | ||||
|             return; | ||||
|  | ||||
|         let diff = nPages - this._nPages; | ||||
|         if (diff > 0) { | ||||
|             for (let i = 0; i < diff; i++) { | ||||
|                 let pageIndex = this._nPages + i; | ||||
|                 let indicator = new St.Button({ style_class: 'page-indicator', | ||||
|                                                 button_mask: St.ButtonMask.ONE | | ||||
|                                                              St.ButtonMask.TWO | | ||||
|                                                              St.ButtonMask.THREE, | ||||
|                                                 toggle_mode: true, | ||||
|                                                 checked: pageIndex == this._currentPage }); | ||||
|                 indicator.child = new St.Widget({ style_class: 'page-indicator-icon' }); | ||||
|                 indicator.connect('clicked', () => { | ||||
|                     this.emit('page-activated', pageIndex); | ||||
|                 }); | ||||
|                 this.actor.add_actor(indicator); | ||||
|             } | ||||
|         } else { | ||||
|             let children = this.actor.get_children().splice(diff); | ||||
|             for (let i = 0; i < children.length; i++) | ||||
|                 children[i].destroy(); | ||||
|         } | ||||
|         this._nPages = nPages; | ||||
|         this.actor.visible = (this._nPages > 1); | ||||
|     } | ||||
|  | ||||
|     setCurrentPage(currentPage) { | ||||
|         this._currentPage = currentPage; | ||||
|  | ||||
|         let children = this.actor.get_children(); | ||||
|         for (let i = 0; i < children.length; i++) | ||||
|             children[i].set_checked(i == this._currentPage); | ||||
|     } | ||||
|  | ||||
|     animateIndicators(animationDirection) { | ||||
|         if (!this.actor.mapped) | ||||
|             return; | ||||
|  | ||||
|         let children = this.actor.get_children(); | ||||
|         if (children.length == 0) | ||||
|             return; | ||||
|  | ||||
|         for (let i = 0; i < this._nPages; i++) | ||||
|             Tweener.removeTweens(children[i]); | ||||
|  | ||||
|         let offset; | ||||
|         if (this.actor.get_text_direction() == Clutter.TextDirection.RTL) | ||||
|             offset = -children[0].width; | ||||
|         else | ||||
|             offset = children[0].width; | ||||
|  | ||||
|         let isAnimationIn = animationDirection == IconGrid.AnimationDirection.IN; | ||||
|         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; | ||||
|         if (totalAnimationTime > maxTime) | ||||
|             delay -= (totalAnimationTime - maxTime) / this._nPages; | ||||
|  | ||||
|         for (let i = 0; i < this._nPages; i++) { | ||||
|             children[i].translation_x = isAnimationIn ? offset : 0; | ||||
|             Tweener.addTween(children[i], | ||||
|                              { translation_x: isAnimationIn ? 0 : offset, | ||||
|                                time: baseTime + delay * i, | ||||
|                                transition: 'easeInOutQuad', | ||||
|                                delay: isAnimationIn ? VIEWS_SWITCH_ANIMATION_DELAY : 0 | ||||
|                              }); | ||||
|         } | ||||
|     } | ||||
| }; | ||||
| Signals.addSignalMethods(PageIndicators.prototype); | ||||
|  | ||||
| var AllView = class AllView extends BaseAppView { | ||||
|     constructor() { | ||||
|         super({ usePagination: true }, null); | ||||
| @@ -370,17 +249,17 @@ var AllView = class AllView extends BaseAppView { | ||||
|                                      x_expand:true, y_expand:true }); | ||||
|         this.actor.add_actor(this._scrollView); | ||||
|  | ||||
|         this._scrollView.set_policy(Gtk.PolicyType.NEVER, | ||||
|                                     Gtk.PolicyType.EXTERNAL); | ||||
|         this._scrollView.set_policy(St.PolicyType.NEVER, | ||||
|                                     St.PolicyType.EXTERNAL); | ||||
|         this._adjustment = this._scrollView.vscroll.adjustment; | ||||
|  | ||||
|         this._pageIndicators = new PageIndicators(); | ||||
|         this._pageIndicators = new PageIndicators.AnimatedPageIndicators(); | ||||
|         this._pageIndicators.connect('page-activated', | ||||
|             (indicators, pageIndex) => { | ||||
|                 this.goToPage(pageIndex); | ||||
|             }); | ||||
|         this._pageIndicators.actor.connect('scroll-event', this._onScroll.bind(this)); | ||||
|         this.actor.add_actor(this._pageIndicators.actor); | ||||
|         this._pageIndicators.connect('scroll-event', this._onScroll.bind(this)); | ||||
|         this.actor.add_actor(this._pageIndicators); | ||||
|  | ||||
|         this.folderIcons = []; | ||||
|  | ||||
| @@ -487,15 +366,21 @@ var AllView = class AllView extends BaseAppView { | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     getAppInfos() { | ||||
|         return this._appInfoList; | ||||
|     } | ||||
|  | ||||
|     _loadApps() { | ||||
|         let apps = Gio.AppInfo.get_all().filter(appInfo => { | ||||
|         this._appInfoList = Shell.AppSystem.get_default().get_installed().filter(appInfo => { | ||||
|             try { | ||||
|                 let id = appInfo.get_id(); // catch invalid file encodings | ||||
|             } catch(e) { | ||||
|                 return false; | ||||
|             } | ||||
|             return appInfo.should_show(); | ||||
|         }).map(app => app.get_id()); | ||||
|         }); | ||||
|  | ||||
|         let apps = this._appInfoList.map(app => app.get_id()); | ||||
|  | ||||
|         let appSys = Shell.AppSystem.get_default(); | ||||
|  | ||||
| @@ -529,7 +414,7 @@ var AllView = class AllView extends BaseAppView { | ||||
|         this._refilterApps(); | ||||
|     } | ||||
|  | ||||
|     // Overriden from BaseAppView | ||||
|     // Overridden from BaseAppView | ||||
|     animate(animationDirection, onComplete) { | ||||
|         this._scrollView.reactive = false; | ||||
|         let completionFunc = () => { | ||||
| @@ -747,9 +632,9 @@ var AllView = class AllView extends BaseAppView { | ||||
|             this._scrollView.get_effect('fade').fade_edges = true; | ||||
|  | ||||
|         if (this._availWidth != availWidth || this._availHeight != availHeight || oldNPages != this._grid.nPages()) { | ||||
|             this._adjustment.value = 0; | ||||
|             this._grid.currentPage = 0; | ||||
|             Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => { | ||||
|                 this._adjustment.value = 0; | ||||
|                 this._grid.currentPage = 0; | ||||
|                 this._pageIndicators.setNPages(this._grid.nPages()); | ||||
|                 this._pageIndicators.setCurrentPage(0); | ||||
|             }); | ||||
| @@ -1118,7 +1003,7 @@ var FolderView = class FolderView extends BaseAppView { | ||||
|         this._grid.x_expand = true; | ||||
|  | ||||
|         this.actor = new St.ScrollView({ overlay_scrollbars: true }); | ||||
|         this.actor.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC); | ||||
|         this.actor.set_policy(St.PolicyType.NEVER, St.PolicyType.AUTOMATIC); | ||||
|         let scrollableContainer = new St.BoxLayout({ vertical: true, reactive: true }); | ||||
|         scrollableContainer.add_actor(this._grid); | ||||
|         this.actor.add_actor(scrollableContainer); | ||||
| @@ -1132,7 +1017,7 @@ var FolderView = class FolderView extends BaseAppView { | ||||
|         Util.ensureActorVisibleInScrollView(this.actor, actor); | ||||
|     } | ||||
|  | ||||
|     // Overriden from BaseAppView | ||||
|     // Overridden from BaseAppView | ||||
|     animate(animationDirection) { | ||||
|         this._grid.animatePulse(animationDirection); | ||||
|     } | ||||
| @@ -1196,7 +1081,7 @@ var FolderView = class FolderView extends BaseAppView { | ||||
|  | ||||
|         let contentBox = this.actor.get_theme_node().get_content_box(pageBox); | ||||
|         // We only can show icons inside the collection view boxPointer | ||||
|         // so we have to substract the required padding etc of the boxpointer | ||||
|         // so we have to subtract the required padding etc of the boxpointer | ||||
|         return [(contentBox.x2 - contentBox.x1) - 2 * this._offsetForEachSide, (contentBox.y2 - contentBox.y1) - 2 * this._offsetForEachSide]; | ||||
|     } | ||||
|  | ||||
| @@ -1298,15 +1183,13 @@ var FolderIcon = class FolderIcon { | ||||
|         folderApps.forEach(addAppId); | ||||
|  | ||||
|         let folderCategories = this._folder.get_strv('categories'); | ||||
|         Gio.AppInfo.get_all().forEach(appInfo => { | ||||
|         let appInfos = this._parentView.getAppInfos(); | ||||
|         appInfos.forEach(appInfo => { | ||||
|             let appCategories = _getCategories(appInfo); | ||||
|             if (!_listsIntersect(folderCategories, appCategories)) | ||||
|                 return; | ||||
|  | ||||
|             try { | ||||
|                 addAppId(appInfo.get_id()); // catch invalid file encodings | ||||
|             } catch(e) { | ||||
|             } | ||||
|             addAppId(appInfo.get_id()); | ||||
|         }); | ||||
|  | ||||
|         this.actor.visible = this.view.getAllItems().length > 0; | ||||
| @@ -1418,16 +1301,16 @@ var AppFolderPopup = class AppFolderPopup { | ||||
|                                                        x_expand: true, | ||||
|                                                        x_align: St.Align.START }); | ||||
|  | ||||
|         this._boxPointer.actor.style_class = 'app-folder-popup'; | ||||
|         this.actor.add_actor(this._boxPointer.actor); | ||||
|         this._boxPointer.style_class = 'app-folder-popup'; | ||||
|         this.actor.add_actor(this._boxPointer); | ||||
|         this._boxPointer.bin.set_child(this._view.actor); | ||||
|  | ||||
|         this.closeButton = Util.makeCloseButton(this._boxPointer); | ||||
|         this.closeButton.connect('clicked', this.popdown.bind(this)); | ||||
|         this.actor.add_actor(this.closeButton); | ||||
|  | ||||
|         this._boxPointer.actor.bind_property('opacity', this.closeButton, 'opacity', | ||||
|                                              GObject.BindingFlags.SYNC_CREATE); | ||||
|         this._boxPointer.bind_property('opacity', this.closeButton, 'opacity', | ||||
|                                        GObject.BindingFlags.SYNC_CREATE); | ||||
|  | ||||
|         global.focus_manager.add_group(this.actor); | ||||
|  | ||||
| @@ -1464,18 +1347,18 @@ var AppFolderPopup = class AppFolderPopup { | ||||
|         let isLtr = Clutter.get_default_text_direction() == Clutter.TextDirection.LTR; | ||||
|         switch (event.get_key_symbol()) { | ||||
|             case Clutter.Down: | ||||
|                 direction = Gtk.DirectionType.TAB_FORWARD; | ||||
|                 direction = St.DirectionType.TAB_FORWARD; | ||||
|                 break; | ||||
|             case Clutter.Right: | ||||
|                 direction = isLtr ? Gtk.DirectionType.TAB_FORWARD : | ||||
|                                     Gtk.DirectionType.TAB_BACKWARD; | ||||
|                 direction = isLtr ? St.DirectionType.TAB_FORWARD : | ||||
|                                     St.DirectionType.TAB_BACKWARD; | ||||
|                 break; | ||||
|             case Clutter.Up: | ||||
|                 direction = Gtk.DirectionType.TAB_BACKWARD; | ||||
|                 direction = St.DirectionType.TAB_BACKWARD; | ||||
|                 break; | ||||
|             case Clutter.Left: | ||||
|                 direction = isLtr ? Gtk.DirectionType.TAB_BACKWARD : | ||||
|                                     Gtk.DirectionType.TAB_FORWARD; | ||||
|                 direction = isLtr ? St.DirectionType.TAB_BACKWARD : | ||||
|                                     St.DirectionType.TAB_FORWARD; | ||||
|                 break; | ||||
|             default: | ||||
|                 return Clutter.EVENT_PROPAGATE; | ||||
| @@ -1596,7 +1479,7 @@ var AppIcon = class AppIcon { | ||||
|         this.actor.connect('popup-menu', this._onKeyboardPopupMenu.bind(this)); | ||||
|  | ||||
|         this._menu = null; | ||||
|         this._menuManager = new PopupMenu.PopupMenuManager(this); | ||||
|         this._menuManager = new PopupMenu.PopupMenuManager(this.actor); | ||||
|  | ||||
|         if (isDraggable) { | ||||
|             this._draggable = DND.makeDraggable(this.actor); | ||||
| @@ -1686,7 +1569,7 @@ var AppIcon = class AppIcon { | ||||
|  | ||||
|     _onKeyboardPopupMenu() { | ||||
|         this.popupMenu(); | ||||
|         this._menu.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false); | ||||
|         this._menu.actor.navigate_focus(null, St.DirectionType.TAB_FORWARD, false); | ||||
|     } | ||||
|  | ||||
|     getId() { | ||||
| @@ -1824,25 +1707,20 @@ var AppIconMenu = class AppIconMenu extends PopupMenu.PopupMenu { | ||||
|             w => !w.skip_taskbar | ||||
|         ); | ||||
|  | ||||
|         // Display the app windows menu items and the separator between windows | ||||
|         // of the current desktop and other windows. | ||||
|         let workspaceManager = global.workspace_manager; | ||||
|         let activeWorkspace = workspaceManager.get_active_workspace(); | ||||
|         let separatorShown = windows.length > 0 && windows[0].get_workspace() != activeWorkspace; | ||||
|         if (windows.length > 0) | ||||
|             this.addMenuItem( | ||||
|                 /* Translators: This is the heading of a list of open windows */ | ||||
|                 new PopupMenu.PopupSeparatorMenuItem(_("Open Windows")) | ||||
|             ); | ||||
|  | ||||
|         for (let i = 0; i < windows.length; i++) { | ||||
|             let window = windows[i]; | ||||
|             if (!separatorShown && window.get_workspace() != activeWorkspace) { | ||||
|                 this._appendSeparator(); | ||||
|                 separatorShown = true; | ||||
|             } | ||||
|         windows.forEach(window => { | ||||
|             let title = window.title ? window.title | ||||
|                                      : this._source.app.get_name(); | ||||
|             let item = this._appendMenuItem(title); | ||||
|             item.connect('activate', () => { | ||||
|                 this.emit('activate-window', window); | ||||
|             }); | ||||
|         } | ||||
|         }); | ||||
|  | ||||
|         if (!this._source.app.is_window_backed()) { | ||||
|             this._appendSeparator(); | ||||
|   | ||||
| @@ -14,36 +14,47 @@ const RENAMED_DESKTOP_IDS = { | ||||
|     'epiphany.desktop': 'org.gnome.Epiphany.desktop', | ||||
|     'evolution.desktop': 'org.gnome.Evolution.desktop', | ||||
|     'file-roller.desktop': 'org.gnome.FileRoller.desktop', | ||||
|     'five-or-more.desktop': 'org.gnome.five-or-more.desktop', | ||||
|     'four-in-a-row.desktop': 'org.gnome.Four-in-a-row.desktop', | ||||
|     'gcalctool.desktop': 'org.gnome.Calculator.desktop', | ||||
|     'geary.desktop': 'org.gnome.Geary.desktop', | ||||
|     'gedit.desktop': 'org.gnome.gedit.desktop', | ||||
|     'glchess.desktop': 'gnome-chess.desktop', | ||||
|     'glines.desktop': 'five-or-more.desktop', | ||||
|     'gnect.desktop': 'four-in-a-row.desktop', | ||||
|     'glchess.desktop': 'org.gnome.Chess.desktop', | ||||
|     'glines.desktop': 'org.gnome.five-or-more.desktop', | ||||
|     'gnect.desktop': 'org.gnome.Four-in-a-row.desktop', | ||||
|     'gnibbles.desktop': 'org.gnome.Nibbles.desktop', | ||||
|     'gnobots2.desktop': 'gnome-robots.desktop', | ||||
|     'gnobots2.desktop': 'org.gnome.Robots.desktop', | ||||
|     'gnome-boxes.desktop': 'org.gnome.Boxes.desktop', | ||||
|     'gnome-calculator.desktop': 'org.gnome.Calculator.desktop', | ||||
|     'gnome-chess.desktop': 'org.gnome.Chess.desktop', | ||||
|     'gnome-clocks.desktop': 'org.gnome.clocks.desktop', | ||||
|     'gnome-contacts.desktop': 'org.gnome.Contacts.desktop', | ||||
|     'gnome-documents.desktop': 'org.gnome.Documents.desktop', | ||||
|     'gnome-font-viewer.desktop': 'org.gnome.font-viewer.desktop', | ||||
|     'gnome-klotski.desktop': 'org.gnome.Klotski.desktop', | ||||
|     'gnome-nibbles.desktop': 'org.gnome.Nibbles.desktop', | ||||
|     'gnome-mahjongg.desktop': 'org.gnome.Mahjongg.desktop', | ||||
|     'gnome-mines.desktop': 'org.gnome.Mines.desktop', | ||||
|     'gnome-music.desktop': 'org.gnome.Music.desktop', | ||||
|     'gnome-photos.desktop': 'org.gnome.Photos.desktop', | ||||
|     'gnome-robots.desktop': 'org.gnome.Robots.desktop', | ||||
|     'gnome-screenshot.desktop': 'org.gnome.Screenshot.desktop', | ||||
|     'gnome-software.desktop': 'org.gnome.Software.desktop', | ||||
|     'gnome-terminal.desktop': 'org.gnome.Terminal.desktop', | ||||
|     'gnome-tetravex.desktop': 'org.gnome.Tetravex.desktop', | ||||
|     'gnome-tweaks.desktop': 'org.gnome.tweaks.desktop', | ||||
|     'gnome-weather.desktop': 'org.gnome.Weather.Application.desktop', | ||||
|     'gnomine.desktop': 'gnome-mines.desktop', | ||||
|     'gnotravex.desktop': 'gnome-tetravex.desktop', | ||||
|     'gnotski.desktop': 'gnome-klotski.desktop', | ||||
|     'gtali.desktop': 'tali.desktop', | ||||
|     'iagno.desktop': 'org.gnome.Iagno.desktop', | ||||
|     'gnome-weather.desktop': 'org.gnome.Weather.desktop', | ||||
|     'gnomine.desktop': 'org.gnome.Mines.desktop', | ||||
|     'gnotravex.desktop': 'org.gnome.Tetravex.desktop', | ||||
|     'gnotski.desktop': 'org.gnome.Klotski.desktop', | ||||
|     'gtali.desktop': 'org.gnome.Tali.desktop', | ||||
|     'iagno.desktop': 'org.gnome.Reversi.desktop', | ||||
|     'nautilus.desktop': 'org.gnome.Nautilus.desktop', | ||||
|     'org.gnome.gnome-2048.desktop': 'org.gnome.TwentyFortyEight.desktop', | ||||
|     'org.gnome.taquin.desktop': 'org.gnome.Taquin.desktop', | ||||
|     'org.gnome.Weather.Application.desktop': 'org.gnome.Weather.desktop', | ||||
|     'polari.desktop': 'org.gnome.Polari.desktop', | ||||
|     'tali.desktop': 'org.gnome.Tali.desktop', | ||||
|     'totem.desktop': 'org.gnome.Totem.desktop', | ||||
|     'evince.desktop': 'org.gnome.Evince.desktop', | ||||
| }; | ||||
| @@ -153,7 +164,7 @@ class AppFavorites { | ||||
|     } | ||||
|  | ||||
|     _removeFavorite(appId) { | ||||
|         if (!appId in this._favorites) | ||||
|         if (!(appId in this._favorites)) | ||||
|             return false; | ||||
|  | ||||
|         let ids = this._getIds().filter(id => id != appId); | ||||
|   | ||||
| @@ -1,9 +1,4 @@ | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const Gio = imports.gi.Gio; | ||||
| const GLib = imports.gi.GLib; | ||||
| const Meta = imports.gi.Meta; | ||||
| const Shell = imports.gi.Shell; | ||||
| const St = imports.gi.St; | ||||
| const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi; | ||||
|  | ||||
| const Main = imports.ui.main; | ||||
| const ModalDialog = imports.ui.modalDialog; | ||||
| @@ -18,10 +13,11 @@ var AudioDevice = { | ||||
|  | ||||
| const AudioDeviceSelectionIface = loadInterfaceXML('org.gnome.Shell.AudioDeviceSelection'); | ||||
|  | ||||
| var AudioDeviceSelectionDialog = | ||||
| class AudioDeviceSelectionDialog extends ModalDialog.ModalDialog { | ||||
|     constructor(devices) { | ||||
|         super({ styleClass: 'audio-device-selection-dialog' }); | ||||
| var AudioDeviceSelectionDialog = GObject.registerClass({ | ||||
|     Signals: { 'device-selected': { param_types: [GObject.TYPE_UINT] } } | ||||
| }, class AudioDeviceSelectionDialog extends ModalDialog.ModalDialog { | ||||
|     _init(devices) { | ||||
|         super._init({ styleClass: 'audio-device-selection-dialog' }); | ||||
|  | ||||
|         this._deviceItems = {}; | ||||
|  | ||||
| @@ -38,10 +34,6 @@ class AudioDeviceSelectionDialog extends ModalDialog.ModalDialog { | ||||
|             throw new Error('Too few devices for a selection'); | ||||
|     } | ||||
|  | ||||
|     destroy() { | ||||
|         super.destroy(); | ||||
|     } | ||||
|  | ||||
|     _buildLayout(devices) { | ||||
|         let title = new St.Label({ style_class: 'audio-selection-title', | ||||
|                                    text: _("Select Audio Device"), | ||||
| @@ -130,7 +122,7 @@ class AudioDeviceSelectionDialog extends ModalDialog.ModalDialog { | ||||
|         Main.overview.hide(); | ||||
|         app.activate(); | ||||
|     } | ||||
| }; | ||||
| }); | ||||
|  | ||||
| var AudioDeviceSelectionDBus = class AudioDeviceSelectionDBus { | ||||
|     constructor() { | ||||
|   | ||||
| @@ -93,12 +93,7 @@ | ||||
| //     MetaBackgroundImage         MetaBackgroundImage | ||||
| //     MetaBackgroundImage         MetaBackgroundImage | ||||
|  | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const GDesktopEnums = imports.gi.GDesktopEnums; | ||||
| const Gio = imports.gi.Gio; | ||||
| const GLib = imports.gi.GLib; | ||||
| const GnomeDesktop = imports.gi.GnomeDesktop; | ||||
| const Meta = imports.gi.Meta; | ||||
| const { Clutter, GDesktopEnums, Gio, GLib, GnomeDesktop, Meta } = imports.gi; | ||||
| const Signals = imports.signals; | ||||
|  | ||||
| const LoginManager = imports.misc.loginManager; | ||||
| @@ -262,14 +257,15 @@ var Background = class Background { | ||||
|                 this._refreshAnimation(); | ||||
|             }); | ||||
|  | ||||
|         this._settingsChangedSignalId = this._settings.connect('changed', () => { | ||||
|             this.emit('changed'); | ||||
|         }); | ||||
|         this._settingsChangedSignalId = | ||||
|             this._settings.connect('changed', this._emitChangedSignal.bind(this)); | ||||
|  | ||||
|         this._load(); | ||||
|     } | ||||
|  | ||||
|     destroy() { | ||||
|         this.background = null; | ||||
|  | ||||
|         this._cancellable.cancel(); | ||||
|         this._removeAnimationTimeout(); | ||||
|  | ||||
| @@ -293,6 +289,22 @@ var Background = class Background { | ||||
|         if (this._settingsChangedSignalId != 0) | ||||
|             this._settings.disconnect(this._settingsChangedSignalId); | ||||
|         this._settingsChangedSignalId = 0; | ||||
|  | ||||
|         if (this._changedIdleId) { | ||||
|             GLib.source_remove(this._changedIdleId); | ||||
|             this._changedIdleId = 0; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     _emitChangedSignal() { | ||||
|         if (this._changedIdleId) | ||||
|             return; | ||||
|  | ||||
|         this._changedIdleId = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => { | ||||
|             this._changedIdleId = 0; | ||||
|             this.emit('changed'); | ||||
|             return GLib.SOURCE_REMOVE; | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     updateResolution() { | ||||
| @@ -348,7 +360,7 @@ var Background = class Background { | ||||
|                                                if (changedFile.equal(file)) { | ||||
|                                                    let imageCache = Meta.BackgroundImageCache.get_default(); | ||||
|                                                    imageCache.purge(changedFile); | ||||
|                                                    this.emit('changed'); | ||||
|                                                    this._emitChangedSignal(); | ||||
|                                                } | ||||
|                                            }); | ||||
|         this._fileWatches[key] = signalId; | ||||
| @@ -704,7 +716,6 @@ var BackgroundManager = class BackgroundManager { | ||||
|                            time: FADE_ANIMATION_TIME, | ||||
|                            transition: 'easeOutQuad', | ||||
|                            onComplete() { | ||||
|                                oldBackgroundActor.background.run_dispose(); | ||||
|                                oldBackgroundActor.destroy(); | ||||
|                            } | ||||
|                          }); | ||||
| @@ -751,10 +762,8 @@ var BackgroundManager = class BackgroundManager { | ||||
|  | ||||
|         this._container.add_child(backgroundActor); | ||||
|  | ||||
|         let monitor = this._layoutManager.monitors[this._monitorIndex]; | ||||
|  | ||||
|         backgroundActor.set_size(monitor.width, monitor.height); | ||||
|         if (this._controlPosition) { | ||||
|             let monitor = this._layoutManager.monitors[this._monitorIndex]; | ||||
|             backgroundActor.set_position(monitor.x, monitor.y); | ||||
|             backgroundActor.lower_bottom(); | ||||
|         } | ||||
|   | ||||
| @@ -1,8 +1,6 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const St = imports.gi.St; | ||||
| const Shell = imports.gi.Shell; | ||||
| const { Clutter, St } = imports.gi; | ||||
|  | ||||
| const BoxPointer = imports.ui.boxpointer; | ||||
| const Main = imports.ui.main; | ||||
| @@ -27,7 +25,7 @@ var BackgroundMenu = class BackgroundMenu extends PopupMenu.PopupMenu { | ||||
| function addBackgroundMenu(actor, layoutManager) { | ||||
|     actor.reactive = true; | ||||
|     actor._backgroundMenu = new BackgroundMenu(layoutManager); | ||||
|     actor._backgroundManager = new PopupMenu.PopupMenuManager({ actor: actor }); | ||||
|     actor._backgroundManager = new PopupMenu.PopupMenuManager(actor); | ||||
|     actor._backgroundManager.addMenu(actor._backgroundMenu); | ||||
|  | ||||
|     function openMenu(x, y) { | ||||
|   | ||||
| @@ -1,9 +1,6 @@ | ||||
| /* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */ | ||||
|  | ||||
| const Atk = imports.gi.Atk; | ||||
| const Cairo = imports.cairo; | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const St = imports.gi.St; | ||||
| const { Atk, Clutter, St } = imports.gi; | ||||
| const Signals = imports.signals; | ||||
|  | ||||
| var BarLevel = class { | ||||
| @@ -124,7 +121,8 @@ var BarLevel = class { | ||||
|         cr.lineTo(x, (height - barLevelHeight) / 2); | ||||
|         cr.lineTo(x, (height + barLevelHeight) / 2); | ||||
|         cr.lineTo(barLevelBorderRadius + barLevelBorderWidth, (height + barLevelHeight) / 2); | ||||
|         Clutter.cairo_set_source_color(cr, barLevelActiveColor); | ||||
|         if (this._value > 0) | ||||
|           Clutter.cairo_set_source_color(cr, barLevelActiveColor); | ||||
|         cr.fillPreserve(); | ||||
|         Clutter.cairo_set_source_color(cr, barLevelActiveBorderColor); | ||||
|         cr.setLineWidth(barLevelBorderWidth); | ||||
| @@ -146,17 +144,19 @@ var BarLevel = class { | ||||
|         } | ||||
|  | ||||
|         /* end progress bar arc */ | ||||
|         if (this._value <= this._overdriveStart) | ||||
|             Clutter.cairo_set_source_color(cr, barLevelActiveColor); | ||||
|         else | ||||
|             Clutter.cairo_set_source_color(cr, barLevelOverdriveColor); | ||||
|         cr.arc(endX, height / 2, barLevelBorderRadius, TAU * 3 / 4, TAU * 1 / 4); | ||||
|         cr.lineTo(Math.floor(endX), (height + barLevelHeight) / 2); | ||||
|         cr.lineTo(Math.floor(endX), (height - barLevelHeight) / 2); | ||||
|         cr.lineTo(endX, (height - barLevelHeight) / 2); | ||||
|         cr.fillPreserve(); | ||||
|         cr.setLineWidth(barLevelBorderWidth); | ||||
|         cr.stroke(); | ||||
|         if (this._value > 0) { | ||||
|           if (this._value <= this._overdriveStart) | ||||
|               Clutter.cairo_set_source_color(cr, barLevelActiveColor); | ||||
|           else | ||||
|               Clutter.cairo_set_source_color(cr, barLevelOverdriveColor); | ||||
|           cr.arc(endX, height / 2, barLevelBorderRadius, TAU * 3 / 4, TAU * 1 / 4); | ||||
|           cr.lineTo(Math.floor(endX), (height + barLevelHeight) / 2); | ||||
|           cr.lineTo(Math.floor(endX), (height - barLevelHeight) / 2); | ||||
|           cr.lineTo(endX, (height - barLevelHeight) / 2); | ||||
|           cr.fillPreserve(); | ||||
|           cr.setLineWidth(barLevelBorderWidth); | ||||
|           cr.stroke(); | ||||
|         } | ||||
|  | ||||
|         /* draw overdrive separator */ | ||||
|         if (overdriveActive) { | ||||
|   | ||||
| @@ -1,11 +1,6 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const GObject = imports.gi.GObject; | ||||
| const Meta = imports.gi.Meta; | ||||
| const Shell = imports.gi.Shell; | ||||
| const Signals = imports.signals; | ||||
| const St = imports.gi.St; | ||||
| const { Clutter, GObject, Meta, Shell, St } = imports.gi; | ||||
|  | ||||
| const Main = imports.ui.main; | ||||
| const Tweener = imports.ui.tweener; | ||||
| @@ -29,7 +24,7 @@ var POPUP_ANIMATION_TIME = 0.15; | ||||
|  * placed.  The arrow position may be controlled via | ||||
|  * setArrowOrigin(). The arrow side might be temporarily flipped | ||||
|  * depending on the box size and source position to keep the box | ||||
|  * totally inside the monitor if possible. | ||||
|  * totally inside the monitor workarea if possible. | ||||
|  * | ||||
|  */ | ||||
| var BoxPointer = GObject.registerClass({ | ||||
| @@ -38,8 +33,6 @@ var BoxPointer = GObject.registerClass({ | ||||
|     _init(arrowSide, binProperties) { | ||||
|         super._init(); | ||||
|  | ||||
|         this.actor = this; | ||||
|  | ||||
|         this.set_offscreen_redirect(Clutter.OffscreenRedirect.ALWAYS); | ||||
|  | ||||
|         this._arrowSide = arrowSide; | ||||
| @@ -52,13 +45,18 @@ var BoxPointer = GObject.registerClass({ | ||||
|         this._border.connect('repaint', this._drawBorder.bind(this)); | ||||
|         this.add_actor(this._border); | ||||
|         this.bin.raise(this._border); | ||||
|         this._xOffset = 0; | ||||
|         this._yOffset = 0; | ||||
|         this._xPosition = 0; | ||||
|         this._yPosition = 0; | ||||
|         this._sourceAlignment = 0.5; | ||||
|         this._capturedEventId = 0; | ||||
|         this._muteInput(); | ||||
|  | ||||
|         this.connect('destroy', this._onDestroy.bind(this)); | ||||
|     } | ||||
|  | ||||
|     _onDestroy() { | ||||
|         if (this._sourceActorDestroyId) { | ||||
|             this._sourceActor.disconnect(this._sourceActorDestroyId); | ||||
|             delete this._sourceActorDestroyId; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     get arrowSide() { | ||||
| @@ -78,36 +76,6 @@ var BoxPointer = GObject.registerClass({ | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // BoxPointer.show() and BoxPointer.hide() are here for only compatibility | ||||
|     // purposes, and will be removed in 3.32. | ||||
|     show(animate, onComplete) { | ||||
|         if (animate !== undefined) { | ||||
|             try { | ||||
|                 throw new Error('BoxPointer.show() has been moved to BoxPointer.open(), this code will break in the future.'); | ||||
|             } catch(e) { | ||||
|                 logError(e); | ||||
|                 this.open(animate, onComplete); | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         this.visible = true; | ||||
|     } | ||||
|  | ||||
|     hide(animate, onComplete) { | ||||
|         if (animate !== undefined) { | ||||
|             try { | ||||
|                 throw new Error('BoxPointer.hide() has been moved to BoxPointer.close(), this code will break in the future.'); | ||||
|             } catch(e) { | ||||
|                 logError(e); | ||||
|                 this.close(animate, onComplete); | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         this.visible = false; | ||||
|     } | ||||
|  | ||||
|     open(animate, onComplete) { | ||||
|         let themeNode = this.get_theme_node(); | ||||
|         let rise = themeNode.get_length('-arrow-rise'); | ||||
| @@ -123,23 +91,23 @@ var BoxPointer = GObject.registerClass({ | ||||
|         if (animate & PopupAnimation.SLIDE) { | ||||
|             switch (this._arrowSide) { | ||||
|                 case St.Side.TOP: | ||||
|                     this.yOffset = -rise; | ||||
|                     this.translation_y = -rise; | ||||
|                     break; | ||||
|                 case St.Side.BOTTOM: | ||||
|                     this.yOffset = rise; | ||||
|                     this.translation_y = rise; | ||||
|                     break; | ||||
|                 case St.Side.LEFT: | ||||
|                     this.xOffset = -rise; | ||||
|                     this.translation_x = -rise; | ||||
|                     break; | ||||
|                 case St.Side.RIGHT: | ||||
|                     this.xOffset = rise; | ||||
|                     this.translation_x = rise; | ||||
|                     break; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         Tweener.addTween(this, { opacity: 255, | ||||
|                                  xOffset: 0, | ||||
|                                  yOffset: 0, | ||||
|                                  translation_x: 0, | ||||
|                                  translation_y: 0, | ||||
|                                  transition: 'linear', | ||||
|                                  onComplete: () => { | ||||
|                                      this._unmuteInput(); | ||||
| @@ -153,8 +121,8 @@ var BoxPointer = GObject.registerClass({ | ||||
|         if (!this.visible) | ||||
|             return; | ||||
|  | ||||
|         let xOffset = 0; | ||||
|         let yOffset = 0; | ||||
|         let translationX = 0; | ||||
|         let translationY = 0; | ||||
|         let themeNode = this.get_theme_node(); | ||||
|         let rise = themeNode.get_length('-arrow-rise'); | ||||
|         let fade = (animate & PopupAnimation.FADE); | ||||
| @@ -163,16 +131,16 @@ var BoxPointer = GObject.registerClass({ | ||||
|         if (animate & PopupAnimation.SLIDE) { | ||||
|             switch (this._arrowSide) { | ||||
|                 case St.Side.TOP: | ||||
|                     yOffset = rise; | ||||
|                     translationY = rise; | ||||
|                     break; | ||||
|                 case St.Side.BOTTOM: | ||||
|                     yOffset = -rise; | ||||
|                     translationY = -rise; | ||||
|                     break; | ||||
|                 case St.Side.LEFT: | ||||
|                     xOffset = rise; | ||||
|                     translationX = rise; | ||||
|                     break; | ||||
|                 case St.Side.RIGHT: | ||||
|                     xOffset = -rise; | ||||
|                     translationX = -rise; | ||||
|                     break; | ||||
|             } | ||||
|         } | ||||
| @@ -181,15 +149,15 @@ var BoxPointer = GObject.registerClass({ | ||||
|  | ||||
|         Tweener.removeTweens(this); | ||||
|         Tweener.addTween(this, { opacity: fade ? 0 : 255, | ||||
|                                  xOffset: xOffset, | ||||
|                                  yOffset: yOffset, | ||||
|                                  translation_x: translationX, | ||||
|                                  translation_y: translationY, | ||||
|                                  transition: 'linear', | ||||
|                                  time: animationTime, | ||||
|                                  onComplete: () => { | ||||
|                                      this.hide(); | ||||
|                                      this.opacity = 0; | ||||
|                                      this.xOffset = 0; | ||||
|                                      this.yOffset = 0; | ||||
|                                      this.translation_x = 0; | ||||
|                                      this.translation_y = 0; | ||||
|                                      if (onComplete) | ||||
|                                          onComplete(); | ||||
|                                  } | ||||
| @@ -236,13 +204,10 @@ var BoxPointer = GObject.registerClass({ | ||||
|         this.set_allocation(box, flags); | ||||
|  | ||||
|         let themeNode = this.get_theme_node(); | ||||
|         box = themeNode.get_content_box(box); | ||||
|  | ||||
|         let borderWidth = themeNode.get_length('-arrow-border-width'); | ||||
|         let rise = themeNode.get_length('-arrow-rise'); | ||||
|         let childBox = new Clutter.ActorBox(); | ||||
|         let availWidth = box.x2 - box.x1; | ||||
|         let availHeight = box.y2 - box.y1; | ||||
|         let [availWidth, availHeight] = themeNode.get_content_box(box).get_size(); | ||||
|  | ||||
|         childBox.x1 = 0; | ||||
|         childBox.y1 = 0; | ||||
| @@ -271,8 +236,9 @@ var BoxPointer = GObject.registerClass({ | ||||
|         this.bin.allocate(childBox, flags); | ||||
|  | ||||
|         if (this._sourceActor && this._sourceActor.mapped) { | ||||
|             this._reposition(); | ||||
|             this._updateFlip(); | ||||
|             this._reposition(box); | ||||
|             this._updateFlip(box); | ||||
|             this.set_allocation(box, flags); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -459,15 +425,25 @@ var BoxPointer = GObject.registerClass({ | ||||
|     } | ||||
|  | ||||
|     setPosition(sourceActor, alignment) { | ||||
|         // We need to show it now to force an allocation, | ||||
|         // so that we can query the correct size. | ||||
|         this.show(); | ||||
|         if (!this._sourceActor || sourceActor != this._sourceActor) { | ||||
|             if (this._sourceActorDestroyId) { | ||||
|                 this._sourceActor.disconnect(this._sourceActorDestroyId); | ||||
|                 delete this._sourceActorDestroyId; | ||||
|             } | ||||
|  | ||||
|             this._sourceActor = sourceActor; | ||||
|  | ||||
|             if (this._sourceActor) { | ||||
|                 this._sourceActorDestroyId = this._sourceActor.connect('destroy', () => { | ||||
|                     this._sourceActor = null; | ||||
|                     delete this._sourceActorDestroyId; | ||||
|                 }) | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         this._sourceActor = sourceActor; | ||||
|         this._arrowAlignment = alignment; | ||||
|  | ||||
|         this._reposition(); | ||||
|         this._updateFlip(); | ||||
|         this.queue_relayout(); | ||||
|     } | ||||
|  | ||||
|     setSourceAlignment(alignment) { | ||||
| @@ -479,14 +455,18 @@ var BoxPointer = GObject.registerClass({ | ||||
|         this.setPosition(this._sourceActor, this._arrowAlignment); | ||||
|     } | ||||
|  | ||||
|     _reposition() { | ||||
|     _reposition(allocationBox) { | ||||
|         let sourceActor = this._sourceActor; | ||||
|         let alignment = this._arrowAlignment; | ||||
|         let monitorIndex = Main.layoutManager.findIndexForActor(sourceActor); | ||||
|  | ||||
|         this._sourceAllocation = Shell.util_get_transformed_allocation(sourceActor); | ||||
|         this._workArea = Main.layoutManager.getWorkAreaForMonitor(monitorIndex); | ||||
|  | ||||
|         // Position correctly relative to the sourceActor | ||||
|         let sourceNode = sourceActor.get_theme_node(); | ||||
|         let sourceContentBox = sourceNode.get_content_box(sourceActor.get_allocation_box()); | ||||
|         let sourceAllocation = Shell.util_get_transformed_allocation(sourceActor); | ||||
|         let sourceAllocation = this._sourceAllocation; | ||||
|         let sourceCenterX = sourceAllocation.x1 + sourceContentBox.x1 + (sourceContentBox.x2 - sourceContentBox.x1) * this._sourceAlignment; | ||||
|         let sourceCenterY = sourceAllocation.y1 + sourceContentBox.y1 + (sourceContentBox.y2 - sourceContentBox.y1) * this._sourceAlignment; | ||||
|         let [minWidth, minHeight, natWidth, natHeight] = this.get_preferred_size(); | ||||
| @@ -494,7 +474,7 @@ var BoxPointer = GObject.registerClass({ | ||||
|         // We also want to keep it onscreen, and separated from the | ||||
|         // edge by the same distance as the main part of the box is | ||||
|         // separated from its sourceActor | ||||
|         let monitor = Main.layoutManager.findMonitorForActor(sourceActor); | ||||
|         let workarea = this._workArea; | ||||
|         let themeNode = this.get_theme_node(); | ||||
|         let borderWidth = themeNode.get_length('-arrow-border-width'); | ||||
|         let arrowBase = themeNode.get_length('-arrow-base'); | ||||
| @@ -544,8 +524,8 @@ var BoxPointer = GObject.registerClass({ | ||||
|         case St.Side.BOTTOM: | ||||
|             resX = sourceCenterX - (halfMargin + (natWidth - margin) * alignment); | ||||
|  | ||||
|             resX = Math.max(resX, monitor.x + padding); | ||||
|             resX = Math.min(resX, monitor.x + monitor.width - (padding + natWidth)); | ||||
|             resX = Math.max(resX, workarea.x + padding); | ||||
|             resX = Math.min(resX, workarea.x + workarea.width - (padding + natWidth)); | ||||
|  | ||||
|             arrowOrigin = sourceCenterX - resX; | ||||
|             if (arrowOrigin <= (x1 + (borderRadius + halfBase))) { | ||||
| @@ -563,8 +543,8 @@ var BoxPointer = GObject.registerClass({ | ||||
|         case St.Side.RIGHT: | ||||
|             resY = sourceCenterY - (halfMargin + (natHeight - margin) * alignment); | ||||
|  | ||||
|             resY = Math.max(resY, monitor.y + padding); | ||||
|             resY = Math.min(resY, monitor.y + monitor.height - (padding + natHeight)); | ||||
|             resY = Math.max(resY, workarea.y + padding); | ||||
|             resY = Math.min(resY, workarea.y + workarea.height - (padding + natHeight)); | ||||
|  | ||||
|             arrowOrigin = sourceCenterY - resY; | ||||
|             if (arrowOrigin <= (y1 + (borderRadius + halfBase))) { | ||||
| @@ -588,9 +568,8 @@ var BoxPointer = GObject.registerClass({ | ||||
|             parent = parent.get_parent(); | ||||
|         } | ||||
|  | ||||
|         this._xPosition = Math.floor(x); | ||||
|         this._yPosition = Math.floor(y); | ||||
|         this._shiftActor(); | ||||
|         // Actually set the position | ||||
|         allocationBox.set_origin(Math.floor(x), Math.floor(y)); | ||||
|     } | ||||
|  | ||||
|     // @origin: Coordinate specifying middle of the arrow, along | ||||
| @@ -613,44 +592,30 @@ var BoxPointer = GObject.registerClass({ | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     _shiftActor() { | ||||
|         // Since the position of the BoxPointer depends on the allocated size | ||||
|         // of the BoxPointer and the position of the source actor, trying | ||||
|         // to position the BoxPointer via the x/y properties will result in | ||||
|         // allocation loops and warnings. Instead we do the positioning via | ||||
|         // the anchor point, which is independent of allocation, and leave | ||||
|         // x == y == 0. | ||||
|         this.set_anchor_point(-(this._xPosition + this._xOffset), | ||||
|                               -(this._yPosition + this._yOffset)); | ||||
|     } | ||||
|  | ||||
|     _calculateArrowSide(arrowSide) { | ||||
|         let sourceAllocation = Shell.util_get_transformed_allocation(this._sourceActor); | ||||
|         let sourceAllocation = this._sourceAllocation; | ||||
|         let [minWidth, minHeight, boxWidth, boxHeight] = this.get_preferred_size(); | ||||
|         let monitorActor = this.sourceActor; | ||||
|         if (!monitorActor) | ||||
|             monitorActor = this; | ||||
|         let monitor = Main.layoutManager.findMonitorForActor(monitorActor); | ||||
|         let workarea = this._workArea; | ||||
|  | ||||
|         switch (arrowSide) { | ||||
|         case St.Side.TOP: | ||||
|             if (sourceAllocation.y2 + boxHeight > monitor.y + monitor.height && | ||||
|                 boxHeight < sourceAllocation.y1 - monitor.y) | ||||
|             if (sourceAllocation.y2 + boxHeight > workarea.y + workarea.height && | ||||
|                 boxHeight < sourceAllocation.y1 - workarea.y) | ||||
|                 return St.Side.BOTTOM; | ||||
|             break; | ||||
|         case St.Side.BOTTOM: | ||||
|             if (sourceAllocation.y1 - boxHeight < monitor.y && | ||||
|                 boxHeight < monitor.y + monitor.height - sourceAllocation.y2) | ||||
|             if (sourceAllocation.y1 - boxHeight < workarea.y && | ||||
|                 boxHeight < workarea.y + workarea.height - sourceAllocation.y2) | ||||
|                 return St.Side.TOP; | ||||
|             break; | ||||
|         case St.Side.LEFT: | ||||
|             if (sourceAllocation.x2 + boxWidth > monitor.x + monitor.width && | ||||
|                 boxWidth < sourceAllocation.x1 - monitor.x) | ||||
|             if (sourceAllocation.x2 + boxWidth > workarea.x + workarea.width && | ||||
|                 boxWidth < sourceAllocation.x1 - workarea.x) | ||||
|                 return St.Side.RIGHT; | ||||
|             break; | ||||
|         case St.Side.RIGHT: | ||||
|             if (sourceAllocation.x1 - boxWidth < monitor.x && | ||||
|                 boxWidth < monitor.x + monitor.width - sourceAllocation.x2) | ||||
|             if (sourceAllocation.x1 - boxWidth < workarea.x && | ||||
|                 boxWidth < workarea.x + workarea.width - sourceAllocation.x2) | ||||
|                 return St.Side.LEFT; | ||||
|             break; | ||||
|         } | ||||
| @@ -658,38 +623,16 @@ var BoxPointer = GObject.registerClass({ | ||||
|         return arrowSide; | ||||
|     } | ||||
|  | ||||
|     _updateFlip() { | ||||
|     _updateFlip(allocationBox) { | ||||
|         let arrowSide = this._calculateArrowSide(this._userArrowSide); | ||||
|         if (this._arrowSide != arrowSide) { | ||||
|             this._arrowSide = arrowSide; | ||||
|             this._reposition(); | ||||
|             Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => { | ||||
|                 this.queue_relayout(); | ||||
|                 return false; | ||||
|             }); | ||||
|             this._reposition(allocationBox); | ||||
|  | ||||
|             this.emit('arrow-side-changed'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     set xOffset(offset) { | ||||
|         this._xOffset = offset; | ||||
|         this._shiftActor(); | ||||
|     } | ||||
|  | ||||
|     get xOffset() { | ||||
|         return this._xOffset; | ||||
|     } | ||||
|  | ||||
|     set yOffset(offset) { | ||||
|         this._yOffset = offset; | ||||
|         this._shiftActor(); | ||||
|     } | ||||
|  | ||||
|     get yOffset() { | ||||
|         return this._yOffset; | ||||
|     } | ||||
|  | ||||
|     updateArrowSide(side) { | ||||
|         this._arrowSide = side; | ||||
|         this._border.queue_repaint(); | ||||
|   | ||||
| @@ -1,12 +1,7 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const Gio = imports.gi.Gio; | ||||
| const GLib = imports.gi.GLib; | ||||
| const Gtk = imports.gi.Gtk; | ||||
| const St = imports.gi.St; | ||||
| const { Clutter, Gio, GLib, Shell, St } = imports.gi; | ||||
| const Signals = imports.signals; | ||||
| const Shell = imports.gi.Shell; | ||||
|  | ||||
| const Main = imports.ui.main; | ||||
| const MessageList = imports.ui.messageList; | ||||
| @@ -14,6 +9,8 @@ const MessageTray = imports.ui.messageTray; | ||||
| const Mpris = imports.ui.mpris; | ||||
| const Util = imports.misc.util; | ||||
|  | ||||
| const { loadInterfaceXML } = imports.misc.fileUtils; | ||||
|  | ||||
| var MSECS_IN_DAY = 24 * 60 * 60 * 1000; | ||||
| var SHOW_WEEKDATE_KEY = 'show-weekdate'; | ||||
| var ELLIPSIS_CHAR = '\u2026'; | ||||
| @@ -126,19 +123,7 @@ var EmptyEventSource = class EmptyEventSource { | ||||
| }; | ||||
| Signals.addSignalMethods(EmptyEventSource.prototype); | ||||
|  | ||||
| const CalendarServerIface = ` | ||||
| <node> | ||||
| <interface name="org.gnome.Shell.CalendarServer"> | ||||
| <method name="GetEvents"> | ||||
|     <arg type="x" direction="in" /> | ||||
|     <arg type="x" direction="in" /> | ||||
|     <arg type="b" direction="in" /> | ||||
|     <arg type="a(sssbxxa{sv})" direction="out" /> | ||||
| </method> | ||||
| <property name="HasCalendars" type="b" access="read" /> | ||||
| <signal name="Changed" /> | ||||
| </interface> | ||||
| </node>`; | ||||
| const CalendarServerIface = loadInterfaceXML('org.gnome.Shell.CalendarServer'); | ||||
|  | ||||
| const CalendarServerInfo  = Gio.DBusInterfaceInfo.new_for_xml(CalendarServerIface); | ||||
|  | ||||
| @@ -1083,7 +1068,7 @@ var CalendarMessageList = class CalendarMessageList { | ||||
|                                                overlay_scrollbars: true, | ||||
|                                                x_expand: true, y_expand: true, | ||||
|                                                x_fill: true, y_fill: true }); | ||||
|         this._scrollView.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC); | ||||
|         this._scrollView.set_policy(St.PolicyType.NEVER, St.PolicyType.AUTOMATIC); | ||||
|         box.add_actor(this._scrollView); | ||||
|  | ||||
|         this._clearButton = new St.Button({ style_class: 'message-list-clear-button button', | ||||
|   | ||||
| @@ -1,6 +1,4 @@ | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const Pango = imports.gi.Pango; | ||||
| const St = imports.gi.St; | ||||
| const { Clutter, Pango, St } = imports.gi; | ||||
|  | ||||
| var CheckBox = class CheckBox { | ||||
|     constructor(label) { | ||||
|   | ||||
| @@ -1,11 +1,6 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const Gio = imports.gi.Gio; | ||||
| const GLib = imports.gi.GLib; | ||||
| const GObject = imports.gi.GObject; | ||||
| const Meta = imports.gi.Meta; | ||||
| const Shell = imports.gi.Shell; | ||||
| const { Clutter, Gio, GLib, GObject, Meta, Shell } = imports.gi; | ||||
|  | ||||
| const Dialog = imports.ui.dialog; | ||||
| const Main = imports.ui.main; | ||||
|   | ||||
| @@ -1,10 +1,8 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const { Gio, GLib } = imports.gi; | ||||
| const Mainloop = imports.mainloop; | ||||
| const GLib = imports.gi.GLib; | ||||
| const Gio = imports.gi.Gio; | ||||
| const Params = imports.misc.params; | ||||
| const Shell = imports.gi.Shell; | ||||
|  | ||||
| const GnomeSession = imports.misc.gnomeSession; | ||||
| const Main = imports.ui.main; | ||||
| @@ -96,10 +94,10 @@ var AutomountManager = class { | ||||
|         if (!this._session.SessionIsActive) | ||||
|             return; | ||||
|  | ||||
|         let sound = global.display.get_sound(); | ||||
|         sound.play_from_theme('device-removed-media', | ||||
|                               _("External drive disconnected"), | ||||
|                               null); | ||||
|         let player = global.display.get_sound_player(); | ||||
|         player.play_from_theme('device-removed-media', | ||||
|                                _("External drive disconnected"), | ||||
|                                null); | ||||
|     } | ||||
|  | ||||
|     _onDriveEjectButton(monitor, drive) { | ||||
| @@ -202,12 +200,20 @@ var AutomountManager = class { | ||||
|             // error strings are not unique for the cases in the comments below. | ||||
|             if (e.message.includes('No key available with this passphrase') || // cryptsetup | ||||
|                 e.message.includes('No key available to unlock device') ||     // udisks (no password) | ||||
|                 e.message.includes('Error unlocking')) {                       // udisks (wrong password) | ||||
|                 // libblockdev wrong password opening LUKS device | ||||
|                 e.message.includes('Failed to activate device: Incorrect passphrase') || | ||||
|                 // cryptsetup returns EINVAL in many cases, including wrong TCRYPT password/parameters | ||||
|                 e.message.includes('Failed to load device\'s parameters: Invalid argument')) { | ||||
|  | ||||
|                 this._reaskPassword(volume); | ||||
|             } else { | ||||
|                 if (e.message.includes('Compiled against a version of libcryptsetup that does not support the VeraCrypt PIM setting')) { | ||||
|                     Main.notifyError(_("Unable to unlock volume"), | ||||
|                         _("The installed udisks version does not support the PIM setting")); | ||||
|                 } | ||||
|  | ||||
|                 if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.FAILED_HANDLED)) | ||||
|                     log('Unable to mount volume ' + volume.get_name() + ': ' + e.toString()); | ||||
|  | ||||
|                 this._closeOperation(volume); | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Gio = imports.gi.Gio; | ||||
| const St = imports.gi.St; | ||||
| const { Gio, St } = imports.gi; | ||||
|  | ||||
| const GnomeSession = imports.misc.gnomeSession; | ||||
| const Main = imports.ui.main; | ||||
|   | ||||
| @@ -1,25 +1,19 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Shell = imports.gi.Shell; | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const St = imports.gi.St; | ||||
| const Pango = imports.gi.Pango; | ||||
| const Gio = imports.gi.Gio; | ||||
| const GObject = imports.gi.GObject; | ||||
| const Gcr = imports.gi.Gcr; | ||||
| const { Clutter, Gcr, Gio, GObject, Pango, Shell, St } = imports.gi; | ||||
|  | ||||
| const Animation = imports.ui.animation; | ||||
| const Dialog = imports.ui.dialog; | ||||
| const ModalDialog = imports.ui.modalDialog; | ||||
| const ShellEntry = imports.ui.shellEntry; | ||||
| const CheckBox = imports.ui.checkBox; | ||||
| const Tweener = imports.ui.tweener; | ||||
|  | ||||
| var WORK_SPINNER_ICON_SIZE = 16; | ||||
|  | ||||
| var KeyringDialog = class extends ModalDialog.ModalDialog { | ||||
|     constructor() { | ||||
|         super({ styleClass: 'prompt-dialog' }); | ||||
| var KeyringDialog = GObject.registerClass( | ||||
| class KeyringDialog extends ModalDialog.ModalDialog { | ||||
|     _init() { | ||||
|         super._init({ styleClass: 'prompt-dialog' }); | ||||
|  | ||||
|         this.prompt = new Shell.KeyringPrompt(); | ||||
|         this.prompt.connect('show-password', this._onShowPassword.bind(this)); | ||||
| @@ -30,20 +24,8 @@ var KeyringDialog = class extends ModalDialog.ModalDialog { | ||||
|         this._content = new Dialog.MessageDialogContent({ icon }); | ||||
|         this.contentLayout.add(this._content); | ||||
|  | ||||
|         // FIXME: Why does this break now? | ||||
|         /* | ||||
|         this.prompt.bind_property('message', this._content, 'title', GObject.BindingFlags.SYNC_CREATE); | ||||
|         this.prompt.bind_property('description', this._content, 'body', GObject.BindingFlags.SYNC_CREATE); | ||||
|         */ | ||||
|         this.prompt.connect('notify::message', () => { | ||||
|             this._content.title = this.prompt.message; | ||||
|         }); | ||||
|         this._content.title = this.prompt.message; | ||||
|  | ||||
|         this.prompt.connect('notify::description', () => { | ||||
|             this._content.body = this.prompt.description; | ||||
|         }); | ||||
|         this._content.body = this.prompt.description; | ||||
|  | ||||
|         this._workSpinner = null; | ||||
|         this._controlTable = null; | ||||
| @@ -231,7 +213,7 @@ var KeyringDialog = class extends ModalDialog.ModalDialog { | ||||
|     _onCancelButton() { | ||||
|         this.prompt.cancel(); | ||||
|     } | ||||
| }; | ||||
| }); | ||||
|  | ||||
| var KeyringDummyDialog = class { | ||||
|     constructor() { | ||||
|   | ||||
| @@ -1,28 +1,21 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const Gio = imports.gi.Gio; | ||||
| const GLib = imports.gi.GLib; | ||||
| const GObject = imports.gi.GObject; | ||||
| const NM = imports.gi.NM; | ||||
| const Pango = imports.gi.Pango; | ||||
| const Shell = imports.gi.Shell; | ||||
| const { Clutter, Gio, GLib, GObject, NM, Pango, Shell, St } = imports.gi; | ||||
| const Signals = imports.signals; | ||||
| const St = imports.gi.St; | ||||
|  | ||||
| const Config = imports.misc.config; | ||||
| const Dialog = imports.ui.dialog; | ||||
| const Main = imports.ui.main; | ||||
| const MessageTray = imports.ui.messageTray; | ||||
| const ModalDialog = imports.ui.modalDialog; | ||||
| const PopupMenu = imports.ui.popupMenu; | ||||
| const ShellEntry = imports.ui.shellEntry; | ||||
|  | ||||
| const VPN_UI_GROUP = 'VPN Plugin UI'; | ||||
|  | ||||
| var NetworkSecretDialog = class extends ModalDialog.ModalDialog { | ||||
|     constructor(agent, requestId, connection, settingName, hints, flags, contentOverride) { | ||||
|         super({ styleClass: 'prompt-dialog' }); | ||||
| var NetworkSecretDialog = GObject.registerClass( | ||||
| class NetworkSecretDialog extends ModalDialog.ModalDialog { | ||||
|     _init(agent, requestId, connection, settingName, hints, flags, contentOverride) { | ||||
|         super._init({ styleClass: 'prompt-dialog' }); | ||||
|  | ||||
|         this._agent = agent; | ||||
|         this._requestId = requestId; | ||||
| @@ -111,10 +104,10 @@ var NetworkSecretDialog = class extends ModalDialog.ModalDialog { | ||||
|             descriptionLabel.clutter_text.line_wrap = true; | ||||
|             descriptionLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE; | ||||
|  | ||||
|             messageBox.add(descriptionLabel, | ||||
|                            { y_fill:  true, | ||||
|                              y_align: St.Align.START, | ||||
|                              expand: true }); | ||||
|             contentBox.messageBox.add(descriptionLabel, | ||||
|                                       { y_fill:  true, | ||||
|                                         y_align: St.Align.START, | ||||
|                                         expand: true }); | ||||
|         } | ||||
|  | ||||
|         this._okButton = { label:  _("Connect"), | ||||
| @@ -355,7 +348,7 @@ var NetworkSecretDialog = class extends ModalDialog.ModalDialog { | ||||
|  | ||||
|         return content; | ||||
|     } | ||||
| }; | ||||
| }); | ||||
|  | ||||
| var VPNRequestHandler = class { | ||||
|     constructor(agent, requestId, authHelper, serviceType, connection, hints, flags) { | ||||
| @@ -705,14 +698,14 @@ var NetworkAgent = class { | ||||
|             if (hints.indexOf('pin') != -1) { | ||||
|                 let gsmSetting = connection.get_setting_gsm(); | ||||
|                 title = _("PIN code required"); | ||||
|                 message = _("PIN code is needed for the mobile broadband device"); | ||||
|                 body = _("PIN code is needed for the mobile broadband device"); | ||||
|                 break; | ||||
|             } | ||||
|             // fall through | ||||
|         case 'cdma': | ||||
|         case 'bluetooth': | ||||
|             title = _("Mobile broadband network password"); | ||||
|             message = _("A password is required to connect to “%s”.").format(connectionSetting.get_id()); | ||||
|             body = _("A password is required to connect to “%s”.").format(connectionSetting.get_id()); | ||||
|             break; | ||||
|         default: | ||||
|             log('Invalid connection type: ' + connectionType); | ||||
|   | ||||
| @@ -1,33 +1,25 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const { AccountsService, Clutter, Gio, GLib, | ||||
|         GObject, Pango, PolkitAgent, Polkit, Shell, St } = imports.gi; | ||||
| const Signals = imports.signals; | ||||
| const Shell = imports.gi.Shell; | ||||
| const AccountsService = imports.gi.AccountsService; | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const St = imports.gi.St; | ||||
| const Pango = imports.gi.Pango; | ||||
| const GLib = imports.gi.GLib; | ||||
| const Gio = imports.gi.Gio; | ||||
| const Mainloop = imports.mainloop; | ||||
| const Polkit = imports.gi.Polkit; | ||||
| const PolkitAgent = imports.gi.PolkitAgent; | ||||
|  | ||||
| const Animation = imports.ui.animation; | ||||
| const Components = imports.ui.components; | ||||
| const Dialog = imports.ui.dialog; | ||||
| const Main = imports.ui.main; | ||||
| const ModalDialog = imports.ui.modalDialog; | ||||
| const ShellEntry = imports.ui.shellEntry; | ||||
| const UserWidget = imports.ui.userWidget; | ||||
| const Tweener = imports.ui.tweener; | ||||
|  | ||||
| var DIALOG_ICON_SIZE = 48; | ||||
|  | ||||
| var WORK_SPINNER_ICON_SIZE = 16; | ||||
|  | ||||
| var AuthenticationDialog = class extends ModalDialog.ModalDialog { | ||||
|     constructor(actionId, body, cookie, userNames) { | ||||
|         super({ styleClass: 'prompt-dialog' }); | ||||
| var AuthenticationDialog = GObject.registerClass({ | ||||
|     Signals: { 'done': { param_types: [GObject.TYPE_BOOLEAN] } } | ||||
| }, class AuthenticationDialog extends ModalDialog.ModalDialog { | ||||
|     _init(actionId, body, cookie, userNames) { | ||||
|         super._init({ styleClass: 'prompt-dialog' }); | ||||
|  | ||||
|         this.actionId = actionId; | ||||
|         this.message = body; | ||||
| @@ -35,7 +27,7 @@ var AuthenticationDialog = class extends ModalDialog.ModalDialog { | ||||
|         this._wasDismissed = false; | ||||
|  | ||||
|         this._sessionUpdatedId = Main.sessionMode.connect('updated', () => { | ||||
|             this._group.visible = !Main.sessionMode.isLocked; | ||||
|             this.visible = !Main.sessionMode.isLocked; | ||||
|         }); | ||||
|  | ||||
|         this.connect('closed', this._onDialogClosed.bind(this)); | ||||
| @@ -336,8 +328,7 @@ var AuthenticationDialog = class extends ModalDialog.ModalDialog { | ||||
|  | ||||
|         this._destroySession(); | ||||
|     } | ||||
| }; | ||||
| Signals.addSignalMethods(AuthenticationDialog.prototype); | ||||
| }); | ||||
|  | ||||
| var AuthenticationAgent = class { | ||||
|     constructor() { | ||||
|   | ||||
| @@ -1,20 +1,13 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const Gio = imports.gi.Gio; | ||||
| const GLib = imports.gi.GLib; | ||||
| const GObject = imports.gi.GObject; | ||||
| const Gtk = imports.gi.Gtk; | ||||
| const { Clutter, Gio, GLib, GObject, St } = imports.gi; | ||||
| const Lang = imports.lang; | ||||
| const Mainloop = imports.mainloop; | ||||
| const Signals = imports.signals; | ||||
| const St = imports.gi.St; | ||||
|  | ||||
| var Tpl = null; | ||||
| var Tp = null; | ||||
| try { | ||||
|     Tpl = imports.gi.TelepathyLogger; | ||||
|     Tp = imports.gi.TelepathyGLib; | ||||
|     ({ TelepathyGLib: Tp, TelepathyLogger: Tpl } = imports.gi); | ||||
| } catch(e) { | ||||
|     log('Telepathy is not available, chat integration will be disabled.'); | ||||
| } | ||||
| @@ -24,7 +17,6 @@ const Main = imports.ui.main; | ||||
| const MessageList = imports.ui.messageList; | ||||
| const MessageTray = imports.ui.messageTray; | ||||
| const Params = imports.misc.params; | ||||
| const PopupMenu = imports.ui.popupMenu; | ||||
| const Util = imports.misc.util; | ||||
|  | ||||
| const HAVE_TP = (Tp != null && Tpl != null); | ||||
| @@ -409,7 +401,7 @@ var ChatSource = class extends MessageTray.Source { | ||||
|         if (this._client.is_handling_channel(this._channel)) { | ||||
|             // We are handling the channel, try to pass it to Empathy or Polari | ||||
|             // (depending on the channel type) | ||||
|             // We don't check if either app is availble - mission control will | ||||
|             // We don't check if either app is available - mission control will | ||||
|             // fallback to something else if activation fails | ||||
|  | ||||
|             let target; | ||||
| @@ -821,8 +813,8 @@ var ChatNotificationBanner = class extends MessageTray.NotificationBanner { | ||||
|         }); | ||||
|  | ||||
|         this._scrollArea = new St.ScrollView({ style_class: 'chat-scrollview vfade', | ||||
|                                                vscrollbar_policy: Gtk.PolicyType.AUTOMATIC, | ||||
|                                                hscrollbar_policy: Gtk.PolicyType.NEVER, | ||||
|                                                vscrollbar_policy: St.PolicyType.AUTOMATIC, | ||||
|                                                hscrollbar_policy: St.PolicyType.NEVER, | ||||
|                                                visible: this.expanded }); | ||||
|         this._contentArea = new St.BoxLayout({ style_class: 'chat-body', | ||||
|                                                vertical: true }); | ||||
|   | ||||
| @@ -1,15 +1,10 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const Gtk = imports.gi.Gtk; | ||||
| const Meta = imports.gi.Meta; | ||||
| const Shell = imports.gi.Shell; | ||||
| const St = imports.gi.St; | ||||
| const { Clutter, GObject, Meta, Shell, St } = imports.gi; | ||||
|  | ||||
| const Main = imports.ui.main; | ||||
| const SwitcherPopup = imports.ui.switcherPopup; | ||||
| const Params = imports.misc.params; | ||||
| const Tweener = imports.ui.tweener; | ||||
|  | ||||
| var POPUP_APPICON_SIZE = 96; | ||||
| var POPUP_FADE_TIME = 0.1; // seconds | ||||
| @@ -58,7 +53,7 @@ var CtrlAltTabManager = class CtrlAltTabManager { | ||||
|         if (item.focusCallback) | ||||
|             item.focusCallback(timestamp); | ||||
|         else | ||||
|             item.root.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false); | ||||
|             item.root.navigate_focus(null, St.DirectionType.TAB_FORWARD, false); | ||||
|     } | ||||
|  | ||||
|     // Sort the items into a consistent order; panel first, tray last, | ||||
| @@ -99,7 +94,9 @@ var CtrlAltTabManager = class CtrlAltTabManager { | ||||
|                     if (app) | ||||
|                         icon = app.create_icon_texture(POPUP_APPICON_SIZE); | ||||
|                     else | ||||
|                         icon = textureCache.bind_cairo_surface_property(windows[i], 'icon'); | ||||
|                         icon = textureCache.bind_cairo_surface_property(windows[i], | ||||
|                                                                         'icon', | ||||
|                                                                         POPUP_APPICON_SIZE); | ||||
|                 } | ||||
|  | ||||
|                 items.push({ name: windows[i].title, | ||||
| @@ -134,10 +131,10 @@ var CtrlAltTabManager = class CtrlAltTabManager { | ||||
|     } | ||||
| }; | ||||
|  | ||||
| var CtrlAltTabPopup = | ||||
| var CtrlAltTabPopup = GObject.registerClass( | ||||
| class CtrlAltTabPopup extends SwitcherPopup.SwitcherPopup { | ||||
|     constructor(items) { | ||||
|         super(items); | ||||
|     _init(items) { | ||||
|         super._init(items); | ||||
|  | ||||
|         this._switcherList = new CtrlAltTabSwitcher(this._items); | ||||
|     } | ||||
| @@ -161,12 +158,12 @@ class CtrlAltTabPopup extends SwitcherPopup.SwitcherPopup { | ||||
|         super._finish(time); | ||||
|         Main.ctrlAltTabManager.focusGroup(this._items[this._selectedIndex], time); | ||||
|     } | ||||
| }; | ||||
| }); | ||||
|  | ||||
| var CtrlAltTabSwitcher = | ||||
| var CtrlAltTabSwitcher = GObject.registerClass( | ||||
| class CtrlAltTabSwitcher extends SwitcherPopup.SwitcherList { | ||||
|     constructor(items) { | ||||
|         super(true); | ||||
|     _init(items) { | ||||
|         super._init(true); | ||||
|  | ||||
|         for (let i = 0; i < items.length; i++) | ||||
|             this._addIcon(items[i]); | ||||
| @@ -188,4 +185,4 @@ class CtrlAltTabSwitcher extends SwitcherPopup.SwitcherList { | ||||
|  | ||||
|         this.addItem(box, text); | ||||
|     } | ||||
| }; | ||||
| }); | ||||
|   | ||||
| @@ -1,14 +1,8 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const Gio = imports.gi.Gio; | ||||
| const GLib = imports.gi.GLib; | ||||
| const GObject = imports.gi.GObject; | ||||
| const Signals = imports.signals; | ||||
| const Meta = imports.gi.Meta; | ||||
| const Shell = imports.gi.Shell; | ||||
| const St = imports.gi.St; | ||||
| const { Clutter, GLib, GObject, Meta, Shell, St } = imports.gi; | ||||
| const Mainloop = imports.mainloop; | ||||
| const Signals = imports.signals; | ||||
|  | ||||
| const AppDisplay = imports.ui.appDisplay; | ||||
| const AppFavorites = imports.ui.appFavorites; | ||||
| @@ -16,7 +10,6 @@ const DND = imports.ui.dnd; | ||||
| const IconGrid = imports.ui.iconGrid; | ||||
| const Main = imports.ui.main; | ||||
| const Tweener = imports.ui.tweener; | ||||
| const Workspace = imports.ui.workspace; | ||||
|  | ||||
| var DASH_ANIMATION_TIME = 0.2; | ||||
| var DASH_ITEM_LABEL_SHOW_TIME = 0.15; | ||||
| @@ -591,22 +584,18 @@ var Dash = class Dash { | ||||
|         let firstButton = iconChildren[0].child; | ||||
|         let firstIcon = firstButton._delegate.icon; | ||||
|  | ||||
|         let minHeight, natHeight; | ||||
|         let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; | ||||
|  | ||||
|         // Enforce the current icon size during the size request | ||||
|         // Enforce valid spacings during the size request | ||||
|         firstIcon.icon.ensure_style(); | ||||
|         let [, currentHeight] = firstIcon.icon.get_size(); | ||||
|         firstIcon.icon.set_height(this.iconSize * scaleFactor); | ||||
|         [minHeight, natHeight] = firstButton.get_preferred_height(-1); | ||||
|         firstIcon.icon.set_height(currentHeight); | ||||
|         let [, iconHeight] = firstIcon.icon.get_preferred_height(-1); | ||||
|         let [, buttonHeight] = firstButton.get_preferred_height(-1); | ||||
|  | ||||
|         // Subtract icon padding and box spacing from the available height | ||||
|         availHeight -= iconChildren.length * (natHeight - this.iconSize * scaleFactor) + | ||||
|         availHeight -= iconChildren.length * (buttonHeight - iconHeight) + | ||||
|                        (iconChildren.length - 1) * spacing; | ||||
|  | ||||
|         let availSize = availHeight / iconChildren.length; | ||||
|  | ||||
|         let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; | ||||
|         let iconSizes = baseIconSizes.map(s => s * scaleFactor); | ||||
|  | ||||
|         let newIconSize = baseIconSizes[0]; | ||||
| @@ -910,7 +899,7 @@ var Dash = class Dash { | ||||
|                 favPos++; | ||||
|         } | ||||
|  | ||||
|         // No drag placeholder means we don't wan't to favorite the app | ||||
|         // No drag placeholder means we don't want to favorite the app | ||||
|         // and we are dragging it to its original position | ||||
|         if (!this._dragPlaceholder) | ||||
|             return true; | ||||
|   | ||||
| @@ -1,28 +1,17 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const GLib = imports.gi.GLib; | ||||
| const Gio = imports.gi.Gio; | ||||
| const GnomeDesktop = imports.gi.GnomeDesktop; | ||||
| const GObject = imports.gi.GObject; | ||||
| const Gtk = imports.gi.Gtk; | ||||
| const GWeather = imports.gi.GWeather; | ||||
| const Mainloop = imports.mainloop; | ||||
| const Pango = imports.gi.Pango; | ||||
| const Cairo = imports.cairo; | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const Shell = imports.gi.Shell; | ||||
| const St = imports.gi.St; | ||||
| const Atk = imports.gi.Atk; | ||||
| const { Clutter, GLib, GnomeDesktop, | ||||
|         GObject, GWeather, Shell, St } = imports.gi; | ||||
|  | ||||
| const Params = imports.misc.params; | ||||
| const Util = imports.misc.util; | ||||
| const Main = imports.ui.main; | ||||
| const PanelMenu = imports.ui.panelMenu; | ||||
| const PopupMenu = imports.ui.popupMenu; | ||||
| const Calendar = imports.ui.calendar; | ||||
| const Weather = imports.misc.weather; | ||||
| const System = imports.system; | ||||
|  | ||||
| const MAX_FORECASTS = 5; | ||||
|  | ||||
| function _isToday(date) { | ||||
|     let now = new Date(); | ||||
|     return now.getYear() == date.getYear() && | ||||
| @@ -129,7 +118,7 @@ var WorldClocksSection = class WorldClocksSection { | ||||
|             if (!clocks[i].location) | ||||
|                 continue; | ||||
|             let l = world.deserialize(clocks[i].location); | ||||
|             if (l) | ||||
|             if (l && l.get_timezone() != null) | ||||
|                 this._locations.push({ location: l }); | ||||
|         } | ||||
|  | ||||
| @@ -147,26 +136,37 @@ var WorldClocksSection = class WorldClocksSection { | ||||
|         layout.attach(header, 0, 0, 2, 1); | ||||
|         this.actor.label_actor = header; | ||||
|  | ||||
|         let localOffset = GLib.DateTime.new_now_local().get_utc_offset(); | ||||
|  | ||||
|         for (let i = 0; i < this._locations.length; i++) { | ||||
|             let l = this._locations[i].location; | ||||
|  | ||||
|             let name = l.get_level() == GWeather.LocationLevel.NAMED_TIMEZONE ? l.get_name() | ||||
|                                                                               : l.get_city_name(); | ||||
|             let name = l.get_city_name() || l.get_name(); | ||||
|             let label = new St.Label({ style_class: 'world-clocks-city', | ||||
|                                        text: name, | ||||
|                                        x_align: Clutter.ActorAlign.START, | ||||
|                                        y_align: Clutter.ActorAlign.CENTER, | ||||
|                                        x_expand: true }); | ||||
|  | ||||
|             let time = new St.Label({ style_class: 'world-clocks-time', | ||||
|                                       x_align: Clutter.ActorAlign.END, | ||||
|                                       x_expand: true }); | ||||
|             let time = new St.Label({ style_class: 'world-clocks-time' }); | ||||
|  | ||||
|             let otherOffset = this._getTimeAtLocation(l).get_utc_offset(); | ||||
|             let offset = (otherOffset - localOffset) / GLib.TIME_SPAN_HOUR; | ||||
|             let fmt = (Math.trunc(offset) == offset) ? '%s%.0f' : '%s%.1f'; | ||||
|             let prefix = (offset >= 0) ? '+' : '-'; | ||||
|             let tz = new St.Label({ style_class: 'world-clocks-timezone', | ||||
|                                     text: fmt.format(prefix, Math.abs(offset)), | ||||
|                                     x_align: Clutter.ActorAlign.END, | ||||
|                                     y_align: Clutter.ActorAlign.CENTER }); | ||||
|  | ||||
|             if (this._grid.text_direction == Clutter.TextDirection.RTL) { | ||||
|                 layout.attach(time, 0, i + 1, 1, 1); | ||||
|                 layout.attach(label, 1, i + 1, 1, 1); | ||||
|                 layout.attach(tz, 0, i + 1, 1, 1); | ||||
|                 layout.attach(time, 1, i + 1, 1, 1); | ||||
|                 layout.attach(label, 2, i + 1, 1, 1); | ||||
|             } else { | ||||
|                 layout.attach(label, 0, i + 1, 1, 1); | ||||
|                 layout.attach(time, 1, i + 1, 1, 1); | ||||
|                 layout.attach(tz, 2, i + 1, 1, 1); | ||||
|             } | ||||
|  | ||||
|             this._locations[i].actor = time; | ||||
| @@ -184,11 +184,15 @@ var WorldClocksSection = class WorldClocksSection { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     _getTimeAtLocation(location) { | ||||
|         let tz = GLib.TimeZone.new(location.get_timezone().get_tzid()); | ||||
|         return GLib.DateTime.new_now(tz); | ||||
|     } | ||||
|  | ||||
|     _updateLabels() { | ||||
|         for (let i = 0; i < this._locations.length; i++) { | ||||
|             let l = this._locations[i]; | ||||
|             let tz = GLib.TimeZone.new(l.location.get_timezone().get_tzid()); | ||||
|             let now = GLib.DateTime.new_now(tz); | ||||
|             let now = this._getTimeAtLocation(l.location); | ||||
|             l.actor.text = Util.formatTime(now, { timeOnly: true }); | ||||
|         } | ||||
|     } | ||||
| @@ -217,110 +221,114 @@ var WeatherSection = class WeatherSection { | ||||
|  | ||||
|         this.actor.child = box; | ||||
|  | ||||
|         box.add_child(new St.Label({ style_class: 'weather-header', | ||||
|                                      x_align: Clutter.ActorAlign.START, | ||||
|                                      text: _("Weather") })); | ||||
|         let titleBox = new St.BoxLayout(); | ||||
|         titleBox.add_child(new St.Label({ style_class: 'weather-header', | ||||
|                                           x_align: Clutter.ActorAlign.START, | ||||
|                                           x_expand: true, | ||||
|                                           text: _("Weather") })); | ||||
|         box.add_child(titleBox); | ||||
|  | ||||
|         this._conditionsLabel = new St.Label({ style_class: 'weather-conditions', | ||||
|                                                x_align: Clutter.ActorAlign.START }); | ||||
|         this._conditionsLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE; | ||||
|         this._conditionsLabel.clutter_text.line_wrap = true; | ||||
|         box.add_child(this._conditionsLabel); | ||||
|         this._titleLocation = new St.Label({ style_class: 'weather-header location', | ||||
|                                              x_align: Clutter.ActorAlign.END }); | ||||
|         titleBox.add_child(this._titleLocation); | ||||
|  | ||||
|         let layout = new Clutter.GridLayout({ orientation: Clutter.Orientation.VERTICAL }); | ||||
|         this._forecastGrid = new St.Widget({ style_class: 'weather-grid', | ||||
|                                              layout_manager: layout }); | ||||
|         layout.hookup_style(this._forecastGrid); | ||||
|         box.add_child(this._forecastGrid); | ||||
|  | ||||
|         this._weatherClient.connect('changed', this._sync.bind(this)); | ||||
|         this._sync(); | ||||
|     } | ||||
|  | ||||
|     _getSummary(info, capitalize=false) { | ||||
|         let options = capitalize ? GWeather.FormatOptions.SENTENCE_CAPITALIZATION | ||||
|                                  : GWeather.FormatOptions.NO_CAPITALIZATION; | ||||
|  | ||||
|         let [ok, phenomenon, qualifier] = info.get_value_conditions(); | ||||
|         if (ok) | ||||
|             return new GWeather.Conditions({ significant: true, | ||||
|                                              phenomenon, | ||||
|                                              qualifier }).to_string_full(options); | ||||
|  | ||||
|         let [, sky] = info.get_value_sky(); | ||||
|         return GWeather.Sky.to_string_full(sky, options); | ||||
|     } | ||||
|  | ||||
|     _sameSummary(info1, info2) { | ||||
|         let [ok1, phenom1, qualifier1] = info1.get_value_conditions(); | ||||
|         let [ok2, phenom2, qualifier2] = info2.get_value_conditions(); | ||||
|         if (ok1 || ok2) | ||||
|             return ok1 == ok2 && phenom1 == phenom2 && qualifier1 == qualifier2; | ||||
|  | ||||
|         let [, sky1] = info1.get_value_sky(); | ||||
|         let [, sky2] = info2.get_value_sky(); | ||||
|         return sky1 == sky2; | ||||
|     } | ||||
|  | ||||
|     _getSummaryText() { | ||||
|     _getInfos() { | ||||
|         let info = this._weatherClient.info; | ||||
|         let forecasts = info.get_forecast_list(); | ||||
|         if (forecasts.length == 0) // No forecasts, just current conditions | ||||
|             return '%s.'.format(this._getSummary(info, true)); | ||||
|  | ||||
|         let current = info; | ||||
|         let infos = [info]; | ||||
|         for (let i = 0; i < forecasts.length; i++) { | ||||
|             let [ok, timestamp] = forecasts[i].get_value_update(); | ||||
|             if (!_isToday(new Date(timestamp * 1000))) | ||||
|             let datetime = new Date(timestamp * 1000); | ||||
|             if (!_isToday(datetime)) | ||||
|                 continue; // Ignore forecasts from other days | ||||
|  | ||||
|             if (this._sameSummary(current, forecasts[i])) | ||||
|                 continue; // Ignore consecutive runs of equal summaries | ||||
|             [ok, timestamp] = current.get_value_update(); | ||||
|             let currenttime = new Date(timestamp * 1000); | ||||
|             if (currenttime.getHours() == datetime.getHours()) | ||||
|                 continue; // Enforce a minimum interval of 1h | ||||
|  | ||||
|             current = forecasts[i]; | ||||
|             if (infos.push(current) == 3) | ||||
|                 break; // Use a maximum of three summaries | ||||
|             if (infos.push(current) == MAX_FORECASTS) | ||||
|                 break; // Use a maximum of five forecasts | ||||
|         } | ||||
|  | ||||
|         let fmt; | ||||
|         switch(infos.length) { | ||||
|             /* Translators: %s is a weather condition like "Clear sky"; see | ||||
|                libgweather for the possible condition strings. If at all | ||||
|                possible, the sentence should match the grammatical case etc. of | ||||
|                the inserted conditions. */ | ||||
|             case 1: fmt = _("%s all day."); break; | ||||
|  | ||||
|             /* Translators: %s is a weather condition like "Clear sky"; see | ||||
|                libgweather for the possible condition strings. If at all | ||||
|                possible, the sentence should match the grammatical case etc. of | ||||
|                the inserted conditions. */ | ||||
|             case 2: fmt = _("%s, then %s later."); break; | ||||
|  | ||||
|             /* Translators: %s is a weather condition like "Clear sky"; see | ||||
|                libgweather for the possible condition strings. If at all | ||||
|                possible, the sentence should match the grammatical case etc. of | ||||
|                the inserted conditions. */ | ||||
|             case 3: fmt = _("%s, then %s, followed by %s later."); break; | ||||
|         } | ||||
|         let summaries = infos.map((info, i) => { | ||||
|             let capitalize = i == 0 && fmt.startsWith('%s'); | ||||
|             return this._getSummary(info, capitalize); | ||||
|         }); | ||||
|         return String.prototype.format.apply(fmt, summaries); | ||||
|         return infos; | ||||
|     } | ||||
|  | ||||
|     _getLabelText() { | ||||
|         if (!this._weatherClient.hasLocation) | ||||
|             return _("Select a location…"); | ||||
|     _addForecasts() { | ||||
|         let layout = this._forecastGrid.layout_manager; | ||||
|  | ||||
|         if (this._weatherClient.loading) | ||||
|             return _("Loading…"); | ||||
|         let infos = this._getInfos(); | ||||
|         if (this._forecastGrid.text_direction == Clutter.TextDirection.RTL) | ||||
|             infos.reverse(); | ||||
|  | ||||
|         let col = 0; | ||||
|         infos.forEach(fc => { | ||||
|             let [ok, timestamp] = fc.get_value_update(); | ||||
|             let timeStr = Util.formatTime(new Date(timestamp * 1000), { | ||||
|                 timeOnly: true | ||||
|             }); | ||||
|  | ||||
|             let icon = new St.Icon({ style_class: 'weather-forecast-icon', | ||||
|                                      icon_name: fc.get_symbolic_icon_name(), | ||||
|                                      x_align: Clutter.ActorAlign.CENTER, | ||||
|                                      x_expand: true }); | ||||
|             let temp = new St.Label({ style_class: 'weather-forecast-temp', | ||||
|                                       text: fc.get_temp_summary(), | ||||
|                                       x_align: Clutter.ActorAlign.CENTER }); | ||||
|             let time = new St.Label({ style_class: 'weather-forecast-time', | ||||
|                                       text: timeStr, | ||||
|                                       x_align: Clutter.ActorAlign.CENTER }); | ||||
|  | ||||
|             layout.attach(icon, col, 0, 1, 1); | ||||
|             layout.attach(temp, col, 1, 1, 1); | ||||
|             layout.attach(time, col, 2, 1, 1); | ||||
|             col++; | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     _setStatusLabel(text) { | ||||
|         let layout = this._forecastGrid.layout_manager; | ||||
|         let label = new St.Label({ text }); | ||||
|         layout.attach(label, 0, 0, 1, 1); | ||||
|     } | ||||
|  | ||||
|     _updateForecasts() { | ||||
|         this._forecastGrid.destroy_all_children(); | ||||
|  | ||||
|         if (!this._weatherClient.hasLocation) { | ||||
|             this._setStatusLabel(_("Select a location…")); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         let info = this._weatherClient.info; | ||||
|         if (info.is_valid()) | ||||
|             return this._getSummaryText() + ' ' + | ||||
|                    /* Translators: %s is a temperature with unit, e.g. "23℃" */ | ||||
|                    _("Feels like %s.").format(info.get_apparent()); | ||||
|         this._titleLocation.text = info.get_location().get_name(); | ||||
|  | ||||
|         if (this._weatherClient.loading) { | ||||
|             this._setStatusLabel(_("Loading…")); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (info.is_valid()) { | ||||
|             this._addForecasts(); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (info.network_error()) | ||||
|             return _("Go online for weather information"); | ||||
|  | ||||
|         return _("Weather information is currently unavailable"); | ||||
|             this._setStatusLabel(_("Go online for weather information")); | ||||
|         else | ||||
|             this._setStatusLabel(_("Weather information is currently unavailable")); | ||||
|     } | ||||
|  | ||||
|     _sync() { | ||||
| @@ -329,7 +337,9 @@ var WeatherSection = class WeatherSection { | ||||
|         if (!this.actor.visible) | ||||
|             return; | ||||
|  | ||||
|         this._conditionsLabel.text = this._getLabelText(); | ||||
|         this._titleLocation.visible = this._weatherClient.hasLocation; | ||||
|  | ||||
|         this._updateForecasts(); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| @@ -375,16 +385,17 @@ class IndicatorPad extends St.Widget { | ||||
|     _init(actor) { | ||||
|         this._source = actor; | ||||
|         this._source.connect('notify::visible', () => { this.queue_relayout(); }); | ||||
|         this._source.connect('notify::size', () => { this.queue_relayout(); }); | ||||
|         super._init(); | ||||
|     } | ||||
|  | ||||
|     vfunc_get_preferred_width(container, forHeight) { | ||||
|     vfunc_get_preferred_width(forHeight) { | ||||
|         if (this._source.visible) | ||||
|             return this._source.get_preferred_width(forHeight); | ||||
|         return [0, 0]; | ||||
|     } | ||||
|  | ||||
|     vfunc_get_preferred_height(container, forWidth) { | ||||
|     vfunc_get_preferred_height(forWidth) { | ||||
|         if (this._source.visible) | ||||
|             return this._source.get_preferred_height(forWidth); | ||||
|         return [0, 0]; | ||||
| @@ -465,10 +476,9 @@ class DateMenuButton extends PanelMenu.Button { | ||||
|         box.add_actor(this._clockDisplay); | ||||
|         box.add_actor(this._indicator.actor); | ||||
|  | ||||
|         this.actor.label_actor = this._clockDisplay; | ||||
|         this.actor.add_actor(box); | ||||
|         this.actor.add_style_class_name ('clock-display'); | ||||
|  | ||||
|         this.label_actor = this._clockDisplay; | ||||
|         this.add_actor(box); | ||||
|         this.add_style_class_name ('clock-display'); | ||||
|  | ||||
|         let layout = new FreezableBinLayout(); | ||||
|         let bin = new St.Widget({ layout_manager: layout }); | ||||
| @@ -515,7 +525,7 @@ class DateMenuButton extends PanelMenu.Button { | ||||
|         this._displaysSection = new St.ScrollView({ style_class: 'datemenu-displays-section vfade', | ||||
|                                                     x_expand: true, x_fill: true, | ||||
|                                                     overlay_scrollbars: true }); | ||||
|         this._displaysSection.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC); | ||||
|         this._displaysSection.set_policy(St.PolicyType.NEVER, St.PolicyType.AUTOMATIC); | ||||
|         vbox.add_actor(this._displaysSection); | ||||
|  | ||||
|         let displaysBox = new St.BoxLayout({ vertical: true, | ||||
|   | ||||
| @@ -1,10 +1,6 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const Gio = imports.gi.Gio; | ||||
| const GObject = imports.gi.GObject; | ||||
| const Pango = imports.gi.Pango; | ||||
| const St = imports.gi.St; | ||||
| const { Clutter, Gio, GObject, Pango, St } = imports.gi; | ||||
|  | ||||
| var Dialog = GObject.registerClass( | ||||
| class Dialog extends St.Widget { | ||||
| @@ -179,10 +175,10 @@ var MessageDialogContent = GObject.registerClass({ | ||||
|             this[`_${prop}`].add_style_class_name(`message-dialog-${prop}`); | ||||
|         }); | ||||
|  | ||||
|         let textProps = { ellipsize_mode: Pango.EllipsizeMode.NONE, | ||||
|         let textProps = { ellipsize: Pango.EllipsizeMode.NONE, | ||||
|                           line_wrap: true }; | ||||
|         Object.assign(this._subtitle.clutter_text, textProps); | ||||
|         Object.assign(this._body.clutter_text, textProps); | ||||
|         this._subtitle.clutter_text.set(textProps); | ||||
|         this._body.clutter_text.set(textProps); | ||||
|  | ||||
|         if (!params.hasOwnProperty('style_class')) | ||||
|             params.style_class = 'message-dialog-main-layout'; | ||||
|   | ||||
							
								
								
									
										118
									
								
								js/ui/dnd.js
									
									
									
									
									
								
							
							
						
						| @@ -1,16 +1,11 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const GLib = imports.gi.GLib; | ||||
| const Gtk = imports.gi.Gtk; | ||||
| const St = imports.gi.St; | ||||
| const Meta = imports.gi.Meta; | ||||
| const Shell = imports.gi.Shell; | ||||
| const { Clutter, GLib, Meta, Shell, St } = imports.gi; | ||||
| const Signals = imports.signals; | ||||
| const Tweener = imports.ui.tweener; | ||||
| const Main = imports.ui.main; | ||||
|  | ||||
| const Main = imports.ui.main; | ||||
| const Params = imports.misc.params; | ||||
| const Tweener = imports.ui.tweener; | ||||
|  | ||||
| // Time to scale down to maxDragActorSize | ||||
| var SCALE_ANIMATION_TIME = 0.25; | ||||
| @@ -109,6 +104,7 @@ var _Draggable = class _Draggable { | ||||
|         this._dragCancellable = true; | ||||
|  | ||||
|         this._eventsGrabbed = false; | ||||
|         this._capturedEventId = 0; | ||||
|     } | ||||
|  | ||||
|     _onButtonPress(actor, event) { | ||||
| @@ -119,7 +115,7 @@ var _Draggable = class _Draggable { | ||||
|             return Clutter.EVENT_PROPAGATE; | ||||
|  | ||||
|         this._buttonDown = true; | ||||
|         this._grabActor(); | ||||
|         this._grabActor(event.get_device()); | ||||
|  | ||||
|         let [stageX, stageY] = event.get_coords(); | ||||
|         this._dragStartX = stageX; | ||||
| @@ -129,6 +125,16 @@ var _Draggable = class _Draggable { | ||||
|     } | ||||
|  | ||||
|     _onTouchEvent(actor, event) { | ||||
|         // We only handle touch events here on wayland. On X11 | ||||
|         // we do get emulated pointer events, which already works | ||||
|         // for single-touch cases. Besides, the X11 passive touch grab | ||||
|         // set up by Mutter will make us see first the touch events | ||||
|         // and later the pointer events, so it will look like two | ||||
|         // unrelated series of events, we want to avoid double handling | ||||
|         // in these cases. | ||||
|         if (!Meta.is_wayland_compositor()) | ||||
|             return Clutter.EVENT_PROPAGATE; | ||||
|  | ||||
|         if (event.type() != Clutter.EventType.TOUCH_BEGIN || | ||||
|             !global.display.is_pointer_emulating_sequence(event.get_event_sequence())) | ||||
|             return Clutter.EVENT_PROPAGATE; | ||||
| @@ -136,10 +142,8 @@ var _Draggable = class _Draggable { | ||||
|         if (Tweener.getTweenCount(actor)) | ||||
|             return Clutter.EVENT_PROPAGATE; | ||||
|  | ||||
|         this._touchSequence = event.get_event_sequence(); | ||||
|  | ||||
|         this._buttonDown = true; | ||||
|         this._grabActor(); | ||||
|         this._grabActor(event.get_device(), event.get_event_sequence()); | ||||
|  | ||||
|         let [stageX, stageY] = event.get_coords(); | ||||
|         this._dragStartX = stageX; | ||||
| @@ -148,19 +152,30 @@ var _Draggable = class _Draggable { | ||||
|         return Clutter.EVENT_PROPAGATE; | ||||
|     } | ||||
|  | ||||
|     _grabDevice(actor) { | ||||
|         let manager = Clutter.DeviceManager.get_default(); | ||||
|         let pointer = manager.get_core_device(Clutter.InputDeviceType.POINTER_DEVICE); | ||||
|  | ||||
|         if (pointer && this._touchSequence) | ||||
|             pointer.sequence_grab(this._touchSequence, actor); | ||||
|     _grabDevice(actor, pointer, touchSequence) { | ||||
|         if (touchSequence) | ||||
|             pointer.sequence_grab(touchSequence, actor); | ||||
|         else if (pointer) | ||||
|             pointer.grab (actor); | ||||
|  | ||||
|         this._grabbedDevice = pointer; | ||||
|         this._touchSequence = touchSequence; | ||||
|  | ||||
|         this._capturedEventId = global.stage.connect('captured-event', (actor, event) => { | ||||
|             let device = event.get_device(); | ||||
|             if (device != this._grabbedDevice && | ||||
|                 device.get_device_type() != Clutter.InputDeviceType.KEYBOARD_DEVICE) | ||||
|                 return Clutter.EVENT_STOP; | ||||
|             return Clutter.EVENT_PROPAGATE; | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     _ungrabDevice() { | ||||
|         if (this._capturedEventId != 0) { | ||||
|             global.stage.disconnect(this._capturedEventId); | ||||
|             this._capturedEventId = 0; | ||||
|         } | ||||
|  | ||||
|         if (this._touchSequence) | ||||
|             this._grabbedDevice.sequence_ungrab (this._touchSequence); | ||||
|         else | ||||
| @@ -170,8 +185,8 @@ var _Draggable = class _Draggable { | ||||
|         this._grabbedDevice = null; | ||||
|     } | ||||
|  | ||||
|     _grabActor() { | ||||
|         this._grabDevice(this.actor); | ||||
|     _grabActor(device, touchSequence) { | ||||
|         this._grabDevice(this.actor, device, touchSequence); | ||||
|         this._onEventId = this.actor.connect('event', | ||||
|                                              this._onEvent.bind(this)); | ||||
|     } | ||||
| @@ -185,11 +200,11 @@ var _Draggable = class _Draggable { | ||||
|         this._onEventId = null; | ||||
|     } | ||||
|  | ||||
|     _grabEvents() { | ||||
|     _grabEvents(device, touchSequence) { | ||||
|         if (!this._eventsGrabbed) { | ||||
|             this._eventsGrabbed = Main.pushModal(_getEventHandlerActor()); | ||||
|             if (this._eventsGrabbed) | ||||
|                 this._grabDevice(_getEventHandlerActor()); | ||||
|                 this._grabDevice(_getEventHandlerActor(), device, touchSequence); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -201,14 +216,36 @@ var _Draggable = class _Draggable { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     _eventIsRelease(event) { | ||||
|         if (event.type() == Clutter.EventType.BUTTON_RELEASE) { | ||||
|             let buttonMask = (Clutter.ModifierType.BUTTON1_MASK | | ||||
|                               Clutter.ModifierType.BUTTON2_MASK | | ||||
|                               Clutter.ModifierType.BUTTON3_MASK); | ||||
|             /* We only obey the last button release from the device, | ||||
|              * other buttons may get pressed/released during the DnD op. | ||||
|              */ | ||||
|             return (event.get_state() & buttonMask) == 0; | ||||
|         } else if (event.type() == Clutter.EventType.TOUCH_END) { | ||||
|             /* For touch, we only obey the pointer emulating sequence */ | ||||
|             return global.display.is_pointer_emulating_sequence(event.get_event_sequence()); | ||||
|         } | ||||
|  | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     _onEvent(actor, event) { | ||||
|         let device = event.get_device(); | ||||
|  | ||||
|         if (this._grabbedDevice && | ||||
|             device != this._grabbedDevice && | ||||
|             device.get_device_type() != Clutter.InputDeviceType.KEYBOARD_DEVICE) | ||||
|             return Clutter.EVENT_PROPAGATE; | ||||
|  | ||||
|         // We intercept BUTTON_RELEASE event to know that the button was released in case we | ||||
|         // didn't start the drag, to drop the draggable in case the drag was in progress, and | ||||
|         // to complete the drag and ensure that whatever happens to be under the pointer does | ||||
|         // not get triggered if the drag was cancelled with Esc. | ||||
|         if (event.type() == Clutter.EventType.BUTTON_RELEASE || | ||||
|             (event.type() == Clutter.EventType.TOUCH_END && | ||||
|              global.display.is_pointer_emulating_sequence(event.get_event_sequence()))) { | ||||
|         if (this._eventIsRelease(event)) { | ||||
|             this._buttonDown = false; | ||||
|             if (this._dragState == DragState.DRAGGING) { | ||||
|                 return this._dragActorDropped(event); | ||||
| @@ -268,7 +305,22 @@ var _Draggable = class _Draggable { | ||||
|      * This function is useful to call if you've specified manualMode | ||||
|      * for the draggable. | ||||
|      */ | ||||
|     startDrag(stageX, stageY, time, sequence) { | ||||
|     startDrag(stageX, stageY, time, sequence, device) { | ||||
|         if (currentDraggable) | ||||
|             return; | ||||
|  | ||||
|         if (device == undefined) { | ||||
|             let event = Clutter.get_current_event(); | ||||
|  | ||||
|             if (event) | ||||
|                 device = event.get_device(); | ||||
|  | ||||
|             if (device == undefined) { | ||||
|                 let manager = Clutter.DeviceManager.get_default(); | ||||
|                 device = manager.get_core_device(Clutter.InputDeviceType.POINTER_DEVICE); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         currentDraggable = this; | ||||
|         this._dragState = DragState.DRAGGING; | ||||
|  | ||||
| @@ -283,8 +335,7 @@ var _Draggable = class _Draggable { | ||||
|         if (this._onEventId) | ||||
|             this._ungrabActor(); | ||||
|  | ||||
|         this._touchSequence = sequence; | ||||
|         this._grabEvents(); | ||||
|         this._grabEvents(device, sequence); | ||||
|         global.display.set_cursor(Meta.Cursor.DND_IN_DRAG); | ||||
|  | ||||
|         this._dragX = this._dragStartX = stageX; | ||||
| @@ -352,7 +403,8 @@ var _Draggable = class _Draggable { | ||||
|             this._finishAnimation(); | ||||
|  | ||||
|             this._dragActor = null; | ||||
|             this._dragState = DragState.CANCELLED; | ||||
|             if (this._dragState == DragState.DRAGGING) | ||||
|                 this._dragState = DragState.CANCELLED; | ||||
|         }); | ||||
|         this._dragOrigOpacity = this._dragActor.opacity; | ||||
|         if (this._dragActorOpacity != undefined) | ||||
| @@ -398,10 +450,12 @@ var _Draggable = class _Draggable { | ||||
|         let [stageX, stageY] = event.get_coords(); | ||||
|  | ||||
|         // See if the user has moved the mouse enough to trigger a drag | ||||
|         let threshold = Gtk.Settings.get_default().gtk_dnd_drag_threshold; | ||||
|         if ((Math.abs(stageX - this._dragStartX) > threshold || | ||||
|         let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; | ||||
|         let threshold = St.Settings.get().drag_threshold * scaleFactor; | ||||
|         if (!currentDraggable && | ||||
|             (Math.abs(stageX - this._dragStartX) > threshold || | ||||
|              Math.abs(stageY - this._dragStartY) > threshold)) { | ||||
|             this.startDrag(stageX, stageY, event.get_time(), this._touchSequence); | ||||
|             this.startDrag(stageX, stageY, event.get_time(), this._touchSequence, event.get_device()); | ||||
|             this._updateDragPosition(event); | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -1,10 +1,6 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const GObject = imports.gi.GObject; | ||||
| const Signals = imports.signals; | ||||
| const Meta = imports.gi.Meta; | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const St = imports.gi.St; | ||||
| const { Clutter, GObject, Meta, St } = imports.gi; | ||||
|  | ||||
| const Main = imports.ui.main; | ||||
|  | ||||
| @@ -30,7 +26,7 @@ var EdgeDragAction = GObject.registerClass({ | ||||
|         return global.display.get_monitor_geometry(monitorIndex); | ||||
|     } | ||||
|  | ||||
|     vfunc_gesture_prepare(action, actor) { | ||||
|     vfunc_gesture_prepare(actor) { | ||||
|         if (this.get_n_current_points() == 0) | ||||
|             return false; | ||||
|  | ||||
| @@ -46,7 +42,7 @@ var EdgeDragAction = GObject.registerClass({ | ||||
|                 (this._side == St.Side.BOTTOM && y > monitorRect.y + monitorRect.height - EDGE_THRESHOLD)); | ||||
|     } | ||||
|  | ||||
|     vfunc_gesture_progress(action, actor) { | ||||
|     vfunc_gesture_progress(actor) { | ||||
|         let [startX, startY] = this.get_press_coords(0); | ||||
|         let [x, y] = this.get_motion_coords(0); | ||||
|         let offsetX = Math.abs (x - startX); | ||||
| @@ -66,7 +62,7 @@ var EdgeDragAction = GObject.registerClass({ | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     vfunc_gesture_end(action, actor) { | ||||
|     vfunc_gesture_end(actor) { | ||||
|         let [startX, startY] = this.get_press_coords(0); | ||||
|         let [x, y] = this.get_motion_coords(0); | ||||
|         let monitorRect = this._getMonitorRect(startX, startY); | ||||
|   | ||||
| @@ -18,21 +18,13 @@ | ||||
|  | ||||
| const Mainloop = imports.mainloop; | ||||
|  | ||||
| const AccountsService = imports.gi.AccountsService; | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const Gio = imports.gi.Gio; | ||||
| const GLib = imports.gi.GLib; | ||||
| const Gtk = imports.gi.Gtk; | ||||
| const Pango = imports.gi.Pango; | ||||
| const Polkit = imports.gi.Polkit; | ||||
| const St = imports.gi.St; | ||||
| const Shell = imports.gi.Shell; | ||||
| const { AccountsService, Clutter, Gio, | ||||
|         GLib, GObject, Pango, Polkit, Shell, St }  = imports.gi; | ||||
|  | ||||
| const CheckBox = imports.ui.checkBox; | ||||
| const GnomeSession = imports.misc.gnomeSession; | ||||
| const LoginManager = imports.misc.loginManager; | ||||
| const ModalDialog = imports.ui.modalDialog; | ||||
| const Tweener = imports.ui.tweener; | ||||
| const UserWidget = imports.ui.userWidget; | ||||
|  | ||||
| const { loadInterfaceXML } = imports.misc.fileUtils; | ||||
| @@ -234,10 +226,11 @@ function init() { | ||||
|     _endSessionDialog = new EndSessionDialog(); | ||||
| } | ||||
|  | ||||
| var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog { | ||||
|     constructor() { | ||||
|         super({ styleClass: 'end-session-dialog', | ||||
|                 destroyOnClose: false }); | ||||
| var EndSessionDialog = GObject.registerClass( | ||||
| class EndSessionDialog extends ModalDialog.ModalDialog { | ||||
|     _init() { | ||||
|         super._init({ styleClass: 'end-session-dialog', | ||||
|                       destroyOnClose: false }); | ||||
|  | ||||
|         this._loginManager = LoginManager.getLoginManager(); | ||||
|         this._userManager = AccountsService.UserManager.get_default(); | ||||
| @@ -320,7 +313,7 @@ var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog { | ||||
|         messageLayout.add(this._batteryWarning); | ||||
|  | ||||
|         this._scrollView = new St.ScrollView({ style_class: 'end-session-dialog-list' }); | ||||
|         this._scrollView.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC); | ||||
|         this._scrollView.set_policy(St.PolicyType.NEVER, St.PolicyType.AUTOMATIC); | ||||
|         this.contentLayout.add(this._scrollView, | ||||
|                                { x_fill: true, | ||||
|                                  y_fill: true }); | ||||
| @@ -755,4 +748,4 @@ var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog { | ||||
|     Close(parameters, invocation) { | ||||
|         this.close(); | ||||
|     } | ||||
| }; | ||||
| }); | ||||
|   | ||||
| @@ -4,18 +4,13 @@ const Config = imports.misc.config; | ||||
|  | ||||
| imports.gi.versions.Clutter = Config.LIBMUTTER_API_VERSION; | ||||
| imports.gi.versions.Gio = '2.0'; | ||||
| imports.gi.versions.Gdk = '3.0'; | ||||
| imports.gi.versions.GdkPixbuf = '2.0'; | ||||
| imports.gi.versions.Gtk = '3.0'; | ||||
| imports.gi.versions.TelepathyGLib = '0.12'; | ||||
| imports.gi.versions.TelepathyLogger = '0.2'; | ||||
|  | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const { Clutter, GLib, Shell, St } = imports.gi; | ||||
| const Gettext = imports.gettext; | ||||
| const GLib = imports.gi.GLib; | ||||
| const Gtk = imports.gi.Gtk; | ||||
| const Shell = imports.gi.Shell; | ||||
| const St = imports.gi.St; | ||||
|  | ||||
| // We can't import shell JS modules yet, because they may have | ||||
| // variable initializations, etc, that depend on init() already having | ||||
| @@ -101,6 +96,15 @@ function init() { | ||||
|     Clutter.Actor.prototype.toString = function() { | ||||
|         return St.describe_actor(this); | ||||
|     }; | ||||
|     // Deprecation warning for former JS classes turned into an actor subclass | ||||
|     Object.defineProperty(Clutter.Actor.prototype, 'actor', { | ||||
|         get() { | ||||
|             let klass = this.constructor.name; | ||||
|             let { stack } = new Error(); | ||||
|             log(`Usage of object.actor is deprecated for ${klass}\n${stack}`); | ||||
|             return this; | ||||
|         } | ||||
|     }); | ||||
|  | ||||
|     let origToString = Object.prototype.toString; | ||||
|     Object.prototype.toString = function() { | ||||
|   | ||||
| @@ -1,11 +1,6 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const GLib = imports.gi.GLib; | ||||
| const Gio = imports.gi.Gio; | ||||
| const Soup = imports.gi.Soup; | ||||
| const St = imports.gi.St; | ||||
| const Shell = imports.gi.Shell; | ||||
| const { Clutter, Gio, GLib, GObject, Soup, St } = imports.gi; | ||||
|  | ||||
| const Config = imports.misc.config; | ||||
| const ExtensionUtils = imports.misc.extensionUtils; | ||||
| @@ -181,10 +176,10 @@ function checkForUpdates() { | ||||
|     }); | ||||
| } | ||||
|  | ||||
| var InstallExtensionDialog = | ||||
| var InstallExtensionDialog = GObject.registerClass( | ||||
| class InstallExtensionDialog extends ModalDialog.ModalDialog { | ||||
|     constructor(uuid, info, invocation) { | ||||
|         super({ styleClass: 'extension-dialog' }); | ||||
|     _init(uuid, info, invocation) { | ||||
|         super._init({ styleClass: 'extension-dialog' }); | ||||
|  | ||||
|         this._uuid = uuid; | ||||
|         this._info = info; | ||||
| @@ -260,7 +255,7 @@ class InstallExtensionDialog extends ModalDialog.ModalDialog { | ||||
|  | ||||
|         this.close(); | ||||
|     } | ||||
| }; | ||||
| }); | ||||
|  | ||||
| function init() { | ||||
|     _httpSession = new Soup.SessionAsync({ ssl_use_system_ca_file: true }); | ||||
|   | ||||
| @@ -1,11 +1,8 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const { Gio, St } = imports.gi; | ||||
| const Signals = imports.signals; | ||||
|  | ||||
| const GLib = imports.gi.GLib; | ||||
| const Gio = imports.gi.Gio; | ||||
| const St = imports.gi.St; | ||||
|  | ||||
| const ExtensionUtils = imports.misc.extensionUtils; | ||||
| const Main = imports.ui.main; | ||||
|  | ||||
|   | ||||
| @@ -1,10 +1,6 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const Gtk = imports.gi.Gtk; | ||||
| const Meta = imports.gi.Meta; | ||||
| const Shell = imports.gi.Shell; | ||||
| const St = imports.gi.St; | ||||
| const { Clutter, St } = imports.gi; | ||||
|  | ||||
| const Main = imports.ui.main; | ||||
| const Params = imports.misc.params; | ||||
| @@ -47,6 +43,9 @@ function _popGrabHelper(grabHelper) { | ||||
| // call grab(). | ||||
| var GrabHelper = class GrabHelper { | ||||
|     constructor(owner, params) { | ||||
|         if (!(owner instanceof Clutter.Actor)) | ||||
|             throw new Error('GrabHelper owner must be a Clutter.Actor'); | ||||
|  | ||||
|         this._owner = owner; | ||||
|         this._modalParams = params; | ||||
|  | ||||
| @@ -187,7 +186,7 @@ var GrabHelper = class GrabHelper { | ||||
|         if (params.focus) { | ||||
|             params.focus.grab_key_focus(); | ||||
|         } else if (newFocus && hadFocus) { | ||||
|             if (!newFocus.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false)) | ||||
|             if (!newFocus.navigate_focus(null, St.DirectionType.TAB_FORWARD, false)) | ||||
|                 newFocus.grab_key_focus(); | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -1,9 +1,7 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const IBus = imports.gi.IBus; | ||||
| const { Clutter, IBus, St } = imports.gi; | ||||
| const Signals = imports.signals; | ||||
| const St = imports.gi.St; | ||||
|  | ||||
| const BoxPointer = imports.ui.boxpointer; | ||||
| const Main = imports.ui.main; | ||||
| @@ -236,7 +234,7 @@ var CandidatePopup = class CandidatePopup { | ||||
|  | ||||
|             let indexes = []; | ||||
|             let indexLabel; | ||||
|             for (let i = 0; indexLabel = lookupTable.get_label(i); ++i) | ||||
|             for (let i = 0; (indexLabel = lookupTable.get_label(i)); ++i) | ||||
|                  indexes.push(indexLabel.get_text()); | ||||
|  | ||||
|             Main.keyboard.resetSuggestions(); | ||||
| @@ -274,7 +272,7 @@ var CandidatePopup = class CandidatePopup { | ||||
|  | ||||
|     _setDummyCursorGeometry(x, y, w, h) { | ||||
|         Main.layoutManager.setDummyCursorGeometry(x, y, w, h); | ||||
|         if (this._boxPointer.actor.visible) | ||||
|         if (this._boxPointer.visible) | ||||
|             this._boxPointer.setPosition(Main.layoutManager.dummyCursor, 0); | ||||
|     } | ||||
|  | ||||
| @@ -287,7 +285,7 @@ var CandidatePopup = class CandidatePopup { | ||||
|         if (isVisible) { | ||||
|             this._boxPointer.setPosition(Main.layoutManager.dummyCursor, 0); | ||||
|             this._boxPointer.open(BoxPointer.PopupAnimation.NONE); | ||||
|             this._boxPointer.actor.raise_top(); | ||||
|             this._boxPointer.raise_top(); | ||||
|         } else { | ||||
|             this._boxPointer.close(BoxPointer.PopupAnimation.NONE); | ||||
|         } | ||||
| @@ -295,7 +293,7 @@ var CandidatePopup = class CandidatePopup { | ||||
|  | ||||
|     _setTextAttributes(clutterText, ibusAttrList) { | ||||
|         let attr; | ||||
|         for (let i = 0; attr = ibusAttrList.get(i); ++i) | ||||
|         for (let i = 0; (attr = ibusAttrList.get(i)); ++i) | ||||
|             if (attr.get_attr_type() == IBus.AttrType.BACKGROUND) | ||||
|                 clutterText.set_selection(attr.get_start_index(), attr.get_end_index()); | ||||
|     } | ||||
|   | ||||
| @@ -1,12 +1,6 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const GObject = imports.gi.GObject; | ||||
| const Gtk = imports.gi.Gtk; | ||||
| const Meta = imports.gi.Meta; | ||||
| const Shell = imports.gi.Shell; | ||||
| const Signals = imports.signals; | ||||
| const St = imports.gi.St; | ||||
| const { Clutter, GObject, Meta, St } = imports.gi; | ||||
|  | ||||
| const Params = imports.misc.params; | ||||
| const Tweener = imports.ui.tweener; | ||||
| @@ -49,8 +43,6 @@ class BaseIcon extends St.Bin { | ||||
|                       x_fill: true, | ||||
|                       y_fill: true }); | ||||
|  | ||||
|         this.actor = this; | ||||
|  | ||||
|         this.connect('destroy', this._onDestroy.bind(this)); | ||||
|  | ||||
|         this._box = new St.BoxLayout({ vertical: true }); | ||||
| @@ -87,7 +79,7 @@ class BaseIcon extends St.Bin { | ||||
|     // This can be overridden by a subclass, or by the createIcon | ||||
|     // parameter to _init() | ||||
|     createIcon(size) { | ||||
|         throw new Error('no implementation of createIcon in ' + this); | ||||
|         throw new GObject.NotImplementedError(`createIcon in ${this.constructor.name}`); | ||||
|     } | ||||
|  | ||||
|     setIconSize(size) { | ||||
| @@ -110,6 +102,7 @@ class BaseIcon extends St.Bin { | ||||
|     } | ||||
|  | ||||
|     vfunc_style_changed() { | ||||
|         super.vfunc_style_changed(); | ||||
|         let node = this.get_theme_node(); | ||||
|  | ||||
|         let size; | ||||
| @@ -193,8 +186,6 @@ var IconGrid = GObject.registerClass({ | ||||
|         super._init({ style_class: 'icon-grid', | ||||
|                       y_align: Clutter.ActorAlign.START }); | ||||
|  | ||||
|         this.actor = this; | ||||
|  | ||||
|         params = Params.parse(params, { rowLimit: null, | ||||
|                                         columnLimit: null, | ||||
|                                         minRows: 1, | ||||
| @@ -331,6 +322,7 @@ var IconGrid = GObject.registerClass({ | ||||
|                 leftEmptySpace = availWidth - usedWidth; | ||||
|         } | ||||
|  | ||||
|         let animating = this._clonesAnimating.length > 0; | ||||
|         let x = box.x1 + leftEmptySpace + this.leftPadding; | ||||
|         let y = box.y1 + this.topPadding; | ||||
|         let columnIndex = 0; | ||||
| @@ -340,10 +332,11 @@ var IconGrid = GObject.registerClass({ | ||||
|  | ||||
|             if (this._rowLimit && rowIndex >= this._rowLimit || | ||||
|                 this._fillParent && childBox.y2 > availHeight - this.bottomPadding) { | ||||
|                 children[i].hide(); | ||||
|                 children[i].opacity = 0; | ||||
|             } else { | ||||
|                 if (!animating) | ||||
|                     children[i].opacity = 255; | ||||
|                 children[i].allocate(childBox, flags); | ||||
|                 children[i].show(); | ||||
|             } | ||||
|  | ||||
|             columnIndex++; | ||||
| @@ -387,7 +380,7 @@ var IconGrid = GObject.registerClass({ | ||||
|              child != null; | ||||
|              child = child.get_next_sibling()) { | ||||
|  | ||||
|             if (!child.visible) | ||||
|             if (!child.visible || !child.opacity) | ||||
|                 continue; | ||||
|  | ||||
|             let childVolume = child.get_transformed_paint_volume(this); | ||||
| @@ -425,7 +418,8 @@ var IconGrid = GObject.registerClass({ | ||||
|  | ||||
|     animatePulse(animationDirection) { | ||||
|         if (animationDirection != AnimationDirection.IN) | ||||
|             throw new Error("Pulse animation only implements 'in' animation direction"); | ||||
|             throw new GObject.NotImplementedError("Pulse animation only implements " + | ||||
|                                                   "'in' animation direction"); | ||||
|  | ||||
|         this._cancelAnimation(); | ||||
|  | ||||
| @@ -670,7 +664,7 @@ var IconGrid = GObject.registerClass({ | ||||
|     } | ||||
|  | ||||
|     addItem(item, index) { | ||||
|         if (!item.icon instanceof BaseIcon) | ||||
|         if (!(item.icon instanceof BaseIcon)) | ||||
|             throw new Error('Only items with a BaseIcon icon property can be added to IconGrid'); | ||||
|  | ||||
|         this._items.push(item); | ||||
| @@ -849,7 +843,7 @@ var PaginatedIconGrid = GObject.registerClass({ | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Overriden from IconGrid | ||||
|     // Overridden from IconGrid | ||||
|     _getChildrenToAnimate() { | ||||
|         let children = this._getVisibleChildren(); | ||||
|         let firstIndex = this._childrenPerPage * this.currentPage; | ||||
| @@ -906,10 +900,8 @@ var PaginatedIconGrid = GObject.registerClass({ | ||||
|     getItemPage(item) { | ||||
|         let children = this._getVisibleChildren(); | ||||
|         let index = children.indexOf(item); | ||||
|         if (index == -1) { | ||||
|         if (index == -1) | ||||
|             throw new Error('Item not found.'); | ||||
|             return 0; | ||||
|         } | ||||
|         return Math.floor(index / this._childrenPerPage); | ||||
|     } | ||||
|  | ||||
| @@ -924,10 +916,9 @@ var PaginatedIconGrid = GObject.registerClass({ | ||||
|     openExtraSpace(sourceItem, side, nRows) { | ||||
|         let children = this._getVisibleChildren(); | ||||
|         let index = children.indexOf(sourceItem.actor); | ||||
|         if (index == -1) { | ||||
|         if (index == -1) | ||||
|             throw new Error('Item not found.'); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         let pageIndex = Math.floor(index / this._childrenPerPage); | ||||
|         let pageOffset = pageIndex * this._childrenPerPage; | ||||
|  | ||||
| @@ -959,8 +950,8 @@ var PaginatedIconGrid = GObject.registerClass({ | ||||
|             this._translatedChildren = []; | ||||
|             this.emit('space-opened'); | ||||
|         } else { | ||||
|             this._translateChildren(childrenUp, Gtk.DirectionType.UP, nRowsUp); | ||||
|             this._translateChildren(childrenDown, Gtk.DirectionType.DOWN, nRowsDown); | ||||
|             this._translateChildren(childrenUp, St.DirectionType.UP, nRowsUp); | ||||
|             this._translateChildren(childrenDown, St.DirectionType.DOWN, nRowsDown); | ||||
|             this._translatedChildren = childrenUp.concat(childrenDown); | ||||
|         } | ||||
|     } | ||||
| @@ -970,7 +961,7 @@ var PaginatedIconGrid = GObject.registerClass({ | ||||
|         if (translationY == 0) | ||||
|             return; | ||||
|  | ||||
|         if (direction == Gtk.DirectionType.UP) | ||||
|         if (direction == St.DirectionType.UP) | ||||
|             translationY *= -1; | ||||
|  | ||||
|         for (let i = 0; i < children.length; i++) { | ||||
|   | ||||
| @@ -1,17 +1,16 @@ | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const Gio = imports.gi.Gio; | ||||
| const GObject = imports.gi.GObject; | ||||
| const Gtk = imports.gi.Gtk; | ||||
| const Meta = imports.gi.Meta; | ||||
| const Shell = imports.gi.Shell; | ||||
| const St = imports.gi.St; | ||||
| const { Clutter, Gio, GLib, GObject, Gtk, Meta, Shell } = imports.gi; | ||||
|  | ||||
| const Dialog = imports.ui.dialog; | ||||
| const ModalDialog = imports.ui.modalDialog; | ||||
| const PermissionStore = imports.misc.permissionStore; | ||||
|  | ||||
| const WAYLAND_KEYBINDINGS_SCHEMA = 'org.gnome.mutter.wayland.keybindings'; | ||||
|  | ||||
| const APP_WHITELIST = ['gnome-control-center.desktop']; | ||||
| const APP_PERMISSIONS_TABLE = 'gnome'; | ||||
| const APP_PERMISSIONS_ID = 'shortcuts-inhibitor'; | ||||
| const GRANTED = 'GRANTED'; | ||||
| const DENIED = 'DENIED'; | ||||
|  | ||||
| var DialogResponse = Meta.InhibitShortcutsDialogResponse; | ||||
|  | ||||
| @@ -49,6 +48,29 @@ var InhibitShortcutsDialog = GObject.registerClass({ | ||||
|                                                Gtk.accelerator_parse(accel)); | ||||
|     } | ||||
|  | ||||
|     _shouldUsePermStore() { | ||||
|         return this._app && !this._app.is_window_backed(); | ||||
|     } | ||||
|  | ||||
|     _saveToPermissionStore(grant) { | ||||
|         if (!this._shouldUsePermStore() || this._permStore == null) | ||||
|             return; | ||||
|  | ||||
|         let permissions = {}; | ||||
|         permissions[this._app.get_id()] = [grant]; | ||||
|         let data = GLib.Variant.new('av', {}); | ||||
|  | ||||
|         this._permStore.SetRemote(APP_PERMISSIONS_TABLE, | ||||
|                                   true, | ||||
|                                   APP_PERMISSIONS_ID, | ||||
|                                   permissions, | ||||
|                                   data, | ||||
|             (result, error) => { | ||||
|                 if (error != null) | ||||
|                     log(error.message); | ||||
|             }); | ||||
|     } | ||||
|  | ||||
|     _buildLayout() { | ||||
|         let name = this._app ? this._app.get_name() : this._window.title; | ||||
|  | ||||
| @@ -70,12 +92,14 @@ var InhibitShortcutsDialog = GObject.registerClass({ | ||||
|  | ||||
|         this._dialog.addButton({ label: _("Deny"), | ||||
|                                  action: () => { | ||||
|                                      this._saveToPermissionStore(DENIED); | ||||
|                                      this._emitResponse(DialogResponse.DENY); | ||||
|                                  }, | ||||
|                                  key: Clutter.KEY_Escape }); | ||||
|  | ||||
|         this._dialog.addButton({ label: _("Allow"), | ||||
|                                  action: () => { | ||||
|                                      this._saveToPermissionStore(GRANTED); | ||||
|                                      this._emitResponse(DialogResponse.ALLOW); | ||||
|                                  }, | ||||
|                                  default: true }); | ||||
| @@ -87,10 +111,43 @@ var InhibitShortcutsDialog = GObject.registerClass({ | ||||
|     } | ||||
|  | ||||
|     vfunc_show() { | ||||
|         if (this._app && APP_WHITELIST.indexOf(this._app.get_id()) != -1) | ||||
|         if (this._app && APP_WHITELIST.indexOf(this._app.get_id()) != -1) { | ||||
|             this._emitResponse(DialogResponse.ALLOW); | ||||
|         else | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (!this._shouldUsePermStore()) { | ||||
|             this._dialog.open(); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         /* Check with the permission store */ | ||||
|         let appId = this._app.get_id(); | ||||
|         this._permStore = new PermissionStore.PermissionStore((proxy, error) => { | ||||
|             if (error) { | ||||
|                 log(error.message); | ||||
|                 this._dialog.open(); | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             this._permStore.LookupRemote(APP_PERMISSIONS_TABLE, | ||||
|                                          APP_PERMISSIONS_ID, | ||||
|                 (res, error) => { | ||||
|                     if (error) { | ||||
|                         this._dialog.open(); | ||||
|                         log(error.message); | ||||
|                         return; | ||||
|                     } | ||||
|  | ||||
|                     let [permissions, data] = res; | ||||
|                     if (permissions[appId] === undefined) // Not found | ||||
|                         this._dialog.open(); | ||||
|                     else if (permissions[appId] == GRANTED) | ||||
|                         this._emitResponse(DialogResponse.ALLOW); | ||||
|                     else | ||||
|                         this._emitResponse(DialogResponse.DENY); | ||||
|                 }); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     vfunc_hide() { | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const Gio = imports.gi.Gio; | ||||
| const GObject = imports.gi.GObject; | ||||
| const { Clutter, Gio, GObject } = imports.gi; | ||||
|  | ||||
| const Dialog = imports.ui.dialog; | ||||
| const ModalDialog = imports.ui.modalDialog; | ||||
|  | ||||
| @@ -8,7 +7,7 @@ const KEYBOARD_A11Y_SCHEMA    = 'org.gnome.desktop.a11y.keyboard'; | ||||
| const KEY_STICKY_KEYS_ENABLED = 'stickykeys-enable'; | ||||
| const KEY_SLOW_KEYS_ENABLED   = 'slowkeys-enable'; | ||||
|  | ||||
| var KbdA11yDialog = new GObject.registerClass( | ||||
| var KbdA11yDialog = GObject.registerClass( | ||||
| class KbdA11yDialog extends GObject.Object { | ||||
|     _init() { | ||||
|         super._init(); | ||||
|   | ||||
| @@ -1,27 +1,21 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Atspi = imports.gi.Atspi; | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const Gdk = imports.gi.Gdk; | ||||
| const Gio = imports.gi.Gio; | ||||
| const GLib = imports.gi.GLib; | ||||
| const GObject = imports.gi.GObject; | ||||
| const Meta = imports.gi.Meta; | ||||
| const Shell = imports.gi.Shell; | ||||
| const { Clutter, Gio, GLib, GObject, Meta, St } = imports.gi; | ||||
| const Signals = imports.signals; | ||||
| const St = imports.gi.St; | ||||
| const InputSourceManager = imports.ui.status.keyboard; | ||||
|  | ||||
| const InputSourceManager = imports.ui.status.keyboard; | ||||
| const IBusManager = imports.misc.ibusManager; | ||||
| const BoxPointer = imports.ui.boxpointer; | ||||
| const Layout = imports.ui.layout; | ||||
| const Main = imports.ui.main; | ||||
| const PageIndicators = imports.ui.pageIndicators; | ||||
| const PopupMenu = imports.ui.popupMenu; | ||||
| const Tweener = imports.ui.tweener; | ||||
| const Util = imports.misc.util; | ||||
|  | ||||
| var KEYBOARD_REST_TIME = Layout.KEYBOARD_ANIMATION_TIME * 2 * 1000; | ||||
| var KEY_LONG_PRESS_TIME = 250; | ||||
| var PANEL_SWITCH_ANIMATION_TIME = 0.5; | ||||
| var PANEL_SWITCH_RELATIVE_DISTANCE = 1 / 3; /* A third of the actor width */ | ||||
|  | ||||
| const A11Y_APPLICATIONS_SCHEMA = 'org.gnome.desktop.a11y.applications'; | ||||
| const SHOW_KEYBOARD = 'screen-keyboard-enabled'; | ||||
| @@ -40,28 +34,63 @@ const defaultKeysPost = [ | ||||
|     [ [{ label: '⌫', width: 1.5, keyval: Clutter.KEY_BackSpace }], | ||||
|       [{ width: 2, keyval: Clutter.KEY_Return, extraClassName: 'enter-key' }], | ||||
|       [{ width: 3, level: 1, right: true, extraClassName: 'shift-key-lowercase' }], | ||||
|       [{ width: 1.5, action: 'languageMenu', extraClassName: 'layout-key' }, { width: 1.5, action: 'hide', extraClassName: 'hide-key' }] ], | ||||
|       [{ label: '☻', action: 'emoji' }, { action: 'languageMenu', extraClassName: 'layout-key' }, { action: 'hide', extraClassName: 'hide-key' }] ], | ||||
|     [ [{ label: '⌫', width: 1.5, keyval: Clutter.KEY_BackSpace }], | ||||
|       [{ width: 2, keyval: Clutter.KEY_Return, extraClassName: 'enter-key' }], | ||||
|       [{ width: 3, level: 0, right: true, extraClassName: 'shift-key-uppercase' }], | ||||
|       [{ width: 1.5, action: 'languageMenu', extraClassName: 'layout-key' }, { width: 1.5, action: 'hide', extraClassName: 'hide-key' }] ], | ||||
|       [{ label: '☻', action: 'emoji' }, { action: 'languageMenu', extraClassName: 'layout-key' }, { action: 'hide', extraClassName: 'hide-key' }] ], | ||||
|     [ [{ label: '⌫', width: 1.5, keyval: Clutter.KEY_BackSpace }], | ||||
|       [{ width: 2, keyval: Clutter.KEY_Return, extraClassName: 'enter-key' }], | ||||
|       [{ label: '=/<', width: 3, level: 3, right: true }], | ||||
|       [{ width: 1.5, action: 'languageMenu', extraClassName: 'layout-key' }, { width: 1.5, action: 'hide', extraClassName: 'hide-key' }] ], | ||||
|       [{ label: '☻', action: 'emoji' }, { action: 'languageMenu', extraClassName: 'layout-key' }, { action: 'hide', extraClassName: 'hide-key' }] ], | ||||
|     [ [{ label: '⌫', width: 1.5, keyval: Clutter.KEY_BackSpace }], | ||||
|       [{ width: 2, keyval: Clutter.KEY_Return, extraClassName: 'enter-key' }], | ||||
|       [{ label: '?123', width: 3, level: 2, right: true }], | ||||
|       [{ width: 1.5, action: 'languageMenu', extraClassName: 'layout-key' }, { width: 1.5, action: 'hide', extraClassName: 'hide-key' }] ], | ||||
|       [{ label: '☻', action: 'emoji' }, { action: 'languageMenu', extraClassName: 'layout-key' }, { action: 'hide', extraClassName: 'hide-key' }] ], | ||||
| ]; | ||||
|  | ||||
| var KeyContainer = new GObject.registerClass( | ||||
| var AspectContainer = GObject.registerClass( | ||||
| class AspectContainer extends St.Widget { | ||||
|     _init(params) { | ||||
|         super._init(params); | ||||
|         this._ratio = 1; | ||||
|     } | ||||
|  | ||||
|     setRatio(relWidth, relHeight) { | ||||
|         this._ratio = relWidth / relHeight; | ||||
|         this.queue_relayout(); | ||||
|     } | ||||
|  | ||||
|     vfunc_allocate(box, flags) { | ||||
|         if (box.get_width() > 0 && box.get_height() > 0) { | ||||
|             let sizeRatio = box.get_width() / box.get_height(); | ||||
|  | ||||
|             if (sizeRatio >= this._ratio) { | ||||
|                 /* Restrict horizontally */ | ||||
|                 let width = box.get_height() * this._ratio; | ||||
|                 let diff = box.get_width() - width; | ||||
|  | ||||
|                 box.x1 += Math.floor(diff / 2); | ||||
|                 box.x2 -= Math.ceil(diff / 2); | ||||
|             } else { | ||||
|                 /* Restrict vertically, align to bottom */ | ||||
|                 let height = box.get_width() / this._ratio; | ||||
|                 box.y1 = box.y2 - Math.floor(height); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         super.vfunc_allocate(box, flags); | ||||
|     } | ||||
| }); | ||||
|  | ||||
| var KeyContainer = GObject.registerClass( | ||||
| class KeyContainer extends St.Widget { | ||||
|     _init() { | ||||
|         let gridLayout = new Clutter.GridLayout({ orientation: Clutter.Orientation.HORIZONTAL, | ||||
|                                                   column_homogeneous: true, | ||||
|                                                   row_homogeneous: true }); | ||||
|         super._init({ layout_manager: gridLayout }); | ||||
|         super._init({ layout_manager: gridLayout, | ||||
|                       x_expand: true, y_expand: true }); | ||||
|         this._gridLayout = gridLayout; | ||||
|         this._currentRow = 0; | ||||
|         this._currentCol = 0; | ||||
| @@ -98,32 +127,7 @@ class KeyContainer extends St.Widget { | ||||
|         this._maxCols = Math.max(this._currentCol, this._maxCols); | ||||
|     } | ||||
|  | ||||
|     vfunc_allocate(box, flags) { | ||||
|         if (box.get_width() > 0 && box.get_height() > 0 && this._maxCols > 0) { | ||||
|             let keyboardRatio = this._maxCols / this._rows.length; | ||||
|             let sizeRatio = box.get_width() / box.get_height(); | ||||
|  | ||||
|             if (sizeRatio >= keyboardRatio) { | ||||
|                 /* Restrict horizontally */ | ||||
|                 let width = box.get_height() * keyboardRatio; | ||||
|                 let diff = box.get_width() - width; | ||||
|  | ||||
|                 box.x1 += Math.floor(diff / 2); | ||||
|                 box.x2 -= Math.ceil(diff / 2); | ||||
|             } else { | ||||
|                 /* Restrict vertically */ | ||||
|                 let height = box.get_width() / keyboardRatio; | ||||
|                 let diff = box.get_height() - height; | ||||
|  | ||||
|                 box.y1 += Math.floor(diff / 2); | ||||
|                 box.y2 -= Math.floor(diff / 2); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         super.vfunc_allocate(box, flags); | ||||
|     } | ||||
|  | ||||
|     layoutButtons() { | ||||
|     layoutButtons(container) { | ||||
|         let nCol = 0, nRow = 0; | ||||
|  | ||||
|         for (let i = 0; i < this._rows.length; i++) { | ||||
| @@ -150,6 +154,9 @@ class KeyContainer extends St.Widget { | ||||
|             nRow += KEY_SIZE; | ||||
|             nCol = 0; | ||||
|         } | ||||
|  | ||||
|         if (container) | ||||
|             container.setRatio(this._maxCols, this._rows.length); | ||||
|     } | ||||
| }); | ||||
|  | ||||
| @@ -179,16 +186,20 @@ var LanguageSelectionPopup = class extends PopupMenu.PopupMenu { | ||||
|         let inputSourceManager = InputSourceManager.getInputSourceManager(); | ||||
|         let inputSources = inputSourceManager.inputSources; | ||||
|  | ||||
|         let item; | ||||
|         for (let i in inputSources) { | ||||
|             let is = inputSources[i]; | ||||
|  | ||||
|             this.addAction(is.displayName, () => { | ||||
|             item = this.addAction(is.displayName, () => { | ||||
|                 inputSourceManager.activateInputSource(is, true); | ||||
|             }); | ||||
|             item.actor.can_focus = false; | ||||
|         } | ||||
|  | ||||
|         this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); | ||||
|         this.addSettingsAction(_("Region & Language Settings"), 'gnome-region-panel.desktop'); | ||||
|         item = this.addSettingsAction(_("Region & Language Settings"), 'gnome-region-panel.desktop'); | ||||
|         item.actor.can_focus = false; | ||||
|  | ||||
|         this._capturedEventId = 0; | ||||
|  | ||||
|         this._unmapId = actor.connect('notify::mapped', () => { | ||||
| @@ -232,7 +243,7 @@ var LanguageSelectionPopup = class extends PopupMenu.PopupMenu { | ||||
| }; | ||||
|  | ||||
| var Key = class Key { | ||||
|     constructor(key) { | ||||
|     constructor(key, extendedKeys) { | ||||
|         this.key = key || ""; | ||||
|         this.keyButton = this._makeKey(this.key); | ||||
|  | ||||
| @@ -258,6 +269,8 @@ var Key = class Key { | ||||
|             this._boxPointer.destroy(); | ||||
|             this._boxPointer = null; | ||||
|         } | ||||
|  | ||||
|         this.cancel(); | ||||
|     } | ||||
|  | ||||
|     _ensureExtendedKeysPopup() { | ||||
| @@ -269,21 +282,23 @@ var Key = class Key { | ||||
|                                                        y_fill: true, | ||||
|                                                        x_align: St.Align.START }); | ||||
|         this._boxPointer.hide(); | ||||
|         Main.layoutManager.addChrome(this._boxPointer.actor); | ||||
|         Main.layoutManager.addTopChrome(this._boxPointer); | ||||
|         this._boxPointer.setPosition(this.keyButton, 0.5); | ||||
|  | ||||
|         // Adds style to existing keyboard style to avoid repetition | ||||
|         this._boxPointer.actor.add_style_class_name('keyboard-subkeys'); | ||||
|         this._boxPointer.add_style_class_name('keyboard-subkeys'); | ||||
|         this._getExtendedKeys(); | ||||
|         this.keyButton._extended_keys = this._extended_keyboard; | ||||
|     } | ||||
|  | ||||
|     _getKeyval(key) { | ||||
|         let unicode = String.charCodeAt(key, 0); | ||||
|         return Gdk.unicode_to_keyval(unicode); | ||||
|         let unicode = key.charCodeAt(0); | ||||
|         return Clutter.unicode_to_keysym(unicode); | ||||
|     } | ||||
|  | ||||
|     _press(key) { | ||||
|         this.emit('activated') | ||||
|  | ||||
|         if (key != this.key || this._extended_keys.length == 0) { | ||||
|             this.emit('pressed', this._getKeyval(key), key); | ||||
|         } | ||||
| @@ -324,6 +339,16 @@ var Key = class Key { | ||||
|         this._longPress = false; | ||||
|     } | ||||
|  | ||||
|     cancel() { | ||||
|         if (this._pressTimeoutId != 0) { | ||||
|             GLib.source_remove(this._pressTimeoutId); | ||||
|             this._pressTimeoutId = 0; | ||||
|         } | ||||
|         this._touchPressed = false; | ||||
|         this.keyButton.set_hover(false); | ||||
|         this.keyButton.fake_release(); | ||||
|     } | ||||
|  | ||||
|     _onCapturedEvent(actor, event) { | ||||
|         let type = event.type(); | ||||
|         let press = (type == Clutter.EventType.BUTTON_PRESS || type == Clutter.EventType.TOUCH_BEGIN); | ||||
| @@ -395,13 +420,10 @@ var Key = class Key { | ||||
|  | ||||
|             if (!this._touchPressed && | ||||
|                 event.type() == Clutter.EventType.TOUCH_BEGIN) { | ||||
|                 device.sequence_grab(sequence, actor); | ||||
|                 this._touchPressed = true; | ||||
|                 this._press(key); | ||||
|             } else if (this._touchPressed && | ||||
|                        event.type() == Clutter.EventType.TOUCH_END && | ||||
|                        device.sequence_get_grabbed_actor(sequence) == actor) { | ||||
|                 device.sequence_ungrab(sequence); | ||||
|                        event.type() == Clutter.EventType.TOUCH_END) { | ||||
|                 this._touchPressed = false; | ||||
|                 this._release(key); | ||||
|             } | ||||
| @@ -550,10 +572,469 @@ var FocusTracker = class { | ||||
| }; | ||||
| Signals.addSignalMethods(FocusTracker.prototype); | ||||
|  | ||||
| var EmojiPager = class EmojiPager { | ||||
|     constructor(sections, nCols, nRows) { | ||||
|         this.actor = new St.Widget({ layout_manager: new Clutter.BinLayout(), | ||||
|                                      reactive: true, | ||||
|                                      clip_to_allocation: true }); | ||||
|         this._sections = sections; | ||||
|         this._nCols = nCols; | ||||
|         this._nRows = nRows; | ||||
|  | ||||
|         this._pages = []; | ||||
|         this._panel = null; | ||||
|         this._curPage = null; | ||||
|         this._followingPage = null; | ||||
|         this._followingPanel = null; | ||||
|         this._currentKey = null; | ||||
|         this._delta = 0; | ||||
|         this._width = null; | ||||
|  | ||||
|         this._initPagingInfo(); | ||||
|  | ||||
|         let panAction = new Clutter.PanAction({ interpolate: false }); | ||||
|         panAction.connect('pan', this._onPan.bind(this)); | ||||
|         panAction.connect('gesture-begin', this._onPanBegin.bind(this)); | ||||
|         panAction.connect('gesture-cancel', this._onPanCancel.bind(this)); | ||||
|         panAction.connect('gesture-end', this._onPanEnd.bind(this)); | ||||
|         this._panAction = panAction; | ||||
|         this.actor.add_action(panAction); | ||||
|     } | ||||
|  | ||||
|     get delta() { | ||||
|         return this._delta; | ||||
|     } | ||||
|  | ||||
|     set delta(value) { | ||||
|         if (value > this._width) | ||||
|             value = this._width; | ||||
|         else if (value < -this._width) | ||||
|             value = -this._width; | ||||
|  | ||||
|         this._delta = value; | ||||
|  | ||||
|         if (value == 0) | ||||
|             return; | ||||
|  | ||||
|         let relValue = Math.abs(value / this._width); | ||||
|         let followingPage = this.getFollowingPage(); | ||||
|  | ||||
|         if (this._followingPage != followingPage) { | ||||
|             if (this._followingPanel) { | ||||
|                 this._followingPanel.destroy(); | ||||
|                 this._followingPanel = null; | ||||
|             } | ||||
|  | ||||
|             if (followingPage != null) { | ||||
|                 this._followingPanel = this._generatePanel(followingPage); | ||||
|                 this._followingPanel.set_pivot_point(0.5, 0.5); | ||||
|                 this.actor.add_child(this._followingPanel); | ||||
|                 this.actor.set_child_below_sibling(this._followingPanel, this._panel); | ||||
|             } | ||||
|  | ||||
|             this._followingPage = followingPage; | ||||
|         } | ||||
|  | ||||
|         this._panel.translation_x = value; | ||||
|         this._panel.opacity = 255 * (1 - Math.pow(relValue, 3)); | ||||
|  | ||||
|         if (this._followingPanel) { | ||||
|             this._followingPanel.scale_x = 0.8 + (0.2 * relValue); | ||||
|             this._followingPanel.scale_y = 0.8 + (0.2 * relValue); | ||||
|             this._followingPanel.opacity = 255 * relValue; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     _prevPage(nPage) { | ||||
|         return (nPage + this._pages.length - 1) % this._pages.length; | ||||
|     } | ||||
|  | ||||
|     _nextPage(nPage) { | ||||
|         return (nPage + 1) % this._pages.length; | ||||
|     } | ||||
|  | ||||
|     getFollowingPage() { | ||||
|         if (this.delta == 0) | ||||
|             return null; | ||||
|  | ||||
|         if ((this.delta < 0 && global.stage.text_direction == Clutter.TextDirection.LTR) || | ||||
|             (this.delta > 0 && global.stage.text_direction == Clutter.TextDirection.RTL)) | ||||
|             return this._nextPage(this._curPage); | ||||
|         else | ||||
|             return this._prevPage(this._curPage); | ||||
|     } | ||||
|  | ||||
|     _onPan(action) { | ||||
|         let [dist, dx, dy] = action.get_motion_delta(0); | ||||
|         this.delta = this.delta + dx; | ||||
|  | ||||
|         if (this._currentKey != null) { | ||||
|             this._currentKey.cancel(); | ||||
|             this._currentKey = null; | ||||
|         } | ||||
|  | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     _onPanBegin() { | ||||
|         this._width = this.actor.width; | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     _onPanEnd() { | ||||
|         if (Math.abs(this._delta) < this.actor.width * PANEL_SWITCH_RELATIVE_DISTANCE) { | ||||
|             this._onPanCancel() | ||||
|         } else { | ||||
|             let value; | ||||
|             if (this._delta > 0) | ||||
|                 value = this._width; | ||||
|             else if (this._delta < 0) | ||||
|                 value = -this._width; | ||||
|  | ||||
|             let relDelta = Math.abs(this._delta - value) / this._width; | ||||
|             let time = PANEL_SWITCH_ANIMATION_TIME * Math.abs(relDelta); | ||||
|  | ||||
|             Tweener.removeTweens(this); | ||||
|             Tweener.addTween(this, | ||||
|                              { delta: value, | ||||
|                                time: time, | ||||
|                                transition: 'easeInOutQuad', | ||||
|                                onComplete() { | ||||
|                                    this.setCurrentPage(this.getFollowingPage()); | ||||
|                                } | ||||
|                              }); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     _onPanCancel() { | ||||
|         let relDelta = Math.abs(this._delta) / this.actor.width; | ||||
|         let time = PANEL_SWITCH_ANIMATION_TIME * Math.abs(relDelta); | ||||
|  | ||||
|         Tweener.removeTweens(this); | ||||
|         Tweener.addTween(this, | ||||
|                          { delta: 0, | ||||
|                            time: time, | ||||
|                            transition: 'easeInOutQuad', | ||||
|                          }); | ||||
|     } | ||||
|  | ||||
|     _initPagingInfo() { | ||||
|         for (let i = 0; i < this._sections.length; i++) { | ||||
|             let section = this._sections[i]; | ||||
|             let itemsPerPage = this._nCols * this._nRows; | ||||
|             let nPages = Math.ceil(section.keys.length / itemsPerPage); | ||||
|             let page = -1; | ||||
|             let pageKeys; | ||||
|  | ||||
|             for (let j = 0; j < section.keys.length; j++) { | ||||
|                 if (j % itemsPerPage == 0) { | ||||
|                     page++; | ||||
|                     pageKeys = []; | ||||
|                     this._pages.push({ pageKeys, nPages, page, section: this._sections[i] }); | ||||
|                 } | ||||
|  | ||||
|                 pageKeys.push(section.keys[j]); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     _lookupSection(section, nPage) { | ||||
|         for (let i = 0; i < this._pages.length; i++) { | ||||
|             let page = this._pages[i]; | ||||
|  | ||||
|             if (page.section == section && page.page == nPage) | ||||
|                 return i; | ||||
|         } | ||||
|  | ||||
|         return -1; | ||||
|     } | ||||
|  | ||||
|     _generatePanel(nPage) { | ||||
|         let gridLayout = new Clutter.GridLayout({ orientation: Clutter.Orientation.HORIZONTAL, | ||||
|                                                   column_homogeneous: true, | ||||
|                                                   row_homogeneous: true }); | ||||
|         let panel = new St.Widget({ layout_manager: gridLayout, | ||||
|                                     style_class: 'emoji-page', | ||||
|                                     x_expand: true, | ||||
|                                     y_expand: true }); | ||||
|  | ||||
|         /* Set an expander actor so all proportions are right despite the panel | ||||
|          * not having all rows/cols filled in. | ||||
|          */ | ||||
|         let expander = new Clutter.Actor(); | ||||
|         gridLayout.attach(expander, 0, 0, this._nCols, this._nRows); | ||||
|  | ||||
|         let page = this._pages[nPage]; | ||||
|         let col = 0; | ||||
|         let row = 0; | ||||
|  | ||||
|         for (let i = 0; i < page.pageKeys.length; i++) { | ||||
|             let modelKey = page.pageKeys[i]; | ||||
|             let key = new Key(modelKey.label, modelKey.variants); | ||||
|  | ||||
|             key.keyButton.set_button_mask(0); | ||||
|  | ||||
|             key.connect('activated', () => { | ||||
|                 this._currentKey = key; | ||||
|             }); | ||||
|             key.connect('long-press', () => { | ||||
|                 this._panAction.cancel(); | ||||
|             }); | ||||
|             key.connect('released', (actor, keyval, str) => { | ||||
|                 if (this._currentKey != key) | ||||
|                     return; | ||||
|                 this._currentKey = null; | ||||
|                 this.emit('emoji', str); | ||||
|             }); | ||||
|  | ||||
|             gridLayout.attach(key.actor, col, row, 1, 1); | ||||
|  | ||||
|             col++; | ||||
|             if (col >= this._nCols) { | ||||
|                 col = 0; | ||||
|                 row++; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return panel; | ||||
|     } | ||||
|  | ||||
|     setCurrentPage(nPage) { | ||||
|         if (this._curPage == nPage) | ||||
|             return; | ||||
|  | ||||
|         this._curPage = nPage; | ||||
|  | ||||
|         if (this._panel) { | ||||
|             this._panel.destroy(); | ||||
|             this._panel = null; | ||||
|         } | ||||
|  | ||||
|         /* Reuse followingPage if possible */ | ||||
|         if (nPage == this._followingPage) { | ||||
|             this._panel = this._followingPanel; | ||||
|             this._followingPanel = null; | ||||
|         } | ||||
|  | ||||
|         if (this._followingPanel) | ||||
|             this._followingPanel.destroy(); | ||||
|  | ||||
|         this._followingPanel = null; | ||||
|         this._followingPage = null; | ||||
|         this._delta = 0; | ||||
|  | ||||
|         if (!this._panel) { | ||||
|             this._panel = this._generatePanel(nPage); | ||||
|             this.actor.add_child(this._panel); | ||||
|         } | ||||
|  | ||||
|         let page = this._pages[nPage]; | ||||
|         this.emit('page-changed', page.section, page.page, page.nPages); | ||||
|     } | ||||
|  | ||||
|     setCurrentSection(section, nPage) { | ||||
|         for (let i = 0; i < this._pages.length; i++) { | ||||
|             let page = this._pages[i]; | ||||
|  | ||||
|             if (page.section == section && page.page == nPage) { | ||||
|                 this.setCurrentPage(i); | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| }; | ||||
| Signals.addSignalMethods(EmojiPager.prototype); | ||||
|  | ||||
| var EmojiSelection = class EmojiSelection { | ||||
|     constructor() { | ||||
|         this._sections = [ | ||||
|             { first: 'grinning face', label: '🙂️' }, | ||||
|             { first: 'selfie', label: '👍️' }, | ||||
|             { first: 'monkey face', label: '🌷️' }, | ||||
|             { first: 'grapes', label: '🍴️' }, | ||||
|             { first: 'globe showing Europe-Africa', label: '✈️' }, | ||||
|             { first: 'jack-o-lantern', label: '🏃️' }, | ||||
|             { first: 'muted speaker', label: '🔔️' }, | ||||
|             { first: 'ATM sign', label: '❤️' }, | ||||
|             { first: 'chequered flag', label: '🚩️' }, | ||||
|         ]; | ||||
|  | ||||
|         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('emoji', (pager, str) => { | ||||
|             this.emit('emoji-selected', str); | ||||
|         }); | ||||
|         this.actor.add(this._emojiPager.actor, { expand: true }); | ||||
|  | ||||
|         this._pageIndicator = new PageIndicators.PageIndicators(false); | ||||
|         this.actor.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._emojiPager.setCurrentPage(0); | ||||
|     } | ||||
|  | ||||
|     _onPageChanged(section, 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); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     _findSection(emoji) { | ||||
|         for (let i = 0; i < this._sections.length; i++) { | ||||
|             if (this._sections[i].first == emoji) | ||||
|                 return this._sections[i]; | ||||
|         } | ||||
|  | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     _populateSections() { | ||||
|         let file = Gio.File.new_for_uri('resource:///org/gnome/shell/osk-layouts/emoji.json'); | ||||
|         let [success, contents] = file.load_contents(null); | ||||
|  | ||||
|         if (contents instanceof Uint8Array) | ||||
|             contents = imports.byteArray.toString(contents); | ||||
|         let emoji = JSON.parse(contents); | ||||
|  | ||||
|         let pages = []; | ||||
|         let variants = []; | ||||
|         let currentKey = 0; | ||||
|         let currentSection = null; | ||||
|  | ||||
|         for (let i = 0; i < emoji.length; i++) { | ||||
|             /* Group variants of a same emoji so they appear on the key popover */ | ||||
|             if (emoji[i].name.startsWith(emoji[currentKey].name)) { | ||||
|                 variants.push(emoji[i].char); | ||||
|                 if (i < emoji.length - 1) | ||||
|                     continue; | ||||
|             } | ||||
|  | ||||
|             let newSection = this._findSection(emoji[currentKey].name); | ||||
|             if (newSection != null) { | ||||
|                 currentSection = newSection; | ||||
|                 currentSection.keys = []; | ||||
|             } | ||||
|  | ||||
|             /* Create the key */ | ||||
|             let label = emoji[currentKey].char + String.fromCharCode(0xFE0F); | ||||
|             currentSection.keys.push({ label, variants }); | ||||
|             currentKey = i; | ||||
|             variants = []; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     _createBottomRow() { | ||||
|         let row = new KeyContainer(); | ||||
|         let key; | ||||
|  | ||||
|         row.appendRow(); | ||||
|  | ||||
|         key = new Key('ABC', []); | ||||
|         key.keyButton.add_style_class_name('default-key'); | ||||
|         key.connect('released', () => { this.emit('toggle'); }); | ||||
|         row.appendKey(key.actor, 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); | ||||
|  | ||||
|             section.button = key; | ||||
|         } | ||||
|  | ||||
|         key = new Key(null, []); | ||||
|         key.keyButton.add_style_class_name('default-key'); | ||||
|         key.keyButton.add_style_class_name('hide-key'); | ||||
|         key.connect('released', () => { | ||||
|             this.emit('hide'); | ||||
|         }); | ||||
|         row.appendKey(key.actor); | ||||
|         row.layoutButtons(); | ||||
|  | ||||
|         let actor = new AspectContainer({ layout_manager: new Clutter.BinLayout(), | ||||
|                                           x_expand: true, y_expand: true }); | ||||
|         actor.add_child(row); | ||||
|         /* Regular keyboard layouts are 11.5×4 grids, optimize for that | ||||
|          * at the moment. Ideally this should be as wide as the current | ||||
|          * keymap. | ||||
|          */ | ||||
|         actor.setRatio(11.5, 1); | ||||
|  | ||||
|         return actor; | ||||
|     } | ||||
| }; | ||||
| Signals.addSignalMethods(EmojiSelection.prototype); | ||||
|  | ||||
| var Keypad = class Keypad { | ||||
|     constructor() { | ||||
|         let keys = [ | ||||
|             { label: '1', keyval: Clutter.KEY_1, left: 0, top: 0 }, | ||||
|             { label: '2', keyval: Clutter.KEY_2, left: 1, top: 0 }, | ||||
|             { label: '3', keyval: Clutter.KEY_3, left: 2, top: 0 }, | ||||
|             { label: '4', keyval: Clutter.KEY_4, left: 0, top: 1 }, | ||||
|             { label: '5', keyval: Clutter.KEY_5, left: 1, top: 1 }, | ||||
|             { label: '6', keyval: Clutter.KEY_6, left: 2, top: 1 }, | ||||
|             { label: '7', keyval: Clutter.KEY_7, left: 0, top: 2 }, | ||||
|             { label: '8', keyval: Clutter.KEY_8, left: 1, top: 2 }, | ||||
|             { label: '9', keyval: Clutter.KEY_9, left: 2, top: 2 }, | ||||
|             { label: '0', keyval: Clutter.KEY_0, left: 1, top: 3 }, | ||||
|             { label: '⌫', keyval: Clutter.KEY_BackSpace, left: 3, top: 0 }, | ||||
|             { keyval: Clutter.KEY_Return, extraClassName: 'enter-key', left: 3, top: 1, height: 2 }, | ||||
|         ]; | ||||
|  | ||||
|         this.actor = new AspectContainer({ 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); | ||||
|  | ||||
|         for (let i = 0; i < keys.length; i++) { | ||||
|             let cur = keys[i]; | ||||
|             let key = new Key(cur.label || "", []); | ||||
|  | ||||
|             if (keys[i].extraClassName) | ||||
|                 key.keyButton.add_style_class_name(cur.extraClassName); | ||||
|  | ||||
|             let w, h; | ||||
|             w = cur.width || 1; | ||||
|             h = cur.height || 1; | ||||
|             gridLayout.attach(key.actor, cur.left, cur.top, w, h); | ||||
|  | ||||
|             key.connect('released', () => { | ||||
|                 this.emit('keyval', cur.keyval); | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
| }; | ||||
| Signals.addSignalMethods(Keypad.prototype); | ||||
|  | ||||
| var Keyboard = class Keyboard { | ||||
|     constructor() { | ||||
|         this.actor = null; | ||||
|         this._focusInExtendedKeys = false; | ||||
|         this._emojiActive = false; | ||||
|  | ||||
|         this._languagePopup = null; | ||||
|         this._currentFocusWindow = null; | ||||
| @@ -568,6 +1049,7 @@ var Keyboard = class Keyboard { | ||||
|         this._a11yApplicationsSettings.connect('changed', this._syncEnabled.bind(this)); | ||||
|         this._lastDeviceId = null; | ||||
|         this._suggestions = null; | ||||
|         this._emojiKeyVisible = Meta.is_wayland_compositor(); | ||||
|  | ||||
|         this._focusTracker = new FocusTracker(); | ||||
|         this._focusTracker.connect('position-changed', this._onFocusPositionChanged.bind(this)); | ||||
| @@ -656,8 +1138,13 @@ var Keyboard = class Keyboard { | ||||
|             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); | ||||
|         this._clearShowIdle(); | ||||
|         this._keyboard = null; | ||||
|         this.actor.destroy(); | ||||
|         this.actor = null; | ||||
| @@ -676,16 +1163,35 @@ var Keyboard = class Keyboard { | ||||
|         this._keyboardController = new KeyboardController(); | ||||
|  | ||||
|         this._groups = {}; | ||||
|         this._current_page = null; | ||||
|         this._currentPage = null; | ||||
|  | ||||
|         this._suggestions = new Suggestions(); | ||||
|         this._suggestions.connect('suggestion-clicked', (suggestions, str) => { | ||||
|             this._keyboardController.commitString(str); | ||||
|         }); | ||||
|         this.actor.add(this._suggestions.actor, | ||||
|                        { 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._emojiSelection = new EmojiSelection(); | ||||
|         this._emojiSelection.connect('toggle', this._toggleEmoji.bind(this)); | ||||
|         this._emojiSelection.connect('hide', (selection) => { this.hide(); }); | ||||
|         this._emojiSelection.connect('emoji-selected', (selection, emoji) => { | ||||
|             this._keyboardController.commitString(emoji); | ||||
|         }); | ||||
|  | ||||
|         this._aspectContainer.add_child(this._emojiSelection.actor); | ||||
|         this._emojiSelection.actor.hide(); | ||||
|  | ||||
|         this._keypad = new Keypad(); | ||||
|         this._keypad.connect('keyval', (keypad, keyval) => { | ||||
|             this._keyboardController.keyvalPress(keyval); | ||||
|             this._keyboardController.keyvalRelease(keyval); | ||||
|         }); | ||||
|         this._aspectContainer.add_child(this._keypad.actor); | ||||
|         this._keypad.actor.hide(); | ||||
|         this._keypadVisible = false; | ||||
|  | ||||
|         this._ensureKeysForGroup(this._keyboardController.getCurrentGroup()); | ||||
|         this._setActiveLayer(0); | ||||
|  | ||||
| @@ -697,8 +1203,12 @@ var Keyboard = class Keyboard { | ||||
|         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)); | ||||
|  | ||||
|         if (Meta.is_wayland_compositor()) | ||||
|             this._emojiKeyVisibleId = this._keyboardController.connect('emoji-visible', this._onEmojiKeyVisible.bind(this)); | ||||
|  | ||||
|         this._relayout(); | ||||
|     } | ||||
|  | ||||
| @@ -720,6 +1230,7 @@ var Keyboard = class Keyboard { | ||||
|         if (!this._showIdleId) { | ||||
|           this._showIdleId = GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => { | ||||
|               this.show(Main.layoutManager.focusIndex); | ||||
|               this._showIdleId = 0; | ||||
|               return GLib.SOURCE_REMOVE; | ||||
|           }); | ||||
|           GLib.Source.set_name_by_id(this._showIdleId, '[gnome-shell] this.show'); | ||||
| @@ -743,11 +1254,12 @@ var Keyboard = class Keyboard { | ||||
|  | ||||
|             this._loadRows(currentLevel, level, levels.length, layout); | ||||
|             layers[level] = layout; | ||||
|             this.actor.add(layout, { expand: true }); | ||||
|             layout.layoutButtons(); | ||||
|             this._aspectContainer.add_child(layout); | ||||
|             layout.layoutButtons(this._aspectContainer); | ||||
|  | ||||
|             layout.hide(); | ||||
|         } | ||||
|  | ||||
|         return layers; | ||||
|     } | ||||
|  | ||||
| @@ -794,7 +1306,7 @@ var Keyboard = class Keyboard { | ||||
|             this._languagePopup.destroy(); | ||||
|  | ||||
|         this._languagePopup = new LanguageSelectionPopup(keyActor); | ||||
|         Main.layoutManager.addChrome(this._languagePopup.actor); | ||||
|         Main.layoutManager.addTopChrome(this._languagePopup.actor); | ||||
|         this._languagePopup.open(true); | ||||
|     } | ||||
|  | ||||
| @@ -806,7 +1318,11 @@ var Keyboard = class Keyboard { | ||||
|             let switchToLevel = key.level; | ||||
|             let action = key.action; | ||||
|  | ||||
|             extraButton = new Key(key.label, []); | ||||
|             /* Skip emoji button if necessary */ | ||||
|             if (!this._emojiKeyVisible && action == 'emoji') | ||||
|                 continue; | ||||
|  | ||||
|             extraButton = new Key(key.label || '', []); | ||||
|  | ||||
|             extraButton.keyButton.add_style_class_name('default-key'); | ||||
|             if (key.extraClassName != null) | ||||
| @@ -832,6 +1348,8 @@ var Keyboard = class Keyboard { | ||||
|                     this.hide(); | ||||
|                 else if (action == 'languageMenu') | ||||
|                     this._popupLanguageMenu(actor); | ||||
|                 else if (action == 'emoji') | ||||
|                     this._toggleEmoji(); | ||||
|             }); | ||||
|  | ||||
|             if (switchToLevel == 0) { | ||||
| @@ -839,7 +1357,7 @@ var Keyboard = class Keyboard { | ||||
|             } else if (switchToLevel == 1) { | ||||
|                 extraButton.connect('long-press', () => { | ||||
|                     this._latched = true; | ||||
|                     this._setCurrentLevelLatched(this._current_page, this._latched); | ||||
|                     this._setCurrentLevelLatched(this._currentPage, this._latched); | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
| @@ -857,14 +1375,31 @@ var Keyboard = class Keyboard { | ||||
|                 extraButton.setWidth(2); | ||||
|             } else if (keyval == Clutter.KEY_Return && numKeys > 9) { | ||||
|                 extraButton.setWidth(1.5); | ||||
|             } else if (!this._emojiKeyVisible && (action == 'hide' || action == 'languageMenu')) { | ||||
|                 extraButton.setWidth(1.5); | ||||
|             } | ||||
|  | ||||
|             layout.appendKey(extraButton.actor, extraButton.keyButton.keyWidth); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     _updateCurrentPageVisible() { | ||||
|         if (this._currentPage) | ||||
|             this._currentPage.visible = !this._emojiActive && !this._keypadVisible; | ||||
|     } | ||||
|  | ||||
|     _setEmojiActive(active) { | ||||
|         this._emojiActive = active; | ||||
|         this._emojiSelection.actor.visible = this._emojiActive; | ||||
|         this._updateCurrentPageVisible(); | ||||
|     } | ||||
|  | ||||
|     _toggleEmoji() { | ||||
|         this._setEmojiActive(!this._emojiActive); | ||||
|     } | ||||
|  | ||||
|     _setCurrentLevelLatched(layout, latched) { | ||||
|         for (let i = 0; layout.shiftKeys[i]; i++) { | ||||
|         for (let i = 0; i < layout.shiftKeys.length; i++) { | ||||
|             let key = layout.shiftKeys[i]; | ||||
|             key.setLatched(latched); | ||||
|         } | ||||
| @@ -909,7 +1444,7 @@ var Keyboard = class Keyboard { | ||||
|  | ||||
|     _getGridSlots() { | ||||
|         let numOfHorizSlots = 0, numOfVertSlots; | ||||
|         let rows = this._current_page.get_children(); | ||||
|         let rows = this._currentPage.get_children(); | ||||
|         numOfVertSlots = rows.length; | ||||
|  | ||||
|         for (let i = 0; i < rows.length; ++i) { | ||||
| @@ -939,10 +1474,33 @@ var Keyboard = class Keyboard { | ||||
|     } | ||||
|  | ||||
|     _onKeyboardGroupsChanged(keyboard) { | ||||
|         this._groups = []; | ||||
|         let nonGroupActors = [this._emojiSelection.actor, this._keypad.actor]; | ||||
|         this._aspectContainer.get_children().filter(c => !nonGroupActors.includes(c)).forEach(c => { | ||||
|             c.destroy(); | ||||
|         }); | ||||
|  | ||||
|         this._groups = {}; | ||||
|         this._onGroupChanged(); | ||||
|     } | ||||
|  | ||||
|     _onKeypadVisible(controller, visible) { | ||||
|         if (visible == this._keypadVisible) | ||||
|             return; | ||||
|  | ||||
|         this._keypadVisible = visible; | ||||
|         this._keypad.actor.visible = this._keypadVisible; | ||||
|         this._updateCurrentPageVisible(); | ||||
|     } | ||||
|  | ||||
|     _onEmojiKeyVisible(controller, visible) { | ||||
|         if (visible == this._emojiKeyVisible) | ||||
|             return; | ||||
|  | ||||
|         this._emojiKeyVisible = visible; | ||||
|         /* Rebuild keyboard widgetry to include emoji button */ | ||||
|         this._onKeyboardGroupsChanged(); | ||||
|     } | ||||
|  | ||||
|     _onKeyboardStateChanged(controller, state) { | ||||
|         let enabled; | ||||
|         if (state == Clutter.InputPanelState.OFF) | ||||
| @@ -963,14 +1521,25 @@ var Keyboard = class Keyboard { | ||||
|     _setActiveLayer(activeLevel) { | ||||
|         let activeGroupName = this._keyboardController.getCurrentGroup(); | ||||
|         let layers = this._groups[activeGroupName]; | ||||
|         let currentPage = layers[activeLevel]; | ||||
|  | ||||
|         if (this._current_page != null) { | ||||
|             this._setCurrentLevelLatched(this._current_page, false); | ||||
|             this._current_page.hide(); | ||||
|         if (this._currentPage == currentPage) { | ||||
|             this._updateCurrentPageVisible(); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         this._current_page = layers[activeLevel]; | ||||
|         this._current_page.show(); | ||||
|         if (this._currentPage != null) { | ||||
|             this._setCurrentLevelLatched(this._currentPage, false); | ||||
|             this._currentPage.disconnect(this._currentPage._destroyID); | ||||
|             this._currentPage.hide(); | ||||
|             delete this._currentPage._destroyID; | ||||
|         } | ||||
|  | ||||
|         this._currentPage = currentPage; | ||||
|         this._currentPage._destroyID = this._currentPage.connect('destroy', () => { | ||||
|             this._currentPage = null; | ||||
|         }); | ||||
|         this._updateCurrentPageVisible(); | ||||
|     } | ||||
|  | ||||
|     shouldTakeEvent(event) { | ||||
| @@ -1020,6 +1589,8 @@ var Keyboard = class Keyboard { | ||||
|         this._relayout(); | ||||
|         Main.layoutManager.showKeyboard(); | ||||
|  | ||||
|         this._setEmojiActive(false); | ||||
|  | ||||
|         if (this._delayedAnimFocusWindow) { | ||||
|             this._setAnimationWindow(this._delayedAnimFocusWindow); | ||||
|             this._delayedAnimFocusWindow = null; | ||||
| @@ -1055,18 +1626,6 @@ var Keyboard = class Keyboard { | ||||
|         this.setCursorLocation(null); | ||||
|     } | ||||
|  | ||||
|     _hideSubkeys() { | ||||
|         if (this._subkeysBoxPointer) { | ||||
|             this._subkeysBoxPointer.hide(BoxPointer.PopupAnimation.FULL); | ||||
|             this._subkeysBoxPointer = null; | ||||
|         } | ||||
|         if (this._capturedEventId) { | ||||
|             this.actor.disconnect(this._capturedEventId); | ||||
|             this._capturedEventId = 0; | ||||
|         } | ||||
|         this._capturedPress = false; | ||||
|     } | ||||
|  | ||||
|     resetSuggestions() { | ||||
|         if (this._suggestions) | ||||
|             this._suggestions.clear(); | ||||
| @@ -1187,8 +1746,21 @@ var KeyboardController = class { | ||||
|     _onContentPurposeHintsChanged(method) { | ||||
|         let hints = method.content_hints; | ||||
|         let purpose = method.content_purpose; | ||||
|         let emojiVisible = false; | ||||
|         let keypadVisible = false; | ||||
|  | ||||
|         // XXX: hook numeric/emoji/etc special keyboards | ||||
|         if (purpose == Clutter.InputContentPurpose.NORMAL || | ||||
|             purpose == Clutter.InputContentPurpose.ALPHA || | ||||
|             purpose == Clutter.InputContentPurpose.PASSWORD || | ||||
|             purpose == Clutter.InputContentPurpose.TERMINAL) | ||||
|             emojiVisible = true; | ||||
|         if (purpose == Clutter.InputContentPurpose.DIGITS || | ||||
|             purpose == Clutter.InputContentPurpose.NUMBER || | ||||
|             purpose == Clutter.InputContentPurpose.PHONE) | ||||
|             keypadVisible = true; | ||||
|  | ||||
|         this.emit('emoji-visible', emojiVisible) | ||||
|         this.emit('keypad-visible', keypadVisible); | ||||
|     } | ||||
|  | ||||
|     getGroups() { | ||||
|   | ||||
							
								
								
									
										123
									
								
								js/ui/layout.js
									
									
									
									
									
								
							
							
						
						| @@ -1,12 +1,7 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const GLib = imports.gi.GLib; | ||||
| const GObject = imports.gi.GObject; | ||||
| const Meta = imports.gi.Meta; | ||||
| const Shell = imports.gi.Shell; | ||||
| const { Clutter, GLib, GObject, Meta, Shell, St } = imports.gi; | ||||
| const Signals = imports.signals; | ||||
| const St = imports.gi.St; | ||||
|  | ||||
| const Background = imports.ui.background; | ||||
| const BackgroundMenu = imports.ui.backgroundMenu; | ||||
| @@ -16,6 +11,7 @@ const DND = imports.ui.dnd; | ||||
| const Main = imports.ui.main; | ||||
| const Params = imports.misc.params; | ||||
| const Tweener = imports.ui.tweener; | ||||
| const Ripples = imports.ui.ripples; | ||||
|  | ||||
| var STARTUP_ANIMATION_TIME = 0.5; | ||||
| var KEYBOARD_ANIMATION_TIME = 0.15; | ||||
| @@ -151,12 +147,13 @@ var MonitorConstraint = GObject.registerClass({ | ||||
| }); | ||||
|  | ||||
| var Monitor = class Monitor { | ||||
|     constructor(index, geometry) { | ||||
|     constructor(index, geometry, geometry_scale) { | ||||
|         this.index = index; | ||||
|         this.x = geometry.x; | ||||
|         this.y = geometry.y; | ||||
|         this.width = geometry.width; | ||||
|         this.height = geometry.height; | ||||
|         this.geometry_scale = geometry_scale; | ||||
|     } | ||||
|  | ||||
|     get inFullscreen() { | ||||
| @@ -164,6 +161,19 @@ var Monitor = class Monitor { | ||||
|     } | ||||
| }; | ||||
|  | ||||
| const UiActor = GObject.registerClass( | ||||
| class UiActor extends St.Widget { | ||||
|     vfunc_get_preferred_width (forHeight) { | ||||
|         let width = global.stage.width; | ||||
|         return [width, width]; | ||||
|     } | ||||
|  | ||||
|     vfunc_get_preferred_height (forWidth) { | ||||
|         let height = global.stage.height; | ||||
|         return [height, height]; | ||||
|     } | ||||
| }); | ||||
|  | ||||
| const defaultParams = { | ||||
|     trackFullscreen: false, | ||||
|     affectsStruts: false, | ||||
| @@ -204,17 +214,20 @@ var LayoutManager = GObject.registerClass({ | ||||
|         global.stage.no_clear_hint = true; | ||||
|  | ||||
|         // Set up stage hierarchy to group all UI actors under one container. | ||||
|         this.uiGroup = new St.Widget({ name: 'uiGroup' }); | ||||
|         this.uiGroup = new UiActor({ name: 'uiGroup' }); | ||||
|         this.uiGroup.set_flags(Clutter.ActorFlags.NO_LAYOUT); | ||||
|         this.uiGroup.add_constraint(new Clutter.BindConstraint({ | ||||
|             source: global.stage, | ||||
|             coordinate: Clutter.BindCoordinate.ALL, | ||||
|         })); | ||||
|  | ||||
|         global.stage.add_child(this.uiGroup); | ||||
|  | ||||
|         global.stage.remove_actor(global.window_group); | ||||
|         this.uiGroup.add_actor(global.window_group); | ||||
|  | ||||
|         global.stage.add_child(this.uiGroup); | ||||
|         // Using addChrome() to add actors to uiGroup will position actors | ||||
|         // underneath the top_window_group. | ||||
|         // To insert actors at the top of uiGroup, we use addTopChrome() or | ||||
|         // add the actor directly using uiGroup.add_actor(). | ||||
|         global.stage.remove_actor(global.top_window_group); | ||||
|         this.uiGroup.add_actor(global.top_window_group); | ||||
|  | ||||
|         this.overviewGroup = new St.Widget({ name: 'overviewGroup', | ||||
|                                              visible: false, | ||||
| @@ -226,7 +239,7 @@ var LayoutManager = GObject.registerClass({ | ||||
|                                                  clip_to_allocation: true, | ||||
|                                                  layout_manager: new Clutter.BinLayout(), | ||||
|                                                }); | ||||
|         this.addChrome(this.screenShieldGroup); | ||||
|         this.addTopChrome(this.screenShieldGroup); | ||||
|  | ||||
|         this.panelBox = new St.BoxLayout({ name: 'panelBox', | ||||
|                                            vertical: true }); | ||||
| @@ -242,17 +255,14 @@ var LayoutManager = GObject.registerClass({ | ||||
|         this.keyboardBox = new St.BoxLayout({ name: 'keyboardBox', | ||||
|                                               reactive: true, | ||||
|                                               track_hover: true }); | ||||
|         this.addChrome(this.keyboardBox); | ||||
|         this.addTopChrome(this.keyboardBox); | ||||
|         this._keyboardHeightNotifyId = 0; | ||||
|  | ||||
|         // A dummy actor that tracks the mouse or text cursor, based on the | ||||
|         // position and size set in setDummyCursorGeometry. | ||||
|         this.dummyCursor = new St.Widget({ width: 0, height: 0, visible: false }); | ||||
|         this.dummyCursor = new St.Widget({ width: 0, height: 0, opacity: 0 }); | ||||
|         this.uiGroup.add_actor(this.dummyCursor); | ||||
|  | ||||
|         global.stage.remove_actor(global.top_window_group); | ||||
|         this.uiGroup.add_actor(global.top_window_group); | ||||
|  | ||||
|         let feedbackGroup = Meta.get_feedback_group_for_display(global.display); | ||||
|         global.stage.remove_actor(feedbackGroup); | ||||
|         this.uiGroup.add_actor(feedbackGroup); | ||||
| @@ -323,7 +333,9 @@ var LayoutManager = GObject.registerClass({ | ||||
|         this.monitors = []; | ||||
|         let nMonitors = display.get_n_monitors(); | ||||
|         for (let i = 0; i < nMonitors; i++) | ||||
|             this.monitors.push(new Monitor(i, display.get_monitor_geometry(i))); | ||||
|             this.monitors.push(new Monitor(i, | ||||
|                                            display.get_monitor_geometry(i), | ||||
|                                            display.get_monitor_scale(i))); | ||||
|  | ||||
|         if (nMonitors == 0) { | ||||
|             this.primaryIndex = this.bottomIndex = -1; | ||||
| @@ -795,6 +807,16 @@ var LayoutManager = GObject.registerClass({ | ||||
|         this._trackActor(actor, params); | ||||
|     } | ||||
|  | ||||
|     // addTopChrome: | ||||
|     // @actor: an actor to add to the chrome | ||||
|     // @params: (optional) additional params | ||||
|     // | ||||
|     // Like addChrome(), but adds @actor above all windows, including popups. | ||||
|     addTopChrome(actor, params) { | ||||
|         this.uiGroup.add_actor(actor); | ||||
|         this._trackActor(actor, params); | ||||
|     } | ||||
|  | ||||
|     // trackChrome: | ||||
|     // @actor: a descendant of the chrome to begin tracking | ||||
|     // @params: parameters describing how to track @actor | ||||
| @@ -1051,8 +1073,7 @@ var LayoutManager = GObject.registerClass({ | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (!Meta.is_wayland_compositor()) | ||||
|             global.set_stage_input_region(rects); | ||||
|         global.set_stage_input_region(rects); | ||||
|         this._isPopupWindowVisible = isPopupMenuVisible; | ||||
|  | ||||
|         let workspaceManager = global.workspace_manager; | ||||
| @@ -1097,14 +1118,15 @@ var HotCorner = class HotCorner { | ||||
|                                                     Shell.ActionMode.OVERVIEW); | ||||
|         this._pressureBarrier.connect('trigger', this._toggleOverview.bind(this)); | ||||
|  | ||||
|         // Cache the three ripples instead of dynamically creating and destroying them. | ||||
|         this._ripple1 = new St.BoxLayout({ style_class: 'ripple-box', opacity: 0, visible: false }); | ||||
|         this._ripple2 = new St.BoxLayout({ style_class: 'ripple-box', opacity: 0, visible: false }); | ||||
|         this._ripple3 = new St.BoxLayout({ style_class: 'ripple-box', opacity: 0, visible: false }); | ||||
|         let px = 0.0; | ||||
|         let py = 0.0; | ||||
|         if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) { | ||||
|             px = 1.0; | ||||
|             py = 0.0; | ||||
|         } | ||||
|  | ||||
|         layoutManager.uiGroup.add_actor(this._ripple1); | ||||
|         layoutManager.uiGroup.add_actor(this._ripple2); | ||||
|         layoutManager.uiGroup.add_actor(this._ripple3); | ||||
|         this._ripples = new Ripples.Ripples(px, py, 'ripple-box'); | ||||
|         this._ripples.addTo(layoutManager.uiGroup); | ||||
|     } | ||||
|  | ||||
|     setBarrierSize(size) { | ||||
| @@ -1186,53 +1208,12 @@ var HotCorner = class HotCorner { | ||||
|             this.actor.destroy(); | ||||
|     } | ||||
|  | ||||
|     _animRipple(ripple, delay, time, 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 | ||||
|         // or it looks unrealistic, but if the opacity of the ripple goes | ||||
|         // linearly to zero it fades away too quickly, so we use Tweener's | ||||
|         // 'onUpdate' to give a non-linear curve to the fade-away and make | ||||
|         // it more visible in the middle section. | ||||
|  | ||||
|         ripple._opacity = startOpacity; | ||||
|  | ||||
|         if (ripple.get_text_direction() == Clutter.TextDirection.RTL) | ||||
|             ripple.set_anchor_point_from_gravity(Clutter.Gravity.NORTH_EAST); | ||||
|  | ||||
|         ripple.visible = true; | ||||
|         ripple.opacity = 255 * Math.sqrt(startOpacity); | ||||
|         ripple.scale_x = ripple.scale_y = startScale; | ||||
|  | ||||
|         ripple.x = this._x; | ||||
|         ripple.y = this._y; | ||||
|  | ||||
|         Tweener.addTween(ripple, { _opacity: 0, | ||||
|                                    scale_x: finalScale, | ||||
|                                    scale_y: finalScale, | ||||
|                                    delay: delay, | ||||
|                                    time: time, | ||||
|                                    transition: 'linear', | ||||
|                                    onUpdate() { ripple.opacity = 255 * Math.sqrt(ripple._opacity); }, | ||||
|                                    onComplete() { ripple.visible = false; } }); | ||||
|     } | ||||
|  | ||||
|     _rippleAnimation() { | ||||
|         // Show three concentric ripples expanding outwards; the exact | ||||
|         // parameters were found by trial and error, so don't look | ||||
|         // for them to make perfect sense mathematically | ||||
|  | ||||
|         //                              delay  time  scale opacity => scale | ||||
|         this._animRipple(this._ripple1, 0.0,   0.83,  0.25,  1.0,     1.5); | ||||
|         this._animRipple(this._ripple2, 0.05,  1.0,   0.0,   0.7,     1.25); | ||||
|         this._animRipple(this._ripple3, 0.35,  1.0,   0.0,   0.3,     1); | ||||
|     } | ||||
|  | ||||
|     _toggleOverview() { | ||||
|         if (this._monitor.inFullscreen && !Main.overview.visible) | ||||
|             return; | ||||
|  | ||||
|         if (Main.overview.shouldToggleByCornerOrButton()) { | ||||
|             this._rippleAnimation(); | ||||
|             this._ripples.playAnimation(this._x, this._y); | ||||
|             Main.overview.toggle(); | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -1,11 +1,7 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const GObject = imports.gi.GObject; | ||||
| const Meta = imports.gi.Meta; | ||||
| const { Clutter, GObject, Shell, St } = imports.gi; | ||||
| const Signals = imports.signals; | ||||
| const St = imports.gi.St; | ||||
| const Shell = imports.gi.Shell; | ||||
|  | ||||
| const Params = imports.misc.params; | ||||
| const Tweener = imports.ui.tweener; | ||||
|   | ||||
							
								
								
									
										24
									
								
								js/ui/locatePointer.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,24 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const { Clutter, Gio, GLib, St } = imports.gi; | ||||
| const Ripples = imports.ui.ripples; | ||||
| const Main = imports.ui.main; | ||||
|  | ||||
| const LOCATE_POINTER_KEY = "locate-pointer"; | ||||
| 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); | ||||
|     } | ||||
|  | ||||
|     show() { | ||||
|         if (!this._settings.get_boolean("locate-pointer")) | ||||
|             return; | ||||
|  | ||||
|         let [x, y, mods] = global.get_pointer(); | ||||
|         this._ripples.playAnimation(x, y); | ||||
|     } | ||||
| }; | ||||