Architecture rewrite and new features

This commit is contained in:
Romain
2020-05-25 08:41:35 +00:00
parent c64f0e8993
commit f21bc025b7
83 changed files with 4563 additions and 1686 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
build
node_modules
tests/_variants.js
tests/**/_variants.js
+3
View File
@@ -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 -4
View File
@@ -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
View File
@@ -1,3 +1,4 @@
<!-- Don't remove this line -->
/label ~discussion
+2 -1
View File
@@ -1,4 +1,5 @@
- Theme name:
- Theme repository or download link:
/label ~theme
<!-- Don't remove this line -->
/label ~"theme::request"
+4 -1
View File
@@ -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
+23 -5
View File
@@ -2,15 +2,15 @@
![](./screenshot.png)
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
View File
@@ -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.
+277 -157
View File
@@ -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
View File
@@ -8,6 +8,6 @@
"test": "ava"
},
"devDependencies": {
"ava": "^3.3.0"
"ava": "^3.8.2"
}
}
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 425 KiB

After

Width:  |  Height:  |  Size: 435 KiB

-64
View File
@@ -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;
+91
View File
@@ -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
View File
@@ -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
View File
@@ -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
}
+131
View File
@@ -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;
}
}
+93
View File
@@ -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.`);
}
}
+171
View File
@@ -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();
+427
View File
@@ -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);
+179
View File
@@ -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);
+103
View File
@@ -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;
}
}
-115
View File
@@ -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);
}
}
}
-219
View File
@@ -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
View File
@@ -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);
+322
View File
@@ -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);
+114
View File
@@ -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);
+88
View File
@@ -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
View File
@@ -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 lextension."
#: 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 lextension."
#: 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 darriè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 ""
"Lextension essayera de détecter automatiquement les variantes diurne et "
"nocturne de votre thème.\n"
"Si le thème que vous utilisez nest pas supporté, merci <a href=\"https://"
"gitlab.com/rmnvgr/nightthemeswitcher-gnome-shell-extension/-/issues\">den "
"faire la requête</a>.\n"
"Si vous préférez, vous pouvez définir manuellement les variantes."
"Lextension essayera de déterminer automatiquement les variantes diurnes et "
"nocturnes de votre thème GTK.\n"
"\n"
"Si le thème que vous utilisez nest 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 ""
"Sils sont activés, lextension essayera dutiliser 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 "
"dhoraires."
#: src/prefs.js:238
#: src/preferences/Schedule.js:43
msgid "Manual time source"
msgstr "Source dhoraires manuelle"
#: src/preferences/Schedule.js:44
#: src/schemas/org.gnome.shell.extensions.nightthemeswitcher.gschema.xml:51
msgid "Time source"
msgstr "Source dhoraires"
#: 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 ""
"Lextension 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 lextension."
"Lextension 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 nest 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 dobtenir 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 dobtenir lemplacement 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 lextension 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 lextension 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 lextension 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 dhoraires 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 dhoraires"
#: 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 dhoraire"
#: 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 ""
#~ "Lextension essayera de détecter automatiquement les variantes diurne et "
#~ "nocturne de votre thème.\n"
#~ "Si le thème que vous utilisez nest pas supporté, merci <a href=\"https://"
#~ "gitlab.com/rmnvgr/nightthemeswitcher-gnome-shell-extension/-/issues"
#~ "\">den 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 ""
#~ "Sils sont activés, lextension essayera dutiliser 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 ""
#~ "Lextension 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 lextension."
#~ 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 dobtenir 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 dobtenir lemplacement 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 lextension 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 :"
+236 -101
View File
@@ -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 ""
+111
View File
@@ -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;
}
}
+99
View File
@@ -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;
}
}
+95
View File
@@ -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;
}
}
+224
View File
@@ -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;
}
}
+94
View File
@@ -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;
}
}
+106
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -1 +0,0 @@
exports.Variants = Variants;
+1
View File
@@ -0,0 +1 @@
exports.Variants = GtkVariants;
+45
View File
@@ -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');
});
+45
View File
@@ -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');
});
+59
View File
@@ -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`);
});
});
+40
View File
@@ -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}`);
});
})
+42
View File
@@ -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}`);
});
})
})
+57
View File
@@ -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');
});
+41
View File
@@ -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}`);
});
})
+41
View File
@@ -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}`);
});
})
+37
View File
@@ -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}`);
});
});
});
+35
View File
@@ -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}`);
});
})
+41
View File
@@ -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}`);
});
})
+43
View File
@@ -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`);
});
});
});
+37
View File
@@ -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}`);
});
})
});
+50
View File
@@ -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');
});
+42
View File
@@ -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}`);
});
});
});
+39
View File
@@ -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');
});
+1
View File
@@ -0,0 +1 @@
exports.Variants = ShellVariants;
+50
View File
@@ -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');
});