* * *

Author Topic: How to detect if macOS changed Theme (Dark vs Light) while running?  (Read 549 times)

Hansaplast

  • Sr. Member
  • ****
  • Posts: 446
  • Tweaking4All.com
    • Tweaking4All
The latest SVN version (r59451) seems to include some impressive work on support for Dark and Light Theme under Mojave. When switching theme, the IDE changes as well. This even works with my own applications now! Awesome!!  8)


I was wondering if there is an event that I can tie a procedure to so I can have my application respond to the color changes (for custom drawn controls etc)?

CCRDude

  • Sr. Member
  • ****
  • Posts: 407
Re: How to detect if macOS changed Theme (Dark vs Light) while running?
« Reply #1 on: November 05, 2018, 05:15:36 pm »
I would like to second that request :)

Or simply a way to query as a first step.

Hansaplast

  • Sr. Member
  • ****
  • Posts: 446
  • Tweaking4All.com
    • Tweaking4All
Re: How to detect if macOS changed Theme (Dark vs Light) while running?
« Reply #2 on: November 05, 2018, 05:29:27 pm »
Hi CCRDude!


I found a way to query if Dark Theme is active or not, even if it's not the most elegant way, but it's fast and it works.
The preferences value updates right away when a user switched back and forth between dark and light theme.
You can glue this in one function of course, I just use the GetPrefString function for other purposes as well.



Code: Pascal  [Select]
  1. // Retrieve key's string value from user preferences. Result is encoded using NSStrToStr's default encoding.
  2. function GetPrefString(const KeyName : string) : string;
  3. begin
  4.   Result := NSStringToString(NSUserDefaults.standardUserDefaults.stringForKey(NSStr(@KeyName[1])));
  5. end;
  6.  
  7.  
  8. // IsDarkTheme: Detects if the Dark Theme (true) has been enabled or not (false)
  9. function IsDarkTheme:boolean;
  10. begin
  11.   Result := pos('DARK',UpperCase(GetPrefString('AppleInterfaceStyle')))>0;
  12. end;
  13.  
   


Note: I got the function to get the preference keyword from one of Phil's units if I recall correctly - there are some very neat and useful tools in his units.
The biggest problem I run into is that I need to update other controls as well to match the new colors, but have no means to get alerted about the change  :o

Hansaplast

  • Sr. Member
  • ****
  • Posts: 446
  • Tweaking4All.com
    • Tweaking4All
Re: How to detect if macOS changed Theme (Dark vs Light) while running?
« Reply #3 on: November 09, 2018, 03:28:10 pm »
Using the function above, I did find a way to detect the change by using the onPaint event.
However I'm not happy, or maybe I should say "concerned", with how often the onPaint event is fired, especially when resizing a form.


Code: Pascal  [Select]
  1. procedure TForm1.FormPaint(Sender: TObject);
  2. begin
  3.   if IsDarkTheme then
  4.     label1.Caption:='Dark Theme'
  5.   else
  6.     label1.Caption:='Light Theme';
  7. end;


I'd rather see a specific event, based on theme change. I've tried looking at something like this (usign addObserver, with themeChanged() being the notification function);


Code: C  [Select]
  1. [NSDistributedNotificationCenter.defaultCenter addObserver:self selector:@selector(themeChanged:) name:@"AppleInterfaceThemeChangedNotification" object: nil];
  2.  
  3.  
  4. -(void)themeChanged:(NSNotification *) notification {
  5.     NSLog (@"%@", notification);
  6. }


But I have not been successful in translating this to Pascal, even with Dmitry's help who suggested looking at (in cocoawsforms)
Code: Pascal  [Select]
  1. NSNotificationCenter.defaultCenter.addObserver_selector_name_object(cnt, objcselector('didResignKeyNotification:'), NSWindowDidResignKeyNotification, cnt.window);


Any help would be much appreciated.
« Last Edit: November 11, 2018, 12:19:39 pm by Hansaplast »

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus