rsthemes icon indicating copy to clipboard operation
rsthemes copied to clipboard

Change theme according to macOS dark mode

Open quassy opened this issue 4 years ago • 7 comments

I regularly change my macOS into dark mode according to time of day and light. Maybe rsthemes could detect this and follow suit (the same for other OSes if applicable).

Something like

rsthemes::use_theme_auto(dark_start = "18:00", dark_end = "6:00", dark_follow_os = TRUE)

quassy avatar Oct 28 '19 16:10 quassy

Thanks! This was the motivation for use_theme_auto() but I don't know of an easy way to find out the OS light/dark state. If you or anyone else has any suggestions I'd be interested and open to incorporating them.

OTOH, I frequently switch light/dark themes too and it's very quick to do if you set up a keyboard shortcut for the Toggle Dark Mode addin. I used Ctrl + Alt + D.

gadenbuie avatar Oct 29 '19 13:10 gadenbuie

Is it possible to run the addin from console or similar? Currently I use an automator script to toggle macOS light / dark mode (so it's just Spotlight + "toggle" + return to switch the system), if I could also call toggle dark mode at the same time, that would already help a lot for my use case.

In Catalina you can get status of darkmode with:

$ defaults read NSGlobalDomain AppleInterfaceStyle

It returns either dark or ... does not exist. Maybe that helps?

quassy avatar Oct 29 '19 17:10 quassy

Interesting! I can definitely get this using a system() call on macOS. I wonder if there are similar commands on Linux and Windows.

I'll think about incorporating this into the package, but in the mean time you can make this work by adding something like this to your ~/.Rprofile. This polls the operating systems once per delay seconds to update the theme. I haven't really used this but it shouldn't have much impact on performance but feel free to test it and pick an appropriate poll rate.

local({
  auto_dark <- function(delay = 1) {
    cmd_is_dark <- "defaults read NSGlobalDomain AppleInterfaceStyle"
    macos_style <- suppressWarnings(
      system(cmd_is_dark, intern = TRUE, ignore.stderr = TRUE)
    )
    if (identical(tolower(macos_style), "dark")) {
      rsthemes::use_theme_dark()
    } else {
      rsthemes::use_theme_light()
    }
    
    later::later(auto_dark, delay)
  }
  
  auto_dark()
})

auto-rstudio-light-dark

gadenbuie avatar Oct 29 '19 18:10 gadenbuie

Nice, it works with some tweaking. For reference this is my whole .Rprofile

if (
  interactive() && 
  requireNamespace("rsthemes", quietly = TRUE) && 
  requireNamespace("later", quietly = TRUE)
) {
  # Use later to delay until RStudio is ready
  later::later(function() {
    rsthemes::set_theme_light("One Light {rsthemes}")  # light theme
    rsthemes::set_theme_dark("One Dark {rsthemes}")  # dark theme

    # To automatically choose theme based on time of day
    # rsthemes::use_theme_auto(dark_start = "17:00", dark_end = "7:00")

    auto_dark <- function(delay = 1) {
        cmd_is_dark <- "defaults read NSGlobalDomain AppleInterfaceStyle"
        macos_style <- suppressWarnings(
        system(cmd_is_dark, intern = TRUE, ignore.stderr = TRUE)
        )
        if (identical(tolower(macos_style), "dark")) {
        rsthemes::use_theme_dark()
        } else {
        rsthemes::use_theme_light()
        }
        
        later::later(auto_dark, delay)
    }
  
    auto_dark()

  }, delay = 1)
}

quassy avatar Oct 29 '19 19:10 quassy

Thanks! Does delay = 1 make it into the inner auto_dark() call? It looks like the anonymous function called by the outer later needs function(delay = 1) and then call auto_dark(delay) at the end.

gadenbuie avatar Oct 29 '19 19:10 gadenbuie

I... am not sure I can follow 😅.

quassy avatar Oct 29 '19 19:10 quassy

On Windows, this would be:

cmd_is_dark <- " powershell.exe Get-ItemPropertyValue -Path HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize -Name AppsUseLightTheme"

303951546 avatar Mar 06 '21 23:03 303951546