Difference between revisions of "Dark theme"
From Lazarus wiki
Jump to navigationJump to search (new page) |
|||
Line 5: | Line 5: | ||
<syntaxhighlight lang="pascal"> | <syntaxhighlight lang="pascal"> | ||
// by "dbannon" from Lazarus forum | // by "dbannon" from Lazarus forum | ||
+ | function IsDarkTheme: boolean; | ||
var | var | ||
Col : string | Col : string | ||
Line 10: | Line 11: | ||
// if char 3, 5 and 7 are all 'A' or above, we are not in a DarkTheme | // if char 3, 5 and 7 are all 'A' or above, we are not in a DarkTheme | ||
Col := HexStr(qword(GetRGBColorResolvingParent()), 8); | Col := HexStr(qword(GetRGBColorResolvingParent()), 8); | ||
− | + | Result := (Col[3] < 'A') and (Col[5] < 'A') and (Col[7] < 'A'); | |
+ | end; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Revision as of 16:15, 27 August 2020
How to detect dark theme is OS?
Universal method
// by "dbannon" from Lazarus forum
function IsDarkTheme: boolean;
var
Col : string
begin
// if char 3, 5 and 7 are all 'A' or above, we are not in a DarkTheme
Col := HexStr(qword(GetRGBColorResolvingParent()), 8);
Result := (Col[3] < 'A') and (Col[5] < 'A') and (Col[7] < 'A');
end;
Windows
Example 1
// by "jwdietrich" from Lazarus forum
uses
Windows, Win32Proc, Registry;
// IsDarkTheme: Detects if the Dark Theme (true) has been enabled or not (false)
function DarkTheme: boolean;
const
KEYPATH = '\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize';
KEYNAME = 'AppsUseLightTheme';
var
LightKey: boolean;
Registry: TRegistry;
begin
Result := false;
Registry := TRegistry.Create;
try
Registry.RootKey := HKEY_CURRENT_USER;
if Registry.OpenKeyReadOnly(KEYPATH) then
begin
if Registry.ValueExists(KEYNAME) then
LightKey := Registry.ReadBool(KEYNAME)
else
LightKey := true;
end
else
LightKey := true;
Result := not LightKey
finally
Registry.Free;
end;
end;
macOS
Example 1
// by "jwdietrich" from Lazarus forum
uses
MacOSAll;
function IsMinMacOS(Maj, Min: integer): boolean;
{ returns true, if this app runs on a macOS version as specified or newer }
var
Major, Minor: SInt32;
theError: SInt16;
begin
result := false;
theError := Gestalt(gestaltSystemVersionMajor, Major);
if theError = 0 then
theError := Gestalt(gestaltSystemVersionMinor, Minor);
if theError = 0 then
if (Major = Maj) and (Minor >= Min) or (Major > Maj) then
Result := True;
end;
function MojaveOrNewer: boolean;
{ returns true, if this app runs on macOS X 10.14 Mojave or newer }
begin
result := IsMinMacOS(10, 14);
end;
{ The following two functions were suggested by Hansaplast at https://forum.lazarus.freepascal.org/index.php/topic,43111.msg304366.html }
// 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 DarkTheme: boolean;
begin
Result := false;
if MojaveOrNewer then
Result := pos('DARK',UpperCase(GetPrefString('AppleInterfaceStyle'))) > 0;
end;
Example 2
Catalina added an "Auto" option where the computer switches between Light and Dark modes depending on time of day. The 'AppleInterfaceStyle' method apparently doesn't work if auto is enabled.
The solution is to get the NSApp.effectiveAppearance string which will be one of a number of values including 'NSAppearanceNameAqua' (standard light mode) and 'NSAppearanceNameDarkAqua' (standard dark mode). Google these to see the whole list which includes other light and dark modes with added contrast. The effectiveAppearance is correct in all modes including when auto mode kicks in.
Tested on Mojave, Catalina, Big Sur.
// by "Clover" from Lazarus forum
function IsMacDarkMode: Boolean;
var
sMode: string;
begin
//sMode := CFStringToStr( CFStringRef( NSUserDefaults.StandardUserDefaults.stringForKey( NSSTR('AppleInterfaceStyle') ))); // Doesn't work in auto mode
sMode := CFStringToStr( CFStringRef( NSApp.effectiveAppearance.name ));
Result := Pos('Dark', sMode) > 0;
end;