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

Add automatic switching between Dark Mode and Light Mode or ability to change it programmatically. #5037

Closed
nehayward opened this issue Jun 26, 2018 · 21 comments · Fixed by #6051
Labels
enhancement help wanted Issues marked as ideal for external contributors

Comments

@nehayward
Copy link

Request
I love the new the dark mode and I would love it if it automatically switched with the change between Light and Dark mode on macOS.

Describe the solution you'd like
We could add an observer to check which theme the the OS is in, maybe add an option on the prefs to match system mode? You can check the current theme from defaults, here's an example in swift.

Describe alternatives you've considered
Alternatively, we could add an option to change this from the CLI or adding a preference file and let the user be able to switch between modes.

@niik Thanks!

@nehayward nehayward changed the title Add automatic switching to Dark Mode and Light Mode or ability to change it programmatically. Add automatic switching between Dark Mode and Light Mode or ability to change it programmatically. Jun 26, 2018
@shiftkey
Copy link
Member

@nehayward thanks for the suggestion!

It looks like there's already an explicit API for this in Electron 2.0.2 (we're on 1.8.x but planning to catch up soon):

const {systemPreferences} = require('electron')
console.log(systemPreferences.isDarkMode())

Alternatively, if there's a way to listen for changes to this value from native code there could be a way to wrap that up in a Node native module that can be used from in the app.

@nehayward
Copy link
Author

@shiftkey oh that's awesome, so it's really just adding the ability to the CLI or in prefs options for the desktop app. I'm working on an app to be able to easily toggle app themes, and I'm hoping to open source it soon. This is why I'd like this feature.

I linked to some swift code for doing this natively, I can work on wrapping it in a node module if that'd be helpful?

@j-f1
Copy link
Contributor

j-f1 commented Jun 26, 2018

@nehayward It would be awesome if you were to create a tool that would allow Node apps to read & write user defaults since this could be applied to uses other than just checking which theme is activated.

@shiftkey
Copy link
Member

@nehayward let's put the technical stuff aside for the moment and talk about how this would look to the user:

I love the new the dark mode and I would love it if it automatically switched with the change between Light and Dark mode on macOS.

  • What does "automatically switch" mean here?
  • What would "switching" look like to the user while they have the app open? Currently the app just flicks between themes, I gather there's a smoother way to do this but what other examples are out there that we can be inspired by?
  • Where is this setting found for the user? Under Preferences | Appearances?
  • What should this value default to? Do we make this opt-in? Or opt-out?

@nehayward
Copy link
Author

@j-f1 I'm not too familiar with node apps, however I've been doing a lot work with defaults and I'm sure we could collaborate or open source something if there is interest in the community.

@j-f1
Copy link
Contributor

j-f1 commented Jun 26, 2018

  • I’d assume it means that when the user changes the Dark Mode setting in System Preferences, the app will change its theme.
  • If the other apps animate, it should probably animate, but if they don’t, the current behavior is fine.
  • How about adding a third “theme” option in the settings called something like “Automatic” that adapts to the dark mode setting?
  • This should probably be opt-out since people who never use Dark Mode will never see the difference, and everyone else will see it as an improvement (or, likely, be able to change the setting).

@nehayward
Copy link
Author

Q: What does "automatically switch" mean here?
A: Great question, my intent is to have it match the system theme and change whenever the OS does. However we could go beyond this and have it change with sunrise and sunset. I think to start we should shoot for the former.

Q: What would "switching" look like to the user while they have the app open? Currently the app just flicks between themes, I gather there's a smoother way to do this but what other examples are out there that we can be inspired by?
A: We should match the system and do a crossfade transition.
fade transition

Q: Where is this setting found for the user? Under Preferences | Appearances?
A: Yes it could be a toggle or another option would be good as @j-f1 suggested.
theme switch preview

Q: What should this value default to? Do we make this opt-in? Or opt-out?
A: I agree with @j-f1

@shiftkey shiftkey added the help wanted Issues marked as ideal for external contributors label Aug 14, 2018
@say25
Copy link
Member

say25 commented Aug 15, 2018

We should now be able to use the Electron 2.0.2 API as Desktop now used Electron 2.0.5 https://github.com/desktop/desktop/pull/5136/files

@shiftkey
Copy link
Member

Thanks for the reminder @say25!

const {systemPreferences} = require('electron')
console.log(systemPreferences.isDarkMode())

The preferences check is currently static, and there's been discussion about updating the app when the OS updates which I think requires something callback-based. This would be a neat addition to Electron core (or whatever API pattern they prefer):

const {systemPreferences} = require('electron')
const callback = (enabled) => {
   // signal to app that dark mode has been enabled/disabled
}
systemPreferences.subscribeToDarkModeChange(callback)

If someone wanted to explore that it'd be greatly appreciated, but that requires some C++ skills, familiarity with Electron source, and getting something reviewed and merged and included in an update.

Otherwise if there's a native Node module we can use to bring this into that'd be a good interim step.

@j-f1
Copy link
Contributor

j-f1 commented Aug 15, 2018

Perhaps systemPreferences.on('dark-mode-changed', () => { ... })? (this is not a current API)

@shiftkey
Copy link
Member

I'd suggest discussing this hypothetical API over here electron/electron#13387 rather than in this issue.

@MarshallOfSound
Copy link

MarshallOfSound commented Sep 21, 2018

@shiftkey You can use existing Electron APIs to monitor for dark mode changes. Check out my implementation here

The basics are:

systemPreferences.subscribeNotification(
  'AppleInterfaceThemeChangedNotification',
  function theThemeHasChanged() {
    updateMyAppTheme(systemPreferences.isDarkMode())
  }
);

Also worth noting there are a bunch of new dark mode APIs coming down the pipe in Electron Core --> electron/electron#14755

@shiftkey
Copy link
Member

@MarshallOfSound excellent - I can see that available in 2.0.9 so we don't need to wait to upgrade to 3.0 to play around with this!

@say25
Copy link
Member

say25 commented Oct 31, 2018

@MarshallOfSound it would appear that this isn't working

const subscriptionID = systemPreferences.subscribeNotification('AppleInterfaceThemeChangedNotification', updateThemeBasedOnSystem);

I think it has do with a problem in electron.d.ts :/ See above PR for more context.

@MarshallOfSound
Copy link

@say25 Yeah looks like the subscribeNotification method isn't documented to be returning a number. I've raised a PR to fix this, for now you'll probably have to do some any / number casting to make it work 👍

electron/electron#15490

@say25
Copy link
Member

say25 commented Oct 31, 2018

@MarshallOfSound not sure how involved you are on Electron but would this be back ported to 2.0.X?

@shiftkey
Copy link
Member

shiftkey commented Oct 31, 2018

@say25 we have the ability to polyfill things in ourselves while we catch up to upstream. Here's where you can add what the correct signature should be, using one of our previous examples:

interface SystemPreferences {
getUserDefault(
key: 'AppleActionOnDoubleClick',
type: 'string'
): AppleActionOnDoubleClickPref
}

EDIT: and I see the PR has been labelled target/2-0-x so I suspect it will land on 2.0.x with a future update 🤘

@say25
Copy link
Member

say25 commented Oct 31, 2018

@shiftkey is it worth waiting for official support or just polyfilling it until then?

@shiftkey
Copy link
Member

@say25 polyfill to unblock yourself, and at some point in the future we'll come back and clean up the polyfill if the official declarations have the update.

@say25
Copy link
Member

say25 commented Nov 1, 2018

Got ready to do work on it, an noticed Electron 2.0.13 was dropped today (thanks @MarshallOfSound). Opened #6068 as a potential avenue to avoid the need for polyfill.

Not sure if:

  1. We should just simply polyfill
  2. We should update to Electron 2.0.13
  3. We should update to Electron 3.X

@shiftkey
Copy link
Member

shiftkey commented Nov 1, 2018

For the moment I'd just polyfill your PR until we've had a chance to figure out when we want to land the Electron upgrade. We're in the middle of doing QA for the next big release, so we're further away from getting that Electron upgrade reviewed, tested and merged.

Electron 3.0 migration is even further away - keytar and fs-admin need to be upgraded and replaced, respectively, and there might be other dependencies that need changes to support inside a new version of Node.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement help wanted Issues marked as ideal for external contributors
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants
@shiftkey @MarshallOfSound @nehayward @say25 @j-f1 and others