Architecture rewrite and new features
This commit is contained in:
+1
-1
@@ -1,4 +1,4 @@
|
||||
build
|
||||
node_modules
|
||||
|
||||
tests/_variants.js
|
||||
tests/**/_variants.js
|
||||
|
||||
@@ -34,6 +34,9 @@ before_script:
|
||||
test:
|
||||
stage: test
|
||||
rules:
|
||||
- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"'
|
||||
- if: '$CI_COMMIT_TAG'
|
||||
- if: '$CI_COMMIT_BRANCH == "master"'
|
||||
- changes:
|
||||
- src/
|
||||
script:
|
||||
|
||||
@@ -2,10 +2,7 @@
|
||||
|
||||
- Distribution (name and version):
|
||||
- GNOME Shell version:
|
||||
- I installed the extension:
|
||||
- [ ] Manually from the repository
|
||||
- [x] From extensions.gnome.org
|
||||
- [ ] From my distribution package manager (or it was preinstalled)
|
||||
- I installed the extension: <!-- Manually? From extensions.gnome.org? From my distribution? -->
|
||||
|
||||
# My problem
|
||||
|
||||
@@ -17,4 +14,5 @@
|
||||
1.
|
||||
|
||||
|
||||
<!-- Don't remove this line -->
|
||||
/label ~"bug::not confirmed"
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<!-- Describe as precisely as possible the feature you want to be added: how should it work? What does it do? -->
|
||||
|
||||
|
||||
<!-- Don't remove this line -->
|
||||
/label ~"feature::request"
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
|
||||
<!-- Don't remove this line -->
|
||||
/label ~discussion
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
- Theme name:
|
||||
- Theme repository or download link:
|
||||
|
||||
/label ~theme
|
||||
<!-- Don't remove this line -->
|
||||
/label ~"theme::request"
|
||||
|
||||
@@ -29,8 +29,10 @@ build: build-clean
|
||||
gnome-extensions pack \
|
||||
--extra-source=../LICENSE \
|
||||
--extra-source=./config.js \
|
||||
--extra-source=./convenience.js \
|
||||
--extra-source=./utils.js \
|
||||
--extra-source=./modules/ \
|
||||
--extra-source=./preferences/ \
|
||||
--extra-source=./schemas/ \
|
||||
--podir=./po/ \
|
||||
--gettext-domain=$(UUID) \
|
||||
@@ -54,7 +56,8 @@ clean: build-clean deps-clean
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
cat ./src/modules/Variants.js ./tests/_variants.js.template > ./tests/_variants.js
|
||||
cat ./src/modules/GtkVariants.js ./tests/gtk_themes/_variants.js.template > ./tests/gtk_themes/_variants.js
|
||||
cat ./src/modules/ShellVariants.js ./tests/shell_themes/_variants.js.template > ./tests/shell_themes/_variants.js
|
||||
npm run test
|
||||
|
||||
.PHONY: deps-install
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
|
||||

|
||||
|
||||
Automatically toggle between your light and dark GTK theme variants.
|
||||
Automatically toggle your light and dark GTK and GNOME Shell theme variants, switch backgrounds and launch custom commands at sunset and sunrise.
|
||||
|
||||
Supports Night Light, Location Services and manual schedule.
|
||||
|
||||
_Do you need to change your GNOME shell theme as well? Try [Night Shell Switcher](https://gitlab.com/rmnvgr/nightshellswitcher-gnome-shell-extension/)!_
|
||||
|
||||
## Theme compatibility
|
||||
|
||||
These themes have been tested and work:
|
||||
These themes have been tested and work out of the box without any configuration. Other themes might work as well, let me know if there is a specific theme you'd like supported! And you can also manually set your day and night variants.
|
||||
|
||||
### GTK themes
|
||||
|
||||
- Adapta
|
||||
- Adwaita (GNOME & Fedora default)
|
||||
@@ -37,7 +37,25 @@ These themes have been tested and work:
|
||||
- Vimix
|
||||
- Yaru (Ubuntu default)
|
||||
|
||||
Other themes with a dark variant might work as well, let me know if there is a specific theme you'd like supported! And you can also manually set your day and night theme.
|
||||
### Shell themes
|
||||
|
||||
- Adapta
|
||||
- Arc
|
||||
- Canta
|
||||
- ChromeOS
|
||||
- Flat-Remix
|
||||
- Kimi
|
||||
- Layan
|
||||
- Matcha (Manjaro default)
|
||||
- Materia
|
||||
- Mojave
|
||||
- Orchis
|
||||
- Plata (Solus default)
|
||||
- Pop (Pop!_OS default)
|
||||
- Qogir
|
||||
- Simply Circles
|
||||
- Teja
|
||||
- Vimix
|
||||
|
||||
## Graphical installation
|
||||
|
||||
|
||||
+2
-31
@@ -1,34 +1,5 @@
|
||||
Night mode for GNOME apps! Automatically toggle between your light and dark GTK theme variants.
|
||||
Night mode for GNOME! Automatically toggle your light and dark GTK and GNOME Shell theme variants, switch backgrounds and launch custom commands at sunset and sunrise.
|
||||
|
||||
Supports Night Light, Location Services and manual schedule.
|
||||
|
||||
These themes have been tested and work:
|
||||
- Adapta
|
||||
- Adwaita (GNOME & Fedora default)
|
||||
- Arc
|
||||
- Cabinet
|
||||
- Canta
|
||||
- ChromeOS
|
||||
- Flat-Remix-GTK
|
||||
- HighContrast
|
||||
- Kimi
|
||||
- Layan
|
||||
- Macwaita
|
||||
- Matcha (Manjaro default)
|
||||
- Materia
|
||||
- Mojave
|
||||
- Nextwaita
|
||||
- Orchis
|
||||
- Plata (Solus default)
|
||||
- Pop (Pop!_OS default)
|
||||
- Prof-Gnome-3
|
||||
- Qogir
|
||||
- Simply Circles
|
||||
- Teja
|
||||
- Vimix
|
||||
- Yaru (Ubuntu default)
|
||||
|
||||
Other themes with a dark variant might work as well, let me know if there is a specific theme you'd like supported! And you can also manually set your day and night theme.
|
||||
|
||||
If you need to change your GNOME shell theme as well, try Night Shell Switcher:
|
||||
https://extensions.gnome.org/extension/2356/night-shell-switcher/
|
||||
It works out of the box with numerous themes (see the list on the repository), and you can manually choose the variants you want.
|
||||
|
||||
Generated
+277
-157
@@ -11,14 +11,20 @@
|
||||
"@babel/highlight": "^7.8.3"
|
||||
}
|
||||
},
|
||||
"@babel/helper-validator-identifier": {
|
||||
"version": "7.9.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz",
|
||||
"integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==",
|
||||
"dev": true
|
||||
},
|
||||
"@babel/highlight": {
|
||||
"version": "7.8.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz",
|
||||
"integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==",
|
||||
"version": "7.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz",
|
||||
"integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/helper-validator-identifier": "^7.9.0",
|
||||
"chalk": "^2.0.0",
|
||||
"esutils": "^2.0.2",
|
||||
"js-tokens": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -162,9 +168,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "13.7.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-13.7.1.tgz",
|
||||
"integrity": "sha512-Zq8gcQGmn4txQEJeiXo/KiLpon8TzAl0kmKH4zdWctPj05nWwp1ClMdAVEloqrQKfaC48PNLdgN/aVaLqUrluA==",
|
||||
"version": "14.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.5.tgz",
|
||||
"integrity": "sha512-90hiq6/VqtQgX8Sp0EzeIsv3r+ellbGj4URKj5j30tLlZvRUpnAe9YbYnjl3pJM93GyXU0tghHhvXHq+5rnCKA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/normalize-package-data": {
|
||||
@@ -173,6 +179,18 @@
|
||||
"integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==",
|
||||
"dev": true
|
||||
},
|
||||
"acorn": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.2.0.tgz",
|
||||
"integrity": "sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==",
|
||||
"dev": true
|
||||
},
|
||||
"acorn-walk": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.1.1.tgz",
|
||||
"integrity": "sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ==",
|
||||
"dev": true
|
||||
},
|
||||
"aggregate-error": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz",
|
||||
@@ -298,20 +316,23 @@
|
||||
"dev": true
|
||||
},
|
||||
"ava": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ava/-/ava-3.3.0.tgz",
|
||||
"integrity": "sha512-RaH6jpiS/9ZdIuP1QkyhHvhprk0h38LVdkkpL7Mw25XR3z/6w1N3Nq9O2qm3awnw38CfIztmipzkv+671nWH2w==",
|
||||
"version": "3.8.2",
|
||||
"resolved": "https://registry.npmjs.org/ava/-/ava-3.8.2.tgz",
|
||||
"integrity": "sha512-sph3oUsVTGsq4qbgeWys03QKCmXjkZUO3oPnFWXEW6g1SReCY9vuONGghMgw1G6VOzkg1k+niqJsOzwfO8h9Ng==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@concordance/react": "^2.0.0",
|
||||
"acorn": "^7.1.1",
|
||||
"acorn-walk": "^7.1.1",
|
||||
"ansi-styles": "^4.2.1",
|
||||
"arrgv": "^1.0.2",
|
||||
"arrify": "^2.0.1",
|
||||
"chalk": "^3.0.0",
|
||||
"chokidar": "^3.3.1",
|
||||
"callsites": "^3.1.0",
|
||||
"chalk": "^4.0.0",
|
||||
"chokidar": "^3.4.0",
|
||||
"chunkd": "^2.0.1",
|
||||
"ci-info": "^2.0.0",
|
||||
"ci-parallel-vars": "^1.0.0",
|
||||
"clean-stack": "^2.2.0",
|
||||
"clean-yaml-object": "^0.1.0",
|
||||
"cli-cursor": "^3.1.0",
|
||||
"cli-truncate": "^2.1.0",
|
||||
@@ -322,39 +343,39 @@
|
||||
"currently-unhandled": "^0.4.1",
|
||||
"debug": "^4.1.1",
|
||||
"del": "^5.1.0",
|
||||
"emittery": "^0.5.1",
|
||||
"emittery": "^0.6.0",
|
||||
"equal-length": "^1.0.0",
|
||||
"figures": "^3.1.0",
|
||||
"figures": "^3.2.0",
|
||||
"globby": "^11.0.0",
|
||||
"ignore-by-default": "^1.0.0",
|
||||
"import-local": "^3.0.2",
|
||||
"indent-string": "^4.0.0",
|
||||
"is-ci": "^2.0.0",
|
||||
"is-error": "^2.2.2",
|
||||
"is-plain-object": "^3.0.0",
|
||||
"is-promise": "^2.1.0",
|
||||
"is-promise": "^4.0.0",
|
||||
"lodash": "^4.17.15",
|
||||
"matcher": "^2.1.0",
|
||||
"matcher": "^3.0.0",
|
||||
"md5-hex": "^3.0.1",
|
||||
"mem": "^6.1.0",
|
||||
"ms": "^2.1.2",
|
||||
"ora": "^4.0.3",
|
||||
"p-map": "^3.0.0",
|
||||
"picomatch": "^2.2.1",
|
||||
"ora": "^4.0.4",
|
||||
"p-map": "^4.0.0",
|
||||
"picomatch": "^2.2.2",
|
||||
"pkg-conf": "^3.1.0",
|
||||
"plur": "^3.1.1",
|
||||
"pretty-ms": "^5.1.0",
|
||||
"plur": "^4.0.0",
|
||||
"pretty-ms": "^7.0.0",
|
||||
"read-pkg": "^5.2.0",
|
||||
"resolve-cwd": "^3.0.0",
|
||||
"slash": "^3.0.0",
|
||||
"source-map-support": "^0.5.16",
|
||||
"stack-utils": "^2.0.1",
|
||||
"source-map-support": "^0.5.19",
|
||||
"stack-utils": "^2.0.2",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"supertap": "^1.0.0",
|
||||
"temp-dir": "^2.0.0",
|
||||
"trim-off-newlines": "^1.0.1",
|
||||
"update-notifier": "^4.0.0",
|
||||
"write-file-atomic": "^3.0.1",
|
||||
"yargs": "^15.1.0"
|
||||
"update-notifier": "^4.1.0",
|
||||
"write-file-atomic": "^3.0.3",
|
||||
"yargs": "^15.3.1"
|
||||
}
|
||||
},
|
||||
"balanced-match": {
|
||||
@@ -370,9 +391,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"blueimp-md5": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.12.0.tgz",
|
||||
"integrity": "sha512-zo+HIdIhzojv6F1siQPqPFROyVy7C50KzHv/k/Iz+BtvtVzSHXiMXOpq2wCfNkeBqdCv+V8XOV96tsEt2W/3rQ==",
|
||||
"version": "2.16.0",
|
||||
"resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.16.0.tgz",
|
||||
"integrity": "sha512-j4nzWIqEFpLSbdhUApHRGDwfXbV8ALhqOn+FY5L6XBdKPAXU9BpGgFSbDsgqogfqPPR9R2WooseWCsfhfEC6uQ==",
|
||||
"dev": true
|
||||
},
|
||||
"boxen": {
|
||||
@@ -391,6 +412,16 @@
|
||||
"widest-line": "^3.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"chalk": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
|
||||
"integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
}
|
||||
},
|
||||
"type-fest": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
|
||||
@@ -456,6 +487,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"callsites": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
|
||||
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
|
||||
"dev": true
|
||||
},
|
||||
"camelcase": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
|
||||
@@ -463,9 +500,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"chalk": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
|
||||
"integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz",
|
||||
"integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
@@ -473,9 +510,9 @@
|
||||
}
|
||||
},
|
||||
"chokidar": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.1.tgz",
|
||||
"integrity": "sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==",
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz",
|
||||
"integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"anymatch": "~3.1.1",
|
||||
@@ -485,7 +522,7 @@
|
||||
"is-binary-path": "~2.1.0",
|
||||
"is-glob": "~4.0.1",
|
||||
"normalize-path": "~3.0.0",
|
||||
"readdirp": "~3.3.0"
|
||||
"readdirp": "~3.4.0"
|
||||
}
|
||||
},
|
||||
"chunkd": {
|
||||
@@ -534,9 +571,9 @@
|
||||
}
|
||||
},
|
||||
"cli-spinners": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.2.0.tgz",
|
||||
"integrity": "sha512-tgU3fKwzYjiLEQgPMD9Jt+JjHVL9kW93FiIMX/l7rivvOD4/LL0Mf7gda3+4U2KJBloybwgj5KEoQgGRioMiKQ==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.3.0.tgz",
|
||||
"integrity": "sha512-Xs2Hf2nzrvJMFKimOR7YR0QwZ8fc0u98kdtwN1eNAZzNQgH3vK2pXzff6GJtKh7S5hoJ87ECiAiZFS2fb5Ii2w==",
|
||||
"dev": true
|
||||
},
|
||||
"cli-truncate": {
|
||||
@@ -770,6 +807,15 @@
|
||||
"merge2": "^1.2.3",
|
||||
"slash": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"p-map": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz",
|
||||
"integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"aggregate-error": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -798,9 +844,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"emittery": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/emittery/-/emittery-0.5.1.tgz",
|
||||
"integrity": "sha512-sYZXNHH9PhTfs98ROEFVC3bLiR8KSqXQsEHIwZ9J6H0RaQObC3JYq4G8IvDd0b45/LxfGKYBpmaUN4LiKytaNw==",
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/emittery/-/emittery-0.6.0.tgz",
|
||||
"integrity": "sha512-6EMRGr9KzYWp8DzHFZsKVZBsMO6QhAeHMeHND8rhyBNCHKMLpgW9tZv40bwN3rAIKRS5CxcK8oLRKUJSB9h7yQ==",
|
||||
"dev": true
|
||||
},
|
||||
"emoji-regex": {
|
||||
@@ -833,6 +879,12 @@
|
||||
"is-arrayish": "^0.2.1"
|
||||
}
|
||||
},
|
||||
"escape-goat": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz",
|
||||
"integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==",
|
||||
"dev": true
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
@@ -858,31 +910,32 @@
|
||||
"dev": true
|
||||
},
|
||||
"fast-glob": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.1.1.tgz",
|
||||
"integrity": "sha512-nTCREpBY8w8r+boyFYAx21iL6faSsQynliPHM4Uf56SbkyohCNxpVPEH9xrF5TXKy+IsjkPUHDKiUkzBVRXn9g==",
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.2.tgz",
|
||||
"integrity": "sha512-UDV82o4uQyljznxwMxyVRJgZZt3O5wENYojjzbaGEGZgeOxkLFf+V4cnUD+krzb2F72E18RhamkMZ7AdeggF7A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@nodelib/fs.stat": "^2.0.2",
|
||||
"@nodelib/fs.walk": "^1.2.3",
|
||||
"glob-parent": "^5.1.0",
|
||||
"merge2": "^1.3.0",
|
||||
"micromatch": "^4.0.2"
|
||||
"micromatch": "^4.0.2",
|
||||
"picomatch": "^2.2.1"
|
||||
}
|
||||
},
|
||||
"fastq": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.6.0.tgz",
|
||||
"integrity": "sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==",
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz",
|
||||
"integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"reusify": "^1.0.0"
|
||||
"reusify": "^1.0.4"
|
||||
}
|
||||
},
|
||||
"figures": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/figures/-/figures-3.1.0.tgz",
|
||||
"integrity": "sha512-ravh8VRXqHuMvZt/d8GblBeqDMkdJMBdv/2KntFH+ra5MXkO7nxNKpzQ3n6QD/2da1kH0aWmNISdvhM7gl2gVg==",
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
|
||||
"integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"escape-string-regexp": "^1.0.5"
|
||||
@@ -914,9 +967,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"fsevents": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz",
|
||||
"integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==",
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
|
||||
"integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
@@ -950,9 +1003,9 @@
|
||||
}
|
||||
},
|
||||
"glob-parent": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz",
|
||||
"integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==",
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
|
||||
"integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-glob": "^4.0.1"
|
||||
@@ -1001,9 +1054,9 @@
|
||||
}
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
|
||||
"integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==",
|
||||
"version": "4.2.4",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
|
||||
"integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
|
||||
"dev": true
|
||||
},
|
||||
"has-flag": {
|
||||
@@ -1019,21 +1072,21 @@
|
||||
"dev": true
|
||||
},
|
||||
"hosted-git-info": {
|
||||
"version": "2.8.5",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz",
|
||||
"integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==",
|
||||
"version": "2.8.8",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
|
||||
"integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==",
|
||||
"dev": true
|
||||
},
|
||||
"http-cache-semantics": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz",
|
||||
"integrity": "sha512-Z2EICWNJou7Tr9Bd2M2UqDJq3A9F2ePG9w3lIpjoyuSyXFP9QbniJVu3XQYytuw5ebmG7dXSXO9PgAjJG8DDKA==",
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
|
||||
"integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
|
||||
"dev": true
|
||||
},
|
||||
"ignore": {
|
||||
"version": "5.1.4",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz",
|
||||
"integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==",
|
||||
"version": "5.1.6",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.6.tgz",
|
||||
"integrity": "sha512-cgXgkypZBcCnOgSihyeqbo6gjIaIyDqPQB7Ra4vhE9m6kigdGoQDMHjviFhRZo3IMlRy6yElosoviMs5YxZXUA==",
|
||||
"dev": true
|
||||
},
|
||||
"ignore-by-default": {
|
||||
@@ -1093,9 +1146,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"irregular-plurals": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-2.0.0.tgz",
|
||||
"integrity": "sha512-Y75zBYLkh0lJ9qxeHlMjQ7bSbyiSqNW/UOPWDmzC7cXskL1hekSITh1Oc6JV0XCWWZ9DE8VYSB71xocLk3gmGw==",
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.2.0.tgz",
|
||||
"integrity": "sha512-YqTdPLfwP7YFN0SsD3QUVCkm9ZG2VzOXv3DOrw5G5mkMbVwptTwVcFv7/C0vOpBmgTxAeTG19XpUs1E522LW9Q==",
|
||||
"dev": true
|
||||
},
|
||||
"is-arrayish": {
|
||||
@@ -1150,9 +1203,9 @@
|
||||
}
|
||||
},
|
||||
"is-installed-globally": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.1.tgz",
|
||||
"integrity": "sha512-oiEcGoQbGc+3/iijAijrK2qFpkNoNjsHOm/5V5iaeydyrS/hnwaRCEgH5cpW0P3T1lSjV5piB7S5b5lEugNLhg==",
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz",
|
||||
"integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"global-dirs": "^2.0.1",
|
||||
@@ -1205,9 +1258,9 @@
|
||||
}
|
||||
},
|
||||
"is-promise": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
|
||||
"integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
|
||||
"integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
|
||||
"dev": true
|
||||
},
|
||||
"is-typedarray": {
|
||||
@@ -1241,9 +1294,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"js-yaml": {
|
||||
"version": "3.13.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
|
||||
"integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
|
||||
"version": "3.14.0",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz",
|
||||
"integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"argparse": "^1.0.7",
|
||||
@@ -1406,9 +1459,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"make-dir": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.2.tgz",
|
||||
"integrity": "sha512-rYKABKutXa6vXTXhoV18cBE7PaewPXHe/Bdq4v+ZLMhxbWApkFFplT0LcbMW+6BbjnQXzZ/sAvSE/JdguApG5w==",
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
|
||||
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"semver": "^6.0.0"
|
||||
@@ -1422,19 +1475,28 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"matcher": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/matcher/-/matcher-2.1.0.tgz",
|
||||
"integrity": "sha512-o+nZr+vtJtgPNklyeUKkkH42OsK8WAfdgaJE2FNxcjLPg+5QbeEoT6vRj8Xq/iv18JlQ9cmKsEu0b94ixWf1YQ==",
|
||||
"map-age-cleaner": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz",
|
||||
"integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"escape-string-regexp": "^2.0.0"
|
||||
"p-defer": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"matcher": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz",
|
||||
"integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"escape-string-regexp": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"escape-string-regexp": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
|
||||
"integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
@@ -1454,6 +1516,24 @@
|
||||
"integrity": "sha1-givM1l4RfFFPqxdrJZRdVBAKA8M=",
|
||||
"dev": true
|
||||
},
|
||||
"mem": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mem/-/mem-6.1.0.tgz",
|
||||
"integrity": "sha512-RlbnLQgRHk5lwqTtpEkBTQ2ll/CG/iB+J4Hy2Wh97PjgZgXgWJWrFF+XXujh3UUVLvR4OOTgZzcWMMwnehlEUg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"map-age-cleaner": "^0.1.3",
|
||||
"mimic-fn": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"mimic-fn": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.0.0.tgz",
|
||||
"integrity": "sha512-PiVO95TKvhiwgSwg1IdLYlCTdul38yZxZMIcnDSFIBUm4BNZha2qpQ4GpJ++15bHoKDtrW2D69lMfFwdFYtNZQ==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"merge2": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz",
|
||||
@@ -1492,9 +1572,9 @@
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
||||
"dev": true
|
||||
},
|
||||
"ms": {
|
||||
@@ -1552,9 +1632,9 @@
|
||||
}
|
||||
},
|
||||
"ora": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/ora/-/ora-4.0.3.tgz",
|
||||
"integrity": "sha512-fnDebVFyz309A73cqCipVL1fBZewq4vwgSHfxh43vVy31mbyoQ8sCH3Oeaog/owYOs/lLlGVPCISQonTneg6Pg==",
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/ora/-/ora-4.0.4.tgz",
|
||||
"integrity": "sha512-77iGeVU1cIdRhgFzCK8aw1fbtT1B/iZAvWjS+l/o1x0RShMgxHUZaD2yDpWsNCPwXg9z1ZA78Kbdvr8kBmG/Ww==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "^3.0.0",
|
||||
@@ -1565,6 +1645,18 @@
|
||||
"mute-stream": "0.0.8",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"wcwidth": "^1.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"chalk": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
|
||||
"integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"p-cancelable": {
|
||||
@@ -1573,10 +1665,16 @@
|
||||
"integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==",
|
||||
"dev": true
|
||||
},
|
||||
"p-defer": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
|
||||
"integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=",
|
||||
"dev": true
|
||||
},
|
||||
"p-limit": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz",
|
||||
"integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
|
||||
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"p-try": "^2.0.0"
|
||||
@@ -1592,9 +1690,9 @@
|
||||
}
|
||||
},
|
||||
"p-map": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz",
|
||||
"integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==",
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
|
||||
"integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"aggregate-error": "^3.0.0"
|
||||
@@ -1667,9 +1765,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"picomatch": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz",
|
||||
"integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==",
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
|
||||
"integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
|
||||
"dev": true
|
||||
},
|
||||
"pify": {
|
||||
@@ -1734,12 +1832,12 @@
|
||||
}
|
||||
},
|
||||
"plur": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/plur/-/plur-3.1.1.tgz",
|
||||
"integrity": "sha512-t1Ax8KUvV3FFII8ltczPn2tJdjqbd1sIzu6t4JL7nQ3EyeL/lTrj5PWKb06ic5/6XYDr65rQ4uzQEGN70/6X5w==",
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/plur/-/plur-4.0.0.tgz",
|
||||
"integrity": "sha512-4UGewrYgqDFw9vV6zNV+ADmPAUAfJPKtGvb/VdpQAx25X5f3xXdGdyOEVFwkl8Hl/tl7+xbeHqSEM+D5/TirUg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"irregular-plurals": "^2.0.0"
|
||||
"irregular-plurals": "^3.2.0"
|
||||
}
|
||||
},
|
||||
"prepend-http": {
|
||||
@@ -1749,9 +1847,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"pretty-ms": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-5.1.0.tgz",
|
||||
"integrity": "sha512-4gaK1skD2gwscCfkswYQRmddUb2GJZtzDGRjHWadVHtK/DIKFufa12MvES6/xu1tVbUYeia5bmLcwJtZJQUqnw==",
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.0.tgz",
|
||||
"integrity": "sha512-J3aPWiC5e9ZeZFuSeBraGxSkGMOvulSWsxDByOcbD1Pr75YL3LSNIKIb52WXbCLE1sS5s4inBBbryjF4Y05Ceg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"parse-ms": "^2.1.0"
|
||||
@@ -1767,6 +1865,15 @@
|
||||
"once": "^1.3.1"
|
||||
}
|
||||
},
|
||||
"pupa": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pupa/-/pupa-2.0.1.tgz",
|
||||
"integrity": "sha512-hEJH0s8PXLY/cdXh66tNEQGndDrIKNqNC5xmrysZy3i5C3oEoLna7YAOad+7u125+zH1HNXUmGEkrhb3c2VriA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"escape-goat": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"rc": {
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
|
||||
@@ -1812,12 +1919,12 @@
|
||||
}
|
||||
},
|
||||
"readdirp": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.3.0.tgz",
|
||||
"integrity": "sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ==",
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz",
|
||||
"integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"picomatch": "^2.0.7"
|
||||
"picomatch": "^2.2.1"
|
||||
}
|
||||
},
|
||||
"registry-auth-token": {
|
||||
@@ -1851,9 +1958,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.15.1",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz",
|
||||
"integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==",
|
||||
"version": "1.17.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
|
||||
"integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"path-parse": "^1.0.6"
|
||||
@@ -1956,9 +2063,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"signal-exit": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
|
||||
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
|
||||
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
|
||||
"dev": true
|
||||
},
|
||||
"slash": {
|
||||
@@ -1985,9 +2092,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"source-map-support": {
|
||||
"version": "0.5.16",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz",
|
||||
"integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==",
|
||||
"version": "0.5.19",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
|
||||
"integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"buffer-from": "^1.0.0",
|
||||
@@ -1995,9 +2102,9 @@
|
||||
}
|
||||
},
|
||||
"spdx-correct": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
|
||||
"integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==",
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
|
||||
"integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"spdx-expression-parse": "^3.0.0",
|
||||
@@ -2005,15 +2112,15 @@
|
||||
}
|
||||
},
|
||||
"spdx-exceptions": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz",
|
||||
"integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
|
||||
"integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
|
||||
"dev": true
|
||||
},
|
||||
"spdx-expression-parse": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
|
||||
"integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
|
||||
"integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"spdx-exceptions": "^2.1.0",
|
||||
@@ -2033,9 +2140,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"stack-utils": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.1.tgz",
|
||||
"integrity": "sha512-BvBTnHGm8boe+HiJFqP19ywEsGlfQAKqW78pbfvUuzCbUuxPPUyLrH5dYFY+Xn9IpLY3b5ZmMcl8jAqXB4wddg==",
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz",
|
||||
"integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"escape-string-regexp": "^2.0.0"
|
||||
@@ -2196,14 +2303,14 @@
|
||||
}
|
||||
},
|
||||
"update-notifier": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.0.0.tgz",
|
||||
"integrity": "sha512-p9zf71hWt5GVXM4iEBujpUgx8mK9AWiCCapEJm/O1z5ntCim83Z1ATqzZFBHFYqx03laMqv8LiDgs/7ikXjf/g==",
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.0.tgz",
|
||||
"integrity": "sha512-w3doE1qtI0/ZmgeoDoARmI5fjDoT93IfKgEGqm26dGUOh8oNpaSTsGNdYRN/SjOuo10jcJGwkEL3mroKzktkew==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"boxen": "^4.2.0",
|
||||
"chalk": "^3.0.0",
|
||||
"configstore": "^5.0.0",
|
||||
"configstore": "^5.0.1",
|
||||
"has-yarn": "^2.1.0",
|
||||
"import-lazy": "^2.1.0",
|
||||
"is-ci": "^2.0.0",
|
||||
@@ -2211,8 +2318,21 @@
|
||||
"is-npm": "^4.0.0",
|
||||
"is-yarn-global": "^0.3.0",
|
||||
"latest-version": "^5.0.0",
|
||||
"pupa": "^2.0.1",
|
||||
"semver-diff": "^3.1.1",
|
||||
"xdg-basedir": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"chalk": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
|
||||
"integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"url-parse-lax": {
|
||||
@@ -2282,9 +2402,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"write-file-atomic": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.1.tgz",
|
||||
"integrity": "sha512-JPStrIyyVJ6oCSz/691fAjFtefZ6q+fP6tm+OS4Qw6o+TGQxNp1ziY2PgS+X/m0V8OWhZiO/m4xSj+Pr4RrZvw==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz",
|
||||
"integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"imurmurhash": "^0.1.4",
|
||||
@@ -2306,9 +2426,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"yargs": {
|
||||
"version": "15.1.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.1.0.tgz",
|
||||
"integrity": "sha512-T39FNN1b6hCW4SOIk1XyTOWxtXdcen0t+XYrysQmChzSipvhBO8Bj0nK1ozAasdk24dNWuMZvr4k24nz+8HHLg==",
|
||||
"version": "15.3.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz",
|
||||
"integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cliui": "^6.0.0",
|
||||
@@ -2321,13 +2441,13 @@
|
||||
"string-width": "^4.2.0",
|
||||
"which-module": "^2.0.0",
|
||||
"y18n": "^4.0.0",
|
||||
"yargs-parser": "^16.1.0"
|
||||
"yargs-parser": "^18.1.1"
|
||||
}
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "16.1.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-16.1.0.tgz",
|
||||
"integrity": "sha512-H/V41UNZQPkUMIT5h5hiwg4QKIY1RPvoBV4XcjUbRM8Bk2oKqqyZ0DIEbTFZB0XjbtSPG8SAa/0DxCQmiRgzKg==",
|
||||
"version": "18.1.3",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
|
||||
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"camelcase": "^5.0.0",
|
||||
|
||||
+1
-1
@@ -8,6 +8,6 @@
|
||||
"test": "ava"
|
||||
},
|
||||
"devDependencies": {
|
||||
"ava": "^3.3.0"
|
||||
"ava": "^3.8.2"
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 425 KiB After Width: | Height: | Size: 435 KiB |
@@ -16,68 +16,4 @@ You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
var THEME_GSETTINGS_SCHEMA = 'org.gnome.desktop.interface';
|
||||
var THEME_GSETTINGS_PROPERTY = 'gtk-theme';
|
||||
|
||||
var NIGHTLIGHT_GSETTINGS_SCHEMA = 'org.gnome.settings-daemon.plugins.color';
|
||||
var NIGHTLIGHT_GSETTINGS_PROPERTY = 'night-light-enabled';
|
||||
|
||||
var LOCATION_GSETTINGS_SCHEMA = 'org.gnome.system.location';
|
||||
var LOCATION_GSETTINGS_PROPERTY = 'enabled';
|
||||
|
||||
// GeoClue2 interfaces from https://gitlab.freedesktop.org/geoclue/geoclue/
|
||||
var GEOCLUE_MANAGER_INTERFACE = `
|
||||
<node>
|
||||
<interface name="org.freedesktop.GeoClue2.Manager">
|
||||
<property name="InUse" type="b" access="read"/>
|
||||
<property name="AvailableAccuracyLevel" type="u" access="read"/>
|
||||
<method name="GetClient">
|
||||
<arg name="client" type="o" direction="out"/>
|
||||
</method>
|
||||
<method name="CreateClient">
|
||||
<arg name="client" type="o" direction="out"/>
|
||||
</method>
|
||||
<method name="DeleteClient">
|
||||
<arg name="client" type="o" direction="in"/>
|
||||
</method>
|
||||
<method name="AddAgent">
|
||||
<arg name="id" type="s" direction="in"/>
|
||||
</method>
|
||||
</interface>
|
||||
</node>`;
|
||||
var GEOCLUE_CLIENT_INTERFACE = `
|
||||
<node>
|
||||
<interface name="org.freedesktop.GeoClue2.Client">
|
||||
<property name="Location" type="o" access="read"/>
|
||||
<property name="DistanceThreshold" type="u" access="readwrite">
|
||||
<annotation name="org.freedesktop.Accounts.DefaultValue" value="0"/>
|
||||
</property>
|
||||
<property name="TimeThreshold" type="u" access="readwrite">
|
||||
<annotation name="org.freedesktop.Accounts.DefaultValue" value="0"/>
|
||||
</property>
|
||||
<property name="DesktopId" type="s" access="readwrite"/>
|
||||
<property name="RequestedAccuracyLevel" type="u" access="readwrite"/>
|
||||
<property name="Active" type="b" access="read"/>
|
||||
<method name="Start"/>
|
||||
<method name="Stop"/>
|
||||
<signal name="LocationUpdated">
|
||||
<arg name="old" type="o"/>
|
||||
<arg name="new" type="o"/>
|
||||
</signal>
|
||||
</interface>
|
||||
</node>`;
|
||||
var GEOCLUE_LOCATION_INTERFACE = `
|
||||
<node>
|
||||
<interface name="org.freedesktop.GeoClue2.Location">
|
||||
<property name="Latitude" type="d" access="read"/>
|
||||
<property name="Longitude" type="d" access="read"/>
|
||||
<property name="Accuracy" type="d" access="read"/>
|
||||
<property name="Altitude" type="d" access="read"/>
|
||||
<property name="Speed" type="d" access="read"/>
|
||||
<property name="Heading" type="d" access="read"/>
|
||||
<property name="Description" type="s" access="read"/>
|
||||
<property name="Timestamp" type="(tt)" access="read"/>
|
||||
</interface>
|
||||
</node>`;
|
||||
|
||||
var debug = false;
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
Copyright (c) 2011-2012, Giovanni Campagna <scampa.giovanni@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the GNOME nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
const Gettext = imports.gettext;
|
||||
const Gio = imports.gi.Gio;
|
||||
|
||||
const Config = imports.misc.config;
|
||||
const ExtensionUtils = imports.misc.extensionUtils;
|
||||
|
||||
/**
|
||||
* 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 = ExtensionUtils.getCurrentExtension();
|
||||
|
||||
domain = domain || extension.metadata['gettext-domain'];
|
||||
|
||||
// check if this extension was built with "make zip-file", and thus
|
||||
// has the locale files in a subfolder
|
||||
// otherwise assume that extension has been installed in the
|
||||
// same prefix as gnome-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 return a GSettings schema for @schema, using schema files
|
||||
* in extensionsdir/schemas. If @schema is not provided, it is taken from
|
||||
* metadata['settings-schema'].
|
||||
*/
|
||||
function getSettings(schema) {
|
||||
let extension = ExtensionUtils.getCurrentExtension();
|
||||
|
||||
schema = schema || extension.metadata['settings-schema'];
|
||||
|
||||
const GioSSS = Gio.SettingsSchemaSource;
|
||||
|
||||
// check if this extension was built with "make zip-file", and thus
|
||||
// has the schema files in a subfolder
|
||||
// otherwise assume that extension has been installed in the
|
||||
// same prefix as gnome-shell (and therefore schemas are available
|
||||
// in the standard folders)
|
||||
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 });
|
||||
}
|
||||
+86
-3
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2019, 2020 Romain Vigier
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
@@ -19,11 +19,94 @@ this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
'use strict';
|
||||
|
||||
const { extensionUtils } = imports.misc;
|
||||
const { main } = imports.ui;
|
||||
|
||||
const Me = extensionUtils.getCurrentExtension();
|
||||
const { Switcher } = Me.imports.modules.Switcher;
|
||||
|
||||
const { log_debug } = Me.imports.utils;
|
||||
const { SettingsManager } = Me.imports.modules.SettingsManager;
|
||||
const { Timer } = Me.imports.modules.Timer;
|
||||
const { GtkThemer } = Me.imports.modules.GtkThemer;
|
||||
const { ShellThemer } = Me.imports.modules.ShellThemer;
|
||||
const { Backgrounder } = Me.imports.modules.Backgrounder;
|
||||
const { Commander } = Me.imports.modules.Commander;
|
||||
|
||||
|
||||
const shell_minor_version = parseInt(imports.misc.config.PACKAGE_VERSION.split('.')[1]);
|
||||
if ( shell_minor_version <= 30 ) {
|
||||
extensionUtils.initTranslations = Me.imports.convenience.initTranslations;
|
||||
}
|
||||
|
||||
|
||||
var enabled = false;
|
||||
var settingsManager = null;
|
||||
var timer = null;
|
||||
var gtkThemer = null;
|
||||
var shellThemer = null;
|
||||
var backgrounder = null;
|
||||
var commander = null;
|
||||
|
||||
|
||||
function init() {
|
||||
return new Switcher();
|
||||
log_debug('Initializing extension...');
|
||||
extensionUtils.initTranslations(Me.metadata.uuid);
|
||||
log_debug('Extension initialized.');
|
||||
}
|
||||
|
||||
function enable() {
|
||||
this._await_extensionManager_init().then(() => {
|
||||
log_debug('Enabling extension...');
|
||||
settingsManager = new SettingsManager();
|
||||
timer = new Timer();
|
||||
gtkThemer = new GtkThemer();
|
||||
shellThemer = new ShellThemer();
|
||||
backgrounder = new Backgrounder();
|
||||
commander = new Commander();
|
||||
|
||||
settingsManager.enable();
|
||||
timer.enable();
|
||||
gtkThemer.enable();
|
||||
shellThemer.enable();
|
||||
backgrounder.enable();
|
||||
commander.enable();
|
||||
|
||||
enabled = true;
|
||||
log_debug('Extension enabled.');
|
||||
});
|
||||
}
|
||||
|
||||
function disable() {
|
||||
log_debug('Disabling extension...');
|
||||
enabled = false;
|
||||
|
||||
gtkThemer.disable();
|
||||
shellThemer.disable();
|
||||
backgrounder.disable();
|
||||
commander.disable();
|
||||
timer.disable();
|
||||
settingsManager.disable();
|
||||
|
||||
settingsManager = null;
|
||||
timer = null;
|
||||
gtkThemer = null;
|
||||
shellThemer = null;
|
||||
backgrounder = null;
|
||||
commander = null;
|
||||
log_debug('Extension disabled.');
|
||||
}
|
||||
|
||||
async function _await_extensionManager_init() {
|
||||
log_debug('Waiting for the Extension Manager to be initialized...');
|
||||
if ( shell_minor_version > 32 ) {
|
||||
while ( true ) {
|
||||
if ( main.extensionManager._initialized ) return;
|
||||
await null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
while ( true ) {
|
||||
if ( imports.ui.extensionSystem.initted ) return;
|
||||
await null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"name": "Night Theme Switcher",
|
||||
"description": "Automatically toggle between your light and dark GTK theme variants.",
|
||||
"description": "Automatically toggle your light and dark GTK and GNOME Shell theme variants, switch backgrounds and launch custom commands at sunset and sunrise.",
|
||||
"uuid": "nightthemeswitcher@romainvigier.fr",
|
||||
"gettext-domain": "nightthemeswitcher@romainvigier.fr",
|
||||
"settings-schema": "org.gnome.shell.extensions.nightthemeswitcher",
|
||||
"url": "https://gitlab.com/rmnvgr/nightthemeswitcher-gnome-shell-extension/",
|
||||
"shell-version": ["3.32", "3.34", "3.36"],
|
||||
"version": 29
|
||||
"shell-version": ["3.28", "3.30", "3.32", "3.34", "3.36"],
|
||||
"version": 30
|
||||
}
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const { GLib } = imports.gi;
|
||||
const { extensionUtils } = imports.misc;
|
||||
|
||||
const Me = extensionUtils.getCurrentExtension();
|
||||
|
||||
const e = Me.imports.extension;
|
||||
const { log_debug } = Me.imports.utils;
|
||||
|
||||
/**
|
||||
* The Backgrounder is responsible for changing the desktop background
|
||||
* according to the time.
|
||||
*
|
||||
* When the user changes its desktop background (for example via the system
|
||||
* settings), it will use it as the current time background.
|
||||
*/
|
||||
var Backgrounder = class {
|
||||
|
||||
enable() {
|
||||
log_debug('Enabling Backgrounder...');
|
||||
this._watch_status();
|
||||
if ( e.settingsManager.backgrounds_enabled ) {
|
||||
this._change_background(e.timer.time);
|
||||
this._connect_settings();
|
||||
this._connect_timer();
|
||||
}
|
||||
log_debug('Backgrounder enabled.');
|
||||
}
|
||||
|
||||
disable() {
|
||||
log_debug('Disabling Backgrounder...');
|
||||
this._disconnect_timer();
|
||||
this._disconnect_settings();
|
||||
this._unwatch_status();
|
||||
log_debug('Backgrounder disabled.');
|
||||
}
|
||||
|
||||
|
||||
_watch_status() {
|
||||
log_debug('Watching backgrounds status...');
|
||||
this._backgrounds_status_changed_connect = e.settingsManager.connect('backgrounds-status-changed', this._on_backgrounds_status_changed.bind(this));
|
||||
}
|
||||
|
||||
_unwatch_status() {
|
||||
if ( this._backgrounds_status_changed_connect ) {
|
||||
e.settingsManager.disconnect(this._backgrounds_status_changed_connect);
|
||||
this._backgrounds_status_changed_connect = null;
|
||||
}
|
||||
log_debug('Stopped watching backgrounds status.');
|
||||
}
|
||||
|
||||
_connect_settings() {
|
||||
log_debug('Connecting Backgrounder to settings...');
|
||||
this._background_time_changed_connect = e.settingsManager.connect('background-time-changed', this._on_background_time_changed.bind(this));
|
||||
this._background_changed_connect = e.settingsManager.connect('background-changed', this._on_background_changed.bind(this));
|
||||
}
|
||||
|
||||
_disconnect_settings() {
|
||||
if ( this._background_time_changed_connect ) {
|
||||
e.settingsManager.disconnect(this._background_time_changed_connect);
|
||||
this._background_time_changed_connect = null;
|
||||
}
|
||||
if ( this._background_changed_connect ) {
|
||||
e.settingsManager.disconnect(this._background_changed_connect);
|
||||
this._background_changed_connect = null;
|
||||
}
|
||||
log_debug('Disconnected Backgrounder from settings.');
|
||||
}
|
||||
|
||||
_connect_timer() {
|
||||
log_debug('Connecting Backgrounder to Timer...');
|
||||
this._time_changed_connect = e.timer.connect('time-changed', this._on_time_changed.bind(this));
|
||||
}
|
||||
|
||||
_disconnect_timer() {
|
||||
if ( this._time_changed_connect ) {
|
||||
e.timer.disconnect(this._time_changed_connect);
|
||||
this._time_changed_connect = null;
|
||||
}
|
||||
log_debug('Disconnecting Backgrounder from Timer.');
|
||||
}
|
||||
|
||||
|
||||
_on_backgrounds_status_changed(settings, enabled) {
|
||||
this.disable();
|
||||
this.enable();
|
||||
}
|
||||
|
||||
_on_background_time_changed(settings, changed_background_time) {
|
||||
if ( changed_background_time === e.timer.time ) {
|
||||
this._change_background(changed_background_time);
|
||||
}
|
||||
}
|
||||
|
||||
_on_background_changed(settings, new_background) {
|
||||
switch (e.timer.time) {
|
||||
case 'day':
|
||||
e.settingsManager.background_day = new_background;
|
||||
break;
|
||||
case 'night':
|
||||
e.settingsManager.background_night = new_background;
|
||||
}
|
||||
}
|
||||
|
||||
_on_time_changed(timer, new_time) {
|
||||
this._change_background(new_time);
|
||||
}
|
||||
|
||||
|
||||
_change_background(time) {
|
||||
e.settingsManager.background = time === 'day' ? e.settingsManager.background_day : e.settingsManager.background_night;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const { GLib } = imports.gi;
|
||||
const { extensionUtils } = imports.misc;
|
||||
|
||||
const Me = extensionUtils.getCurrentExtension();
|
||||
|
||||
const e = Me.imports.extension;
|
||||
const { log_debug } = Me.imports.utils;
|
||||
|
||||
|
||||
/**
|
||||
* The Commander is responsible for spawning commands according to the time.
|
||||
*/
|
||||
var Commander = class {
|
||||
|
||||
enable() {
|
||||
log_debug('Enabling Commander...');
|
||||
this._watch_status();
|
||||
if ( e.settingsManager.commands_enabled ) {
|
||||
this._connect_timer();
|
||||
}
|
||||
log_debug('Commander enabled.');
|
||||
}
|
||||
|
||||
disable() {
|
||||
log_debug('Disabling Commander...');
|
||||
this._disconnect_timer();
|
||||
this._unwatch_status();
|
||||
log_debug('Commander disabled.');
|
||||
}
|
||||
|
||||
|
||||
_watch_status() {
|
||||
log_debug('Watching commands status...');
|
||||
this._commands_status_changed_connect = e.settingsManager.connect('commands-status-changed', this._on_commands_status_changed.bind(this));
|
||||
}
|
||||
|
||||
_unwatch_status() {
|
||||
if ( this._commands_status_changed_connect ) {
|
||||
e.settingsManager.disconnect(this._commands_status_changed_connect);
|
||||
this._commands_status_changed_connect = null;
|
||||
}
|
||||
log_debug('Stopped watching commands status.');
|
||||
}
|
||||
|
||||
_connect_timer() {
|
||||
log_debug('Connecting Commander to Timer...');
|
||||
this._time_changed_connect = e.timer.connect('time-changed', this._on_time_changed.bind(this));
|
||||
}
|
||||
|
||||
_disconnect_timer() {
|
||||
if ( this._time_changed_connect ) {
|
||||
e.timer.disconnect(this._time_changed_connect);
|
||||
this._time_changed_connect = null;
|
||||
}
|
||||
log_debug('Disconnecting Commander from Timer.');
|
||||
}
|
||||
|
||||
|
||||
_on_commands_status_changed(settings, enabled) {
|
||||
this.disable();
|
||||
this.enable();
|
||||
}
|
||||
|
||||
_on_time_changed(timer, new_time) {
|
||||
this._spawn_command(new_time);
|
||||
}
|
||||
|
||||
|
||||
_spawn_command(time) {
|
||||
const command = time === 'day' ? e.settingsManager.command_sunrise : e.settingsManager.command_sunset;
|
||||
GLib.spawn_async(null, ['sh', '-c', command], null, GLib.SpawnFlags.SEARCH_PATH, null);
|
||||
log_debug(`Spawned ${time} command.`);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const { Gio, GLib, Gtk } = imports.gi;
|
||||
const { extensionUtils } = imports.misc;
|
||||
const { main } = imports.ui;
|
||||
|
||||
const Me = extensionUtils.getCurrentExtension();
|
||||
|
||||
const e = Me.imports.extension;
|
||||
const { log_debug, log_error, get_installed_gtk_themes } = Me.imports.utils;
|
||||
const { GtkVariants } = Me.imports.modules.GtkVariants;
|
||||
|
||||
const Gettext = imports.gettext.domain(Me.metadata.uuid);
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
|
||||
/**
|
||||
* The GTK Themer is responsible for changing the GTK theme according to the
|
||||
* time.
|
||||
*
|
||||
* When the user changes its GTK theme (for example via GNOME Tweaks), it will
|
||||
* try to automatically guess the day and night variants for this theme. It
|
||||
* will warn the user if it is unable to guess.
|
||||
*
|
||||
* In manual mode, it will not attempt to update the variants. The user can
|
||||
* change the GTK variants in the extension's preferences.
|
||||
*/
|
||||
var GtkThemer = class {
|
||||
|
||||
enable() {
|
||||
log_debug('Enabling GTK Themer...');
|
||||
try {
|
||||
this._update_variants();
|
||||
this._set_variant(e.timer.time);
|
||||
this._connect_settings();
|
||||
this._connect_timer();
|
||||
}
|
||||
catch(e) {
|
||||
log_error(e);
|
||||
}
|
||||
log_debug('GTK Themer enabled.');
|
||||
}
|
||||
|
||||
disable() {
|
||||
log_debug('Disabling GTK Themer...');
|
||||
this._disconnect_timer();
|
||||
this._disconnect_settings();
|
||||
this._reset_theme();
|
||||
log_debug('GTK Themer disabled.');
|
||||
}
|
||||
|
||||
|
||||
_connect_settings() {
|
||||
log_debug('Connecting GTK Themer to settings...');
|
||||
this._gtk_variant_changed_connect = e.settingsManager.connect('gtk-variant-changed', this._on_gtk_variant_changed.bind(this));
|
||||
this._gtk_theme_changed_connect = e.settingsManager.connect('gtk-theme-changed', this._on_gtk_theme_changed.bind(this));
|
||||
}
|
||||
|
||||
_disconnect_settings() {
|
||||
if ( this._gtk_variant_changed_connect ) {
|
||||
e.settingsManager.disconnect(this._gtk_variant_changed_connect);
|
||||
this._gtk_variant_changed_connect = null;
|
||||
}
|
||||
if ( this._gtk_theme_changed_connect ) {
|
||||
e.settingsManager.disconnect(this._gtk_theme_changed_connect);
|
||||
this._gtk_theme_changed_connect = null;
|
||||
}
|
||||
log_debug('Disconnected GTK Themer from settings.');
|
||||
}
|
||||
|
||||
_connect_timer() {
|
||||
log_debug('Connecting GTK Themer to Timer...');
|
||||
this._time_changed_connect = e.timer.connect('time-changed', this._on_time_changed.bind(this));
|
||||
}
|
||||
|
||||
_disconnect_timer() {
|
||||
if ( this._time_changed_connect ) {
|
||||
e.timer.disconnect(this._time_changed_connect);
|
||||
this._time_changed_connect = null;
|
||||
}
|
||||
log_debug('Disconnected GTK Themer from Timer.');
|
||||
}
|
||||
|
||||
|
||||
_on_gtk_variant_changed(settings, changed_variant_time) {
|
||||
if ( changed_variant_time === e.timer.time ) {
|
||||
this._set_variant(changed_variant_time);
|
||||
}
|
||||
}
|
||||
|
||||
_on_gtk_theme_changed(settings, new_theme) {
|
||||
try {
|
||||
this._update_variants();
|
||||
this._set_variant(e.timer.time);
|
||||
}
|
||||
catch(e) {
|
||||
log_error(e);
|
||||
}
|
||||
}
|
||||
|
||||
_on_time_changed(timer, new_time) {
|
||||
this._set_variant(new_time);
|
||||
}
|
||||
|
||||
|
||||
_are_variants_up_to_date() {
|
||||
return ( e.settingsManager.gtk_theme === e.settingsManager.gtk_variant_day || e.settingsManager.gtk_theme === e.settingsManager.gtk_variant_night );
|
||||
}
|
||||
|
||||
_set_variant(time) {
|
||||
log_debug(`Setting the GTK ${time} variant...`);
|
||||
switch (time) {
|
||||
case 'day':
|
||||
e.settingsManager.gtk_theme = e.settingsManager.gtk_variant_day;
|
||||
break;
|
||||
case 'night':
|
||||
e.settingsManager.gtk_theme = e.settingsManager.gtk_variant_night;
|
||||
break;
|
||||
case 'original':
|
||||
e.settingsManager.gtk_theme = e.settingsManager.gtk_variant_original;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_update_variants() {
|
||||
if ( e.settingsManager.manual_gtk_variants || this._are_variants_up_to_date() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
log_debug('Updating GTK variants...');
|
||||
const variants = GtkVariants.guess_from(e.settingsManager.gtk_theme);
|
||||
const installed_themes = get_installed_gtk_themes();
|
||||
|
||||
if ( !installed_themes.has(variants.get('day')) || !installed_themes.has(variants.get('night')) ) {
|
||||
e.settingsManager.gtk_variant_original = variants.get('original');
|
||||
const message = _('Unable to automatically detect the day and night variants for the "%s" GTK theme. Please manually choose them in the extension\'s preferences.').format(variants.get('original'));
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
e.settingsManager.gtk_variant_day = variants.get('day');
|
||||
e.settingsManager.gtk_variant_night = variants.get('night');
|
||||
e.settingsManager.gtk_variant_original = variants.get('original');
|
||||
log_debug(`New GTK variants. { day: '${variants.get('day')}'; night: '${variants.get('night')}' }`);
|
||||
}
|
||||
|
||||
_reset_theme() {
|
||||
// We don't reset the theme when locking the session to prevent
|
||||
// flicker on unlocking
|
||||
if ( !main.screenShield.locked ) {
|
||||
log_debug('Resetting to the user\'s original GTK theme...');
|
||||
this._set_variant('original');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,32 +17,30 @@ You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
The magic of guessing theme variants happens here.
|
||||
|
||||
If the theme doesn't fit a particular case, we'll do the following:
|
||||
- Remove any signs of a dark variant to the theme name to get the day
|
||||
variant
|
||||
- Remove any signs of a light variant to the day variant and add '-dark' to
|
||||
get the night variant
|
||||
|
||||
For themes that don't work with the general rule, a particular case must be
|
||||
written. Day and night variants should be guessed with the most generic light
|
||||
and dark variants the theme offer, except if the user explicitly chose a
|
||||
specific variant.
|
||||
|
||||
Light variants, from the most to the least generic:
|
||||
- ''
|
||||
- '-light'
|
||||
- '-darker'
|
||||
|
||||
Dark variants, from the most the least generic:
|
||||
- '-dark'
|
||||
- '-darkest'
|
||||
*/
|
||||
|
||||
var Variants = class {
|
||||
/**
|
||||
* The magic of guessing theme variants happens here.
|
||||
*
|
||||
* If the theme doesn't fit a particular case, we'll do the following:
|
||||
* - Remove any signs of a dark variant to the theme name to get the day
|
||||
* variant
|
||||
* - Remove any signs of a light variant to the day variant and add '-dark' to
|
||||
* get the night variant
|
||||
*
|
||||
* For themes that don't work with the general rule, a particular case must be
|
||||
* written. Day and night variants should be guessed with the most generic light
|
||||
* and dark variants the theme offer, except if the user explicitly chose a
|
||||
* specific variant.
|
||||
*
|
||||
* Light variants, from the most to the least generic:
|
||||
* - ''
|
||||
* - '-light'
|
||||
* - '-darker'
|
||||
*
|
||||
* Dark variants, from the most the least generic:
|
||||
* - '-dark'
|
||||
* - '-darkest'
|
||||
*/
|
||||
var GtkVariants = class {
|
||||
|
||||
static guess_from(name) {
|
||||
const variants = new Map();
|
||||
@@ -0,0 +1,427 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const { Gio } = imports.gi;
|
||||
const { extensionUtils } = imports.misc;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const Me = extensionUtils.getCurrentExtension();
|
||||
|
||||
const { log_debug, get_userthemes_extension, get_userthemes_settings } = Me.imports.utils;
|
||||
|
||||
|
||||
const shell_minor_version = parseInt(imports.misc.config.PACKAGE_VERSION.split('.')[1]);
|
||||
if ( shell_minor_version <= 30 ) {
|
||||
extensionUtils.getSettings = Me.imports.convenience.getSettings;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The Settings Manager centralizes all the different settings the extension
|
||||
* needs. It handles getting and settings values as well as signaling any
|
||||
* changes.
|
||||
*/
|
||||
var SettingsManager = class {
|
||||
|
||||
constructor() {
|
||||
log_debug('Initializing settings...');
|
||||
this._extensionsSettings = extensionUtils.getSettings();
|
||||
this._colorSettings = new Gio.Settings({ schema: 'org.gnome.settings-daemon.plugins.color' });
|
||||
this._locationSettings = new Gio.Settings({ schema: 'org.gnome.system.location' });
|
||||
this._interfaceSettings = new Gio.Settings({ schema: 'org.gnome.desktop.interface' });
|
||||
this._backgroundSettings = new Gio.Settings({ schema: 'org.gnome.desktop.background' });
|
||||
this._userthemesSettings = get_userthemes_settings();
|
||||
log_debug('Settings initialized.');
|
||||
}
|
||||
|
||||
enable() {
|
||||
log_debug('Connecting settings signals...');
|
||||
this._gtk_variant_day_changed_connect = this._extensionsSettings.connect('changed::gtk-variant-day', this._on_gtk_variant_day_changed.bind(this));
|
||||
this._gtk_variant_night_changed_connect = this._extensionsSettings.connect('changed::gtk-variant-night', this._on_gtk_variant_night_changed.bind(this));
|
||||
this._gtk_variant_original_changed_connect = this._extensionsSettings.connect('changed::gtk-variant-original', this._on_gtk_variant_original_changed.bind(this));
|
||||
this._shell_variant_day_changed_connect = this._extensionsSettings.connect('changed::shell-variant-day', this._on_shell_variant_day_changed.bind(this));
|
||||
this._shell_variant_night_changed_connect = this._extensionsSettings.connect('changed::shell-variant-night', this._on_shell_variant_night_changed.bind(this));
|
||||
this._shell_variant_original_changed_connect = this._extensionsSettings.connect('changed::shell-variant-original', this._on_shell_variant_original_changed.bind(this));
|
||||
this._time_source_changed_connect = this._extensionsSettings.connect('changed::time-source', this._on_time_source_changed.bind(this));
|
||||
this._manual_time_source_changed_connect = this._extensionsSettings.connect('changed::manual-time-source', this._on_manual_time_source_changed.bind(this));
|
||||
this._commands_status_connect = this._extensionsSettings.connect('changed::commands-enabled', this._on_commands_status_changed.bind(this));
|
||||
this._backgrounds_status_connect = this._extensionsSettings.connect('changed::backgrounds-enabled', this._on_backgrounds_status_changed.bind(this));
|
||||
this._background_day_changed_connect = this._extensionsSettings.connect('changed::background-day', this._on_background_day_changed.bind(this));
|
||||
this._background_night_changed_connect = this._extensionsSettings.connect('changed::background-night', this._on_background_night_changed.bind(this));
|
||||
this._nightlight_status_connect = this._colorSettings.connect('changed::night-light-enabled', this._on_nightlight_status_changed.bind(this));
|
||||
this._location_status_connect = this._locationSettings.connect('changed::enabled', this._on_location_status_changed.bind(this));
|
||||
this._gtk_theme_changed_connect = this._interfaceSettings.connect('changed::gtk-theme', this._on_gtk_theme_changed.bind(this));
|
||||
this._background_changed_connect = this._backgroundSettings.connect('changed::picture-uri', this._on_background_changed.bind(this));
|
||||
if ( this._userthemesSettings ) {
|
||||
this._shell_theme_changed_connect = this._userthemesSettings.connect('changed::name', this._on_shell_theme_changed.bind(this));
|
||||
}
|
||||
log_debug('Settings signals connected.');
|
||||
}
|
||||
|
||||
disable() {
|
||||
log_debug('Disconnecting settings signals...');
|
||||
this._extensionsSettings.disconnect(this._gtk_variant_day_changed_connect);
|
||||
this._extensionsSettings.disconnect(this._gtk_variant_night_changed_connect);
|
||||
this._extensionsSettings.disconnect(this._gtk_variant_original_changed_connect);
|
||||
this._extensionsSettings.disconnect(this._shell_variant_day_changed_connect);
|
||||
this._extensionsSettings.disconnect(this._shell_variant_night_changed_connect);
|
||||
this._extensionsSettings.disconnect(this._shell_variant_original_changed_connect);
|
||||
this._extensionsSettings.disconnect(this._time_source_changed_connect);
|
||||
this._extensionsSettings.disconnect(this._manual_time_source_changed_connect);
|
||||
this._extensionsSettings.disconnect(this._commands_status_connect);
|
||||
this._extensionsSettings.disconnect(this._backgrounds_status_connect);
|
||||
this._extensionsSettings.disconnect(this._background_day_changed_connect);
|
||||
this._extensionsSettings.disconnect(this._background_night_changed_connect);
|
||||
this._colorSettings.disconnect(this._nightlight_status_connect);
|
||||
this._locationSettings.disconnect(this._location_status_connect);
|
||||
this._interfaceSettings.disconnect(this._gtk_theme_changed_connect);
|
||||
this._backgroundSettings.disconnect(this._background_changed_connect);
|
||||
if ( this._userthemesSettings ) {
|
||||
this._userthemesSettings.disconnect(this._shell_theme_changed_connect);
|
||||
}
|
||||
log_debug('Settings signals disconnected.');
|
||||
}
|
||||
|
||||
/**
|
||||
* SETTERS AND GETTERS
|
||||
*/
|
||||
|
||||
/* GTK variants settings */
|
||||
|
||||
get gtk_variant_day() {
|
||||
return this._extensionsSettings.get_string('gtk-variant-day');
|
||||
}
|
||||
|
||||
set gtk_variant_day(value) {
|
||||
if ( value !== this.gtk_variant_day ) {
|
||||
this._extensionsSettings.set_string('gtk-variant-day', value);
|
||||
log_debug(`The GTK day variant has been set to '${value}'.`);
|
||||
}
|
||||
}
|
||||
|
||||
get gtk_variant_night() {
|
||||
return this._extensionsSettings.get_string('gtk-variant-night');
|
||||
}
|
||||
|
||||
set gtk_variant_night(value) {
|
||||
if ( value !== this.gtk_variant_night ) {
|
||||
this._extensionsSettings.set_string('gtk-variant-night', value);
|
||||
log_debug(`The GTK night variant has been set to '${value}'.`);
|
||||
}
|
||||
}
|
||||
|
||||
get gtk_variant_original() {
|
||||
return this._extensionsSettings.get_string('gtk-variant-original');
|
||||
}
|
||||
|
||||
set gtk_variant_original(value) {
|
||||
if ( value !== this.gtk_variant_original ) {
|
||||
this._extensionsSettings.set_string('gtk-variant-original', value);
|
||||
log_debug(`The GTK original variant has been set to '${value}'.`);
|
||||
}
|
||||
}
|
||||
|
||||
get manual_gtk_variants() {
|
||||
return this._extensionsSettings.get_boolean('manual-gtk-variants');
|
||||
}
|
||||
|
||||
|
||||
/* Shell variants settings */
|
||||
|
||||
get shell_variant_day() {
|
||||
return this._extensionsSettings.get_string('shell-variant-day');
|
||||
}
|
||||
|
||||
set shell_variant_day(value) {
|
||||
if ( value !== this.shell_variant_day ) {
|
||||
this._extensionsSettings.set_string('shell-variant-day', value);
|
||||
log_debug(`The shell day variant has been set to '${value}'.`);
|
||||
}
|
||||
}
|
||||
|
||||
get shell_variant_night() {
|
||||
return this._extensionsSettings.get_string('shell-variant-night');
|
||||
}
|
||||
|
||||
set shell_variant_night(value) {
|
||||
if ( value !== this.shell_variant_night ) {
|
||||
this._extensionsSettings.set_string('shell-variant-night', value);
|
||||
log_debug(`The shell night variant has been set to '${value}'.`);
|
||||
}
|
||||
}
|
||||
|
||||
get shell_variant_original() {
|
||||
return this._extensionsSettings.get_string('shell-variant-original');
|
||||
}
|
||||
|
||||
set shell_variant_original(value) {
|
||||
if ( value !== this.shell_variant_original ) {
|
||||
this._extensionsSettings.set_string('shell-variant-original', value);
|
||||
log_debug(`The shell original variant has been set to '${value}'.`);
|
||||
}
|
||||
}
|
||||
|
||||
get manual_shell_variants() {
|
||||
return this._extensionsSettings.get_boolean('manual-shell-variants');
|
||||
}
|
||||
|
||||
|
||||
/* Time source settings */
|
||||
|
||||
get time_source() {
|
||||
return this._extensionsSettings.get_string('time-source');
|
||||
}
|
||||
|
||||
get manual_time_source() {
|
||||
return this._extensionsSettings.get_boolean('manual-time-source');
|
||||
}
|
||||
|
||||
set time_source(value) {
|
||||
if ( value !== this.time_source ) {
|
||||
this._extensionsSettings.set_string('time-source', value);
|
||||
log_debug(`The time source has been set to ${value}.`);
|
||||
}
|
||||
}
|
||||
|
||||
get schedule_sunrise() {
|
||||
return this._extensionsSettings.get_double('schedule-sunrise');
|
||||
}
|
||||
|
||||
get schedule_sunset() {
|
||||
return this._extensionsSettings.get_double('schedule-sunset');
|
||||
}
|
||||
|
||||
|
||||
/* Commands settings */
|
||||
|
||||
get commands_enabled() {
|
||||
return this._extensionsSettings.get_boolean('commands-enabled');
|
||||
}
|
||||
|
||||
get command_sunrise() {
|
||||
return this._extensionsSettings.get_string('command-sunrise');
|
||||
}
|
||||
|
||||
get command_sunset() {
|
||||
return this._extensionsSettings.get_string('command-sunset');
|
||||
}
|
||||
|
||||
|
||||
/* Background settings */
|
||||
|
||||
get backgrounds_enabled() {
|
||||
return this._extensionsSettings.get_boolean('backgrounds-enabled');
|
||||
}
|
||||
|
||||
get background_day() {
|
||||
return this._extensionsSettings.get_string('background-day') || this.background;
|
||||
}
|
||||
|
||||
set background_day(value) {
|
||||
this._extensionsSettings.set_string('background-day', value);
|
||||
}
|
||||
|
||||
get background_night() {
|
||||
return this._extensionsSettings.get_string('background-night') || this.background;
|
||||
}
|
||||
|
||||
set background_night(value) {
|
||||
this._extensionsSettings.set_string('background-night', value);
|
||||
}
|
||||
|
||||
|
||||
/* Night Light settings */
|
||||
|
||||
get nightlight_enabled() {
|
||||
return this._colorSettings.get_boolean('night-light-enabled');
|
||||
}
|
||||
|
||||
|
||||
/* Location settings */
|
||||
|
||||
get location_enabled() {
|
||||
return this._locationSettings.get_boolean('enabled');
|
||||
}
|
||||
|
||||
|
||||
/* GTK theme settings */
|
||||
|
||||
get gtk_theme() {
|
||||
return this._interfaceSettings.get_string('gtk-theme');
|
||||
}
|
||||
|
||||
set gtk_theme(value) {
|
||||
if ( value !== this.gtk_theme ) {
|
||||
this._interfaceSettings.set_string('gtk-theme', value);
|
||||
log_debug(`GTK theme has been set to '${value}.'`);
|
||||
}
|
||||
}
|
||||
|
||||
/* Shell theme settings */
|
||||
|
||||
get shell_theme() {
|
||||
if ( this._userthemesSettings ) {
|
||||
return this._userthemesSettings.get_string('name');
|
||||
}
|
||||
}
|
||||
|
||||
set shell_theme(value) {
|
||||
if ( this._userthemesSettings && value !== this.shell_theme ) {
|
||||
this._userthemesSettings.set_string('name', value);
|
||||
}
|
||||
}
|
||||
|
||||
get use_userthemes() {
|
||||
const extension = get_userthemes_extension();
|
||||
return (extension && extension.state === 1);
|
||||
}
|
||||
|
||||
|
||||
/* Background settings */
|
||||
|
||||
get background() {
|
||||
return this._backgroundSettings.get_string('picture-uri');
|
||||
}
|
||||
|
||||
set background(value) {
|
||||
if ( value !== this.background ) {
|
||||
this._backgroundSettings.set_string('picture-uri', value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* SIGNALS
|
||||
*/
|
||||
|
||||
/* GTK variants */
|
||||
|
||||
_on_gtk_variant_day_changed(settings, changed_key) {
|
||||
log_debug(`GTK day variant has changed to '${this.gtk_variant_day}'.`);
|
||||
this.emit('gtk-variant-changed', 'day');
|
||||
}
|
||||
|
||||
_on_gtk_variant_night_changed(settings, changed_key) {
|
||||
log_debug(`GTK night variant has changed to '${this.gtk_variant_night}'.`);
|
||||
this.emit('gtk-variant-changed', 'night');
|
||||
}
|
||||
|
||||
_on_gtk_variant_original_changed(settings, changed_key) {
|
||||
log_debug(`GTK original variant has changed to '${this.gtk_variant_original}'.`);
|
||||
this.emit('gtk-variant-changed', 'original');
|
||||
}
|
||||
|
||||
|
||||
/* Shell variants */
|
||||
|
||||
_on_shell_variant_day_changed(settings, changed_key) {
|
||||
log_debug(`Shell day variant has changed to '${this.shell_variant_day}'.`);
|
||||
this.emit('shell-variant-changed', 'day');
|
||||
}
|
||||
|
||||
_on_shell_variant_night_changed(settings, changed_key) {
|
||||
log_debug(`Shell night variant has changed to '${this.shell_variant_night}'.`);
|
||||
this.emit('shell-variant-changed', 'night');
|
||||
}
|
||||
|
||||
_on_shell_variant_original_changed(settings, changed_key) {
|
||||
log_debug(`Shell original variant has changed to '${this.shell_variant_original}'.`);
|
||||
this.emit('shell-variant-changed', 'original');
|
||||
}
|
||||
|
||||
|
||||
/* Time source */
|
||||
|
||||
_on_time_source_changed(settings, changed_key) {
|
||||
log_debug(`Time source has changed to ${this.time_source}.`);
|
||||
this.emit('time-source-changed', this.time_source);
|
||||
}
|
||||
|
||||
_on_manual_time_source_changed(settings, changed_key) {
|
||||
log_debug('Manual time source has been ' + (this.manual_time_source ? 'ena' : 'disa') + 'bled.');
|
||||
this.emit('manual-time-source-changed', this.manual_time_source);
|
||||
}
|
||||
|
||||
|
||||
/* Commands */
|
||||
|
||||
_on_commands_status_changed(settings, changed_key) {
|
||||
log_debug('Commands have been ' + (this.commands_enabled ? 'ena' : 'disa') + 'bled.');
|
||||
this.emit('commands-status-changed', this.commands_enabled);
|
||||
}
|
||||
|
||||
|
||||
/* Backgrounds */
|
||||
|
||||
_on_backgrounds_status_changed(settings, changed_key) {
|
||||
log_debug('Backgrounds have been ' + (this.backgrounds_enabled ? 'ena' : 'disa') + 'bled.');
|
||||
this.emit('backgrounds-status-changed', this.backgrounds_enabled);
|
||||
}
|
||||
|
||||
_on_background_day_changed(settings, changed_key) {
|
||||
log_debug(`Day background has changed to '${this.background_day}'.`);
|
||||
this.emit('background-time-changed', 'day');
|
||||
}
|
||||
|
||||
_on_background_night_changed(settings, changed_key) {
|
||||
log_debug(`Night background has changed to '${this.background_night}'.`);
|
||||
this.emit('background-time-changed', 'night');
|
||||
}
|
||||
|
||||
|
||||
/* Night Light */
|
||||
|
||||
_on_nightlight_status_changed(settings, changed_key) {
|
||||
log_debug('Night Light has been ' + (this.nightlight_enabled ? 'ena' : 'disa') + 'bled.');
|
||||
this.emit('nightlight-status-changed', this.nightlight_enabled);
|
||||
}
|
||||
|
||||
|
||||
/* Location */
|
||||
|
||||
_on_location_status_changed(settings, changed_key) {
|
||||
log_debug('Location has been ' + (this.location_enabled ? 'ena' : 'disa') + 'bled.');
|
||||
this.emit('location-status-changed', this.location_enabled);
|
||||
}
|
||||
|
||||
|
||||
/* GTK theme */
|
||||
|
||||
_on_gtk_theme_changed(settings, changed_key) {
|
||||
log_debug(`GTK theme has changed to '${this.gtk_theme}'.`);
|
||||
this.emit('gtk-theme-changed', this.gtk_theme);
|
||||
}
|
||||
|
||||
|
||||
/* Background */
|
||||
|
||||
_on_background_changed(settings, changed_key) {
|
||||
log_debug(`Background has changed to '${this.background}'.`);
|
||||
this.emit('background-changed', this.background);
|
||||
}
|
||||
|
||||
|
||||
/* Shell theme */
|
||||
|
||||
_on_shell_theme_changed(settings, changed_key) {
|
||||
log_debug(`Shell theme has changed to '${this.shell_theme}'.`);
|
||||
this.emit('shell-theme-changed', this.shell_theme);
|
||||
}
|
||||
|
||||
}
|
||||
Signals.addSignalMethods(SettingsManager.prototype);
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const { extensionUtils } = imports.misc;
|
||||
const Signals = imports.signals;
|
||||
const { main } = imports.ui;
|
||||
|
||||
const Me = extensionUtils.getCurrentExtension();
|
||||
|
||||
const e = Me.imports.extension;
|
||||
const { log_debug, log_error, get_theme_dirs_paths, get_installed_shell_themes, get_shell_theme_stylesheet, apply_shell_stylesheet } = Me.imports.utils;
|
||||
const { ShellVariants } = Me.imports.modules.ShellVariants;
|
||||
|
||||
const Gettext = imports.gettext.domain(Me.metadata.uuid);
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
/**
|
||||
* The Shell Themer is responsible for changing the GTK theme according to the
|
||||
* time. It will use the User Themes extension to do so if it is enabled.
|
||||
*
|
||||
* When the user changes its shell theme (for example via GNOME Tweaks), it will
|
||||
* try to automatically guess the day and night variants for this theme. It
|
||||
* will warn the user if it is unable to guess.
|
||||
*
|
||||
* In manual mode, it will not attempt to update the variants. The user can
|
||||
* change the shell variants in the extension's preferences.
|
||||
*/
|
||||
var ShellThemer = class {
|
||||
|
||||
enable() {
|
||||
log_debug('Enabling Shell Themer...');
|
||||
try {
|
||||
this._update_variants();
|
||||
this._set_variant(e.timer.time);
|
||||
this._connect_settings();
|
||||
this._connect_timer();
|
||||
}
|
||||
catch(e) {
|
||||
log_error(e);
|
||||
}
|
||||
log_debug('Shell Themer enabled.');
|
||||
}
|
||||
|
||||
disable() {
|
||||
log_debug('Disabling Shell Themer...');
|
||||
this._disconnect_timer();
|
||||
this._disconnect_settings();
|
||||
this._reset_theme();
|
||||
log_debug('Shell Themer disabled.');
|
||||
}
|
||||
|
||||
|
||||
_connect_settings() {
|
||||
log_debug('Connecting Shell Themer to settings...');
|
||||
this._shell_variant_changed_connect = e.settingsManager.connect('shell-variant-changed', this._on_shell_variant_changed.bind(this));
|
||||
this._shell_theme_changed_connect = e.settingsManager.connect('shell-theme-changed', this._on_shell_theme_changed.bind(this));
|
||||
}
|
||||
|
||||
_disconnect_settings() {
|
||||
if ( this._shell_variant_changed_connect ) {
|
||||
e.settingsManager.disconnect(this._shell_variant_changed_connect);
|
||||
this._shell_variant_changed_connect = null;
|
||||
}
|
||||
if ( this._shell_theme_changed_connect ) {
|
||||
e.settingsManager.disconnect(this._shell_theme_changed_connect);
|
||||
this._shell_theme_changed_connect = null;
|
||||
}
|
||||
log_debug('Disconnected Shell Themer from settings.');
|
||||
}
|
||||
|
||||
_connect_timer() {
|
||||
log_debug('Connecting Shell Themer to Timer...');
|
||||
this._time_changed_connect = e.timer.connect('time-changed', this._on_time_changed.bind(this));
|
||||
}
|
||||
|
||||
_disconnect_timer() {
|
||||
if ( this._time_changed_connect ) {
|
||||
e.timer.disconnect(this._time_changed_connect);
|
||||
this._time_changed_connect = null;
|
||||
}
|
||||
log_debug('Disconnected Shell Themer from Timer.');
|
||||
}
|
||||
|
||||
|
||||
_on_shell_variant_changed(settings, changed_variant_time) {
|
||||
if ( changed_variant_time === e.timer.time ) {
|
||||
this._set_variant(e.timer.time);
|
||||
}
|
||||
}
|
||||
|
||||
_on_shell_theme_changed(settings, new_theme) {
|
||||
try {
|
||||
this._update_variants();
|
||||
this._set_variant(e.timer.time);
|
||||
}
|
||||
catch(e) {
|
||||
log_error(e);
|
||||
}
|
||||
}
|
||||
|
||||
_on_time_changed(timer, new_time) {
|
||||
this._set_variant(new_time);
|
||||
}
|
||||
|
||||
|
||||
_are_variants_up_to_date() {
|
||||
return ( e.settingsManager.shell_theme === e.settingsManager.shell_variant_day || e.settingsManager.shell_theme === e.settingsManager.shell_variant_night );
|
||||
}
|
||||
|
||||
_set_variant(time) {
|
||||
log_debug(`Setting the shell ${time} variant...`);
|
||||
let shell_theme;
|
||||
switch (time) {
|
||||
case 'day':
|
||||
shell_theme = e.settingsManager.shell_variant_day;
|
||||
break;
|
||||
case 'night':
|
||||
shell_theme = e.settingsManager.shell_variant_night;
|
||||
break;
|
||||
case 'original':
|
||||
shell_theme = e.settingsManager.shell_variant_original;
|
||||
break;
|
||||
}
|
||||
if ( e.settingsManager.use_userthemes ) {
|
||||
e.settingsManager.shell_theme = shell_theme;
|
||||
}
|
||||
else {
|
||||
const stylesheet = get_shell_theme_stylesheet(shell_theme);
|
||||
apply_shell_stylesheet(stylesheet);
|
||||
}
|
||||
}
|
||||
|
||||
_update_variants() {
|
||||
if ( !e.settingsManager.use_userthemes || e.settingsManager.manual_shell_variants || this._are_variants_up_to_date() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
log_debug('Updating Shell variants...');
|
||||
const variants = ShellVariants.guess_from(e.settingsManager.shell_theme);
|
||||
const installed_themes = get_installed_shell_themes();
|
||||
|
||||
if ( !installed_themes.has(variants.get('day')) || !installed_themes.has(variants.get('night')) ) {
|
||||
e.settingsManager.shell_variant_original = variants.get('original');
|
||||
const message = _('Unable to automatically detect the day and night variants for the "%s" GNOME Shell theme. Please manually choose them in the extension\'s preferences.').format(variants.get('original'));
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
e.settingsManager.shell_variant_day = variants.get('day');
|
||||
e.settingsManager.shell_variant_night = variants.get('night');
|
||||
e.settingsManager.shell_variant_original = variants.get('original');
|
||||
log_debug(`New Shell variants. { day: '${variants.get('day')}'; night: '${variants.get('night')}' }`);
|
||||
}
|
||||
|
||||
_reset_theme() {
|
||||
// We don't reset the theme when locking the session to prevent
|
||||
// flicker on unlocking
|
||||
if ( !main.screenShield.locked ) {
|
||||
log_debug('Resetting to the user\'s original Shell theme...');
|
||||
this._set_variant('original');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Signals.addSignalMethods(ShellThemer.prototype);
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2019, 2020 Romain Vigier
|
||||
Copyright (C) 2020 Matti Hyttinen
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The magic of guessing theme variants happens here.
|
||||
*
|
||||
* If the theme doesn't fit a particular case, we'll do the following:
|
||||
* - Remove any signs of a dark variant to the theme name to get the day
|
||||
* variant
|
||||
* - Remove any signs of a light variant to the day variant and add '-dark' to
|
||||
* get the night variant
|
||||
*
|
||||
* For themes that don't work with the general rule, a particular case must be
|
||||
* written. Day and night variants should be guessed with the most generic light
|
||||
* and dark variants the theme offer, except if the user explicitly chose a
|
||||
* specific variant.
|
||||
*
|
||||
* Light variants, from the most to the least generic:
|
||||
* - ''
|
||||
* - '-light'
|
||||
* - '-darker'
|
||||
*
|
||||
* Dark variants, from the most the least generic:
|
||||
* - '-dark'
|
||||
* - '-darkest'
|
||||
*/
|
||||
var ShellVariants = class {
|
||||
|
||||
static guess_from(name) {
|
||||
const variants = new Map();
|
||||
variants.set('original', name);
|
||||
|
||||
if ( name.includes('Adapta') ) {
|
||||
variants.set('day', name.replace('-Nokto', ''));
|
||||
variants.set('night', variants.get('day').replace('Adapta', 'Adapta-Nokto'));
|
||||
}
|
||||
else if ( name.includes('Arc') ) {
|
||||
variants.set('day', name.replace('-Dark', ''));
|
||||
variants.set('night', variants.get('day').replace('Arc', 'Arc-Dark'));
|
||||
}
|
||||
else if ( name.match(/^(Canta|ChromeOS|Materia|Orchis).*-compact/) ) {
|
||||
variants.set('day', name.replace('-dark', ''));
|
||||
variants.set('night', variants.get('day').replace(/(-light)?-compact/, '-dark-compact'));
|
||||
}
|
||||
else if ( name.includes('Flat-Remix') ) {
|
||||
const color = ( name.split('-')[2] && !['Dark', 'Darkest', 'fullPanel'].includes(name.split('-')[2]) ) ? '-' + name.split('-')[2] : '';
|
||||
const dark_variant = name.includes('Darkest') ? '-Darkest' : '-Dark';
|
||||
const size = name.includes('fullPanel')? '-fullPanel' : '';
|
||||
variants.set('day', name.replace(/-Dark(est)?/, ''));
|
||||
variants.set('night', `Flat-Remix${color}${dark_variant}${size}`);
|
||||
}
|
||||
else if ( name.match(/^(Layan|Matcha)/) ) {
|
||||
const basename = name.split('-')[0];
|
||||
variants.set('day', name.replace('-dark', ''));
|
||||
variants.set('night', variants.get('day').replace(new RegExp(`${basename}(-light)?`), `${basename}-dark`));
|
||||
}
|
||||
else if ( name.includes('Mojave') ) {
|
||||
variants.set('day', name.replace('-dark', '-light'));
|
||||
variants.set('night', variants.get('day').replace('-light', '-dark'));
|
||||
}
|
||||
else if ( name.includes('Plata') ) {
|
||||
variants.set('day', name.replace('-Noir', ''));
|
||||
variants.set('night', variants.get('day').replace(/Plata(-Lumine)?/, 'Plata-Noir'));
|
||||
}
|
||||
else if ( name.includes('Simply_Circles') ) {
|
||||
variants.set('day', name.replace('_Dark', '_Light'));
|
||||
variants.set('night', name.replace('_Light', '_Dark'));
|
||||
}
|
||||
else if ( name.includes('Teja') ) {
|
||||
const dark_variant = '_' + (name.replace('_Light').split('_')[1] || 'Dark');
|
||||
variants.set('day', name.replace(/(_Dark(est)?|_Black)/, ''));
|
||||
variants.set('night', variants.get('day').replace('_Light', '') + dark_variant);
|
||||
}
|
||||
else if ( name.includes('vimix') ) {
|
||||
variants.set('day', name.replace('-dark', ''));
|
||||
variants.set('night', variants.get('day').replace(/vimix(-light)?/, 'vimix-dark'));
|
||||
}
|
||||
else {
|
||||
variants.set('day', name.replace(/-dark(?!er)(est)?/, ''));
|
||||
variants.set('night', variants.get('day').replace(/(-light|-darker)/, '') + (name.includes('-darkest') ? '-darkest' : '-dark'));
|
||||
}
|
||||
|
||||
return variants;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const { extensionUtils } = imports.misc;
|
||||
const { main } = imports.ui;
|
||||
|
||||
const Me = extensionUtils.getCurrentExtension();
|
||||
const config = Me.imports.config;
|
||||
|
||||
const { log_debug, log_error } = Me.imports.utils;
|
||||
|
||||
const { Themer } = Me.imports.modules.Themer;
|
||||
const { Timer } = Me.imports.modules.Timer;
|
||||
|
||||
|
||||
/*
|
||||
The Switcher is the orchestrator of the extension.
|
||||
|
||||
When the extension is enabled, it asks the Themer to listen to theme changes
|
||||
from the user and the Timer to listen to changes in the current time:
|
||||
- On theme change, it asks the Themer to guess the new day and night
|
||||
variants for that theme, and to apply the relevant variant depending on the
|
||||
time of the day.
|
||||
- On time of the day change, it asks the Themer to apply the relevant
|
||||
variant.
|
||||
|
||||
When the extension is disabled, it asks the Themer and the Timer to disable
|
||||
themselves.
|
||||
*/
|
||||
|
||||
var Switcher = class {
|
||||
|
||||
constructor() {
|
||||
log_debug('Initializing extension...');
|
||||
extensionUtils.initTranslations(Me.metadata.uuid);
|
||||
log_debug('Extension initialized.');
|
||||
}
|
||||
|
||||
enable() {
|
||||
log_debug('Enabling extension...');
|
||||
try {
|
||||
this.theme = new Themer();
|
||||
this.theme.enable();
|
||||
this.theme.subscribe(this._on_theme_changed.bind(this));
|
||||
|
||||
this.time = new Timer();
|
||||
this.time.enable();
|
||||
this.time.subscribe(this._on_time_changed.bind(this));
|
||||
|
||||
this.theme.set_variant(this.time.current);
|
||||
|
||||
log_debug('Extension enabled.');
|
||||
}
|
||||
catch(e) {
|
||||
log_error(e);
|
||||
}
|
||||
}
|
||||
|
||||
disable() {
|
||||
log_debug('Disabling extension...');
|
||||
try {
|
||||
this.theme.disable();
|
||||
this.time.disable();
|
||||
}
|
||||
catch(e) {} // Since we're disabling, we'll just ignore errors.
|
||||
finally {
|
||||
this.theme = null;
|
||||
this.time = null;
|
||||
}
|
||||
log_debug('Extension disabled.');
|
||||
}
|
||||
|
||||
_on_theme_changed() {
|
||||
if ( !this.theme || !this.time ) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
this.theme.update_variants();
|
||||
this.theme.set_variant(this.time.current);
|
||||
}
|
||||
catch(e) {
|
||||
log_error(e);
|
||||
}
|
||||
}
|
||||
|
||||
_on_time_changed() {
|
||||
if ( !this.theme || !this.time ) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
this.theme.set_variant(this.time.current);
|
||||
}
|
||||
catch(e) {
|
||||
log_error(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,219 +0,0 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const { extensionUtils } = imports.misc;
|
||||
const { Gio } = imports.gi;
|
||||
const { main } = imports.ui;
|
||||
|
||||
const Me = extensionUtils.getCurrentExtension();
|
||||
const config = Me.imports.config;
|
||||
const utils = Me.imports.utils;
|
||||
|
||||
const { log_debug, log_error } = Me.imports.utils;
|
||||
|
||||
const { Variants } = Me.imports.modules.Variants;
|
||||
|
||||
const Gettext = imports.gettext.domain(Me.metadata.uuid);
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
|
||||
/*
|
||||
The Themer communicates with the system to get the current theme or set a new
|
||||
one, and get the day and night variants of a theme. It listens to theme changes
|
||||
and reports them.
|
||||
*/
|
||||
|
||||
var Themer = class {
|
||||
|
||||
constructor() {
|
||||
log_debug('Initializing Themer...');
|
||||
this.settings = extensionUtils.getSettings();
|
||||
this.theme_gsettings = new Gio.Settings({ schema: config.THEME_GSETTINGS_SCHEMA });
|
||||
log_debug('Themer initialized.');
|
||||
}
|
||||
|
||||
enable() {
|
||||
try {
|
||||
log_debug('Enabling Themer...');
|
||||
this.ready = false;
|
||||
this._listen_to_force_manual_status();
|
||||
if ( this._is_force_manual_enabled() ) {
|
||||
log_debug('Using manually set variants.');
|
||||
this._listen_to_prefs_theme_change();
|
||||
}
|
||||
else {
|
||||
log_debug('Automatically detecting variants.');
|
||||
this._listen_to_theme_changes();
|
||||
this.update_variants();
|
||||
}
|
||||
this.ready = true;
|
||||
this.emit();
|
||||
log_debug('Themer enabled.');
|
||||
}
|
||||
catch(e) {
|
||||
log_error(e);
|
||||
}
|
||||
}
|
||||
|
||||
disable() {
|
||||
log_debug('Disabling Themer...');
|
||||
this._stop_listening_to_force_manual_status();
|
||||
if ( this._is_force_manual_enabled() ) {
|
||||
this._stop_listening_to_prefs_theme_change();
|
||||
}
|
||||
else {
|
||||
this._stop_listening_to_theme_changes();
|
||||
// GNOME Shell disables extensions when locking the screen. We'll
|
||||
// only reset the theme if the user disables the extension to
|
||||
// prevent flickering when unlocking.
|
||||
if ( !main.screenShield.locked ) {
|
||||
this.reset_theme();
|
||||
}
|
||||
}
|
||||
log_debug('Themer disabled.');
|
||||
}
|
||||
|
||||
get current_theme() {
|
||||
return this.theme_gsettings.get_string(config.THEME_GSETTINGS_PROPERTY);
|
||||
}
|
||||
|
||||
set current_theme(theme) {
|
||||
if ( theme !== this.current_theme ) {
|
||||
this.theme_gsettings.set_string(config.THEME_GSETTINGS_PROPERTY, theme);
|
||||
log_debug(`Theme has been set to "${theme}".`);
|
||||
}
|
||||
}
|
||||
|
||||
subscribe(callback) {
|
||||
this.theme_change_callback = callback;
|
||||
}
|
||||
|
||||
emit() {
|
||||
if ( this.theme_change_callback ) {
|
||||
this.theme_change_callback();
|
||||
}
|
||||
}
|
||||
|
||||
set_variant(variant) {
|
||||
if ( this.ready ) {
|
||||
log_debug(`Setting theme to the "${variant}" variant...`);
|
||||
this.current_theme = this.settings.get_string(`theme-${variant}`);
|
||||
}
|
||||
}
|
||||
|
||||
reset_theme() {
|
||||
this.set_variant('original');
|
||||
log_debug('Theme has been reset to the user\'s original variant.')
|
||||
}
|
||||
|
||||
update_variants() {
|
||||
if ( !this._are_variants_up_to_date() && !this._is_force_manual_enabled() ) {
|
||||
this._update_variants();
|
||||
}
|
||||
}
|
||||
|
||||
_update_variants() {
|
||||
if ( this.current_theme ) {
|
||||
const variants = Variants.guess_from(this.current_theme);
|
||||
if ( utils.is_theme_installed(variants.get('day')) && utils.is_theme_installed(variants.get('night')) ) {
|
||||
variants.forEach( (theme, variant) => this.settings.set_string(`theme-${variant}`, theme) );
|
||||
log_debug(`Variants updated: {day: "${variants.get('day')}", night: "${variants.get('night')}"}`);
|
||||
}
|
||||
else {
|
||||
const message = _('The extension cannot detect the day and night variants for the "%s" theme. Please choose another theme or manually set variants in the extension preferences.').format(variants.get('original'));
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_are_variants_up_to_date() {
|
||||
return ( this.current_theme === this.settings.get_string('theme-day') || this.current_theme === this.settings.get_string('theme-night') );
|
||||
}
|
||||
|
||||
_is_force_manual_enabled() {
|
||||
return this.settings.get_boolean('theme-force-manual');
|
||||
}
|
||||
|
||||
_listen_to_force_manual_status() {
|
||||
if ( !this.force_manual_status_connect ) {
|
||||
this.force_manual_status_connect = this.settings.connect(
|
||||
'changed::theme-force-manual',
|
||||
this._on_force_manual_status_changed.bind(this)
|
||||
);
|
||||
log_debug('Listening to manual variants status changes...');
|
||||
}
|
||||
}
|
||||
|
||||
_stop_listening_to_force_manual_status() {
|
||||
if ( this.settings && this.force_manual_status_connect ) {
|
||||
this.settings.disconnect(this.force_manual_status_connect);
|
||||
this.force_manual_status_connect = null;
|
||||
log_debug('Stopped listening to manual variants status changes.');
|
||||
}
|
||||
}
|
||||
|
||||
_on_force_manual_status_changed() {
|
||||
log_debug('Manual variants status has changed.');
|
||||
this.enable();
|
||||
}
|
||||
|
||||
_listen_to_theme_changes() {
|
||||
if ( !this.theme_change_connect ) {
|
||||
this.theme_change_connect = this.theme_gsettings.connect(
|
||||
'changed::' + config.THEME_GSETTINGS_PROPERTY,
|
||||
this._on_theme_changed.bind(this)
|
||||
);
|
||||
log_debug('Listening for theme changes...');
|
||||
}
|
||||
}
|
||||
|
||||
_stop_listening_to_theme_changes() {
|
||||
if ( this.theme_gsettings && this.theme_change_connect ){
|
||||
this.theme_gsettings.disconnect(this.theme_change_connect);
|
||||
this.theme_change_connect = null;
|
||||
log_debug('Stopped listening for theme changes.');
|
||||
}
|
||||
}
|
||||
|
||||
_on_theme_changed() {
|
||||
log_debug(`Theme has changed to "${this.current_theme}".`);
|
||||
this.ready ? this.emit() : this.enable();
|
||||
}
|
||||
|
||||
_listen_to_prefs_theme_change() {
|
||||
if ( !this.prefs_theme_change_connect ) {
|
||||
this.prefs_theme_change_connect = new Map();
|
||||
['day', 'night'].forEach(time => {
|
||||
this.prefs_theme_change_connect.set(time, this.settings.connect(
|
||||
`changed::theme-${time}`,
|
||||
this._on_theme_changed.bind(this)
|
||||
));
|
||||
log_debug(`Listening for ${time} theme preference changes...`);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_stop_listening_to_prefs_theme_change() {
|
||||
if ( this.settings && this.prefs_theme_change_connect ) {
|
||||
this.prefs_theme_change_connect.forEach(connect => this.settings.disconnect(connect));
|
||||
this.prefs_theme_change_connect = null;
|
||||
log_debug('Stopped listening to theme preferences changes.');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+133
-486
@@ -16,527 +16,174 @@ You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const MainLoop = imports.mainloop;
|
||||
const { Gio, GLib } = imports.gi;
|
||||
const { extensionUtils, fileUtils } = imports.misc;
|
||||
const { extensionUtils } = imports.misc;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const Me = extensionUtils.getCurrentExtension();
|
||||
const config = Me.imports.config;
|
||||
|
||||
const { log_debug, log_error } = Me.imports.utils;
|
||||
|
||||
const Gettext = imports.gettext.domain(Me.metadata.uuid);
|
||||
const _ = Gettext.gettext;
|
||||
const e = Me.imports.extension;
|
||||
const { log_debug } = Me.imports.utils;
|
||||
const { TimerNightlight } = Me.imports.modules.TimerNightlight;
|
||||
const { TimerLocation } = Me.imports.modules.TimerLocation;
|
||||
const { TimerSchedule } = Me.imports.modules.TimerSchedule;
|
||||
|
||||
|
||||
/*
|
||||
The Timer checks for changes in the time of day and reports them.
|
||||
|
||||
I can either use Night Light or Location Services as a source.
|
||||
|
||||
As Night Light or Location Services are essential for the extension to work,
|
||||
it continuously checks if one of them is enabled and warns the user if that's
|
||||
not the case. To not overwhelm the user with notifications, it only warns once
|
||||
and then only listens to Night Light or Location Services changes to reactivate
|
||||
itself automatically.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Timer is responsible for signaling any time change to the other modules.
|
||||
*
|
||||
* They can connect to its 'time-changed' signal and ask its 'time' property
|
||||
* for the current time.
|
||||
*
|
||||
* It will try to use one of this three different time sources, in this order of
|
||||
* preference:
|
||||
* - Night Light
|
||||
* - Location Services
|
||||
* - Manual schedule
|
||||
*
|
||||
* The user can manually force a specific time source and set the manual
|
||||
* schedule in the extensions's preferences.
|
||||
*/
|
||||
var Timer = class {
|
||||
|
||||
constructor() {
|
||||
log_debug('Initializing Timer...');
|
||||
this.settings = extensionUtils.getSettings();
|
||||
this.nightlight_gsettings = new Gio.Settings({ schema: config.NIGHTLIGHT_GSETTINGS_SCHEMA });
|
||||
this.location_gsettings = new Gio.Settings({ schema: config.LOCATION_GSETTINGS_SCHEMA });
|
||||
log_debug('Timer initialized.');
|
||||
this._source = null;
|
||||
this._previous_time = null;
|
||||
}
|
||||
|
||||
enable() {
|
||||
log_debug('Enabling Timer...');
|
||||
try {
|
||||
this.ready = false;
|
||||
this.settings.set_string('time-source', this._get_source());
|
||||
this._listen_to_nightlight_status();
|
||||
this._listen_to_location_status();
|
||||
this._listen_to_force_manual_status();
|
||||
switch (this.settings.get_string('time-source')) {
|
||||
case 'nightlight':
|
||||
log_debug('Using Night Light as a source.');
|
||||
this._connect_to_color_dbus_proxy();
|
||||
this._listen_to_nightlight_changes();
|
||||
break;
|
||||
case 'location':
|
||||
log_debug('Using Location Services as a source.');
|
||||
this._connect_to_geoclue_dbus_proxy();
|
||||
this._listen_to_location_changes();
|
||||
this._connect_to_geoclue_location_dbus_proxy();
|
||||
this._update_location();
|
||||
this._update_location_suntimes();
|
||||
this._watch_for_location_time_change();
|
||||
this._regularly_update_location_suntimes();
|
||||
break;
|
||||
case 'manual':
|
||||
log_debug('Using manual schedule as a source.');
|
||||
this._watch_for_location_time_change();
|
||||
}
|
||||
this.ready = true;
|
||||
this.emit();
|
||||
log_debug('Timer enabled.');
|
||||
}
|
||||
catch(e) {
|
||||
log_error(e);
|
||||
}
|
||||
this._connect_settings();
|
||||
this._create_source();
|
||||
this._connect_source();
|
||||
this._enable_source();
|
||||
log_debug('Timer enabled.');
|
||||
}
|
||||
|
||||
disable() {
|
||||
log_debug('Disabling Timer...');
|
||||
this._stop_listening_to_nightlight_status();
|
||||
this._stop_listening_to_location_status();
|
||||
this._stop_listening_to_force_manual_status();
|
||||
switch (this.settings.get_string('time-source')) {
|
||||
case 'nightlight':
|
||||
this._stop_listening_to_nightlight_changes();
|
||||
this._disconnect_from_color_dbus_proxy();
|
||||
break;
|
||||
case 'location':
|
||||
this._stop_regularly_updating_location_suntimes();
|
||||
this._stop_watching_for_location_time_change();
|
||||
this._stop_listening_to_location_changes();
|
||||
this._disconnect_from_geoclue_location_dbus_proxy();
|
||||
this._disconnect_from_geoclue_dbus_proxy();
|
||||
break;
|
||||
}
|
||||
this._disconnect_source();
|
||||
this._disable_source();
|
||||
this._disconnect_settings();
|
||||
log_debug('Timer disabled.');
|
||||
}
|
||||
|
||||
get current() {
|
||||
if ( this.ready ) {
|
||||
switch (this.settings.get_string('time-source')) {
|
||||
case 'nightlight':
|
||||
return this._is_nightlight_active() ? 'night' : 'day';
|
||||
case 'location':
|
||||
case 'manual':
|
||||
return this._is_location_daytime() ? 'day' : 'night';
|
||||
}
|
||||
|
||||
get time() {
|
||||
return this._source.time;
|
||||
}
|
||||
|
||||
|
||||
_connect_settings() {
|
||||
log_debug('Connecting Timer to settings...');
|
||||
this._nightlight_status_changed_connect = e.settingsManager.connect('nightlight-status-changed', this._on_source_changed.bind(this));
|
||||
this._location_status_changed_connect = e.settingsManager.connect('location-status-changed', this._on_source_changed.bind(this));
|
||||
this._manual_time_source_changed_connect = e.settingsManager.connect('manual-time-source-changed', this._on_source_changed.bind(this));
|
||||
this._time_source_changed_connect = e.settingsManager.connect('time-source-changed', this._on_time_source_changed.bind(this));
|
||||
}
|
||||
|
||||
_disconnect_settings() {
|
||||
if ( this._nightlight_status_changed_connect ) {
|
||||
e.settingsManager.disconnect(this._nightlight_status_changed_connect);
|
||||
this._nightlight_status_changed_connect = null;
|
||||
}
|
||||
else {
|
||||
return 'day';
|
||||
if ( this._location_status_changed_connect ) {
|
||||
e.settingsManager.disconnect(this._location_status_changed_connect);
|
||||
this._location_status_changed_connect = null;
|
||||
}
|
||||
if ( this._manual_time_source_changed_connect ) {
|
||||
e.settingsManager.disconnect(this._manual_time_source_changed_connect);
|
||||
this._manual_time_source_changed_connect = null;
|
||||
}
|
||||
if ( this._time_source_changed_connect ) {
|
||||
e.settingsManager.disconnect(this._time_source_changed_connect);
|
||||
this._time_source_changed_connect = null;
|
||||
}
|
||||
log_debug('Disconnected Timer from settings.');
|
||||
}
|
||||
|
||||
_create_source() {
|
||||
switch ( this._get_source() ) {
|
||||
case 'nightlight':
|
||||
this._source = new TimerNightlight();
|
||||
break;
|
||||
case 'location':
|
||||
this._source = new TimerLocation();
|
||||
break;
|
||||
case 'schedule':
|
||||
this._source = new TimerSchedule();
|
||||
break;
|
||||
}
|
||||
this._source.enable();
|
||||
}
|
||||
|
||||
_enable_source() {
|
||||
this._source.enable();
|
||||
}
|
||||
|
||||
_disable_source() {
|
||||
if ( this._source ) {
|
||||
this._source.disable();
|
||||
this._source = null;
|
||||
}
|
||||
}
|
||||
|
||||
subscribe(callback) {
|
||||
this.time_change_callback = callback;
|
||||
_connect_source() {
|
||||
log_debug('Connecting to time source...');
|
||||
this._time_changed_connect = this._source.connect('time-changed', this._on_time_changed.bind(this));
|
||||
}
|
||||
|
||||
emit() {
|
||||
if ( this.time_change_callback ) {
|
||||
this.time_change_callback();
|
||||
_disconnect_source() {
|
||||
if ( this._time_changed_connect ) {
|
||||
this._source.disconnect(this._time_changed_connect);
|
||||
this._time_changed_connect = null;
|
||||
}
|
||||
log_debug('Disconnected from time source.');
|
||||
}
|
||||
|
||||
|
||||
_on_source_changed() {
|
||||
this.disable();
|
||||
this.enable();
|
||||
}
|
||||
|
||||
_on_time_source_changed(settings, new_source) {
|
||||
if ( e.settingsManager.manual_time_source ) {
|
||||
this._on_source_changed();
|
||||
}
|
||||
}
|
||||
|
||||
_on_time_changed(source, new_time) {
|
||||
if ( new_time !== this._previous_time) {
|
||||
log_debug(`Time has changed to ${new_time}.`);
|
||||
this.emit('time-changed', new_time);
|
||||
this._previous_time = new_time;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_get_source() {
|
||||
if ( this._is_force_manual_enabled() ) {
|
||||
return 'manual';
|
||||
log_debug('Getting time source...');
|
||||
|
||||
if ( e.settingsManager.manual_time_source ) {
|
||||
log_debug(`Time source is forced to ${e.settingsManager.time_source}.`);
|
||||
return e.settingsManager.time_source;
|
||||
}
|
||||
else if ( this._is_nightlight_enabled() ) {
|
||||
return 'nightlight';
|
||||
|
||||
let source;
|
||||
if ( e.settingsManager.nightlight_enabled ) {
|
||||
source = 'nightlight';
|
||||
}
|
||||
else if ( this._is_location_enabled() ) {
|
||||
return 'location';
|
||||
else if ( e.settingsManager.location_enabled ) {
|
||||
source = 'location';
|
||||
}
|
||||
else {
|
||||
return 'manual';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Check if Night Light is enabled and restart the Timer on changes.
|
||||
*/
|
||||
|
||||
_is_nightlight_enabled() {
|
||||
return this.nightlight_gsettings.get_boolean(config.NIGHTLIGHT_GSETTINGS_PROPERTY);
|
||||
}
|
||||
|
||||
_listen_to_nightlight_status() {
|
||||
if ( !this.nightlight_status_connect ) {
|
||||
this.nightlight_status_connect = this.nightlight_gsettings.connect(
|
||||
'changed::' + config.NIGHTLIGHT_GSETTINGS_PROPERTY,
|
||||
this._on_nightlight_status_changed.bind(this)
|
||||
);
|
||||
log_debug('Listening to Night Light status changes...');
|
||||
}
|
||||
}
|
||||
|
||||
_stop_listening_to_nightlight_status() {
|
||||
if ( this.nightlight_gsettings && this.nightlight_status_connect ) {
|
||||
this.nightlight_gsettings.disconnect(this.nightlight_status_connect);
|
||||
this.nightlight_status_connect = null;
|
||||
log_debug('Stopped listening to Night Light status changes.');
|
||||
}
|
||||
}
|
||||
|
||||
_on_nightlight_status_changed() {
|
||||
log_debug('Night Light status has changed.');
|
||||
this.enable();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Check if Location Services are enabled and restart the Timer on changes.
|
||||
*/
|
||||
|
||||
_is_location_enabled() {
|
||||
return this.location_gsettings.get_boolean(config.LOCATION_GSETTINGS_PROPERTY);
|
||||
}
|
||||
|
||||
_listen_to_location_status() {
|
||||
if ( !this.location_status_connect ) {
|
||||
this.location_status_connect = this.location_gsettings.connect(
|
||||
'changed::' + config.LOCATION_GSETTINGS_PROPERTY,
|
||||
this._on_location_status_changed.bind(this)
|
||||
);
|
||||
log_debug('Listening to Location Services status changes...');
|
||||
}
|
||||
}
|
||||
|
||||
_stop_listening_to_location_status() {
|
||||
if ( this.location_gsettings && this.location_status_connect ) {
|
||||
this.location_gsettings.disconnect(this.location_status_connect);
|
||||
this.location_status_connect = null;
|
||||
log_debug('Stopped listening to Location Services status changes.');
|
||||
}
|
||||
}
|
||||
|
||||
_on_location_status_changed() {
|
||||
log_debug('Location Services status has changed.');
|
||||
this.enable();
|
||||
}
|
||||
|
||||
/*
|
||||
Check if the user wants to force a manual schedule and restart the Timer on
|
||||
changes.
|
||||
*/
|
||||
|
||||
_is_force_manual_enabled() {
|
||||
return this.settings.get_boolean('time-force-manual');
|
||||
}
|
||||
|
||||
_listen_to_force_manual_status() {
|
||||
if ( !this.force_manual_status_connect ) {
|
||||
this.force_manual_status_connect = this.settings.connect(
|
||||
'changed::time-force-manual',
|
||||
this._on_force_manual_status_changed.bind(this)
|
||||
);
|
||||
log_debug('Listening to manual schedule status changes...');
|
||||
}
|
||||
}
|
||||
|
||||
_stop_listening_to_force_manual_status() {
|
||||
if ( this.settings && this.force_manual_status_connect ) {
|
||||
this.settings.disconnect(this.force_manual_status_connect);
|
||||
this.force_manual_status_connect = null;
|
||||
log_debug('Stopped listening to manual schedule status changes.');
|
||||
}
|
||||
}
|
||||
|
||||
_on_force_manual_status_changed() {
|
||||
log_debug('Manual schedule status has changed.');
|
||||
this.enable();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Use Night Light as a time source.
|
||||
*/
|
||||
|
||||
_connect_to_color_dbus_proxy() {
|
||||
try {
|
||||
log_debug('Connecting to Color DBus proxy...');
|
||||
const color_interface = fileUtils.loadInterfaceXML('org.gnome.SettingsDaemon.Color');
|
||||
const ColorProxy = Gio.DBusProxy.makeProxyWrapper(color_interface);
|
||||
this.color_dbus_proxy = new ColorProxy(
|
||||
Gio.DBus.session,
|
||||
'org.gnome.SettingsDaemon.Color',
|
||||
'/org/gnome/SettingsDaemon/Color'
|
||||
);
|
||||
log_debug('Connected to Color DBus proxy.');
|
||||
}
|
||||
catch(e) {
|
||||
const message = _('Unable to connect to Color DBus proxy.');
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
_disconnect_from_color_dbus_proxy() {
|
||||
if ( this.color_dbus_proxy ) {
|
||||
log_debug('Disconnecting from Color DBus Proxy...');
|
||||
this.color_dbus_proxy = null;
|
||||
log_debug('Disconnected from Color DBus Proxy.');
|
||||
}
|
||||
}
|
||||
|
||||
_listen_to_nightlight_changes() {
|
||||
if ( !this.nightlight_changes_connect ) {
|
||||
this.nightlight_changes_connect = this.color_dbus_proxy.connect(
|
||||
'g-properties-changed',
|
||||
this._on_nightlight_changed.bind(this)
|
||||
);
|
||||
log_debug('Listening to Night Light changes...');
|
||||
}
|
||||
}
|
||||
|
||||
_stop_listening_to_nightlight_changes() {
|
||||
if ( this.color_dbus_proxy && this.nightlight_changes_connect ) {
|
||||
this.color_dbus_proxy.disconnect(this.nightlight_changes_connect);
|
||||
this.nightlight_changes_connect = null;
|
||||
log_debug('Stopped listening to Night Light changes.');
|
||||
}
|
||||
}
|
||||
|
||||
_on_nightlight_changed(sender, dbus_properties) {
|
||||
const properties = dbus_properties.deep_unpack();
|
||||
if ( properties.NightLightActive ) {
|
||||
log_debug('Night Light has become ' + (properties.NightLightActive.unpack() ? '' : 'in') + 'active.');
|
||||
this.emit();
|
||||
}
|
||||
}
|
||||
|
||||
_is_nightlight_active() {
|
||||
if ( this.color_dbus_proxy ) {
|
||||
return this.color_dbus_proxy.NightLightActive;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Use location as a time source.
|
||||
*/
|
||||
|
||||
_connect_to_geoclue_dbus_proxy() {
|
||||
try {
|
||||
log_debug('Connecting to GeoClue Manager DBus proxy...');
|
||||
const GeoClueManagerProxy = Gio.DBusProxy.makeProxyWrapper(config.GEOCLUE_MANAGER_INTERFACE);
|
||||
this.geoclue_manager_dbus_proxy = new GeoClueManagerProxy(
|
||||
Gio.DBus.system,
|
||||
'org.freedesktop.GeoClue2',
|
||||
'/org/freedesktop/GeoClue2/Manager'
|
||||
);
|
||||
log_debug('Connected to GeoClue Manager DBus proxy.');
|
||||
}
|
||||
catch(e) {
|
||||
const message = _('Unable to connect to GeoClue Manager DBus proxy.');
|
||||
throw new Error(message);
|
||||
source = 'schedule';
|
||||
}
|
||||
|
||||
try {
|
||||
log_debug('Requesting new GeoClue Client...');
|
||||
this.geoclue_client = this.geoclue_manager_dbus_proxy.GetClientSync()[0];
|
||||
log_debug(`Got a GeoClue Client at ${this.geoclue_client}`);
|
||||
}
|
||||
catch(e) {
|
||||
const message = _('Unable to get a GeoClue Client.');
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
try {
|
||||
log_debug('Connecting to GeoClue Client DBus proxy...');
|
||||
const GeoClueClientProxy = Gio.DBusProxy.makeProxyWrapper(config.GEOCLUE_CLIENT_INTERFACE);
|
||||
this.geoclue_client_dbus_proxy = new GeoClueClientProxy(
|
||||
Gio.DBus.system,
|
||||
'org.freedesktop.GeoClue2',
|
||||
this.geoclue_client
|
||||
);
|
||||
this.geoclue_client_dbus_proxy.DesktopId = Me.metadata.uuid;
|
||||
this.geoclue_client_dbus_proxy.DistanceThreshold = 10000;
|
||||
this.geoclue_client_dbus_proxy.RequestedAccuracyLevel = 4;
|
||||
log_debug('Connected to GeoClue Client DBus proxy.');
|
||||
}
|
||||
catch(e) {
|
||||
const message = _('Unable to connect to GeoClue Client DBus proxy.');
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
_disconnect_from_geoclue_dbus_proxy() {
|
||||
if ( this.geoclue_client_dbus_proxy ) {
|
||||
log_debug('Disconnecting from GeoClue Client DBus proxy...');
|
||||
if ( this.geoclue_manager_dbus_proxy && this.geoclue_client ) {
|
||||
this.geoclue_manager_dbus_proxy.DeleteClientSync(this.geoclue_client);
|
||||
this.geoclue_client = null;
|
||||
}
|
||||
this.geoclue_client_dbus_proxy = null;
|
||||
log_debug('Disconnected from GeoClue Client DBus Proxy.');
|
||||
}
|
||||
|
||||
if ( this.geoclue_manager_dbus_proxy ) {
|
||||
log_debug('Disconnecting from GeoClue Manager DBus proxy...');
|
||||
this.geoclue_manager_dbus_proxy = null;
|
||||
log_debug('Disconnected from GeoClue Manager DBus proxy.');
|
||||
}
|
||||
}
|
||||
|
||||
_listen_to_location_changes() {
|
||||
if ( !this.location_changes_connect ) {
|
||||
this.location_changes_connect = this.geoclue_client_dbus_proxy.connectSignal('LocationUpdated', this._on_location_changed.bind(this));
|
||||
this.geoclue_client_dbus_proxy.StartSync();
|
||||
log_debug('Listening to location changes...');
|
||||
}
|
||||
}
|
||||
|
||||
_stop_listening_to_location_changes() {
|
||||
if ( this.geoclue_client_dbus_proxy && this.location_changes_connect ) {
|
||||
this.geoclue_client_dbus_proxy.disconnectSignal(this.location_changes_connect);
|
||||
this.location_changes_connect = null;
|
||||
this.geoclue_client_dbus_proxy.StopSync();
|
||||
log_debug('Stopped listening to location changes.');
|
||||
}
|
||||
}
|
||||
|
||||
_on_location_changed(proxy, sender, [old_location_path, new_location_path]) {
|
||||
log_debug('Location has changed.');
|
||||
this._connect_to_geoclue_location_dbus_proxy(new_location_path);
|
||||
this._update_location();
|
||||
this._update_location_suntimes();
|
||||
}
|
||||
|
||||
_connect_to_geoclue_location_dbus_proxy(path) {
|
||||
if ( !path && this.geoclue_client_dbus_proxy ) {
|
||||
path = this.geoclue_client_dbus_proxy.Location;
|
||||
}
|
||||
if ( path !== '/' ) {
|
||||
try {
|
||||
log_debug('Connecting to GeoClue Location DBus proxy...');
|
||||
const GeoClueLocationProxy = Gio.DBusProxy.makeProxyWrapper(config.GEOCLUE_LOCATION_INTERFACE);
|
||||
this.geoclue_location_dbus_proxy = new GeoClueLocationProxy(
|
||||
Gio.DBus.system,
|
||||
'org.freedesktop.GeoClue2',
|
||||
path
|
||||
);
|
||||
log_debug('Connected to GeoClue Location DBus proxy.');
|
||||
}
|
||||
catch(e) {
|
||||
const message = _('Unable to connect to GeoClue Location DBus proxy.');
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_disconnect_from_geoclue_location_dbus_proxy() {
|
||||
if ( this.geoclue_location_dbus_proxy ) {
|
||||
log_debug('Disconnecting from GeoClue Location DBus proxy...');
|
||||
this.geoclue_location_dbus_proxy = null;
|
||||
log_debug('Disconnected from GeoClue Location DBus proxy.')
|
||||
}
|
||||
}
|
||||
|
||||
_update_location() {
|
||||
if ( this.geoclue_location_dbus_proxy ) {
|
||||
try {
|
||||
log_debug('Updating location...');
|
||||
const latitude = this.geoclue_location_dbus_proxy.Latitude;
|
||||
const longitude = this.geoclue_location_dbus_proxy.Longitude;
|
||||
|
||||
this.location = new Map([
|
||||
['latitude', latitude],
|
||||
['longitude', longitude]
|
||||
]);
|
||||
log_debug(`Current location: (${latitude};${longitude})`);
|
||||
}
|
||||
catch(e) {
|
||||
const message = _('Unable to get current location.');
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_update_location_suntimes() {
|
||||
if ( !this.location ) {
|
||||
return;
|
||||
}
|
||||
|
||||
log_debug('Updating sun times...');
|
||||
|
||||
Math.rad = degrees => degrees * Math.PI / 180;
|
||||
Math.deg = radians => radians * 180 / Math.PI;
|
||||
|
||||
// Calculations from https://www.esrl.noaa.gov/gmd/grad/solcalc/calcdetails.html
|
||||
const latitude = this.location.get('latitude');
|
||||
const longitude = this.location.get('longitude');
|
||||
|
||||
const dt_now = GLib.DateTime.new_now_local();
|
||||
const dt_zero = GLib.DateTime.new_utc(1900, 1, 1, 0, 0, 0);
|
||||
|
||||
const time_span = dt_now.difference(dt_zero);
|
||||
|
||||
const date = time_span / 1000 / 1000 / 60 / 60 / 24 + 2;
|
||||
const tz_offset = dt_now.get_utc_offset() / 1000 / 1000 / 60 / 60;
|
||||
const time_past_local_midnight = 0;
|
||||
|
||||
const julian_day = date + 2415018.5 + time_past_local_midnight - tz_offset / 24;
|
||||
const julian_century = (julian_day - 2451545) / 36525;
|
||||
const geom_mean_long_sun = (280.46646 + julian_century * (36000.76983 + julian_century * 0.0003032)) % 360;
|
||||
const geom_mean_anom_sun = 357.52911 + julian_century * (35999.05029 - 0.0001537 * julian_century);
|
||||
const eccent_earth_orbit = 0.016708634 - julian_century * (0.000042037 + 0.0000001267 * julian_century);
|
||||
const sun_eq_of_ctr = Math.sin(Math.rad(geom_mean_anom_sun)) * (1.914602 - julian_century * (0.004817 + 0.000014 * julian_century)) + Math.sin(Math.rad(2 * geom_mean_anom_sun)) * (0.019993 - 0.000101 * julian_century) + Math.sin(Math.rad(3 * geom_mean_anom_sun)) * 0.000289;
|
||||
const sun_true_long = geom_mean_long_sun + sun_eq_of_ctr;
|
||||
const sun_app_long = sun_true_long - 0.00569 - 0.00478 * Math.sin(Math.rad(125.04 - 1934.136 * julian_century));
|
||||
const mean_obliq_ecliptic = 23 + (26 + ((21.448 - julian_century * (46.815 + julian_century * (0.00059 - julian_century * 0.001813)))) / 60) / 60;
|
||||
const obliq_corr = mean_obliq_ecliptic + 0.00256 * Math.cos(Math.rad(125.04 - 1934.136 * julian_century));
|
||||
const sun_declin = Math.deg(Math.asin(Math.sin(Math.rad(obliq_corr)) * Math.sin(Math.rad(sun_app_long))));
|
||||
const var_y = Math.tan(Math.rad(obliq_corr / 2)) * Math.tan(Math.rad(obliq_corr / 2));
|
||||
const eq_of_time = 4 * Math.deg(var_y * Math.sin(2 * Math.rad(geom_mean_long_sun)) - 2 * eccent_earth_orbit * Math.sin(Math.rad(geom_mean_anom_sun)) + 4 * eccent_earth_orbit * var_y * Math.sin(Math.rad(geom_mean_anom_sun)) * Math.cos(2 * Math.rad(geom_mean_long_sun)) - 0.5 * var_y * var_y * Math.sin(4 * Math.rad(geom_mean_long_sun)) - 1.25 * eccent_earth_orbit * eccent_earth_orbit * Math.sin(2 * Math.rad(geom_mean_anom_sun)));
|
||||
const ha_sunrise = Math.deg(Math.acos(Math.cos(Math.rad(90.833)) / (Math.cos(Math.rad(latitude)) * Math.cos(Math.rad(sun_declin))) - Math.tan(Math.rad(latitude)) * Math.tan(Math.rad(sun_declin))));
|
||||
const solar_noon = (720 - 4 * longitude - eq_of_time + tz_offset * 60) / 1440;
|
||||
|
||||
const sunrise_time = solar_noon - ha_sunrise * 4 / 1440;
|
||||
const sunset_time = solar_noon + ha_sunrise * 4 / 1440;
|
||||
|
||||
const sunrise = sunrise_time * 24;
|
||||
const sunset = sunset_time * 24;
|
||||
|
||||
this.settings.set_double('time-sunrise', sunrise);
|
||||
this.settings.set_double('time-sunset', sunset);
|
||||
log_debug(`New sun times: (sunrise: ${sunrise}; sunset: ${sunset})`);
|
||||
}
|
||||
|
||||
_regularly_update_location_suntimes() {
|
||||
this.regularly_update_suntimes_timer = MainLoop.timeout_add_seconds(3600, () => {
|
||||
this._update_location_suntimes();
|
||||
return true; // Repeat the loop
|
||||
});
|
||||
}
|
||||
|
||||
_stop_regularly_updating_location_suntimes() {
|
||||
if ( this.regularly_update_suntimes_timer ) {
|
||||
MainLoop.source_remove(this.regularly_update_suntimes_timer);
|
||||
this.regularly_update_suntimes_timer = null;
|
||||
}
|
||||
}
|
||||
|
||||
_is_location_daytime() {
|
||||
const time = GLib.DateTime.new_now_local();
|
||||
const hour = time.get_hour() + time.get_minute() / 60 + time.get_second() / 3600;
|
||||
return ( hour >= this.settings.get_double('time-sunrise') && hour <= this.settings.get_double('time-sunset') );
|
||||
}
|
||||
|
||||
_watch_for_location_time_change() {
|
||||
this.location_time_change_timer = MainLoop.timeout_add_seconds(1, () => {
|
||||
const previous_time = this.location_daytime;
|
||||
if ( previous_time !== this._is_location_daytime() ) {
|
||||
log_debug('Time of the day has changed.');
|
||||
this.location_daytime = this._is_location_daytime();
|
||||
this.emit();
|
||||
}
|
||||
return true; // Repeat the loop
|
||||
}, null);
|
||||
}
|
||||
|
||||
_stop_watching_for_location_time_change() {
|
||||
if ( this.location_time_change_timer ) {
|
||||
MainLoop.source_remove(this.location_time_change_timer);
|
||||
this.location_time_change_timer = null;
|
||||
}
|
||||
log_debug(`Time source is ${source}.`);
|
||||
e.settingsManager.time_source = source;
|
||||
return source;
|
||||
}
|
||||
|
||||
}
|
||||
Signals.addSignalMethods(Timer.prototype);
|
||||
|
||||
@@ -0,0 +1,322 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const { Gio, GLib } = imports.gi;
|
||||
const { extensionUtils } = imports.misc;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const Me = extensionUtils.getCurrentExtension();
|
||||
|
||||
const e = Me.imports.extension;
|
||||
const { log_debug } = Me.imports.utils;
|
||||
|
||||
|
||||
// GeoClue2 interfaces from https://gitlab.freedesktop.org/geoclue/geoclue/
|
||||
const GEOCLUE_MANAGER_INTERFACE = `
|
||||
<node>
|
||||
<interface name="org.freedesktop.GeoClue2.Manager">
|
||||
<property name="InUse" type="b" access="read"/>
|
||||
<property name="AvailableAccuracyLevel" type="u" access="read"/>
|
||||
<method name="GetClient">
|
||||
<arg name="client" type="o" direction="out"/>
|
||||
</method>
|
||||
<method name="CreateClient">
|
||||
<arg name="client" type="o" direction="out"/>
|
||||
</method>
|
||||
<method name="DeleteClient">
|
||||
<arg name="client" type="o" direction="in"/>
|
||||
</method>
|
||||
<method name="AddAgent">
|
||||
<arg name="id" type="s" direction="in"/>
|
||||
</method>
|
||||
</interface>
|
||||
</node>`;
|
||||
|
||||
const GEOCLUE_CLIENT_INTERFACE = `
|
||||
<node>
|
||||
<interface name="org.freedesktop.GeoClue2.Client">
|
||||
<property name="Location" type="o" access="read"/>
|
||||
<property name="DistanceThreshold" type="u" access="readwrite">
|
||||
<annotation name="org.freedesktop.Accounts.DefaultValue" value="0"/>
|
||||
</property>
|
||||
<property name="TimeThreshold" type="u" access="readwrite">
|
||||
<annotation name="org.freedesktop.Accounts.DefaultValue" value="0"/>
|
||||
</property>
|
||||
<property name="DesktopId" type="s" access="readwrite"/>
|
||||
<property name="RequestedAccuracyLevel" type="u" access="readwrite"/>
|
||||
<property name="Active" type="b" access="read"/>
|
||||
<method name="Start"/>
|
||||
<method name="Stop"/>
|
||||
<signal name="LocationUpdated">
|
||||
<arg name="old" type="o"/>
|
||||
<arg name="new" type="o"/>
|
||||
</signal>
|
||||
</interface>
|
||||
</node>`;
|
||||
|
||||
const GEOCLUE_LOCATION_INTERFACE = `
|
||||
<node>
|
||||
<interface name="org.freedesktop.GeoClue2.Location">
|
||||
<property name="Latitude" type="d" access="read"/>
|
||||
<property name="Longitude" type="d" access="read"/>
|
||||
<property name="Accuracy" type="d" access="read"/>
|
||||
<property name="Altitude" type="d" access="read"/>
|
||||
<property name="Speed" type="d" access="read"/>
|
||||
<property name="Heading" type="d" access="read"/>
|
||||
<property name="Description" type="s" access="read"/>
|
||||
<property name="Timestamp" type="(tt)" access="read"/>
|
||||
</interface>
|
||||
</node>`;
|
||||
|
||||
|
||||
/**
|
||||
* The Location Timer uses Location Services to get the current sunrise and
|
||||
* sunset times.
|
||||
*
|
||||
* It gets the current user's location with the GeoClue2 DBus proxy and
|
||||
* calculate the times.
|
||||
*
|
||||
* It will recalculate every hour and when the user's location changed to stay
|
||||
* up to date.
|
||||
*
|
||||
* Every second, it will check if the time has changed and signal if that's the
|
||||
* case.
|
||||
*/
|
||||
var TimerLocation = class {
|
||||
|
||||
constructor() {
|
||||
this._previously_daytime = null;
|
||||
// Before we have the location suntimes, we'll use the manual schedule
|
||||
// times
|
||||
this._suntimes = new Map([
|
||||
['sunrise', e.settingsManager.schedule_sunrise],
|
||||
['sunset', e.settingsManager.schedule_sunrise]
|
||||
]);
|
||||
}
|
||||
|
||||
enable() {
|
||||
log_debug('Enabling Location Timer...');
|
||||
this._connect_to_geoclue_dbus_proxy();
|
||||
this._listen_to_location_updates();
|
||||
this._connect_to_geoclue_location_dbus_proxy();
|
||||
this._update_location();
|
||||
this._update_suntimes();
|
||||
this._watch_for_time_change();
|
||||
this._regularly_update_suntimes();
|
||||
log_debug('Location Timer enabled.');
|
||||
}
|
||||
|
||||
disable() {
|
||||
log_debug('Disabling Location Timer...');
|
||||
this._stop_regularly_updating_suntimes();
|
||||
this._stop_watching_for_time_change();
|
||||
this._stop_listening_to_location_updates();
|
||||
this._disconnect_from_geoclue_location_dbus_proxy();
|
||||
this._disconnect_from_geoclue_dbus_proxy();
|
||||
log_debug('Location Timer disabled.');
|
||||
}
|
||||
|
||||
|
||||
get time() {
|
||||
return this._is_daytime() ? 'day' : 'night';
|
||||
}
|
||||
|
||||
_connect_to_geoclue_dbus_proxy() {
|
||||
log_debug('Connecting to GeoClue manager DBus proxy...');
|
||||
const GeoClueManagerProxy = Gio.DBusProxy.makeProxyWrapper(GEOCLUE_MANAGER_INTERFACE);
|
||||
this._geoclue_manager_dbus_proxy = new GeoClueManagerProxy(
|
||||
Gio.DBus.system,
|
||||
'org.freedesktop.GeoClue2',
|
||||
'/org/freedesktop/GeoClue2/Manager'
|
||||
);
|
||||
log_debug('Connected to GeoClue manager DBus proxy.');
|
||||
|
||||
log_debug('Getting a GeoClue client...');
|
||||
this._geoclue_client = this._geoclue_manager_dbus_proxy.GetClientSync()[0];
|
||||
log_debug(`Got a GeoClue client at ${this._geoclue_client}`);
|
||||
|
||||
log_debug('Connecting to GeoClue client DBus proxy...');
|
||||
const GeoClueClientProxy = Gio.DBusProxy.makeProxyWrapper(GEOCLUE_CLIENT_INTERFACE);
|
||||
this._geoclue_client_dbus_proxy = new GeoClueClientProxy(
|
||||
Gio.DBus.system,
|
||||
'org.freedesktop.GeoClue2',
|
||||
this._geoclue_client
|
||||
);
|
||||
this._geoclue_client_dbus_proxy.DesktopId = Me.metadata.uuid;
|
||||
this._geoclue_client_dbus_proxy.DistanceThreshold = 10000;
|
||||
this._geoclue_client_dbus_proxy.RequestedAccuracyLevel = 4;
|
||||
log_debug('Connected to GeoClue client DBus proxy.');
|
||||
}
|
||||
|
||||
_disconnect_from_geoclue_dbus_proxy() {
|
||||
log_debug('Disconnecting from GeoClue DBus proxy...')
|
||||
this._geoclue_manager_dbus_proxy.DeleteClientSync(this._geoclue_client);
|
||||
this._geoclue_client = null;
|
||||
this._geoclue_client_dbus_proxy = null;
|
||||
this._geoclue_manager_dbus_proxy = null;
|
||||
log_debug('Disconnected from GeoClue DBus proxy.')
|
||||
}
|
||||
|
||||
_listen_to_location_updates() {
|
||||
log_debug('Listening to location updates...');
|
||||
this._location_updates_connect = this._geoclue_client_dbus_proxy.connectSignal('LocationUpdated', this._on_location_updated.bind(this));
|
||||
this._geoclue_client_dbus_proxy.StartSync();
|
||||
}
|
||||
|
||||
_stop_listening_to_location_updates() {
|
||||
this._geoclue_client_dbus_proxy.disconnectSignal(this._location_updates_connect);
|
||||
this._location_updates_connect = null;
|
||||
this._geoclue_client_dbus_proxy.StopSync();
|
||||
log_debug('Stopped listening to location updates.');
|
||||
}
|
||||
|
||||
_on_location_updated(proxy, sender, [old_location_path, new_location_path]) {
|
||||
log_debug('Location has changed.');
|
||||
this._connect_to_geoclue_location_dbus_proxy(new_location_path);
|
||||
this._update_location();
|
||||
this._update_suntimes();
|
||||
}
|
||||
|
||||
_connect_to_geoclue_location_dbus_proxy(path) {
|
||||
if ( !path ) {
|
||||
path = this._geoclue_client_dbus_proxy.Location;
|
||||
}
|
||||
if ( path !== '/' ) {
|
||||
log_debug('Connecting to GeoClue location DBus proxy...');
|
||||
const GeoClueLocationProxy = Gio.DBusProxy.makeProxyWrapper(GEOCLUE_LOCATION_INTERFACE);
|
||||
this._geoclue_location_dbus_proxy = new GeoClueLocationProxy(
|
||||
Gio.DBus.system,
|
||||
'org.freedesktop.GeoClue2',
|
||||
path
|
||||
);
|
||||
log_debug('Connected to GeoClue location DBus proxy.');
|
||||
}
|
||||
}
|
||||
|
||||
_disconnect_from_geoclue_location_dbus_proxy() {
|
||||
log_debug('Disconnecting from GeoClue location DBus proxy...');
|
||||
this._geoclue_location_dbus_proxy = null;
|
||||
log_debug('Disconnected from GeoClue location DBus proxy.');
|
||||
}
|
||||
|
||||
_update_location() {
|
||||
if ( this._geoclue_location_dbus_proxy ) {
|
||||
log_debug('Updating location...');
|
||||
const latitude = this._geoclue_location_dbus_proxy.Latitude;
|
||||
const longitude = this._geoclue_location_dbus_proxy.Longitude;
|
||||
|
||||
this.location = new Map([
|
||||
['latitude', latitude],
|
||||
['longitude', longitude]
|
||||
]);
|
||||
log_debug(`Current location: (${latitude};${longitude})`);
|
||||
}
|
||||
}
|
||||
|
||||
_update_suntimes() {
|
||||
if ( !this.location ) {
|
||||
return;
|
||||
}
|
||||
|
||||
log_debug('Updating sun times...');
|
||||
|
||||
Math.rad = degrees => degrees * Math.PI / 180;
|
||||
Math.deg = radians => radians * 180 / Math.PI;
|
||||
|
||||
// Calculations from https://www.esrl.noaa.gov/gmd/grad/solcalc/calcdetails.html
|
||||
const latitude = this.location.get('latitude');
|
||||
const longitude = this.location.get('longitude');
|
||||
|
||||
const dt_now = GLib.DateTime.new_now_local();
|
||||
const dt_zero = GLib.DateTime.new_utc(1900, 1, 1, 0, 0, 0);
|
||||
|
||||
const time_span = dt_now.difference(dt_zero);
|
||||
|
||||
const date = time_span / 1000 / 1000 / 60 / 60 / 24 + 2;
|
||||
const tz_offset = dt_now.get_utc_offset() / 1000 / 1000 / 60 / 60;
|
||||
const time_past_local_midnight = 0;
|
||||
|
||||
const julian_day = date + 2415018.5 + time_past_local_midnight - tz_offset / 24;
|
||||
const julian_century = (julian_day - 2451545) / 36525;
|
||||
const geom_mean_long_sun = (280.46646 + julian_century * (36000.76983 + julian_century * 0.0003032)) % 360;
|
||||
const geom_mean_anom_sun = 357.52911 + julian_century * (35999.05029 - 0.0001537 * julian_century);
|
||||
const eccent_earth_orbit = 0.016708634 - julian_century * (0.000042037 + 0.0000001267 * julian_century);
|
||||
const sun_eq_of_ctr = Math.sin(Math.rad(geom_mean_anom_sun)) * (1.914602 - julian_century * (0.004817 + 0.000014 * julian_century)) + Math.sin(Math.rad(2 * geom_mean_anom_sun)) * (0.019993 - 0.000101 * julian_century) + Math.sin(Math.rad(3 * geom_mean_anom_sun)) * 0.000289;
|
||||
const sun_true_long = geom_mean_long_sun + sun_eq_of_ctr;
|
||||
const sun_app_long = sun_true_long - 0.00569 - 0.00478 * Math.sin(Math.rad(125.04 - 1934.136 * julian_century));
|
||||
const mean_obliq_ecliptic = 23 + (26 + ((21.448 - julian_century * (46.815 + julian_century * (0.00059 - julian_century * 0.001813)))) / 60) / 60;
|
||||
const obliq_corr = mean_obliq_ecliptic + 0.00256 * Math.cos(Math.rad(125.04 - 1934.136 * julian_century));
|
||||
const sun_declin = Math.deg(Math.asin(Math.sin(Math.rad(obliq_corr)) * Math.sin(Math.rad(sun_app_long))));
|
||||
const var_y = Math.tan(Math.rad(obliq_corr / 2)) * Math.tan(Math.rad(obliq_corr / 2));
|
||||
const eq_of_time = 4 * Math.deg(var_y * Math.sin(2 * Math.rad(geom_mean_long_sun)) - 2 * eccent_earth_orbit * Math.sin(Math.rad(geom_mean_anom_sun)) + 4 * eccent_earth_orbit * var_y * Math.sin(Math.rad(geom_mean_anom_sun)) * Math.cos(2 * Math.rad(geom_mean_long_sun)) - 0.5 * var_y * var_y * Math.sin(4 * Math.rad(geom_mean_long_sun)) - 1.25 * eccent_earth_orbit * eccent_earth_orbit * Math.sin(2 * Math.rad(geom_mean_anom_sun)));
|
||||
const ha_sunrise = Math.deg(Math.acos(Math.cos(Math.rad(90.833)) / (Math.cos(Math.rad(latitude)) * Math.cos(Math.rad(sun_declin))) - Math.tan(Math.rad(latitude)) * Math.tan(Math.rad(sun_declin))));
|
||||
const solar_noon = (720 - 4 * longitude - eq_of_time + tz_offset * 60) / 1440;
|
||||
|
||||
const sunrise_time = solar_noon - ha_sunrise * 4 / 1440;
|
||||
const sunset_time = solar_noon + ha_sunrise * 4 / 1440;
|
||||
|
||||
const sunrise = sunrise_time * 24;
|
||||
const sunset = sunset_time * 24;
|
||||
|
||||
this._suntimes.set('sunrise', sunrise);
|
||||
this._suntimes.set('sunset', sunset);
|
||||
log_debug(`New sun times: (sunrise: ${sunrise}; sunset: ${sunset})`);
|
||||
}
|
||||
|
||||
_regularly_update_suntimes() {
|
||||
log_debug('Regularly updating sun times...');
|
||||
this._regularly_update_suntimes_timer = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 3600, () => {
|
||||
this._update_suntimes();
|
||||
return true; // Repeat the loop
|
||||
});
|
||||
}
|
||||
|
||||
_stop_regularly_updating_suntimes() {
|
||||
GLib.Source.remove(this._regularly_update_suntimes_timer);
|
||||
this._regularly_update_suntimes_timer = null;
|
||||
log_debug('Stopped regularly updating sun times.');
|
||||
}
|
||||
|
||||
_is_daytime() {
|
||||
const time = GLib.DateTime.new_now_local();
|
||||
const hour = time.get_hour() + time.get_minute() / 60 + time.get_second() / 3600;
|
||||
return ( hour >= this._suntimes.get('sunrise') && hour <= this._suntimes.get('sunset') );
|
||||
}
|
||||
|
||||
_watch_for_time_change() {
|
||||
log_debug('Watching for time change...');
|
||||
this._time_change_timer = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 1, () => {
|
||||
if ( !Me.imports.extension.enabled ) {
|
||||
// The extension doesn't exist anymore, quit the loop
|
||||
return false;
|
||||
}
|
||||
if ( this._previously_daytime !== this._is_daytime() ) {
|
||||
this._previously_daytime = this._is_daytime();
|
||||
this.emit('time-changed', this.time);
|
||||
}
|
||||
return true; // Repeat the loop
|
||||
});
|
||||
}
|
||||
|
||||
_stop_watching_for_time_change() {
|
||||
GLib.Source.remove(this._time_change_timer);
|
||||
log_debug('Stopped watching for time change.');
|
||||
}
|
||||
|
||||
}
|
||||
Signals.addSignalMethods(TimerLocation.prototype);
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const { Gio, GLib } = imports.gi;
|
||||
const { extensionUtils, fileUtils } = imports.misc;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const Me = extensionUtils.getCurrentExtension();
|
||||
|
||||
const { log_debug } = Me.imports.utils;
|
||||
|
||||
|
||||
const shell_minor_version = parseInt(imports.misc.config.PACKAGE_VERSION.split('.')[1]);
|
||||
if ( shell_minor_version <= 30 ) {
|
||||
fileUtils.loadInterfaceXML = Me.imports.convenience.loadInterfaceXML;
|
||||
}
|
||||
|
||||
|
||||
const COLOR_INTERFACE = `
|
||||
<node>
|
||||
<interface name="org.gnome.SettingsDaemon.Color">
|
||||
<property name="NightLightActive" type="b" access="read"/>
|
||||
</interface>
|
||||
</node>`;
|
||||
|
||||
|
||||
/**
|
||||
* The Night Light Timer uses Night Light as a time source.
|
||||
*
|
||||
* It connects to the Color SettingsDaemon DBus proxy to listen to the
|
||||
* 'NightLightActive' property and will signal any change.
|
||||
*/
|
||||
var TimerNightlight = class {
|
||||
|
||||
enable() {
|
||||
log_debug('Enabling Night Light Timer...');
|
||||
this._connect_to_color_dbus_proxy();
|
||||
this._listen_to_nightlight_state();
|
||||
this.emit('time-changed', this.time);
|
||||
log_debug('Night Light Timer enabled.');
|
||||
}
|
||||
|
||||
disable() {
|
||||
log_debug('Disabling Night Light Timer...');
|
||||
this._stop_listening_to_nightlight_state();
|
||||
this._disconnect_from_color_dbus_proxy();
|
||||
log_debug('Night Light Timer disabled.');
|
||||
}
|
||||
|
||||
|
||||
get time() {
|
||||
return this._is_nightlight_active() ? 'night' : 'day';
|
||||
}
|
||||
|
||||
|
||||
_connect_to_color_dbus_proxy() {
|
||||
log_debug('Connecting to Color DBus proxy...');
|
||||
const ColorProxy = Gio.DBusProxy.makeProxyWrapper(COLOR_INTERFACE);
|
||||
this._color_dbus_proxy = new ColorProxy(
|
||||
Gio.DBus.session,
|
||||
'org.gnome.SettingsDaemon.Color',
|
||||
'/org/gnome/SettingsDaemon/Color'
|
||||
);
|
||||
log_debug('Connected to Color DBus proxy.');
|
||||
}
|
||||
|
||||
_disconnect_from_color_dbus_proxy() {
|
||||
log_debug('Disconnecting from Color DBus proxy...');
|
||||
this._color_dbus_proxy = null;
|
||||
log_debug('Disconnected from Color DBus proxy.');
|
||||
}
|
||||
|
||||
_listen_to_nightlight_state() {
|
||||
log_debug('Listening to Night Light state...');
|
||||
this._nightlight_state_connect = this._color_dbus_proxy.connect(
|
||||
'g-properties-changed',
|
||||
this._on_nightlight_state_changed.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
_stop_listening_to_nightlight_state() {
|
||||
this._color_dbus_proxy.disconnect(this._nightlight_state_connect);
|
||||
log_debug('Stopped listening to Night Light state.');
|
||||
}
|
||||
|
||||
_on_nightlight_state_changed(sender, dbus_properties) {
|
||||
const properties = dbus_properties.deep_unpack();
|
||||
if ( properties.NightLightActive ) {
|
||||
log_debug('Night Light has become ' + (properties.NightLightActive.unpack() ? '' : 'in') + 'active.');
|
||||
this.emit('time-changed', this.time);
|
||||
}
|
||||
}
|
||||
|
||||
_is_nightlight_active() {
|
||||
return this._color_dbus_proxy.NightLightActive;
|
||||
}
|
||||
|
||||
}
|
||||
Signals.addSignalMethods(TimerNightlight.prototype);
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const { GLib } = imports.gi;
|
||||
const { extensionUtils } = imports.misc;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const Me = extensionUtils.getCurrentExtension();
|
||||
|
||||
const e = Me.imports.extension;
|
||||
const { log_debug } = Me.imports.utils;
|
||||
|
||||
|
||||
/**
|
||||
* The Schedule Timer uses a manual schedule to get the current time.
|
||||
*
|
||||
* Every second, it will check if the time has changed and signal if that's the
|
||||
* case.
|
||||
*
|
||||
* The user can change the schedule in the extension's preferences.
|
||||
*/
|
||||
var TimerSchedule = class {
|
||||
|
||||
constructor() {
|
||||
this._previously_daytime = null;
|
||||
}
|
||||
|
||||
enable() {
|
||||
log_debug('Enabling Schedule Timer...');
|
||||
this._watch_for_time_change();
|
||||
log_debug('Schedule Timer enabled.');
|
||||
}
|
||||
|
||||
disable() {
|
||||
log_debug('Disabling Schedule Timer...');
|
||||
this._stop_watching_for_time_change();
|
||||
log_debug('Schedule Timer disabled.');
|
||||
}
|
||||
|
||||
|
||||
get time() {
|
||||
return this._is_daytime() ? 'day' : 'night';
|
||||
}
|
||||
|
||||
|
||||
_is_daytime() {
|
||||
const time = GLib.DateTime.new_now_local();
|
||||
const hour = time.get_hour() + time.get_minute() / 60 + time.get_second() / 3600;
|
||||
return ( hour >= e.settingsManager.schedule_sunrise && hour <= e.settingsManager.schedule_sunset );
|
||||
}
|
||||
|
||||
_watch_for_time_change() {
|
||||
log_debug('Watching for time change...');
|
||||
this._time_change_timer = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 1, () => {
|
||||
if ( !Me.imports.extension.enabled ) {
|
||||
// The extension doesn't exist anymore, quit the loop
|
||||
return false;
|
||||
}
|
||||
if ( this._previously_daytime !== this._is_daytime() ) {
|
||||
this._previously_daytime = this._is_daytime();
|
||||
this.emit('time-changed', this.time);
|
||||
}
|
||||
return true; // Repeat the loop
|
||||
});
|
||||
}
|
||||
|
||||
_stop_watching_for_time_change() {
|
||||
GLib.Source.remove(this._time_change_timer);
|
||||
log_debug('Stopped watching for time change.');
|
||||
}
|
||||
|
||||
}
|
||||
Signals.addSignalMethods(TimerSchedule.prototype);
|
||||
+329
-89
@@ -7,8 +7,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Night Theme Switcher 7\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-05-09 10:52+0200\n"
|
||||
"PO-Revision-Date: 2020-05-09 10:58+0200\n"
|
||||
"POT-Creation-Date: 2020-05-25 10:09+0200\n"
|
||||
"PO-Revision-Date: 2020-05-24 14:51+0200\n"
|
||||
"Last-Translator: Romain Vigier <romain@romainvigier.fr>\n"
|
||||
"Language-Team: French - France <romain@romainvigier.fr>\n"
|
||||
"Language: fr_FR\n"
|
||||
@@ -18,165 +18,405 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1)\n"
|
||||
"X-Generator: Gtranslator 3.36.0\n"
|
||||
|
||||
#: src/prefs.js:65
|
||||
msgid "Theme"
|
||||
msgstr "Thème"
|
||||
#: src/modules/GtkThemer.js:152
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Unable to automatically detect the day and night variants for the \"%s\" GTK "
|
||||
"theme. Please manually choose them in the extension's preferences."
|
||||
msgstr ""
|
||||
"Impossible de détecter automatiquement les variantes diurnes et nocturnes "
|
||||
"pour le thème GTK \"%s\". Veuillez les sélectionner manuellement dans les "
|
||||
"préférences de l’extension."
|
||||
|
||||
#: src/prefs.js:71
|
||||
#: src/modules/ShellThemer.js:159
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Unable to automatically detect the day and night variants for the \"%s\" "
|
||||
"GNOME Shell theme. Please manually choose them in the extension's "
|
||||
"preferences."
|
||||
msgstr ""
|
||||
"Impossible de détecter automatiquement les variantes diurnes et nocturnes "
|
||||
"pour le thème GNOME Shell \"%s\". Veuillez les sélectionner manuellement "
|
||||
"dans les préférences de l’extension."
|
||||
|
||||
#: src/preferences/Backgrounds.js:39
|
||||
msgid "Backgrounds"
|
||||
msgstr "Arrière-plans"
|
||||
|
||||
#: src/preferences/Backgrounds.js:40
|
||||
msgid "You can set different backgrounds for day and night."
|
||||
msgstr "Vous pouvez définir des arrière-plans diurnes et nocturnes différents."
|
||||
|
||||
#: src/preferences/Backgrounds.js:43
|
||||
msgid "Switch backgrounds"
|
||||
msgstr "Changer les arrière-plans"
|
||||
|
||||
#: src/preferences/Backgrounds.js:44
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:91
|
||||
msgid "Day background"
|
||||
msgstr "Arrière-plan diurne"
|
||||
|
||||
#: src/preferences/Backgrounds.js:45
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:96
|
||||
msgid "Night background"
|
||||
msgstr "Arrière-plan nocturne"
|
||||
|
||||
#: src/preferences/Backgrounds.js:87
|
||||
msgid "Select your background image"
|
||||
msgstr "Sélectionnez votre image d’arrière-plan"
|
||||
|
||||
#: src/preferences/Commands.js:39
|
||||
msgid "Commands"
|
||||
msgstr "Commandes"
|
||||
|
||||
#: src/preferences/Commands.js:40
|
||||
msgid ""
|
||||
"You can set custom commands that will be run when the time of the day "
|
||||
"changes."
|
||||
msgstr ""
|
||||
"Vous pouvez définir des commandes personnalisées qui seront lancées au "
|
||||
"moment du changement."
|
||||
|
||||
#: src/preferences/Commands.js:43
|
||||
msgid "Use custom commands"
|
||||
msgstr "Utiliser des commandes personnalisées"
|
||||
|
||||
#: src/preferences/Commands.js:44 src/preferences/Schedule.js:45
|
||||
msgid "Sunrise"
|
||||
msgstr "Lever du soleil"
|
||||
|
||||
#: src/preferences/Commands.js:45 src/preferences/Schedule.js:46
|
||||
msgid "Sunset"
|
||||
msgstr "Coucher du soleil"
|
||||
|
||||
#: src/preferences/Commands.js:76
|
||||
msgid "Hello sunshine!"
|
||||
msgstr "Bonjour!"
|
||||
|
||||
#: src/preferences/Commands.js:77
|
||||
msgid "Hello moonshine!"
|
||||
msgstr "Bonsoir!"
|
||||
|
||||
#: src/preferences/GtkTheme.js:40
|
||||
msgid "GTK theme"
|
||||
msgstr "Thème GTK"
|
||||
|
||||
#: src/preferences/GtkTheme.js:41
|
||||
msgid ""
|
||||
"The extension will try to automatically detect the day and night variants of "
|
||||
"your theme.\n"
|
||||
"your GTK theme.\n"
|
||||
"\n"
|
||||
"If the theme you use isn't supported, please <a href=\"https://gitlab.com/"
|
||||
"rmnvgr/nightthemeswitcher-gnome-shell-extension/-/issues\">submit a request</"
|
||||
"a>.\n"
|
||||
"If you prefer, you can manually set variants."
|
||||
"a>. You can also manually set variants."
|
||||
msgstr ""
|
||||
"L’extension essayera de détecter automatiquement les variantes diurne et "
|
||||
"nocturne de votre thème.\n"
|
||||
"Si le thème que vous utilisez n’est pas supporté, merci <a href=\"https://"
|
||||
"gitlab.com/rmnvgr/nightthemeswitcher-gnome-shell-extension/-/issues\">d’en "
|
||||
"faire la requête</a>.\n"
|
||||
"Si vous préférez, vous pouvez définir manuellement les variantes."
|
||||
"L’extension essayera de déterminer automatiquement les variantes diurnes et "
|
||||
"nocturnes de votre thème GTK.\n"
|
||||
"\n"
|
||||
"Si le thème que vous utilisez n’est pas pris en charge, merci d’<a href="
|
||||
"\"https://gitlab.com/rmnvgr/nightthemeswitcher-gnome-shell-extension/-/issues"
|
||||
"\">ouvrir une demande</a>. Vous pouvez aussi sélectionner manuellement les "
|
||||
"variantes."
|
||||
|
||||
#: src/prefs.js:107
|
||||
#: src/preferences/GtkTheme.js:44 src/preferences/ShellTheme.js:44
|
||||
msgid "Manual variants"
|
||||
msgstr "Variantes manuelles"
|
||||
|
||||
#: src/prefs.js:151
|
||||
#: src/preferences/GtkTheme.js:45 src/preferences/ShellTheme.js:45
|
||||
msgid "Day variant"
|
||||
msgstr "Variante diurne"
|
||||
|
||||
#: src/prefs.js:152
|
||||
#: src/preferences/GtkTheme.js:46 src/preferences/ShellTheme.js:46
|
||||
msgid "Night variant"
|
||||
msgstr "Variante nocturne"
|
||||
|
||||
#: src/prefs.js:197
|
||||
#: src/preferences/Schedule.js:39
|
||||
msgid "Schedule"
|
||||
msgstr "Horaires"
|
||||
|
||||
#: src/prefs.js:203
|
||||
#: src/preferences/Schedule.js:40
|
||||
msgid ""
|
||||
"The extension will try to use Night Light or Location Services to "
|
||||
"automatically set your current sunrise and sunset times if they are "
|
||||
"enabled.\n"
|
||||
"If you prefer, you can set a manual schedule."
|
||||
"\n"
|
||||
"If you prefer, you can manually choose a time source."
|
||||
msgstr ""
|
||||
"S’ils sont activés, l’extension essayera d’utiliser le mode nuit ou les "
|
||||
"services de localisation pour définir automatiquement les heures de lever et "
|
||||
"de coucher du soleil.\n"
|
||||
"Si vous préférez, vous pouvez définir manuellement un horaire."
|
||||
"services de localisation pour déterminer automatiquement les heures "
|
||||
"actuelles de lever et de coucher du soleil.\n"
|
||||
"\n"
|
||||
"Si vous préférez, vous pouvez sélectionner manuellement une source "
|
||||
"d’horaires."
|
||||
|
||||
#: src/prefs.js:238
|
||||
#: src/preferences/Schedule.js:43
|
||||
msgid "Manual time source"
|
||||
msgstr "Source d’horaires manuelle"
|
||||
|
||||
#: src/preferences/Schedule.js:44
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:51
|
||||
msgid "Time source"
|
||||
msgstr "Source d’horaires"
|
||||
|
||||
#: src/preferences/Schedule.js:87
|
||||
msgid "Night Light"
|
||||
msgstr "Mode nuit"
|
||||
|
||||
#: src/preferences/Schedule.js:102
|
||||
msgid "Location Services"
|
||||
msgstr "Services de localisation"
|
||||
|
||||
#: src/preferences/Schedule.js:118
|
||||
msgid "Manual schedule"
|
||||
msgstr "Horaire manuel"
|
||||
|
||||
#: src/prefs.js:283
|
||||
msgid "Sunrise"
|
||||
msgstr "Lever du soleil"
|
||||
#: src/preferences/ShellTheme.js:40
|
||||
msgid "Shell theme"
|
||||
msgstr "Thème du shell"
|
||||
|
||||
#: src/prefs.js:284
|
||||
msgid "Sunset"
|
||||
msgstr "Coucher du soleil"
|
||||
|
||||
#: src/modules/Themer.js:140
|
||||
#, javascript-format
|
||||
#: src/preferences/ShellTheme.js:41
|
||||
msgid ""
|
||||
"The extension cannot detect the day and night variants for the \"%s\" theme. "
|
||||
"Please choose another theme or manually set variants in the extension "
|
||||
"preferences."
|
||||
"The extension will try to automatically detect the day and night variants of "
|
||||
"your GNOME Shell theme.\n"
|
||||
"\n"
|
||||
"If the theme you use isn't supported, please <a href=\"https://gitlab.com/"
|
||||
"rmnvgr/nightthemeswitcher-gnome-shell-extension/-/issues\">submit a request</"
|
||||
"a>. You can also manually set variants."
|
||||
msgstr ""
|
||||
"L’extension ne parvient pas à détecter les variantes diurne et nocturne pour "
|
||||
"le thème \"%s\". Merci de sélectionner un autre thème ou de définir "
|
||||
"manuellement les variantes dans les préférences de l’extension."
|
||||
"L’extension essayera de déterminer automatiquement les variantes diurnes et "
|
||||
"nocturnes de votre thème GNOME Shell.\n"
|
||||
"\n"
|
||||
"Si le thème que vous utilisez n’est pas pris en charge, merci d’<a href="
|
||||
"\"https://gitlab.com/rmnvgr/nightthemeswitcher-gnome-shell-extension/-/issues"
|
||||
"\">ouvrir une demande</a>. Vous pouvez aussi sélectionner manuellement les "
|
||||
"variantes."
|
||||
|
||||
#: src/modules/Timer.js:269
|
||||
msgid "Unable to connect to Color DBus proxy."
|
||||
msgstr "Impossible de se connecter à la passerelle DBus Color."
|
||||
|
||||
#: src/modules/Timer.js:331
|
||||
msgid "Unable to connect to GeoClue Manager DBus proxy."
|
||||
msgstr "Impossible de se connecter à la passerelle DBus GeoClue Manager."
|
||||
|
||||
#: src/modules/Timer.js:341
|
||||
msgid "Unable to get a GeoClue Client."
|
||||
msgstr "Impossible d’obtenir un client GeoClue."
|
||||
|
||||
#: src/modules/Timer.js:359
|
||||
msgid "Unable to connect to GeoClue Client DBus proxy."
|
||||
msgstr "Impossible de se connecter à la passerelle DBus GeoClue Client."
|
||||
|
||||
#: src/modules/Timer.js:422
|
||||
msgid "Unable to connect to GeoClue Location DBus proxy."
|
||||
msgstr "Impossible de se connecter à la passerelle DBus GeoClue Location."
|
||||
|
||||
#: src/modules/Timer.js:450
|
||||
msgid "Unable to get current location."
|
||||
msgstr "Impossible d’obtenir l’emplacement actuel."
|
||||
#: src/preferences/ShellTheme.js:78
|
||||
msgid "Default"
|
||||
msgstr "Par défaut"
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:6
|
||||
msgid "Use manual variants"
|
||||
msgstr "Utiliser des variantes manuelles"
|
||||
msgid "Day GTK theme"
|
||||
msgstr "Thème GTK diurne"
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:7
|
||||
msgid "Disable automatic variants detection"
|
||||
msgstr "Désactive la détection automatique des variantes"
|
||||
msgid "The GTK theme to use during daytime"
|
||||
msgstr "Le thème GTK à utiliser le jour"
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:11
|
||||
msgid "Day theme"
|
||||
msgstr "Thème diurne"
|
||||
msgid "Night GTK theme"
|
||||
msgstr "Thème GTK nocturne"
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:12
|
||||
msgid "The theme to use during daytime"
|
||||
msgstr "Thème à utiliser pendant la journée"
|
||||
msgid "The GTK theme to use during nighttime"
|
||||
msgstr "Le thème GTK à utiliser la nuit"
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:16
|
||||
msgid "Night theme"
|
||||
msgstr "Thème nocturne"
|
||||
msgid "Original GTK theme"
|
||||
msgstr "Thème GTK original"
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:17
|
||||
msgid "The theme to use during nighttime"
|
||||
msgstr "Thème à utiliser pendant la nuit"
|
||||
msgid "The GTK theme to restore when the extension is disabled"
|
||||
msgstr "Le thème GTK à restaurer quand l’extension est désactivée"
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:21
|
||||
msgid "Original theme"
|
||||
msgstr "Thème original"
|
||||
msgid "Use manual GTK variants"
|
||||
msgstr "Utiliser des variantes GTK manuelles"
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:22
|
||||
msgid "The theme to restore if the extension is disabled"
|
||||
msgstr "Thème à restaurer si l’extension est désactivée"
|
||||
msgid "Disable automatic GTK theme variants detection"
|
||||
msgstr "Désactiver la détection automatique des variantes du thème GTK"
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:26
|
||||
msgid "Use manual schedule"
|
||||
msgstr "Utiliser un horaire manuel"
|
||||
msgid "Day shell theme"
|
||||
msgstr "Thème shell diurne"
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:27
|
||||
msgid "Disable automatic times detection"
|
||||
msgstr "Désactive la détection automatique des horaires"
|
||||
msgid "The shell theme to use during daytime"
|
||||
msgstr "Le thème shell à utiliser le jour"
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:31
|
||||
msgid "Night shell theme"
|
||||
msgstr "Thème shell nocturne"
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:32
|
||||
msgid "The shell theme to use during nighttime"
|
||||
msgstr "Le thème shell à utiliser la nuit"
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:36
|
||||
msgid "Time source"
|
||||
msgstr "Source des horaires"
|
||||
msgid "Original shell theme"
|
||||
msgstr "Thème shell original"
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:37
|
||||
msgid "The shell theme to restore when the extension is disabled"
|
||||
msgstr "Le thème shell à restaurer quand l’extension est désactivée"
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:41
|
||||
msgid "Use manual shell variants"
|
||||
msgstr "Utiliser des variantes shell manuelles"
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:42
|
||||
msgid "Disable automatic shell theme variants detection"
|
||||
msgstr "Désactiver la détection automatique des variantes du thème shell"
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:52
|
||||
msgid "The source used to check current time"
|
||||
msgstr "Source utilisée pour vérifier les horaires"
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:41
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:56
|
||||
msgid "Use manual time source"
|
||||
msgstr "Utiliser une source d’horaires manuelle"
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:57
|
||||
msgid "Disable automatic time source detection"
|
||||
msgstr "Désactive la détection automatique de la source d’horaires"
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:61
|
||||
msgid "Sunrise time"
|
||||
msgstr "Heure du lever"
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:42
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:62
|
||||
msgid "When the day starts"
|
||||
msgstr "Quand le jour se lève"
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:46
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:66
|
||||
msgid "Sunset time"
|
||||
msgstr "Heure du coucher"
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:47
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:67
|
||||
msgid "When the day ends"
|
||||
msgstr "Quand le jour se couche"
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:71
|
||||
msgid "Enable commands"
|
||||
msgstr "Activer les commandes"
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:72
|
||||
msgid "Commands will be spawned on time change"
|
||||
msgstr "Les commandes seront lancées au changement d’horaire"
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:76
|
||||
msgid "Sunrise command"
|
||||
msgstr "Commande du lever de soleil"
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:77
|
||||
msgid "The command to spawn at sunrise"
|
||||
msgstr "La commande à lancer quand le soleil se lève"
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:81
|
||||
msgid "Sunset command"
|
||||
msgstr "Commande du coucher de soleil"
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:82
|
||||
msgid "The command to spawn at sunset"
|
||||
msgstr "La commande à lancer quand le soleil se couche"
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:86
|
||||
msgid "Enable backgrounds"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:87
|
||||
msgid "Background will be changed on time change"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:92
|
||||
msgid "Path to the day background"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:97
|
||||
msgid "Path to the night background"
|
||||
msgstr ""
|
||||
|
||||
#~ msgid "Change backgrounds"
|
||||
#~ msgstr "Changer les arrière-plans"
|
||||
|
||||
#~ msgid "Theme"
|
||||
#~ msgstr "Thème"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "The extension will try to automatically detect the day and night variants "
|
||||
#~ "of your theme.\n"
|
||||
#~ "If the theme you use isn't supported, please <a href=\"https://gitlab.com/"
|
||||
#~ "rmnvgr/nightthemeswitcher-gnome-shell-extension/-/issues\">submit a "
|
||||
#~ "request</a>.\n"
|
||||
#~ "If you prefer, you can manually set variants."
|
||||
#~ msgstr ""
|
||||
#~ "L’extension essayera de détecter automatiquement les variantes diurne et "
|
||||
#~ "nocturne de votre thème.\n"
|
||||
#~ "Si le thème que vous utilisez n’est pas supporté, merci <a href=\"https://"
|
||||
#~ "gitlab.com/rmnvgr/nightthemeswitcher-gnome-shell-extension/-/issues"
|
||||
#~ "\">d’en faire la requête</a>.\n"
|
||||
#~ "Si vous préférez, vous pouvez définir manuellement les variantes."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "The extension will try to use Night Light or Location Services to "
|
||||
#~ "automatically set your current sunrise and sunset times if they are "
|
||||
#~ "enabled.\n"
|
||||
#~ "If you prefer, you can set a manual schedule."
|
||||
#~ msgstr ""
|
||||
#~ "S’ils sont activés, l’extension essayera d’utiliser le mode nuit ou les "
|
||||
#~ "services de localisation pour définir automatiquement les heures de lever "
|
||||
#~ "et de coucher du soleil.\n"
|
||||
#~ "Si vous préférez, vous pouvez définir manuellement un horaire."
|
||||
|
||||
#, javascript-format
|
||||
#~ msgid ""
|
||||
#~ "The extension cannot detect the day and night variants for the \"%s\" "
|
||||
#~ "theme. Please choose another theme or manually set variants in the "
|
||||
#~ "extension preferences."
|
||||
#~ msgstr ""
|
||||
#~ "L’extension ne parvient pas à détecter les variantes diurne et nocturne "
|
||||
#~ "pour le thème \"%s\". Merci de sélectionner un autre thème ou de définir "
|
||||
#~ "manuellement les variantes dans les préférences de l’extension."
|
||||
|
||||
#~ msgid "Unable to connect to Color DBus proxy."
|
||||
#~ msgstr "Impossible de se connecter à la passerelle DBus Color."
|
||||
|
||||
#~ msgid "Unable to connect to GeoClue Manager DBus proxy."
|
||||
#~ msgstr "Impossible de se connecter à la passerelle DBus GeoClue Manager."
|
||||
|
||||
#~ msgid "Unable to get a GeoClue Client."
|
||||
#~ msgstr "Impossible d’obtenir un client GeoClue."
|
||||
|
||||
#~ msgid "Unable to connect to GeoClue Client DBus proxy."
|
||||
#~ msgstr "Impossible de se connecter à la passerelle DBus GeoClue Client."
|
||||
|
||||
#~ msgid "Unable to connect to GeoClue Location DBus proxy."
|
||||
#~ msgstr "Impossible de se connecter à la passerelle DBus GeoClue Location."
|
||||
|
||||
#~ msgid "Unable to get current location."
|
||||
#~ msgstr "Impossible d’obtenir l’emplacement actuel."
|
||||
|
||||
#~ msgid "Use manual variants"
|
||||
#~ msgstr "Utiliser des variantes manuelles"
|
||||
|
||||
#~ msgid "Disable automatic variants detection"
|
||||
#~ msgstr "Désactive la détection automatique des variantes"
|
||||
|
||||
#~ msgid "Day theme"
|
||||
#~ msgstr "Thème diurne"
|
||||
|
||||
#~ msgid "The theme to use during daytime"
|
||||
#~ msgstr "Thème à utiliser pendant la journée"
|
||||
|
||||
#~ msgid "Night theme"
|
||||
#~ msgstr "Thème nocturne"
|
||||
|
||||
#~ msgid "The theme to use during nighttime"
|
||||
#~ msgstr "Thème à utiliser pendant la nuit"
|
||||
|
||||
#~ msgid "Original theme"
|
||||
#~ msgstr "Thème original"
|
||||
|
||||
#~ msgid "The theme to restore if the extension is disabled"
|
||||
#~ msgstr "Thème à restaurer si l’extension est désactivée"
|
||||
|
||||
#~ msgid "Use manual schedule"
|
||||
#~ msgstr "Utiliser un horaire manuel"
|
||||
|
||||
#~ msgid "Disable automatic times detection"
|
||||
#~ msgstr "Désactive la détection automatique des horaires"
|
||||
|
||||
#~ msgid "Manual schedule:"
|
||||
#~ msgstr "Horaire manuel :"
|
||||
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Night Theme Switcher 26\n"
|
||||
"Project-Id-Version: Night Theme Switcher 30\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-05-09 10:52+0200\n"
|
||||
"POT-Creation-Date: 2020-05-25 10:09+0200\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -17,148 +17,283 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: src/prefs.js:65
|
||||
msgid "Theme"
|
||||
#: src/modules/GtkThemer.js:152
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Unable to automatically detect the day and night variants for the \"%s\" GTK "
|
||||
"theme. Please manually choose them in the extension's preferences."
|
||||
msgstr ""
|
||||
|
||||
#: src/prefs.js:71
|
||||
#: src/modules/ShellThemer.js:159
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Unable to automatically detect the day and night variants for the \"%s\" "
|
||||
"GNOME Shell theme. Please manually choose them in the extension's "
|
||||
"preferences."
|
||||
msgstr ""
|
||||
|
||||
#: src/preferences/Backgrounds.js:39
|
||||
msgid "Backgrounds"
|
||||
msgstr ""
|
||||
|
||||
#: src/preferences/Backgrounds.js:40
|
||||
msgid "You can set different backgrounds for day and night."
|
||||
msgstr ""
|
||||
|
||||
#: src/preferences/Backgrounds.js:43
|
||||
msgid "Switch backgrounds"
|
||||
msgstr ""
|
||||
|
||||
#: src/preferences/Backgrounds.js:44
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:91
|
||||
msgid "Day background"
|
||||
msgstr ""
|
||||
|
||||
#: src/preferences/Backgrounds.js:45
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:96
|
||||
msgid "Night background"
|
||||
msgstr ""
|
||||
|
||||
#: src/preferences/Backgrounds.js:87
|
||||
msgid "Select your background image"
|
||||
msgstr ""
|
||||
|
||||
#: src/preferences/Commands.js:39
|
||||
msgid "Commands"
|
||||
msgstr ""
|
||||
|
||||
#: src/preferences/Commands.js:40
|
||||
msgid ""
|
||||
"You can set custom commands that will be run when the time of the day "
|
||||
"changes."
|
||||
msgstr ""
|
||||
|
||||
#: src/preferences/Commands.js:43
|
||||
msgid "Use custom commands"
|
||||
msgstr ""
|
||||
|
||||
#: src/preferences/Commands.js:44 src/preferences/Schedule.js:45
|
||||
msgid "Sunrise"
|
||||
msgstr ""
|
||||
|
||||
#: src/preferences/Commands.js:45 src/preferences/Schedule.js:46
|
||||
msgid "Sunset"
|
||||
msgstr ""
|
||||
|
||||
#: src/preferences/Commands.js:76
|
||||
msgid "Hello sunshine!"
|
||||
msgstr ""
|
||||
|
||||
#: src/preferences/Commands.js:77
|
||||
msgid "Hello moonshine!"
|
||||
msgstr ""
|
||||
|
||||
#: src/preferences/GtkTheme.js:40
|
||||
msgid "GTK theme"
|
||||
msgstr ""
|
||||
|
||||
#: src/preferences/GtkTheme.js:41
|
||||
msgid ""
|
||||
"The extension will try to automatically detect the day and night variants of "
|
||||
"your theme.\n"
|
||||
"your GTK theme.\n"
|
||||
"\n"
|
||||
"If the theme you use isn't supported, please <a href=\"https://gitlab.com/"
|
||||
"rmnvgr/nightthemeswitcher-gnome-shell-extension/-/issues\">submit a request</"
|
||||
"a>.\n"
|
||||
"If you prefer, you can manually set variants."
|
||||
"a>. You can also manually set variants."
|
||||
msgstr ""
|
||||
|
||||
#: src/prefs.js:107
|
||||
#: src/preferences/GtkTheme.js:44 src/preferences/ShellTheme.js:44
|
||||
msgid "Manual variants"
|
||||
msgstr ""
|
||||
|
||||
#: src/prefs.js:151
|
||||
#: src/preferences/GtkTheme.js:45 src/preferences/ShellTheme.js:45
|
||||
msgid "Day variant"
|
||||
msgstr ""
|
||||
|
||||
#: src/prefs.js:152
|
||||
#: src/preferences/GtkTheme.js:46 src/preferences/ShellTheme.js:46
|
||||
msgid "Night variant"
|
||||
msgstr ""
|
||||
|
||||
#: src/prefs.js:197
|
||||
#: src/preferences/Schedule.js:39
|
||||
msgid "Schedule"
|
||||
msgstr ""
|
||||
|
||||
#: src/prefs.js:203
|
||||
#: src/preferences/Schedule.js:40
|
||||
msgid ""
|
||||
"The extension will try to use Night Light or Location Services to "
|
||||
"automatically set your current sunrise and sunset times if they are "
|
||||
"enabled.\n"
|
||||
"If you prefer, you can set a manual schedule."
|
||||
"\n"
|
||||
"If you prefer, you can manually choose a time source."
|
||||
msgstr ""
|
||||
|
||||
#: src/prefs.js:238
|
||||
msgid "Manual schedule"
|
||||
#: src/preferences/Schedule.js:43
|
||||
msgid "Manual time source"
|
||||
msgstr ""
|
||||
|
||||
#: src/prefs.js:283
|
||||
msgid "Sunrise"
|
||||
msgstr ""
|
||||
|
||||
#: src/prefs.js:284
|
||||
msgid "Sunset"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/Themer.js:140
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"The extension cannot detect the day and night variants for the \"%s\" theme. "
|
||||
"Please choose another theme or manually set variants in the extension "
|
||||
"preferences."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/Timer.js:269
|
||||
msgid "Unable to connect to Color DBus proxy."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/Timer.js:331
|
||||
msgid "Unable to connect to GeoClue Manager DBus proxy."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/Timer.js:341
|
||||
msgid "Unable to get a GeoClue Client."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/Timer.js:359
|
||||
msgid "Unable to connect to GeoClue Client DBus proxy."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/Timer.js:422
|
||||
msgid "Unable to connect to GeoClue Location DBus proxy."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/Timer.js:450
|
||||
msgid "Unable to get current location."
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:6
|
||||
msgid "Use manual variants"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:7
|
||||
msgid "Disable automatic variants detection"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:11
|
||||
msgid "Day theme"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:12
|
||||
msgid "The theme to use during daytime"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:16
|
||||
msgid "Night theme"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:17
|
||||
msgid "The theme to use during nighttime"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:21
|
||||
msgid "Original theme"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:22
|
||||
msgid "The theme to restore if the extension is disabled"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:26
|
||||
msgid "Use manual schedule"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:27
|
||||
msgid "Disable automatic times detection"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:36
|
||||
#: src/preferences/Schedule.js:44
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:51
|
||||
msgid "Time source"
|
||||
msgstr ""
|
||||
|
||||
#: src/preferences/Schedule.js:87
|
||||
msgid "Night Light"
|
||||
msgstr ""
|
||||
|
||||
#: src/preferences/Schedule.js:102
|
||||
msgid "Location Services"
|
||||
msgstr ""
|
||||
|
||||
#: src/preferences/Schedule.js:118
|
||||
msgid "Manual schedule"
|
||||
msgstr ""
|
||||
|
||||
#: src/preferences/ShellTheme.js:40
|
||||
msgid "Shell theme"
|
||||
msgstr ""
|
||||
|
||||
#: src/preferences/ShellTheme.js:41
|
||||
msgid ""
|
||||
"The extension will try to automatically detect the day and night variants of "
|
||||
"your GNOME Shell theme.\n"
|
||||
"\n"
|
||||
"If the theme you use isn't supported, please <a href=\"https://gitlab.com/"
|
||||
"rmnvgr/nightthemeswitcher-gnome-shell-extension/-/issues\">submit a request</"
|
||||
"a>. You can also manually set variants."
|
||||
msgstr ""
|
||||
|
||||
#: src/preferences/ShellTheme.js:78
|
||||
msgid "Default"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:6
|
||||
msgid "Day GTK theme"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:7
|
||||
msgid "The GTK theme to use during daytime"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:11
|
||||
msgid "Night GTK theme"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:12
|
||||
msgid "The GTK theme to use during nighttime"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:16
|
||||
msgid "Original GTK theme"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:17
|
||||
msgid "The GTK theme to restore when the extension is disabled"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:21
|
||||
msgid "Use manual GTK variants"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:22
|
||||
msgid "Disable automatic GTK theme variants detection"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:26
|
||||
msgid "Day shell theme"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:27
|
||||
msgid "The shell theme to use during daytime"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:31
|
||||
msgid "Night shell theme"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:32
|
||||
msgid "The shell theme to use during nighttime"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:36
|
||||
msgid "Original shell theme"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:37
|
||||
msgid "The source used to check current time"
|
||||
msgid "The shell theme to restore when the extension is disabled"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:41
|
||||
msgid "Sunrise time"
|
||||
msgid "Use manual shell variants"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:42
|
||||
msgid "Disable automatic shell theme variants detection"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:52
|
||||
msgid "The source used to check current time"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:56
|
||||
msgid "Use manual time source"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:57
|
||||
msgid "Disable automatic time source detection"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:61
|
||||
msgid "Sunrise time"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:62
|
||||
msgid "When the day starts"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:46
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:66
|
||||
msgid "Sunset time"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:47
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:67
|
||||
msgid "When the day ends"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:71
|
||||
msgid "Enable commands"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:72
|
||||
msgid "Commands will be spawned on time change"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:76
|
||||
msgid "Sunrise command"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:77
|
||||
msgid "The command to spawn at sunrise"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:81
|
||||
msgid "Sunset command"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:82
|
||||
msgid "The command to spawn at sunset"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:86
|
||||
msgid "Enable backgrounds"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:87
|
||||
msgid "Background will be changed on time change"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:92
|
||||
msgid "Path to the day background"
|
||||
msgstr ""
|
||||
|
||||
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:97
|
||||
msgid "Path to the night background"
|
||||
msgstr ""
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const { GdkPixbuf, Gio, Gtk } = imports.gi;
|
||||
const { extensionUtils } = imports.misc;
|
||||
|
||||
const Me = extensionUtils.getCurrentExtension();
|
||||
|
||||
const { SettingsPage, SettingsList, SettingsListRow } = Me.imports.preferences.bases;
|
||||
|
||||
const Gettext = imports.gettext.domain(Me.metadata.uuid);
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
|
||||
const shell_minor_version = parseInt(imports.misc.config.PACKAGE_VERSION.split('.')[1]);
|
||||
if ( shell_minor_version <= 30 ) {
|
||||
extensionUtils.getSettings = Me.imports.convenience.getSettings;
|
||||
}
|
||||
|
||||
|
||||
var BackgroundsPreferences = class {
|
||||
|
||||
constructor() {
|
||||
const label = _('Backgrounds');
|
||||
const description = _('You can set different backgrounds for day and night.');
|
||||
const content = new SettingsList();
|
||||
|
||||
content.add_row(new SettingsListRow(_('Switch backgrounds'), new BackgroundsEnabledControl()));
|
||||
content.add_row(new SettingsListRow(_('Day background'), new TimeBackgroundControl('day')));
|
||||
content.add_row(new SettingsListRow(_('Night background'), new TimeBackgroundControl('night')));
|
||||
|
||||
return new SettingsPage(label, description, content);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class BackgroundsEnabledControl {
|
||||
|
||||
constructor() {
|
||||
const settings = extensionUtils.getSettings();
|
||||
const toggle = new Gtk.Switch({
|
||||
active: settings.get_boolean('backgrounds-enabled')
|
||||
});
|
||||
settings.bind(
|
||||
'backgrounds-enabled',
|
||||
toggle,
|
||||
'active',
|
||||
Gio.SettingsBindFlags.DEFAULT
|
||||
);
|
||||
return toggle;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class TimeBackgroundControl {
|
||||
|
||||
constructor(time) {
|
||||
const settings = extensionUtils.getSettings();
|
||||
|
||||
const filter = new Gtk.FileFilter();
|
||||
filter.add_mime_type('image/jpeg');
|
||||
filter.add_mime_type('image/png');
|
||||
filter.add_mime_type('image/tiff');
|
||||
|
||||
const preview = new Gtk.Image({
|
||||
pixel_size: 256
|
||||
});
|
||||
|
||||
const button = new Gtk.FileChooserButton({
|
||||
title: _('Select your background image'),
|
||||
action: Gtk.FileChooserAction.OPEN,
|
||||
filter: filter,
|
||||
preview_widget: preview,
|
||||
use_preview_label: false
|
||||
});
|
||||
button.set_uri(settings.get_string(`background-${time}`));
|
||||
button.connect('update-preview', () => {
|
||||
const file = button.get_preview_filename();
|
||||
const pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(file, 256, 256);
|
||||
preview.set_from_pixbuf(pixbuf);
|
||||
});
|
||||
button.connect('file-set', () => settings.set_string(`background-${time}`, button.get_uri()));
|
||||
settings.bind(
|
||||
'backgrounds-enabled',
|
||||
button,
|
||||
'sensitive',
|
||||
Gio.SettingsBindFlags.DEFAULT
|
||||
);
|
||||
settings.connect(`changed::background-${time}`, () => button.set_uri(settings.get_string(`background-${time}`)));
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const { Gio, Gtk } = imports.gi;
|
||||
const { extensionUtils } = imports.misc;
|
||||
|
||||
const Me = extensionUtils.getCurrentExtension();
|
||||
|
||||
const { SettingsPage, SettingsList, SettingsListRow } = Me.imports.preferences.bases;
|
||||
|
||||
const Gettext = imports.gettext.domain(Me.metadata.uuid);
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
|
||||
const shell_minor_version = parseInt(imports.misc.config.PACKAGE_VERSION.split('.')[1]);
|
||||
if ( shell_minor_version <= 30 ) {
|
||||
extensionUtils.getSettings = Me.imports.convenience.getSettings;
|
||||
}
|
||||
|
||||
|
||||
var CommandsPreferences = class {
|
||||
|
||||
constructor() {
|
||||
const label = _('Commands');
|
||||
const description = _('You can set custom commands that will be run when the time of the day changes.');
|
||||
const content = new SettingsList();
|
||||
|
||||
content.add_row(new SettingsListRow(_('Use custom commands'), new CommandsEnabledControl()));
|
||||
content.add_row(new SettingsListRow(_('Sunrise'), new SuntimeCommandControl('sunrise')));
|
||||
content.add_row(new SettingsListRow(_('Sunset'), new SuntimeCommandControl('sunset')));
|
||||
|
||||
return new SettingsPage(label, description, content);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class CommandsEnabledControl {
|
||||
|
||||
constructor() {
|
||||
const settings = extensionUtils.getSettings();
|
||||
const toggle = new Gtk.Switch({
|
||||
active: settings.get_boolean('commands-enabled')
|
||||
});
|
||||
settings.bind(
|
||||
'commands-enabled',
|
||||
toggle,
|
||||
'active',
|
||||
Gio.SettingsBindFlags.DEFAULT
|
||||
);
|
||||
return toggle;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class SuntimeCommandControl {
|
||||
|
||||
constructor(suntime) {
|
||||
const message = new Map([
|
||||
['sunrise', _('Hello sunshine!')],
|
||||
['sunset', _('Hello moonshine!')]
|
||||
]);
|
||||
const settings = extensionUtils.getSettings();
|
||||
const entry = new Gtk.Entry({
|
||||
width_request: 300,
|
||||
placeholder_text: _(`notify-send "${message.get(suntime)}"`)
|
||||
});
|
||||
settings.bind(
|
||||
`command-${suntime}`,
|
||||
entry,
|
||||
'text',
|
||||
Gio.SettingsBindFlags.DEFAULT
|
||||
);
|
||||
settings.bind(
|
||||
'commands-enabled',
|
||||
entry,
|
||||
'sensitive',
|
||||
Gio.SettingsBindFlags.DEFAULT
|
||||
);
|
||||
return entry;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const { Gio, Gtk } = imports.gi;
|
||||
const { extensionUtils } = imports.misc;
|
||||
|
||||
const Me = extensionUtils.getCurrentExtension();
|
||||
|
||||
const { SettingsPage, SettingsList, SettingsListRow } = Me.imports.preferences.bases;
|
||||
const { get_installed_gtk_themes } = Me.imports.utils;
|
||||
|
||||
const Gettext = imports.gettext.domain(Me.metadata.uuid);
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
|
||||
const shell_minor_version = parseInt(imports.misc.config.PACKAGE_VERSION.split('.')[1]);
|
||||
if ( shell_minor_version <= 30 ) {
|
||||
extensionUtils.getSettings = Me.imports.convenience.getSettings;
|
||||
}
|
||||
|
||||
|
||||
var GtkThemePreferences = class {
|
||||
|
||||
constructor() {
|
||||
const label = _('GTK theme');
|
||||
const description = _('The extension will try to automatically detect the day and night variants of your GTK theme.\n\nIf the theme you use isn\'t supported, please <a href="https://gitlab.com/rmnvgr/nightthemeswitcher-gnome-shell-extension/-/issues">submit a request</a>. You can also manually set variants.');
|
||||
const content = new SettingsList();
|
||||
|
||||
content.add_row(new SettingsListRow(_('Manual variants'), new ManualGtkVariantsControl()));
|
||||
content.add_row(new SettingsListRow(_('Day variant'), new TimeGtkVariantControl('day')));
|
||||
content.add_row(new SettingsListRow(_('Night variant'), new TimeGtkVariantControl('night')));
|
||||
|
||||
return new SettingsPage(label, description, content);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class ManualGtkVariantsControl {
|
||||
|
||||
constructor() {
|
||||
const settings = extensionUtils.getSettings();
|
||||
const toggle = new Gtk.Switch({
|
||||
active: false
|
||||
});
|
||||
settings.bind(
|
||||
'manual-gtk-variants',
|
||||
toggle,
|
||||
'active',
|
||||
Gio.SettingsBindFlags.DEFAULT
|
||||
);
|
||||
return toggle;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class TimeGtkVariantControl {
|
||||
|
||||
constructor(time) {
|
||||
const settings = extensionUtils.getSettings();
|
||||
const combo = new Gtk.ComboBoxText();
|
||||
const themes = Array.from(get_installed_gtk_themes()).sort();
|
||||
themes.forEach(theme => combo.append(theme, theme));
|
||||
settings.bind(
|
||||
`gtk-variant-${time}`,
|
||||
combo,
|
||||
'active-id',
|
||||
Gio.SettingsBindFlags.DEFAULT
|
||||
);
|
||||
settings.bind(
|
||||
'manual-gtk-variants',
|
||||
combo,
|
||||
'sensitive',
|
||||
Gio.SettingsBindFlags.DEFAULT
|
||||
);
|
||||
return combo;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const { Gio, Gtk } = imports.gi;
|
||||
const { extensionUtils } = imports.misc;
|
||||
|
||||
const Me = extensionUtils.getCurrentExtension();
|
||||
|
||||
const { SettingsPage, SettingsList, SettingsListRow } = Me.imports.preferences.bases;
|
||||
|
||||
const Gettext = imports.gettext.domain(Me.metadata.uuid);
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
|
||||
const shell_minor_version = parseInt(imports.misc.config.PACKAGE_VERSION.split('.')[1]);
|
||||
if ( shell_minor_version <= 30 ) {
|
||||
extensionUtils.getSettings = Me.imports.convenience.getSettings;
|
||||
}
|
||||
|
||||
|
||||
var SchedulePreferences = class {
|
||||
|
||||
constructor() {
|
||||
const label = _('Schedule');
|
||||
const description = _('The extension will try to use Night Light or Location Services to automatically set your current sunrise and sunset times if they are enabled.\n\nIf you prefer, you can manually choose a time source.');
|
||||
const content = new SettingsList();
|
||||
|
||||
content.add_row(new SettingsListRow(_('Manual time source'), new ManualTimeSourceControl()));
|
||||
content.add_row(new SettingsListRow(_('Time source'), new TimeSourceControl()));
|
||||
content.add_row(new SettingsListRow(_('Sunrise'), new SuntimeControl('sunrise')));
|
||||
content.add_row(new SettingsListRow(_('Sunset'), new SuntimeControl('sunset')));
|
||||
|
||||
return new SettingsPage(label, description, content);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class ManualTimeSourceControl {
|
||||
|
||||
constructor() {
|
||||
const settings = extensionUtils.getSettings();
|
||||
const toggle = new Gtk.Switch({
|
||||
active: false
|
||||
});
|
||||
settings.bind(
|
||||
'manual-time-source',
|
||||
toggle,
|
||||
'active',
|
||||
Gio.SettingsBindFlags.DEFAULT
|
||||
);
|
||||
return toggle;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class TimeSourceControl {
|
||||
|
||||
constructor() {
|
||||
const settings = extensionUtils.getSettings();
|
||||
const colorSettings = new Gio.Settings({ schema: 'org.gnome.settings-daemon.plugins.color' });
|
||||
const locationSettings = new Gio.Settings({ schema: 'org.gnome.system.location' });
|
||||
|
||||
const box = new Gtk.Box({
|
||||
spacing: 8,
|
||||
orientation: Gtk.Orientation.HORIZONTAL,
|
||||
can_focus: false
|
||||
});
|
||||
|
||||
const nightlight_radio = new Gtk.RadioButton({
|
||||
label: _('Night Light'),
|
||||
active: (settings.get_string('time-source') === 'nightlight')
|
||||
});
|
||||
const update_nightlight_radio_sensitivity = () => nightlight_radio.set_sensitive(!!(settings.get_boolean('manual-time-source') && colorSettings.get_boolean('night-light-enabled')));
|
||||
settings.connect('changed::manual-time-source', update_nightlight_radio_sensitivity);
|
||||
colorSettings.connect('changed::night-light-enabled', update_nightlight_radio_sensitivity);
|
||||
update_nightlight_radio_sensitivity();
|
||||
nightlight_radio.connect('toggled', () => {
|
||||
if ( nightlight_radio.get_active() ) {
|
||||
settings.set_string('time-source', 'nightlight')
|
||||
}
|
||||
});
|
||||
box.pack_start(nightlight_radio, false, false, 0);
|
||||
|
||||
const location_radio = new Gtk.RadioButton({
|
||||
label: _('Location Services'),
|
||||
group: nightlight_radio,
|
||||
active: (settings.get_string('time-source') === 'location')
|
||||
});
|
||||
const update_location_radio_sensitivity = () => location_radio.set_sensitive(!!(settings.get_boolean('manual-time-source') && locationSettings.get_boolean('enabled')));
|
||||
settings.connect('changed::manual-time-source', update_location_radio_sensitivity);
|
||||
locationSettings.connect('changed::enabled', update_location_radio_sensitivity);
|
||||
update_location_radio_sensitivity();
|
||||
location_radio.connect('toggled', () => {
|
||||
if ( location_radio.get_active() ) {
|
||||
settings.set_string('time-source', 'location')
|
||||
}
|
||||
});
|
||||
box.pack_start(location_radio, false, false, 0);
|
||||
|
||||
const schedule_radio = new Gtk.RadioButton({
|
||||
label: _('Manual schedule'),
|
||||
group: nightlight_radio,
|
||||
active: (settings.get_string('time-source') === 'schedule')
|
||||
});
|
||||
settings.bind(
|
||||
'manual-time-source',
|
||||
schedule_radio,
|
||||
'sensitive',
|
||||
Gio.SettingsBindFlags.DEFAULT
|
||||
);
|
||||
schedule_radio.connect('toggled', () => {
|
||||
if ( schedule_radio.get_active() ) {
|
||||
settings.set_string('time-source', 'schedule')
|
||||
}
|
||||
});
|
||||
box.pack_start(schedule_radio, false, false, 0);
|
||||
|
||||
return box;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class SuntimeControl {
|
||||
|
||||
constructor(suntime) {
|
||||
const settings = extensionUtils.getSettings();
|
||||
const box = new Gtk.Box({
|
||||
spacing: 8,
|
||||
orientation: Gtk.Orientation.HORIZONTAL,
|
||||
can_focus: false
|
||||
});
|
||||
|
||||
const update_spin_sensitivity = (spin) => spin.set_sensitive(!!(settings.get_boolean('manual-time-source') && settings.get_string('time-source') === 'schedule'));
|
||||
|
||||
const time = settings.get_double(`schedule-${suntime}`);
|
||||
const hours = Math.trunc(time);
|
||||
const minutes = Math.round((time - hours) * 60);
|
||||
|
||||
const hours_spin = new Gtk.SpinButton({
|
||||
adjustment: new Gtk.Adjustment({
|
||||
value: hours,
|
||||
lower: 0,
|
||||
upper: 23,
|
||||
step_increment: 1,
|
||||
page_increment: 0,
|
||||
page_size: 0
|
||||
}),
|
||||
value: hours,
|
||||
numeric: true,
|
||||
wrap: true,
|
||||
orientation: Gtk.Orientation.VERTICAL
|
||||
});
|
||||
hours_spin.connect('output', () => {
|
||||
const text = hours_spin.adjustment.value.toString().padStart(2, '0');
|
||||
hours_spin.set_text(text);
|
||||
return true;
|
||||
});
|
||||
hours_spin.connect('value-changed', () => {
|
||||
const old_time = settings.get_double(`schedule-${suntime}`);
|
||||
const old_hour = Math.trunc(old_time);
|
||||
const minutes = old_time - old_hour;
|
||||
const new_time = hours_spin.value + minutes;
|
||||
settings.set_double(`schedule-${suntime}`, new_time);
|
||||
});
|
||||
settings.connect('changed::manual-time-source', () => update_spin_sensitivity(hours_spin));
|
||||
settings.connect('changed::time-source', () => update_spin_sensitivity(hours_spin));
|
||||
update_spin_sensitivity(hours_spin);
|
||||
|
||||
const separator = new Gtk.Label({ label: ':' });
|
||||
|
||||
const minutes_spin = new Gtk.SpinButton({
|
||||
adjustment: new Gtk.Adjustment({
|
||||
value: minutes,
|
||||
lower: 0,
|
||||
upper: 59,
|
||||
step_increment: 1,
|
||||
page_increment: 0,
|
||||
page_size: 0
|
||||
}),
|
||||
value: minutes,
|
||||
numeric: true,
|
||||
wrap: true,
|
||||
orientation: Gtk.Orientation.VERTICAL
|
||||
});
|
||||
minutes_spin.connect('output', () => {
|
||||
const text = minutes_spin.adjustment.value.toString().padStart(2, '0');
|
||||
minutes_spin.set_text(text);
|
||||
return true;
|
||||
});
|
||||
minutes_spin.connect('value-changed', () => {
|
||||
const hour = Math.trunc(settings.get_double(`schedule-${suntime}`));
|
||||
const minutes = minutes_spin.value / 60;
|
||||
const new_time = hour + minutes;
|
||||
settings.set_double(`schedule-${suntime}`, new_time);
|
||||
});
|
||||
settings.connect('changed::manual-time-source', () => update_spin_sensitivity(minutes_spin));
|
||||
settings.connect('changed::time-source', () => update_spin_sensitivity(minutes_spin));
|
||||
update_spin_sensitivity(minutes_spin);
|
||||
|
||||
box.pack_start(hours_spin, false, false, 0);
|
||||
box.pack_start(separator, false, false, 0);
|
||||
box.pack_start(minutes_spin, false, false, 0);
|
||||
return box;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const { Gio, Gtk } = imports.gi;
|
||||
const { extensionUtils } = imports.misc;
|
||||
|
||||
const Me = extensionUtils.getCurrentExtension();
|
||||
|
||||
const { SettingsPage, SettingsList, SettingsListRow } = Me.imports.preferences.bases;
|
||||
const { get_installed_shell_themes } = Me.imports.utils;
|
||||
|
||||
const Gettext = imports.gettext.domain(Me.metadata.uuid);
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
|
||||
const shell_minor_version = parseInt(imports.misc.config.PACKAGE_VERSION.split('.')[1]);
|
||||
if ( shell_minor_version <= 30 ) {
|
||||
extensionUtils.getSettings = Me.imports.convenience.getSettings;
|
||||
}
|
||||
|
||||
|
||||
var ShellThemePreferences = class {
|
||||
|
||||
constructor() {
|
||||
const label = _('Shell theme');
|
||||
const description = _('The extension will try to automatically detect the day and night variants of your GNOME Shell theme.\n\nIf the theme you use isn\'t supported, please <a href="https://gitlab.com/rmnvgr/nightthemeswitcher-gnome-shell-extension/-/issues">submit a request</a>. You can also manually set variants.');
|
||||
const content = new SettingsList();
|
||||
|
||||
content.add_row(new SettingsListRow(_('Manual variants'), new ManualShellVariantsControl()));
|
||||
content.add_row(new SettingsListRow(_('Day variant'), new TimeShellVariantControl('day')));
|
||||
content.add_row(new SettingsListRow(_('Night variant'), new TimeShellVariantControl('night')));
|
||||
|
||||
return new SettingsPage(label, description, content);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ManualShellVariantsControl {
|
||||
|
||||
constructor() {
|
||||
const settings = extensionUtils.getSettings();
|
||||
const toggle = new Gtk.Switch({
|
||||
active: false
|
||||
});
|
||||
settings.bind(
|
||||
'manual-shell-variants',
|
||||
toggle,
|
||||
'active',
|
||||
Gio.SettingsBindFlags.DEFAULT
|
||||
);
|
||||
return toggle;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class TimeShellVariantControl {
|
||||
|
||||
constructor(time) {
|
||||
const settings = extensionUtils.getSettings();
|
||||
const combo = new Gtk.ComboBoxText();
|
||||
const themes = Array.from(get_installed_shell_themes()).sort();
|
||||
themes.forEach(theme => combo.append(theme, (theme === '' ? _('Default') : theme)));
|
||||
settings.bind(
|
||||
`shell-variant-${time}`,
|
||||
combo,
|
||||
'active-id',
|
||||
Gio.SettingsBindFlags.DEFAULT
|
||||
);
|
||||
settings.bind(
|
||||
'manual-shell-variants',
|
||||
combo,
|
||||
'sensitive',
|
||||
Gio.SettingsBindFlags.DEFAULT
|
||||
);
|
||||
return combo;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const { Gtk } = imports.gi;
|
||||
|
||||
|
||||
var SettingsPage = class {
|
||||
|
||||
constructor(label, description, content_widget) {
|
||||
this.label = new Gtk.Label({
|
||||
label: label
|
||||
});
|
||||
|
||||
this.page = new Gtk.Box({
|
||||
orientation: Gtk.Orientation.VERTICAL,
|
||||
spacing: 30,
|
||||
margin_top: 30,
|
||||
margin_end: 36,
|
||||
margin_start: 36,
|
||||
margin_bottom: 36,
|
||||
valign: Gtk.Align.START,
|
||||
halign: Gtk.Align.CENTER
|
||||
});
|
||||
|
||||
const description_widget = new Gtk.Label({
|
||||
label: description,
|
||||
use_markup: true,
|
||||
wrap: true,
|
||||
halign: Gtk.Align.START
|
||||
});
|
||||
this.page.pack_start(description_widget, false, false, 0);
|
||||
|
||||
this.page.pack_start(content_widget, false, false, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var SettingsList = class {
|
||||
|
||||
constructor() {
|
||||
const frame = new Gtk.Frame({
|
||||
can_focus: false
|
||||
});
|
||||
|
||||
const list = new Gtk.ListBox({
|
||||
border_width: 0,
|
||||
margin: 0,
|
||||
can_focus: false,
|
||||
selection_mode: Gtk.SelectionMode.NONE
|
||||
});
|
||||
frame.add(list);
|
||||
|
||||
frame.add_row = (widget) => {
|
||||
if ( list.get_children().length > 0 ) {
|
||||
const separator = new Gtk.Separator({
|
||||
orientation: Gtk.Orientation.VERTICAL,
|
||||
can_focus: false
|
||||
});
|
||||
list.add(separator);
|
||||
}
|
||||
list.add(widget);
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var SettingsListRow = class {
|
||||
|
||||
constructor(label, widget) {
|
||||
const row = new Gtk.Box({
|
||||
margin: 16,
|
||||
spacing: 30,
|
||||
orientation: Gtk.Orientation.HORIZONTAL,
|
||||
can_focus: false
|
||||
});
|
||||
|
||||
const label_widget = new Gtk.Label({
|
||||
label: label,
|
||||
halign: Gtk.Align.START
|
||||
});
|
||||
row.pack_start(label_widget, true, true, 0);
|
||||
|
||||
widget.set_halign(Gtk.Align.END);
|
||||
row.pack_start(widget, false, false, 0);
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
}
|
||||
+21
-339
@@ -18,27 +18,26 @@ this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
|
||||
'use strict';
|
||||
|
||||
const { Gio, GLib, Gtk } = imports.gi;
|
||||
const { Gtk } = imports.gi;
|
||||
const { extensionUtils } = imports.misc;
|
||||
|
||||
const Me = extensionUtils.getCurrentExtension();
|
||||
const config = Me.imports.config;
|
||||
const utils = Me.imports.utils;
|
||||
|
||||
const { log_debug } = Me.imports.utils;
|
||||
|
||||
const Gettext = imports.gettext.domain(Me.metadata.uuid);
|
||||
const _ = Gettext.gettext;
|
||||
const { BackgroundsPreferences } = Me.imports.preferences.Backgrounds;
|
||||
const { CommandsPreferences } = Me.imports.preferences.Commands;
|
||||
const { GtkThemePreferences } = Me.imports.preferences.GtkTheme;
|
||||
const { SchedulePreferences } = Me.imports.preferences.Schedule;
|
||||
const { ShellThemePreferences } = Me.imports.preferences.ShellTheme;
|
||||
|
||||
|
||||
let settings;
|
||||
const shell_minor_version = parseInt(imports.misc.config.PACKAGE_VERSION.split('.')[1]);
|
||||
if ( shell_minor_version <= 30 ) {
|
||||
extensionUtils.initTranslations = Me.imports.convenience.initTranslations;
|
||||
}
|
||||
|
||||
|
||||
function init() {
|
||||
log_debug('Initializing preferences...');
|
||||
settings = extensionUtils.getSettings();
|
||||
extensionUtils.initTranslations(Me.metadata.uuid);
|
||||
log_debug('Preferences initialized.');
|
||||
}
|
||||
|
||||
function buildPrefsWidget() {
|
||||
@@ -46,339 +45,22 @@ function buildPrefsWidget() {
|
||||
visible: true
|
||||
});
|
||||
|
||||
/*
|
||||
Theme preferences
|
||||
*/
|
||||
const schedulePreferences = new SchedulePreferences();
|
||||
prefs_widget.append_page(schedulePreferences.page, schedulePreferences.label);
|
||||
|
||||
const prefs_theme_box = new Gtk.Box({
|
||||
orientation: Gtk.Orientation.VERTICAL,
|
||||
spacing: 30,
|
||||
margin_top: 30,
|
||||
margin_end: 36,
|
||||
margin_start: 36,
|
||||
margin_bottom: 36,
|
||||
valign: Gtk.Align.START,
|
||||
halign: Gtk.Align.CENTER,
|
||||
visible: true
|
||||
});
|
||||
const prefs_theme_box_label = new Gtk.Label({
|
||||
label: _('Theme'),
|
||||
visible: true
|
||||
});
|
||||
prefs_widget.append_page(prefs_theme_box, prefs_theme_box_label);
|
||||
const gtkThemePreferences = new GtkThemePreferences();
|
||||
prefs_widget.append_page(gtkThemePreferences.page, gtkThemePreferences.label);
|
||||
|
||||
const prefs_theme_info = new Gtk.Label({
|
||||
label: _('The extension will try to automatically detect the day and night variants of your theme.\nIf the theme you use isn\'t supported, please <a href="https://gitlab.com/rmnvgr/nightthemeswitcher-gnome-shell-extension/-/issues">submit a request</a>.\nIf you prefer, you can manually set variants.'),
|
||||
use_markup: true,
|
||||
max_width_chars: 60,
|
||||
wrap: true,
|
||||
halign: Gtk.Align.START,
|
||||
opacity: 0.7,
|
||||
visible: true
|
||||
});
|
||||
prefs_theme_box.pack_start(prefs_theme_info, false, false, 0);
|
||||
const shellThemePreferences = new ShellThemePreferences();
|
||||
prefs_widget.append_page(shellThemePreferences.page, shellThemePreferences.label);
|
||||
|
||||
const prefs_theme_frame = new Gtk.Frame({
|
||||
can_focus: false,
|
||||
visible: true
|
||||
});
|
||||
prefs_theme_box.pack_start(prefs_theme_frame, false, false, 0);
|
||||
const backgroundsPreferences = new BackgroundsPreferences();
|
||||
prefs_widget.append_page(backgroundsPreferences.page, backgroundsPreferences.label);
|
||||
|
||||
const prefs_theme_list = new Gtk.ListBox({
|
||||
border_width: 0,
|
||||
margin: 0,
|
||||
can_focus: false,
|
||||
selection_mode: Gtk.SelectionMode.NONE,
|
||||
visible: true
|
||||
});
|
||||
prefs_theme_frame.add(prefs_theme_list);
|
||||
const commandsPreferences = new CommandsPreferences();
|
||||
prefs_widget.append_page(commandsPreferences.page, commandsPreferences.label);
|
||||
|
||||
// Force manual toggle
|
||||
const theme_force_manual_box = new Gtk.Box({
|
||||
margin: 16,
|
||||
spacing: 12,
|
||||
orientation: Gtk.Orientation.HORIZONTAL,
|
||||
can_focus: false,
|
||||
visible: true
|
||||
});
|
||||
prefs_theme_list.add(theme_force_manual_box);
|
||||
|
||||
const theme_force_manual_label = new Gtk.Label({
|
||||
label: _('Manual variants'),
|
||||
halign: Gtk.Align.START,
|
||||
visible: true
|
||||
});
|
||||
theme_force_manual_box.pack_start(theme_force_manual_label, true, true, 0);
|
||||
|
||||
const theme_force_manual_toggle = new Gtk.Switch({
|
||||
active: this.settings.get_boolean('time-force-manual'),
|
||||
halign: Gtk.Align.END,
|
||||
visible: true
|
||||
});
|
||||
settings.bind(
|
||||
'theme-force-manual',
|
||||
theme_force_manual_toggle,
|
||||
'active',
|
||||
Gio.SettingsBindFlags.DEFAULT
|
||||
);
|
||||
theme_force_manual_box.pack_start(theme_force_manual_toggle, false, false, 0);
|
||||
|
||||
prefs_theme_list.add(new Gtk.Separator({
|
||||
orientation: Gtk.Orientation.VERTICAL,
|
||||
can_focus: false,
|
||||
visible: true
|
||||
}));
|
||||
|
||||
['day', 'night'].forEach((time, i, times) => {
|
||||
const variant_box = new Gtk.Box({
|
||||
margin: 16,
|
||||
spacing: 12,
|
||||
orientation: Gtk.Orientation.HORIZONTAL,
|
||||
can_focus: false,
|
||||
visible: true
|
||||
});
|
||||
prefs_theme_list.add(variant_box);
|
||||
|
||||
if ( i < times.length - 1 ) {
|
||||
prefs_theme_list.add(new Gtk.Separator({
|
||||
orientation: Gtk.Orientation.VERTICAL,
|
||||
can_focus: false,
|
||||
visible: true
|
||||
}));
|
||||
}
|
||||
|
||||
const variant_labels = new Map([
|
||||
['day', _('Day variant')],
|
||||
['night', _('Night variant')]
|
||||
]);
|
||||
const variant_label = new Gtk.Label({
|
||||
label: variant_labels.get(time),
|
||||
halign: Gtk.Align.START,
|
||||
visible: true
|
||||
})
|
||||
variant_box.pack_start(variant_label, true, true, 0);
|
||||
|
||||
const variant_combo = new Gtk.ComboBoxText({
|
||||
visible: true
|
||||
});
|
||||
const themes = Array.from(utils.get_installed_themes()).sort();
|
||||
themes.forEach(theme => variant_combo.append(theme, theme));
|
||||
settings.bind(
|
||||
`theme-${time}`,
|
||||
variant_combo,
|
||||
'active-id',
|
||||
Gio.SettingsBindFlags.DEFAULT
|
||||
);
|
||||
settings.bind(
|
||||
'theme-force-manual',
|
||||
variant_combo,
|
||||
'sensitive',
|
||||
Gio.SettingsBindFlags.DEFAULT
|
||||
);
|
||||
variant_box.pack_start(variant_combo, false, false, 0);
|
||||
|
||||
});
|
||||
|
||||
/*
|
||||
Schedule preferences
|
||||
*/
|
||||
const prefs_time_box = new Gtk.Box({
|
||||
orientation: Gtk.Orientation.VERTICAL,
|
||||
spacing: 30,
|
||||
margin_top: 30,
|
||||
margin_end: 36,
|
||||
margin_start: 36,
|
||||
margin_bottom: 36,
|
||||
valign: Gtk.Align.START,
|
||||
halign: Gtk.Align.CENTER,
|
||||
visible: true
|
||||
});
|
||||
const prefs_time_box_label = new Gtk.Label({
|
||||
label: _('Schedule'),
|
||||
visible: true
|
||||
});
|
||||
prefs_widget.append_page(prefs_time_box, prefs_time_box_label);
|
||||
|
||||
const prefs_time_info = new Gtk.Label({
|
||||
label: _('The extension will try to use Night Light or Location Services to automatically set your current sunrise and sunset times if they are enabled.\nIf you prefer, you can set a manual schedule.'),
|
||||
max_width_chars: 60,
|
||||
wrap: true,
|
||||
halign: Gtk.Align.START,
|
||||
opacity: 0.7,
|
||||
visible: true
|
||||
});
|
||||
prefs_time_box.pack_start(prefs_time_info, false, false, 0);
|
||||
|
||||
const prefs_time_frame = new Gtk.Frame({
|
||||
can_focus: false,
|
||||
visible: true
|
||||
});
|
||||
prefs_time_box.pack_start(prefs_time_frame, false, false, 0);
|
||||
|
||||
const prefs_time_list = new Gtk.ListBox({
|
||||
border_width: 0,
|
||||
margin: 0,
|
||||
can_focus: false,
|
||||
selection_mode: Gtk.SelectionMode.NONE,
|
||||
visible: true
|
||||
});
|
||||
prefs_time_frame.add(prefs_time_list);
|
||||
|
||||
// Force manual toggle
|
||||
const force_manual_box = new Gtk.Box({
|
||||
margin: 16,
|
||||
spacing: 12,
|
||||
orientation: Gtk.Orientation.HORIZONTAL,
|
||||
can_focus: false,
|
||||
visible: true
|
||||
});
|
||||
prefs_time_list.add(force_manual_box);
|
||||
|
||||
const force_manual_label = new Gtk.Label({
|
||||
label: _('Manual schedule'),
|
||||
halign: Gtk.Align.START,
|
||||
visible: true
|
||||
});
|
||||
force_manual_box.pack_start(force_manual_label, true, true, 0);
|
||||
|
||||
const force_manual_toggle = new Gtk.Switch({
|
||||
active: this.settings.get_boolean('time-force-manual'),
|
||||
halign: Gtk.Align.END,
|
||||
visible: true
|
||||
});
|
||||
settings.bind(
|
||||
'time-force-manual',
|
||||
force_manual_toggle,
|
||||
'active',
|
||||
Gio.SettingsBindFlags.DEFAULT
|
||||
);
|
||||
force_manual_box.pack_start(force_manual_toggle, false, false, 0);
|
||||
|
||||
prefs_time_list.add(new Gtk.Separator({
|
||||
orientation: Gtk.Orientation.VERTICAL,
|
||||
can_focus: false,
|
||||
visible: true
|
||||
}));
|
||||
|
||||
// Times schedule
|
||||
['sunrise', 'sunset'].forEach((suntime, i, suntimes) => {
|
||||
const time_box = new Gtk.Box({
|
||||
margin: 16,
|
||||
spacing: 12,
|
||||
orientation: Gtk.Orientation.HORIZONTAL,
|
||||
can_focus: false,
|
||||
visible: true
|
||||
});
|
||||
prefs_time_list.add(time_box);
|
||||
|
||||
if ( i < suntimes.length - 1 ) {
|
||||
prefs_time_list.add(new Gtk.Separator({
|
||||
orientation: Gtk.Orientation.VERTICAL,
|
||||
can_focus: false,
|
||||
visible: true
|
||||
}));
|
||||
}
|
||||
|
||||
const time_labels = new Map([
|
||||
['sunrise', _('Sunrise')],
|
||||
['sunset', _('Sunset')]
|
||||
]);
|
||||
const time_label = new Gtk.Label({
|
||||
label: time_labels.get(suntime),
|
||||
halign: Gtk.Align.START,
|
||||
visible: true
|
||||
})
|
||||
time_box.pack_start(time_label, true, true, 0);
|
||||
|
||||
const time = settings.get_double(`time-${suntime}`);
|
||||
const hour = Math.trunc(time);
|
||||
const minutes = Math.round((time - hour) * 60);
|
||||
|
||||
const time_hour_spin = new Gtk.SpinButton({
|
||||
adjustment: new Gtk.Adjustment({
|
||||
value: hour,
|
||||
lower: 0,
|
||||
upper: 23,
|
||||
step_increment: 1,
|
||||
page_increment: 0,
|
||||
page_size: 0
|
||||
}),
|
||||
value: hour,
|
||||
numeric: true,
|
||||
wrap: true,
|
||||
orientation: Gtk.Orientation.VERTICAL,
|
||||
visible: true
|
||||
});
|
||||
settings.bind(
|
||||
'time-force-manual',
|
||||
time_hour_spin,
|
||||
'sensitive',
|
||||
Gio.SettingsBindFlags.DEFAULT
|
||||
);
|
||||
settings.connect(`changed::time-${suntime}`, () => {
|
||||
const hour = Math.trunc(settings.get_double(`time-${suntime}`));
|
||||
time_hour_spin.value = hour;
|
||||
});
|
||||
time_hour_spin.connect('output', () => {
|
||||
const text = time_hour_spin.adjustment.value.toString().padStart(2, '0');
|
||||
time_hour_spin.set_text(text);
|
||||
return true;
|
||||
});
|
||||
time_hour_spin.connect('value-changed', () => {
|
||||
const old_time = settings.get_double(`time-${suntime}`);
|
||||
const old_hour = Math.trunc(old_time);
|
||||
const minutes = old_time - old_hour;
|
||||
const new_time = time_hour_spin.value + minutes;
|
||||
settings.set_double(`time-${suntime}`, new_time);
|
||||
});
|
||||
time_box.pack_start(time_hour_spin, false, false, 0);
|
||||
|
||||
const time_separator = new Gtk.Label({
|
||||
label: ':',
|
||||
visible: true
|
||||
})
|
||||
time_box.pack_start(time_separator, false, false, 0);
|
||||
|
||||
const time_minutes_spin = new Gtk.SpinButton({
|
||||
adjustment: new Gtk.Adjustment({
|
||||
value: minutes,
|
||||
lower: 0,
|
||||
upper: 59,
|
||||
step_increment: 1,
|
||||
page_increment: 0,
|
||||
page_size: 0
|
||||
}),
|
||||
value: minutes,
|
||||
numeric: true,
|
||||
wrap: true,
|
||||
orientation: Gtk.Orientation.VERTICAL,
|
||||
visible: true
|
||||
});
|
||||
settings.bind(
|
||||
'time-force-manual',
|
||||
time_minutes_spin,
|
||||
'sensitive',
|
||||
Gio.SettingsBindFlags.DEFAULT
|
||||
);
|
||||
settings.connect(`changed::time-${suntime}`, () => {
|
||||
const time = settings.get_double(`time-${suntime}`);
|
||||
const hour = Math.trunc(time);
|
||||
const minutes = Math.round((time - hour) * 60);
|
||||
time_minutes_spin.value = minutes;
|
||||
});
|
||||
time_minutes_spin.connect('output', () => {
|
||||
const text = time_minutes_spin.adjustment.value.toString().padStart(2, '0');
|
||||
time_minutes_spin.set_text(text);
|
||||
return true;
|
||||
});
|
||||
time_minutes_spin.connect('value-changed', () => {
|
||||
const hour = Math.trunc(settings.get_double(`time-${suntime}`));
|
||||
const minutes = time_minutes_spin.value / 60;
|
||||
const new_time = hour + minutes;
|
||||
settings.set_double(`time-${suntime}`, new_time);
|
||||
});
|
||||
time_box.pack_start(time_minutes_spin, false, false, 0);
|
||||
});
|
||||
prefs_widget.show_all();
|
||||
|
||||
return prefs_widget;
|
||||
}
|
||||
|
||||
@@ -1,50 +1,100 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<schemalist gettext-domain="nightthemeswitcher@romainvigier.fr">
|
||||
<schema id="org.gnome.shell.extensions.nightthemeswitcher" path="/org/gnome/shell/extensions/nightthemeswitcher/">
|
||||
<key name="theme-force-manual" type="b">
|
||||
<default>false</default>
|
||||
<summary>Use manual variants</summary>
|
||||
<description>Disable automatic variants detection</description>
|
||||
</key>
|
||||
<key name="theme-day" type="s">
|
||||
<key name="gtk-variant-day" type="s">
|
||||
<default>"Adwaita"</default>
|
||||
<summary>Day theme</summary>
|
||||
<description>The theme to use during daytime</description>
|
||||
<summary>Day GTK theme</summary>
|
||||
<description>The GTK theme to use during daytime</description>
|
||||
</key>
|
||||
<key name="theme-night" type="s">
|
||||
<key name="gtk-variant-night" type="s">
|
||||
<default>"Adwaita-dark"</default>
|
||||
<summary>Night theme</summary>
|
||||
<description>The theme to use during nighttime</description>
|
||||
<summary>Night GTK theme</summary>
|
||||
<description>The GTK theme to use during nighttime</description>
|
||||
</key>
|
||||
<key name="theme-original" type="s">
|
||||
<default>""</default>
|
||||
<summary>Original theme</summary>
|
||||
<description>The theme to restore if the extension is disabled</description>
|
||||
<key name="gtk-variant-original" type="s">
|
||||
<default>"Adwaita"</default>
|
||||
<summary>Original GTK theme</summary>
|
||||
<description>The GTK theme to restore when the extension is disabled</description>
|
||||
</key>
|
||||
<key name="time-force-manual" type="b">
|
||||
<key name="manual-gtk-variants" type="b">
|
||||
<default>false</default>
|
||||
<summary>Use manual schedule</summary>
|
||||
<description>Disable automatic times detection</description>
|
||||
<summary>Use manual GTK variants</summary>
|
||||
<description>Disable automatic GTK theme variants detection</description>
|
||||
</key>
|
||||
<key name="shell-variant-day" type="s">
|
||||
<default>""</default>
|
||||
<summary>Day shell theme</summary>
|
||||
<description>The shell theme to use during daytime</description>
|
||||
</key>
|
||||
<key name="shell-variant-night" type="s">
|
||||
<default>""</default>
|
||||
<summary>Night shell theme</summary>
|
||||
<description>The shell theme to use during nighttime</description>
|
||||
</key>
|
||||
<key name="shell-variant-original" type="s">
|
||||
<default>""</default>
|
||||
<summary>Original shell theme</summary>
|
||||
<description>The shell theme to restore when the extension is disabled</description>
|
||||
</key>
|
||||
<key name="manual-shell-variants" type="b">
|
||||
<default>false</default>
|
||||
<summary>Use manual shell variants</summary>
|
||||
<description>Disable automatic shell theme variants detection</description>
|
||||
</key>
|
||||
<key name="time-source" type="s">
|
||||
<choices>
|
||||
<choice value="nightlight"/>
|
||||
<choice value="location"/>
|
||||
<choice value="manual"/>
|
||||
<choice value="schedule"/>
|
||||
</choices>
|
||||
<default>"manual"</default>
|
||||
<default>"schedule"</default>
|
||||
<summary>Time source</summary>
|
||||
<description>The source used to check current time</description>
|
||||
</key>
|
||||
<key name="time-sunrise" type="d">
|
||||
<key name="manual-time-source" type="b">
|
||||
<default>false</default>
|
||||
<summary>Use manual time source</summary>
|
||||
<description>Disable automatic time source detection</description>
|
||||
</key>
|
||||
<key name="schedule-sunrise" type="d">
|
||||
<default>6</default>
|
||||
<summary>Sunrise time</summary>
|
||||
<description>When the day starts</description>
|
||||
</key>
|
||||
<key name="time-sunset" type="d">
|
||||
<key name="schedule-sunset" type="d">
|
||||
<default>20</default>
|
||||
<summary>Sunset time</summary>
|
||||
<description>When the day ends</description>
|
||||
</key>
|
||||
<key name="commands-enabled" type="b">
|
||||
<default>false</default>
|
||||
<summary>Enable commands</summary>
|
||||
<description>Commands will be spawned on time change</description>
|
||||
</key>
|
||||
<key name="command-sunrise" type="s">
|
||||
<default>""</default>
|
||||
<summary>Sunrise command</summary>
|
||||
<description>The command to spawn at sunrise</description>
|
||||
</key>
|
||||
<key name="command-sunset" type="s">
|
||||
<default>""</default>
|
||||
<summary>Sunset command</summary>
|
||||
<description>The command to spawn at sunset</description>
|
||||
</key>
|
||||
<key name="backgrounds-enabled" type="b">
|
||||
<default>false</default>
|
||||
<summary>Enable backgrounds</summary>
|
||||
<description>Background will be changed on time change</description>
|
||||
</key>
|
||||
<key name="background-day" type="s">
|
||||
<default>""</default>
|
||||
<summary>Day background</summary>
|
||||
<description>Path to the day background</description>
|
||||
</key>
|
||||
<key name="background-night" type="s">
|
||||
<default>""</default>
|
||||
<summary>Night background</summary>
|
||||
<description>Path to the night background</description>
|
||||
</key>
|
||||
</schema>
|
||||
</schemalist>
|
||||
|
||||
+144
-17
@@ -22,51 +22,79 @@ const { extensionUtils } = imports.misc;
|
||||
const Me = extensionUtils.getCurrentExtension();
|
||||
const config = Me.imports.config;
|
||||
|
||||
const Gettext = imports.gettext.domain(Me.metadata.uuid);
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
var log_debug = function(message) {
|
||||
if ( config.debug ) {
|
||||
|
||||
const shell_minor_version = parseInt(imports.misc.config.PACKAGE_VERSION.split('.')[1]);
|
||||
|
||||
|
||||
/**
|
||||
* Output a debug message to the console if the debug config is active.
|
||||
* @param {string} message The message to log.
|
||||
*/
|
||||
function log_debug(message) {
|
||||
if (config.debug) {
|
||||
log(`[DEBUG] ${Me.metadata.name}: ${message}`);
|
||||
}
|
||||
}
|
||||
|
||||
var log_error = function(error) {
|
||||
logError(error, Me.metadata.name);
|
||||
/**
|
||||
* Log an error and show a notification if it has a message.
|
||||
* @param {Error} error The error to log.
|
||||
*/
|
||||
function log_error(error) {
|
||||
if (config.debug) {
|
||||
logError(error, Me.metadata.name);
|
||||
}
|
||||
if ( error.message && imports.ui ) {
|
||||
imports.ui.main.notifyError(Me.metadata.name, error.message);
|
||||
}
|
||||
}
|
||||
|
||||
var get_installed_themes = function() {
|
||||
/**
|
||||
* Get all the theme directories of the system.
|
||||
* @returns {string[]} An array of paths.
|
||||
*/
|
||||
function get_theme_dirs_paths() {
|
||||
return [
|
||||
GLib.build_filenamev([GLib.get_home_dir(), '.themes']),
|
||||
GLib.build_filenamev([GLib.get_user_data_dir(), 'themes']),
|
||||
...GLib.get_system_data_dirs().map(path => GLib.build_filenamev([path, 'themes']))
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the installed GTK themes on the system.
|
||||
* @returns {Set} A set containing all the installed GTK themes names.
|
||||
*/
|
||||
function get_installed_gtk_themes() {
|
||||
const themes = new Set(['Adwaita', 'HighContrast', 'HighContrastInverse']);
|
||||
|
||||
const data_dirs_paths = GLib.get_system_data_dirs().concat(GLib.get_user_data_dir());
|
||||
const themes_dirs_paths = data_dirs_paths.map(path => GLib.build_filenamev([path, 'themes']));
|
||||
themes_dirs_paths.push(GLib.build_filenamev([GLib.get_home_dir(), '.themes']));
|
||||
|
||||
themes_dirs_paths.forEach(themes_dir_path => {
|
||||
get_theme_dirs_paths().forEach(themes_dir_path => {
|
||||
const themes_dir = Gio.File.new_for_path(themes_dir_path);
|
||||
|
||||
if ( themes_dir.query_file_type(Gio.FileQueryInfoFlags.NONE, null) !== Gio.FileType.DIRECTORY ) {
|
||||
if (themes_dir.query_file_type(Gio.FileQueryInfoFlags.NONE, null) !== Gio.FileType.DIRECTORY) {
|
||||
return;
|
||||
}
|
||||
|
||||
const theme_dirs_enumerator = themes_dir.enumerate_children('', Gio.FileQueryInfoFlags.NONE, null);
|
||||
|
||||
while ( true ) {
|
||||
while (true) {
|
||||
let theme_dir_info = theme_dirs_enumerator.next_file(null);
|
||||
|
||||
if ( theme_dir_info === null ) {
|
||||
if (theme_dir_info === null) {
|
||||
break;
|
||||
}
|
||||
|
||||
const theme_dir = theme_dirs_enumerator.get_child(theme_dir_info);
|
||||
|
||||
[0, Gtk.MINOR_VERSION].forEach(gtk_version => {
|
||||
if ( gtk_version % 2 ) {
|
||||
if (gtk_version % 2) {
|
||||
gtk_version += 1;
|
||||
}
|
||||
const css_file = Gio.File.new_for_path(GLib.build_filenamev([theme_dir.get_path(), `gtk-3.${gtk_version}`, 'gtk.css']));
|
||||
if ( css_file.query_exists(null) ) {
|
||||
if (css_file.query_exists(null)) {
|
||||
themes.add(theme_dir.get_basename());
|
||||
}
|
||||
})
|
||||
@@ -77,6 +105,105 @@ var get_installed_themes = function() {
|
||||
return themes;
|
||||
}
|
||||
|
||||
var is_theme_installed = function(theme) {
|
||||
return get_installed_themes().has(theme);
|
||||
/**
|
||||
* Get all the installed shell themes on the system.
|
||||
* @returns {Set} A set containing all the installed shell themes names.
|
||||
*/
|
||||
function get_installed_shell_themes() {
|
||||
const themes = new Set(['']);
|
||||
|
||||
get_theme_dirs_paths().forEach(themes_dir_path => {
|
||||
const themes_dir = Gio.File.new_for_path(themes_dir_path);
|
||||
|
||||
if (themes_dir.query_file_type(Gio.FileQueryInfoFlags.NONE, null) !== Gio.FileType.DIRECTORY) {
|
||||
return;
|
||||
}
|
||||
|
||||
const theme_dirs_enumerator = themes_dir.enumerate_children('', Gio.FileQueryInfoFlags.NONE, null);
|
||||
|
||||
while (true) {
|
||||
let theme_dir_info = theme_dirs_enumerator.next_file(null);
|
||||
|
||||
if (theme_dir_info === null) {
|
||||
break;
|
||||
}
|
||||
|
||||
const theme_dir = theme_dirs_enumerator.get_child(theme_dir_info);
|
||||
const css_file = Gio.File.new_for_path(GLib.build_filenamev([theme_dir.get_path(), 'gnome-shell', 'gnome-shell.css']));
|
||||
if (css_file.query_exists(null)) {
|
||||
themes.add(theme_dir.get_basename());
|
||||
}
|
||||
}
|
||||
theme_dirs_enumerator.close(null);
|
||||
});
|
||||
|
||||
return themes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the User Themes extension.
|
||||
* @returns {Object|undefined} The User Themes extension object or undefined if
|
||||
* it isn't installed.
|
||||
*/
|
||||
function get_userthemes_extension() {
|
||||
if ( shell_minor_version > 32 ) {
|
||||
return imports.ui.main.extensionManager.lookup('user-theme@gnome-shell-extensions.gcampax.github.com');
|
||||
}
|
||||
else {
|
||||
return extensionUtils.extensions['user-theme@gnome-shell-extensions.gcampax.github.com'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the User Themes extension settings.
|
||||
* @returns {Gio.Settings|null} The User Themes extension settings or null if
|
||||
* the extension isn't installed.
|
||||
*/
|
||||
function get_userthemes_settings() {
|
||||
let extension = get_userthemes_extension();
|
||||
|
||||
if ( !extension ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const schema_dir = extension.dir.get_child('schemas');
|
||||
const GioSSS = Gio.SettingsSchemaSource;
|
||||
let schemaSource;
|
||||
if ( schema_dir.query_exists(null) ) {
|
||||
schemaSource = GioSSS.new_from_directory(schema_dir.get_path(), GioSSS.get_default(), false);
|
||||
}
|
||||
else {
|
||||
schemaSource = GioSSS.get_default();
|
||||
}
|
||||
const schemaObj = schemaSource.lookup('org.gnome.shell.extensions.user-theme', true);
|
||||
return new Gio.Settings({ settings_schema: schemaObj });
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the shell theme stylesheet.
|
||||
* @param {string} theme The shell theme name.
|
||||
* @returns {string} Path to the shell theme stylesheet.
|
||||
*/
|
||||
function get_shell_theme_stylesheet(theme) {
|
||||
log_debug('Getting the ' + (theme ? `'${theme}'` : 'default') + ' theme shell stylesheet...');
|
||||
let stylesheet = null;
|
||||
if ( theme ) {
|
||||
const stylesheet_paths = get_theme_dirs_paths().map(path => `${path}/${theme}/gnome-shell/gnome-shell.css`);
|
||||
stylesheet = stylesheet_paths.find(path => {
|
||||
let file = Gio.file_new_for_path(path);
|
||||
return file.query_exists(null);
|
||||
});
|
||||
}
|
||||
return stylesheet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a stylesheet to the shell.
|
||||
* @param {string} stylesheet The shell stylesheet to apply.
|
||||
*/
|
||||
function apply_shell_stylesheet(stylesheet) {
|
||||
log_debug('Applying shell stylesheet...');
|
||||
imports.ui.main.setThemeStylesheet(stylesheet);
|
||||
imports.ui.main.loadTheme();
|
||||
log_debug('Shell stylesheet applied.');
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
exports.Variants = Variants;
|
||||
@@ -0,0 +1 @@
|
||||
exports.Variants = GtkVariants;
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const test = require('ava');
|
||||
const { Variants } = require('./_variants');
|
||||
|
||||
|
||||
test('Adapta', t => {
|
||||
const variants = Variants.guess_from('Adapta');
|
||||
t.is(variants.get('day'), 'Adapta');
|
||||
t.is(variants.get('night'), 'Adapta-Nokto');
|
||||
});
|
||||
|
||||
test('Adapta-Nokto', t => {
|
||||
const variants = Variants.guess_from('Adapta-Nokto');
|
||||
t.is(variants.get('day'), 'Adapta');
|
||||
t.is(variants.get('night'), 'Adapta-Nokto');
|
||||
});
|
||||
|
||||
test('Adapta-Eta', t => {
|
||||
const variants = Variants.guess_from('Adapta-Eta');
|
||||
t.is(variants.get('day'), 'Adapta-Eta');
|
||||
t.is(variants.get('night'), 'Adapta-Nokto-Eta');
|
||||
});
|
||||
|
||||
test('Adapta-Nokto-Eta', t => {
|
||||
const variants = Variants.guess_from('Adapta-Nokto-Eta');
|
||||
t.is(variants.get('day'), 'Adapta-Eta');
|
||||
t.is(variants.get('night'), 'Adapta-Nokto-Eta');
|
||||
});
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const test = require('ava');
|
||||
const { Variants } = require('./_variants');
|
||||
|
||||
|
||||
test('Arc', t => {
|
||||
const variants = Variants.guess_from('Arc');
|
||||
t.is(variants.get('day'), 'Arc');
|
||||
t.is(variants.get('night'), 'Arc-Dark');
|
||||
});
|
||||
|
||||
test('Arc-Dark', t => {
|
||||
const variants = Variants.guess_from('Arc-Dark');
|
||||
t.is(variants.get('day'), 'Arc');
|
||||
t.is(variants.get('night'), 'Arc-Dark');
|
||||
});
|
||||
|
||||
test('Arc-Dark-solid', t => {
|
||||
const variants = Variants.guess_from('Arc-Dark-solid');
|
||||
t.is(variants.get('day'), 'Arc-solid');
|
||||
t.is(variants.get('night'), 'Arc-Dark-solid');
|
||||
});
|
||||
|
||||
test('Arc-solid', t => {
|
||||
const variants = Variants.guess_from('Arc-solid');
|
||||
t.is(variants.get('day'), 'Arc-solid');
|
||||
t.is(variants.get('night'), 'Arc-Dark-solid');
|
||||
});
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const test = require('ava');
|
||||
const { Variants } = require('./_variants');
|
||||
|
||||
|
||||
['', '-blue', '-indigo'].forEach(color => {
|
||||
test(`Canta${color}`, t => {
|
||||
const variants = Variants.guess_from(`Canta${color}`);
|
||||
t.is(variants.get('day'), `Canta${color}`);
|
||||
t.is(variants.get('night'), `Canta${color}-dark`);
|
||||
});
|
||||
|
||||
test(`Canta${color}-dark`, t => {
|
||||
const variants = Variants.guess_from(`Canta${color}-dark`);
|
||||
t.is(variants.get('day'), `Canta${color}`);
|
||||
t.is(variants.get('night'), `Canta${color}-dark`);
|
||||
});
|
||||
|
||||
test(`Canta${color}-light`, t => {
|
||||
const variants = Variants.guess_from(`Canta${color}-light`);
|
||||
t.is(variants.get('day'), `Canta${color}-light`);
|
||||
t.is(variants.get('night'), `Canta${color}-dark`);
|
||||
});
|
||||
|
||||
test(`Canta${color}-compact`, t => {
|
||||
const variants = Variants.guess_from(`Canta${color}-compact`);
|
||||
t.is(variants.get('day'), `Canta${color}-compact`);
|
||||
t.is(variants.get('night'), `Canta${color}-dark-compact`);
|
||||
});
|
||||
|
||||
test(`Canta${color}-dark-compact`, t => {
|
||||
const variants = Variants.guess_from(`Canta${color}-dark-compact`);
|
||||
t.is(variants.get('day'), `Canta${color}-compact`);
|
||||
t.is(variants.get('night'), `Canta${color}-dark-compact`);
|
||||
});
|
||||
|
||||
test(`Canta${color}-light-compact`, t => {
|
||||
const variants = Variants.guess_from(`Canta${color}-light-compact`);
|
||||
t.is(variants.get('day'), `Canta${color}-light-compact`);
|
||||
t.is(variants.get('night'), `Canta${color}-dark-compact`);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const test = require('ava');
|
||||
const { Variants } = require('./_variants');
|
||||
|
||||
['', '-compact'].forEach(size => {
|
||||
test(`ChromeOS${size}`, t => {
|
||||
const variants = Variants.guess_from(`ChromeOS${size}`);
|
||||
t.is(variants.get('day'), `ChromeOS${size}`);
|
||||
t.is(variants.get('night'), `ChromeOS-dark${size}`);
|
||||
});
|
||||
|
||||
test(`ChromeOS-dark${size}`, t => {
|
||||
const variants = Variants.guess_from(`ChromeOS-dark${size}`);
|
||||
t.is(variants.get('day'), `ChromeOS${size}`);
|
||||
t.is(variants.get('night'), `ChromeOS-dark${size}`);
|
||||
});
|
||||
|
||||
test(`ChromeOS-light${size}`, t => {
|
||||
const variants = Variants.guess_from(`ChromeOS-light${size}`);
|
||||
t.is(variants.get('day'), `ChromeOS-light${size}`);
|
||||
t.is(variants.get('night'), `ChromeOS-dark${size}`);
|
||||
});
|
||||
})
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const test = require('ava');
|
||||
const { Variants } = require('./_variants');
|
||||
|
||||
['', '-Miami'].forEach(color => {
|
||||
['', '-fullPanel'].forEach(size => {
|
||||
test(`Flat-Remix${color}${size}`, t => {
|
||||
const variants = Variants.guess_from(`Flat-Remix${color}${size}`);
|
||||
t.is(variants.get('day'), `Flat-Remix${color}${size}`);
|
||||
t.is(variants.get('night'), `Flat-Remix${color}-Dark${size}`);
|
||||
});
|
||||
|
||||
test(`Flat-Remix${color}-Dark${size}`, t => {
|
||||
const variants = Variants.guess_from(`Flat-Remix${color}-Dark${size}`);
|
||||
t.is(variants.get('day'), `Flat-Remix${color}${size}`);
|
||||
t.is(variants.get('night'), `Flat-Remix${color}-Dark${size}`);
|
||||
});
|
||||
|
||||
test(`Flat-Remix${color}-Darkest${size}`, t => {
|
||||
const variants = Variants.guess_from(`Flat-Remix${color}-Darkest${size}`);
|
||||
t.is(variants.get('day'), `Flat-Remix${color}${size}`);
|
||||
t.is(variants.get('night'), `Flat-Remix${color}-Darkest${size}`);
|
||||
});
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const test = require('ava');
|
||||
const { Variants } = require('./_variants');
|
||||
|
||||
|
||||
test('Layan', t => {
|
||||
const variants = Variants.guess_from('Layan');
|
||||
t.is(variants.get('day'), 'Layan');
|
||||
t.is(variants.get('night'), 'Layan-dark');
|
||||
});
|
||||
|
||||
test('Layan-dark', t => {
|
||||
const variants = Variants.guess_from('Layan-dark');
|
||||
t.is(variants.get('day'), 'Layan');
|
||||
t.is(variants.get('night'), 'Layan-dark');
|
||||
});
|
||||
|
||||
test('Layan-light', t => {
|
||||
const variants = Variants.guess_from('Layan-light');
|
||||
t.is(variants.get('day'), 'Layan-light');
|
||||
t.is(variants.get('night'), 'Layan-dark');
|
||||
});
|
||||
|
||||
test('Layan-solid', t => {
|
||||
const variants = Variants.guess_from('Layan-solid');
|
||||
t.is(variants.get('day'), 'Layan-solid');
|
||||
t.is(variants.get('night'), 'Layan-dark-solid');
|
||||
});
|
||||
|
||||
test('Layan-dark-solid', t => {
|
||||
const variants = Variants.guess_from('Layan-dark-solid');
|
||||
t.is(variants.get('day'), 'Layan-solid');
|
||||
t.is(variants.get('night'), 'Layan-dark-solid');
|
||||
});
|
||||
|
||||
test('Layan-light-solid', t => {
|
||||
const variants = Variants.guess_from('Layan-light-solid');
|
||||
t.is(variants.get('day'), 'Layan-light-solid');
|
||||
t.is(variants.get('night'), 'Layan-dark-solid');
|
||||
});
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const test = require('ava');
|
||||
const { Variants } = require('./_variants');
|
||||
|
||||
|
||||
['aliz', 'azul', 'sea'].forEach(color => {
|
||||
test(`Matcha-${color}`, t => {
|
||||
const variants = Variants.guess_from(`Matcha-${color}`);
|
||||
t.is(variants.get('day'), `Matcha-${color}`);
|
||||
t.is(variants.get('night'), `Matcha-dark-${color}`);
|
||||
});
|
||||
|
||||
test(`Matcha-dark-${color}`, t => {
|
||||
const variants = Variants.guess_from(`Matcha-dark-${color}`);
|
||||
t.is(variants.get('day'), `Matcha-${color}`);
|
||||
t.is(variants.get('night'), `Matcha-dark-${color}`);
|
||||
});
|
||||
|
||||
test(`Matcha-light-${color}`, t => {
|
||||
const variants = Variants.guess_from(`Matcha-light-${color}`);
|
||||
t.is(variants.get('day'), `Matcha-light-${color}`);
|
||||
t.is(variants.get('night'), `Matcha-dark-${color}`);
|
||||
});
|
||||
})
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const test = require('ava');
|
||||
const { Variants } = require('./_variants');
|
||||
|
||||
|
||||
['', '-compact'].forEach(size => {
|
||||
test(`Materia${size}`, t => {
|
||||
const variants = Variants.guess_from(`Materia${size}`);
|
||||
t.is(variants.get('day'), `Materia${size}`);
|
||||
t.is(variants.get('night'), `Materia-dark${size}`);
|
||||
});
|
||||
|
||||
test(`Materia-dark${size}`, t => {
|
||||
const variants = Variants.guess_from(`Materia-dark${size}`);
|
||||
t.is(variants.get('day'), `Materia${size}`);
|
||||
t.is(variants.get('night'), `Materia-dark${size}`);
|
||||
});
|
||||
|
||||
test(`Materia-light${size}`, t => {
|
||||
const variants = Variants.guess_from(`Materia-light${size}`);
|
||||
t.is(variants.get('day'), `Materia-light${size}`);
|
||||
t.is(variants.get('night'), `Materia-dark${size}`);
|
||||
});
|
||||
})
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const test = require('ava');
|
||||
const { Variants } = require('./_variants');
|
||||
|
||||
|
||||
['', '-solid'].forEach(transparency => {
|
||||
['', '-alt'].forEach(alt => {
|
||||
test(`Mojave-light${transparency}${alt}`, t => {
|
||||
const variants = Variants.guess_from(`Mojave-light${transparency}${alt}`);
|
||||
t.is(variants.get('day'), `Mojave-light${transparency}${alt}`);
|
||||
t.is(variants.get('night'), `Mojave-dark${transparency}${alt}`);
|
||||
});
|
||||
|
||||
test(`Mojave-dark${transparency}${alt}`, t => {
|
||||
const variants = Variants.guess_from(`Mojave-dark${transparency}${alt}`);
|
||||
t.is(variants.get('day'), `Mojave-light${transparency}${alt}`);
|
||||
t.is(variants.get('night'), `Mojave-dark${transparency}${alt}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const test = require('ava');
|
||||
const { Variants } = require('./_variants');
|
||||
|
||||
|
||||
['', '-compact'].forEach(size => {
|
||||
test(`Orchis${size}`, t => {
|
||||
const variants = Variants.guess_from(`Orchis${size}`);
|
||||
t.is(variants.get('day'), `Orchis${size}`);
|
||||
t.is(variants.get('night'), `Orchis-dark${size}`);
|
||||
});
|
||||
|
||||
test(`Orchis-dark${size}`, t => {
|
||||
const variants = Variants.guess_from(`Orchis-dark${size}`);
|
||||
t.is(variants.get('day'), `Orchis${size}`);
|
||||
t.is(variants.get('night'), `Orchis-dark${size}`);
|
||||
});
|
||||
})
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const test = require('ava');
|
||||
const { Variants } = require('./_variants');
|
||||
|
||||
|
||||
['', '-Compact'].forEach(size => {
|
||||
test(`Plata${size}`, t => {
|
||||
const variants = Variants.guess_from(`Plata${size}`);
|
||||
t.is(variants.get('day'), `Plata${size}`);
|
||||
t.is(variants.get('night'), `Plata-Noir${size}`);
|
||||
});
|
||||
|
||||
test(`Plata-Noir${size}`, t => {
|
||||
const variants = Variants.guess_from(`Plata-Noir${size}`);
|
||||
t.is(variants.get('day'), `Plata${size}`);
|
||||
t.is(variants.get('night'), `Plata-Noir${size}`);
|
||||
});
|
||||
|
||||
test(`Plata-Lumine${size}`, t => {
|
||||
const variants = Variants.guess_from(`Plata-Lumine${size}`);
|
||||
t.is(variants.get('day'), `Plata-Lumine${size}`);
|
||||
t.is(variants.get('night'), `Plata-Noir${size}`);
|
||||
});
|
||||
})
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const test = require('ava');
|
||||
const { Variants } = require('./_variants');
|
||||
|
||||
|
||||
['', '-manjaro', '-ubuntu'].forEach(color => {
|
||||
['', '-win'].forEach(alt => {
|
||||
test(`Qogir${color}${alt}`, t => {
|
||||
const variants = Variants.guess_from(`Qogir${color}${alt}`);
|
||||
t.is(variants.get('day'), `Qogir${color}${alt}`);
|
||||
t.is(variants.get('night'), `Qogir${color}${alt}-dark`);
|
||||
});
|
||||
|
||||
test(`Qogir${color}${alt}-dark`, t => {
|
||||
const variants = Variants.guess_from(`Qogir${color}${alt}-dark`);
|
||||
t.is(variants.get('day'), `Qogir${color}${alt}`);
|
||||
t.is(variants.get('night'), `Qogir${color}${alt}-dark`);
|
||||
});
|
||||
|
||||
test(`Qogir${color}${alt}light`, t => {
|
||||
const variants = Variants.guess_from(`Qogir${color}${alt}-light`);
|
||||
t.is(variants.get('day'), `Qogir${color}${alt}-light`);
|
||||
t.is(variants.get('night'), `Qogir${color}${alt}-dark`);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const test = require('ava');
|
||||
const { Variants } = require('./_variants');
|
||||
|
||||
|
||||
['', '_Blue', '_Cyan', '_Green', '_Orange', '_Purple'].forEach(color => {
|
||||
['', '_Envolved'].forEach(variant => {
|
||||
test(`Simply_Circles${color}_Light${variant}`, t => {
|
||||
const variants = Variants.guess_from(`Simply_Circles${color}_Light${variant}`);
|
||||
t.is(variants.get('day'), `Simply_Circles${color}_Light${variant}`);
|
||||
t.is(variants.get('night'), `Simply_Circles${color}_Dark${variant}`);
|
||||
});
|
||||
|
||||
test(`Simply_Circles${color}${variant}`, t => {
|
||||
const variants = Variants.guess_from(`Simply_Circles${color}_Dark${variant}`);
|
||||
t.is(variants.get('day'), `Simply_Circles${color}_Light${variant}`);
|
||||
t.is(variants.get('night'), `Simply_Circles${color}_Dark${variant}`);
|
||||
});
|
||||
})
|
||||
});
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const test = require('ava');
|
||||
const { Variants } = require('./_variants');
|
||||
|
||||
test('Teja', t => {
|
||||
const variants = Variants.guess_from('Teja');
|
||||
t.is(variants.get('day'), 'Teja');
|
||||
t.is(variants.get('night'), 'Teja_Dark');
|
||||
});
|
||||
|
||||
test('Teja_Dark', t => {
|
||||
const variants = Variants.guess_from('Teja_Dark');
|
||||
t.is(variants.get('day'), 'Teja');
|
||||
t.is(variants.get('night'), 'Teja_Dark');
|
||||
});
|
||||
|
||||
test('Teja_Darkest', t => {
|
||||
const variants = Variants.guess_from('Teja_Darkest');
|
||||
t.is(variants.get('day'), 'Teja');
|
||||
t.is(variants.get('night'), 'Teja_Darkest');
|
||||
});
|
||||
|
||||
test('Teja_Black', t => {
|
||||
const variants = Variants.guess_from('Teja_Black');
|
||||
t.is(variants.get('day'), 'Teja');
|
||||
t.is(variants.get('night'), 'Teja_Black');
|
||||
});
|
||||
|
||||
test('Teja_Light', t => {
|
||||
const variants = Variants.guess_from('Teja_Light');
|
||||
t.is(variants.get('day'), 'Teja_Light');
|
||||
t.is(variants.get('night'), 'Teja_Dark');
|
||||
});
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const test = require('ava');
|
||||
const { Variants } = require('./_variants');
|
||||
|
||||
|
||||
['', '-laptop'].forEach(size => {
|
||||
['', '-beryl', '-doder', '-ruby'].forEach(color => {
|
||||
test(`vimix${size}${color}`, t => {
|
||||
const variants = Variants.guess_from(`vimix${size}${color}`);
|
||||
t.is(variants.get('day'), `vimix${size}${color}`);
|
||||
t.is(variants.get('night'), `vimix-dark${size}${color}`);
|
||||
});
|
||||
|
||||
test(`vimix-dark${size}${color}`, t => {
|
||||
const variants = Variants.guess_from(`vimix-dark${size}${color}`);
|
||||
t.is(variants.get('day'), `vimix${size}${color}`);
|
||||
t.is(variants.get('night'), `vimix-dark${size}${color}`);
|
||||
});
|
||||
test(`vimix-light${size}${color}`, t => {
|
||||
const variants = Variants.guess_from(`vimix-light${size}${color}`);
|
||||
t.is(variants.get('day'), `vimix-light${size}${color}`);
|
||||
t.is(variants.get('night'), `vimix-dark${size}${color}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const test = require('ava');
|
||||
const { Variants } = require('./_variants');
|
||||
|
||||
|
||||
test('Yaru', t => {
|
||||
const variants = Variants.guess_from('Yaru');
|
||||
t.is(variants.get('day'), 'Yaru');
|
||||
t.is(variants.get('night'), 'Yaru-dark');
|
||||
});
|
||||
|
||||
test('Yaru-dark', t => {
|
||||
const variants = Variants.guess_from('Yaru-dark');
|
||||
t.is(variants.get('day'), 'Yaru');
|
||||
t.is(variants.get('night'), 'Yaru-dark');
|
||||
});
|
||||
|
||||
test('Yaru-light', t => {
|
||||
const variants = Variants.guess_from('Yaru-light');
|
||||
t.is(variants.get('day'), 'Yaru-light');
|
||||
t.is(variants.get('night'), 'Yaru-dark');
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
exports.Variants = ShellVariants;
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
Night Theme Switcher Gnome Shell extension
|
||||
|
||||
Copyright (C) 2020 Romain Vigier
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http s ://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const test = require('ava');
|
||||
const { Variants } = require('./_variants');
|
||||
|
||||
test('default', t => {
|
||||
const variants = Variants.guess_from('default');
|
||||
t.is(variants.get('day'), 'default');
|
||||
t.is(variants.get('night'), 'default-dark');
|
||||
});
|
||||
|
||||
test('default-dark', t => {
|
||||
const variants = Variants.guess_from('default-dark');
|
||||
t.is(variants.get('day'), 'default');
|
||||
t.is(variants.get('night'), 'default-dark');
|
||||
});
|
||||
|
||||
test('default-light', t => {
|
||||
const variants = Variants.guess_from('default-light');
|
||||
t.is(variants.get('day'), 'default-light');
|
||||
t.is(variants.get('night'), 'default-dark');
|
||||
});
|
||||
|
||||
test('default-darker', t => {
|
||||
const variants = Variants.guess_from('default-darker');
|
||||
t.is(variants.get('day'), 'default-darker');
|
||||
t.is(variants.get('night'), 'default-dark');
|
||||
});
|
||||
|
||||
test('default-darkest', t => {
|
||||
const variants = Variants.guess_from('default-darkest');
|
||||
t.is(variants.get('day'), 'default');
|
||||
t.is(variants.get('night'), 'default-darkest');
|
||||
});
|
||||
Reference in New Issue
Block a user