Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed System Theme Detection doesn't work in Firefox #43 #44

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 55 additions & 23 deletions js/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ function init() {
});
}, onError)
.then(() => {
// this needs to be done regardless of settings
// otherwise we don't know what the system theme is, when the user switches to system-theme
enableSystemThemeTracking();

// If flag is not set to check only on startup,
// create alarms to change the theme in the future.
browser.alarms.onAlarm.addListener(alarmListener);
Expand Down Expand Up @@ -107,26 +111,6 @@ function init() {
}
});

// Add listener that will change the theme if the mode is set to "system-theme"
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {

if (!detect_scheme_change_block) {
if (DEBUG_MODE)
console.log("automaticDark DEBUG: 10 - prefers-color-scheme changed.");

browser.storage.local.get(CHANGE_MODE_KEY)
.then((obj) => {
if (obj[CHANGE_MODE_KEY].mode === "system-theme") {
checkSysTheme();
}
});
} else {
if (DEBUG_MODE)
console.log("automaticDark DEBUG: prefers-color-scheme changed, but scheme change detection is currently disabled.");
}

}, onError);

if (obj[CHANGE_MODE_KEY].mode === "system-theme") {
// browser.browserSettings.overrideContentColorScheme changes the following
// about:config to "2", effectively applying a light/dark theme based on the device theme
Expand Down Expand Up @@ -178,7 +162,7 @@ function changeThemeBasedOnChangeMode(mode) {
console.log("automaticDark DEBUG: 50 changeThemeBasedOnChangeMode - Mode is set to: " + mode);

if (mode === "system-theme") {
return checkSysTheme();
return checkSysTheme();
}
else if (mode === "location-suntimes" || mode === "manual-suntimes"){
return checkTime();
Expand Down Expand Up @@ -317,23 +301,29 @@ function checkTime() {
}

// Check the system theme and set the theme accordingly.
// system-theme is updated using events, that are sent on startup and during runtime.
// because the background script cant determine the system theme on it's owb ( #43 ), it cannot update the theme imperatively.
var system_is_dark = null;

function checkSysTheme() {
if (DEBUG_MODE)
console.log("automaticDark DEBUG: Start checkSysTheme");

if(window.matchMedia('(prefers-color-scheme: dark)').matches){
if(system_is_dark == true){
if (DEBUG_MODE)
console.log("automaticDark DEBUG: 90 checkSysTheme - User prefers dark interface");

return browser.storage.local.get(NIGHTTIME_THEME_KEY)
.then((obj) => {
return Promise.all([
browser.storage.local.set({[CURRENT_MODE_KEY]: {mode: "night-mode"}}),
enableTheme(obj, NIGHTTIME_THEME_KEY)
]);
}, onError);
} else {
} else if (system_is_dark == false) {
if (DEBUG_MODE)
console.log("automaticDark DEBUG: 90 checkSysTheme - User prefers light interface");

return browser.storage.local.get(DAYTIME_THEME_KEY)
.then((obj) => {
return Promise.all([
Expand All @@ -342,6 +332,48 @@ function checkSysTheme() {
]);
}, onError);
}
// if system_is_dark is null, it probably won't be for long
// we wouldn't want to assume a default, then change the theme back and forth when events come in
}

// This enables listening to messeges from tabs (system-theme-notifier.js) that are detecting changes to the system theme
// this needs to be done to keep the system_is_dark variable in sync,
// which is then applied normally when checkSysTheme is called.
function enableSystemThemeTracking() {
if (DEBUG_MODE)
console.log("automaticDark DEBUG: Start enableSystemThemeTracking");

// watching the media never did anything
browser.runtime.onMessage.removeListener(systemThemeListener);
browser.runtime.onMessage.addListener(systemThemeListener);
}

function systemThemeListener(msg, sender) {
if (msg.type!=="color-scheme-change") {
return false;
}

if (DEBUG_MODE)
console.log("automaticDark DEBUG: 10 - prefers-color-scheme changed in tab: ", msg.tab, " and is now: ", msg.prefersColorScheme);

if (system_is_dark !== msg.prefersColorScheme) {
if (DEBUG_MODE)
console.log("automaticDark DEBUG: 10 - new system theme recognized: ", msg.prefersColorScheme);

// SAVE the system theme
system_is_dark = msg.prefersColorScheme;

// UPDATE theme (if system-theme mode is on.)
browser.storage.local.get(CHANGE_MODE_KEY)
.then((obj) => {
console.log("automaticDark DEBUG: 10 - new system theme so updating ");
if (obj[CHANGE_MODE_KEY].mode === "system-theme" && !detect_scheme_change_block) { // doesnt update theme, if block is set
checkSysTheme();
}
});
}

return false;
}

// Parse the object given and enable the theme.if it is not
Expand Down
30 changes: 30 additions & 0 deletions js/system-theme-notifier.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
(async () => {
while( true) {
try {
console.log("automaticDark: sending message")
// on startup: send message to extension
await browser.runtime.sendMessage({
type: "color-scheme-change",
tab: document.location.href,
prefersColorScheme: window.matchMedia('(prefers-color-scheme: dark)').matches
});

break; // recieving end has started listening, message delivered!
} catch (err) {
console.log("automaticDark: error, retrying in 200ms ", err)
await new Promise((resolve) => setTimeout(resolve, 200)); // pause, then try again
}
}

console.log("automaticDark: inithandler")
// then repeat on every change
// Add listener that will change the theme if the mode is set to "system-theme"
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', ({matches}) => {
console.log("automaticDark: changed!")
browser.runtime.sendMessage({
type: "color-scheme-change",
tab: document.location.href,
prefersColorScheme: matches
});
});
})()
10 changes: 9 additions & 1 deletion manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,21 @@
"browserSettings",
"management",
"storage",
"theme"
"theme",
"<all_urls>"
],

"background": {
"scripts": ["js/utils.js", "js/common.js", "js/background.js", "lib/suncalc.js"]
},

"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["js/system-theme-notifier.js"]
}
],

"options_ui": {
"page": "html/options.html",
"open_in_tab": true
Expand Down