Forum > Cocoa

How to detect if macOS changed Theme (Dark vs Light) while running?

(1/4) > >>

Hansaplast:
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:
I would like to second that request :)

Or simply a way to query as a first step.

Hansaplast:
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  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---// Retrieve key's string value from user preferences. Result is encoded using NSStrToStr's default encoding.function GetPrefString(const KeyName : string) : string;begin  Result := NSStringToString(NSUserDefaults.standardUserDefaults.stringForKey(NSStr(@KeyName[1])));end;  // IsDarkTheme: Detects if the Dark Theme (true) has been enabled or not (false)function IsDarkTheme:boolean;begin  Result := pos('DARK',UpperCase(GetPrefString('AppleInterfaceStyle')))>0;end;     


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:
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  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TForm1.FormPaint(Sender: TObject);begin  if IsDarkTheme then    label1.Caption:='Dark Theme'  else    label1.Caption:='Light Theme';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  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---[NSDistributedNotificationCenter.defaultCenter addObserver:self selector:@selector(themeChanged:) name:@"AppleInterfaceThemeChangedNotification" object: nil];  -(void)themeChanged:(NSNotification *) notification {    NSLog (@"%@", notification);}

But I have not been successful in translating this to Pascal, even with Dmitry's help who suggested looking at (in cocoawsforms)

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---NSNotificationCenter.defaultCenter.addObserver_selector_name_object(cnt, objcselector('didResignKeyNotification:'), NSWindowDidResignKeyNotification, cnt.window);

Any help would be much appreciated.

jwdietrich:
For me, it works great. The onPaint event seems to be automatically fired every time the theme is changed.

Navigation

[0] Message Index

[#] Next page

Go to full version