Browse Source

Desktop: Deprecate isOSXDarkModeActive() and add isDarkModeActive() for other platforms

v6.1.6
ed 4 years ago
parent
commit
3d282c1078
9 changed files with 433 additions and 28 deletions
  1. +8
    -1
      modules/juce_core/native/juce_android_JNIHelpers.h
  2. +8
    -1
      modules/juce_gui_basics/desktop/juce_Desktop.cpp
  3. +59
    -7
      modules/juce_gui_basics/desktop/juce_Desktop.h
  4. +80
    -0
      modules/juce_gui_basics/native/juce_android_Windowing.cpp
  5. +37
    -12
      modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm
  6. +71
    -0
      modules/juce_gui_basics/native/juce_ios_Windowing.mm
  7. +12
    -0
      modules/juce_gui_basics/native/juce_linux_Windowing.cpp
  8. +67
    -6
      modules/juce_gui_basics/native/juce_mac_Windowing.mm
  9. +91
    -1
      modules/juce_gui_basics/native/juce_win32_Windowing.cpp

+ 8
- 1
modules/juce_core/native/juce_android_JNIHelpers.h View File

@@ -503,11 +503,18 @@ DECLARE_JNI_CLASS (AndroidRect, "android/graphics/Rect")
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
METHOD (getIdentifier, "getIdentifier", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I") \ METHOD (getIdentifier, "getIdentifier", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I") \
METHOD (openRawResourceFd, "openRawResourceFd", "(I)Landroid/content/res/AssetFileDescriptor;")
METHOD (openRawResourceFd, "openRawResourceFd", "(I)Landroid/content/res/AssetFileDescriptor;") \
METHOD (getConfiguration, "getConfiguration", "()Landroid/content/res/Configuration;")
DECLARE_JNI_CLASS (AndroidResources, "android/content/res/Resources") DECLARE_JNI_CLASS (AndroidResources, "android/content/res/Resources")
#undef JNI_CLASS_MEMBERS #undef JNI_CLASS_MEMBERS
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
FIELD (uiMode, "uiMode", "I") \
DECLARE_JNI_CLASS (AndroidConfiguration, "android/content/res/Configuration")
#undef JNI_CLASS_MEMBERS
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
METHOD (getHeight, "getHeight", "()I") \ METHOD (getHeight, "getHeight", "()I") \
METHOD (getWidth, "getWidth", "()I") METHOD (getWidth, "getWidth", "()I")


+ 8
- 1
modules/juce_gui_basics/desktop/juce_Desktop.cpp View File

@@ -28,7 +28,8 @@ namespace juce
Desktop::Desktop() Desktop::Desktop()
: mouseSources (new MouseInputSource::SourceList()), : mouseSources (new MouseInputSource::SourceList()),
masterScaleFactor ((float) getDefaultMasterScale())
masterScaleFactor ((float) getDefaultMasterScale()),
nativeDarkModeChangeDetectorImpl (createNativeDarkModeChangeDetectorImpl())
{ {
displays.reset (new Displays (*this)); displays.reset (new Displays (*this));
} }
@@ -198,6 +199,12 @@ void Desktop::handleAsyncUpdate()
}); });
} }
//==============================================================================
void Desktop::addDarkModeSettingListener (DarkModeSettingListener* l) { darkModeSettingListeners.add (l); }
void Desktop::removeDarkModeSettingListener (DarkModeSettingListener* l) { darkModeSettingListeners.remove (l); }
void Desktop::darkModeChanged() { darkModeSettingListeners.call ([] (DarkModeSettingListener& l) { l.darkModeSettingChanged(); }); }
//============================================================================== //==============================================================================
void Desktop::resetTimer() void Desktop::resetTimer()
{ {


+ 59
- 7
modules/juce_gui_basics/desktop/juce_Desktop.h View File

@@ -45,6 +45,26 @@ public:
virtual void globalFocusChanged (Component* focusedComponent) = 0; virtual void globalFocusChanged (Component* focusedComponent) = 0;
}; };
//==============================================================================
/**
Classes can implement this interface and register themselves with the Desktop class
to receive callbacks when the operating system dark mode setting changes. The
Desktop::isDarkModeActive() method can then be used to query the current setting.
@see Desktop::addDarkModeSettingListener, Desktop::removeDarkModeSettingListener,
Desktop::isDarkModeActive
@tags{GUI}
*/
class JUCE_API DarkModeSettingListener
{
public:
/** Destructor. */
virtual ~DarkModeSettingListener() = default;
/** Callback to indicate that the dark mode setting has changed. */
virtual void darkModeSettingChanged() = 0;
};
//============================================================================== //==============================================================================
/** /**
@@ -135,8 +155,7 @@ public:
*/ */
void addGlobalMouseListener (MouseListener* listener); void addGlobalMouseListener (MouseListener* listener);
/** Unregisters a MouseListener that was added with the addGlobalMouseListener()
method.
/** Unregisters a MouseListener that was added with addGlobalMouseListener().
@see addGlobalMouseListener @see addGlobalMouseListener
*/ */
@@ -150,13 +169,36 @@ public:
*/ */
void addFocusChangeListener (FocusChangeListener* listener); void addFocusChangeListener (FocusChangeListener* listener);
/** Unregisters a FocusChangeListener that was added with the addFocusChangeListener()
method.
/** Unregisters a FocusChangeListener that was added with addFocusChangeListener().
@see addFocusChangeListener @see addFocusChangeListener
*/ */
void removeFocusChangeListener (FocusChangeListener* listener); void removeFocusChangeListener (FocusChangeListener* listener);
//==============================================================================
/** Registers a DarkModeSettingListener that will receive a callback when the
operating system dark mode setting changes. To query whether dark mode is on
use the isDarkModeActive() method.
@see isDarkModeActive, removeDarkModeSettingListener
*/
void addDarkModeSettingListener (DarkModeSettingListener* listener);
/** Unregisters a DarkModeSettingListener that was added with addDarkModeSettingListener().
@see addDarkModeSettingListener
*/
void removeDarkModeSettingListener (DarkModeSettingListener* listener);
/** True if the operating system "dark mode" is active.
To receive a callback when this setting changes implement the DarkModeSettingListener
interface and use the addDarkModeSettingListener() to register a listener.
@see addDarkModeSettingListener, removeDarkModeSettingListener
*/
bool isDarkModeActive() const;
//============================================================================== //==============================================================================
/** Takes a component and makes it full-screen, removing the taskbar, dock, etc. /** Takes a component and makes it full-screen, removing the taskbar, dock, etc.
@@ -352,9 +394,10 @@ public:
/** True if the OS supports semitransparent windows */ /** True if the OS supports semitransparent windows */
static bool canUseSemiTransparentWindows() noexcept; static bool canUseSemiTransparentWindows() noexcept;
#if JUCE_MAC
/** OSX-specific function to check for the "dark" title-bar and menu mode. */
static bool isOSXDarkModeActive();
#if JUCE_MAC && ! defined (DOXYGEN)
[[deprecated ("This macOS-specific method has been deprecated in favour of the cross-platform "
" isDarkModeActive() method.")]]
static bool isOSXDarkModeActive() { return Desktop::getInstance().isDarkModeActive(); }
#endif #endif
//============================================================================== //==============================================================================
@@ -376,6 +419,7 @@ private:
ListenerList<MouseListener> mouseListeners; ListenerList<MouseListener> mouseListeners;
ListenerList<FocusChangeListener> focusListeners; ListenerList<FocusChangeListener> focusListeners;
ListenerList<DarkModeSettingListener> darkModeSettingListeners;
Array<Component*> desktopComponents; Array<Component*> desktopComponents;
Array<ComponentPeer*> peers; Array<ComponentPeer*> peers;
@@ -423,6 +467,14 @@ private:
Desktop(); Desktop();
~Desktop() override; ~Desktop() override;
//==============================================================================
class NativeDarkModeChangeDetectorImpl;
std::unique_ptr<NativeDarkModeChangeDetectorImpl> nativeDarkModeChangeDetectorImpl;
static std::unique_ptr<NativeDarkModeChangeDetectorImpl> createNativeDarkModeChangeDetectorImpl();
void darkModeChanged();
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Desktop) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Desktop)
}; };


+ 80
- 0
modules/juce_gui_basics/native/juce_android_Windowing.cpp View File

@@ -1236,6 +1236,86 @@ bool Desktop::canUseSemiTransparentWindows() noexcept
return true; return true;
} }
class Desktop::NativeDarkModeChangeDetectorImpl : public ActivityLifecycleCallbacks
{
public:
NativeDarkModeChangeDetectorImpl()
{
LocalRef<jobject> appContext (getAppContext());
if (appContext != nullptr)
{
auto* env = getEnv();
myself = GlobalRef (CreateJavaInterface (this, "android/app/Application$ActivityLifecycleCallbacks"));
env->CallVoidMethod (appContext.get(), AndroidApplication.registerActivityLifecycleCallbacks, myself.get());
}
}
~NativeDarkModeChangeDetectorImpl() override
{
LocalRef<jobject> appContext (getAppContext());
if (appContext != nullptr && myself != nullptr)
{
auto* env = getEnv();
env->CallVoidMethod (appContext.get(),
AndroidApplication.unregisterActivityLifecycleCallbacks,
myself.get());
clear();
myself.clear();
}
}
bool isDarkModeEnabled() const noexcept { return darkModeEnabled; }
void onActivityStarted (jobject /*activity*/) override
{
const auto isEnabled = getDarkModeSetting();
if (darkModeEnabled != isEnabled)
{
darkModeEnabled = isEnabled;
Desktop::getInstance().darkModeChanged();
}
}
private:
static bool getDarkModeSetting()
{
auto* env = getEnv();
const LocalRef<jobject> resources (env->CallObjectMethod (getAppContext().get(), AndroidContext.getResources));
const LocalRef<jobject> configuration (env->CallObjectMethod (resources, AndroidResources.getConfiguration));
const auto uiMode = env->GetIntField (configuration, AndroidConfiguration.uiMode);
return ((uiMode & UI_MODE_NIGHT_MASK) == UI_MODE_NIGHT_YES);
}
static constexpr int UI_MODE_NIGHT_MASK = 0x00000030,
UI_MODE_NIGHT_NO = 0x00000010,
UI_MODE_NIGHT_UNDEFINED = 0x00000000,
UI_MODE_NIGHT_YES = 0x00000020;
GlobalRef myself;
bool darkModeEnabled = getDarkModeSetting();
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NativeDarkModeChangeDetectorImpl)
};
std::unique_ptr<Desktop::NativeDarkModeChangeDetectorImpl> Desktop::createNativeDarkModeChangeDetectorImpl()
{
return std::make_unique<NativeDarkModeChangeDetectorImpl>();
}
bool Desktop::isDarkModeActive() const
{
return nativeDarkModeChangeDetectorImpl->isDarkModeEnabled();
}
double Desktop::getDefaultMasterScale() double Desktop::getDefaultMasterScale()
{ {
return 1.0; return 1.0;


+ 37
- 12
modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm View File

@@ -137,6 +137,8 @@ using namespace juce;
- (BOOL) textView: (UITextView*) textView shouldChangeTextInRange: (NSRange) range replacementText: (NSString*) text; - (BOOL) textView: (UITextView*) textView shouldChangeTextInRange: (NSRange) range replacementText: (NSString*) text;
- (void) traitCollectionDidChange: (UITraitCollection*) previousTraitCollection;
- (BOOL) isAccessibilityElement; - (BOOL) isAccessibilityElement;
- (CGRect) accessibilityFrame; - (CGRect) accessibilityFrame;
- (NSArray*) accessibilityElements; - (NSArray*) accessibilityElements;
@@ -270,6 +272,11 @@ public:
return getMouseTime ([e timestamp]); return getMouseTime ([e timestamp]);
} }
static NSString* getDarkModeNotificationName()
{
return @"ViewDarkModeChanged";
}
static MultiTouchMapper<UITouch*> currentTouches; static MultiTouchMapper<UITouch*> currentTouches;
private: private:
@@ -296,25 +303,27 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UIViewComponentPeer) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UIViewComponentPeer)
}; };
static void sendScreenBoundsUpdate (JuceUIViewController* c)
static UIViewComponentPeer* getViewPeer (JuceUIViewController* c)
{ {
JuceUIView* juceView = (JuceUIView*) [c view];
if (JuceUIView* juceView = (JuceUIView*) [c view])
return juceView->owner;
if (juceView != nil && juceView->owner != nullptr)
juceView->owner->updateScreenBounds();
jassertfalse;
return nullptr;
} }
static bool isKioskModeView (JuceUIViewController* c)
static void sendScreenBoundsUpdate (JuceUIViewController* c)
{ {
JuceUIView* juceView = (JuceUIView*) [c view];
if (auto* peer = getViewPeer (c))
peer->updateScreenBounds();
}
if (juceView == nil || juceView->owner == nullptr)
{
jassertfalse;
return false;
}
static bool isKioskModeView (JuceUIViewController* c)
{
if (auto* peer = getViewPeer (c))
return Desktop::getInstance().getKioskModeComponent() == &(peer->getComponent());
return Desktop::getInstance().getKioskModeComponent() == &(juceView->owner->getComponent());
return false;
} }
MultiTouchMapper<UITouch*> UIViewComponentPeer::currentTouches; MultiTouchMapper<UITouch*> UIViewComponentPeer::currentTouches;
@@ -544,6 +553,22 @@ MultiTouchMapper<UITouch*> UIViewComponentPeer::currentTouches;
nsStringToJuce (text)); nsStringToJuce (text));
} }
- (void) traitCollectionDidChange: (UITraitCollection*) previousTraitCollection
{
[super traitCollectionDidChange: previousTraitCollection];
#if defined (__IPHONE_12_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_12_0
if (@available (iOS 12.0, *))
{
const auto wasDarkModeActive = ([previousTraitCollection userInterfaceStyle] == UIUserInterfaceStyleDark);
if (wasDarkModeActive != Desktop::getInstance().isDarkModeActive())
[[NSNotificationCenter defaultCenter] postNotificationName: UIViewComponentPeer::getDarkModeNotificationName()
object: nil];
}
#endif
}
- (BOOL) isAccessibilityElement - (BOOL) isAccessibilityElement
{ {
return NO; return NO;


+ 71
- 0
modules/juce_gui_basics/native/juce_ios_Windowing.mm View File

@@ -678,6 +678,77 @@ bool Desktop::canUseSemiTransparentWindows() noexcept
return true; return true;
} }
bool Desktop::isDarkModeActive() const
{
#if defined (__IPHONE_12_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_12_0
if (@available (iOS 12.0, *))
return [[[UIScreen mainScreen] traitCollection] userInterfaceStyle] == UIUserInterfaceStyleDark;
#endif
return false;
}
class Desktop::NativeDarkModeChangeDetectorImpl
{
public:
NativeDarkModeChangeDetectorImpl()
{
static DelegateClass delegateClass;
delegate = [delegateClass.createInstance() init];
object_setInstanceVariable (delegate, "owner", this);
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector")
[[NSNotificationCenter defaultCenter] addObserver: delegate
selector: @selector (darkModeChanged:)
name: UIViewComponentPeer::getDarkModeNotificationName()
object: nil];
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
}
~NativeDarkModeChangeDetectorImpl()
{
object_setInstanceVariable (delegate, "owner", nullptr);
[[NSNotificationCenter defaultCenter] removeObserver: delegate];
[delegate release];
}
void darkModeChanged()
{
Desktop::getInstance().darkModeChanged();
}
private:
struct DelegateClass : public ObjCClass<NSObject>
{
DelegateClass() : ObjCClass<NSObject> ("JUCEDelegate_")
{
addIvar<NativeDarkModeChangeDetectorImpl*> ("owner");
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector")
addMethod (@selector (darkModeChanged:), darkModeChanged, "v@:@");
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
registerClass();
}
static void darkModeChanged (id self, SEL, NSNotification*)
{
if (auto* owner = getIvar<NativeDarkModeChangeDetectorImpl*> (self, "owner"))
owner->darkModeChanged();
}
};
id delegate = nil;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NativeDarkModeChangeDetectorImpl)
};
std::unique_ptr<Desktop::NativeDarkModeChangeDetectorImpl> Desktop::createNativeDarkModeChangeDetectorImpl()
{
return std::make_unique<NativeDarkModeChangeDetectorImpl>();
}
Point<float> MouseInputSource::getCurrentRawMousePosition() Point<float> MouseInputSource::getCurrentRawMousePosition()
{ {
return juce_lastMousePos; return juce_lastMousePos;


+ 12
- 0
modules/juce_gui_basics/native/juce_linux_Windowing.cpp View File

@@ -534,6 +534,18 @@ bool Desktop::canUseSemiTransparentWindows() noexcept
return XWindowSystem::getInstance()->canUseSemiTransparentWindows(); return XWindowSystem::getInstance()->canUseSemiTransparentWindows();
} }
bool Desktop::isDarkModeActive() const
{
return false;
}
class Desktop::NativeDarkModeChangeDetectorImpl { public: NativeDarkModeChangeDetectorImpl() = default; };
std::unique_ptr<Desktop::NativeDarkModeChangeDetectorImpl> Desktop::createNativeDarkModeChangeDetectorImpl()
{
return nullptr;
}
static bool screenSaverAllowed = true; static bool screenSaverAllowed = true;
void Desktop::setScreenSaverEnabled (bool isEnabled) void Desktop::setScreenSaverEnabled (bool isEnabled)


+ 67
- 6
modules/juce_gui_basics/native/juce_mac_Windowing.mm View File

@@ -430,6 +430,73 @@ Desktop::DisplayOrientation Desktop::getCurrentOrientation() const
return upright; return upright;
} }
bool Desktop::isDarkModeActive() const
{
return [[[NSUserDefaults standardUserDefaults] stringForKey: nsStringLiteral ("AppleInterfaceStyle")]
isEqualToString: nsStringLiteral ("Dark")];
}
class Desktop::NativeDarkModeChangeDetectorImpl
{
public:
NativeDarkModeChangeDetectorImpl()
{
static DelegateClass delegateClass;
delegate = [delegateClass.createInstance() init];
object_setInstanceVariable (delegate, "owner", this);
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector")
[[NSDistributedNotificationCenter defaultCenter] addObserver: delegate
selector: @selector (darkModeChanged:)
name: @"AppleInterfaceThemeChangedNotification"
object: nil];
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
}
~NativeDarkModeChangeDetectorImpl()
{
object_setInstanceVariable (delegate, "owner", nullptr);
[[NSDistributedNotificationCenter defaultCenter] removeObserver: delegate];
[delegate release];
}
void darkModeChanged()
{
Desktop::getInstance().darkModeChanged();
}
private:
struct DelegateClass : public ObjCClass<NSObject>
{
DelegateClass() : ObjCClass<NSObject> ("JUCEDelegate_")
{
addIvar<NativeDarkModeChangeDetectorImpl*> ("owner");
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector")
addMethod (@selector (darkModeChanged:), darkModeChanged, "v@:@");
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
registerClass();
}
static void darkModeChanged (id self, SEL, NSNotification*)
{
if (auto* owner = getIvar<NativeDarkModeChangeDetectorImpl*> (self, "owner"))
owner->darkModeChanged();
}
};
id delegate = nil;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NativeDarkModeChangeDetectorImpl)
};
std::unique_ptr<Desktop::NativeDarkModeChangeDetectorImpl> Desktop::createNativeDarkModeChangeDetectorImpl()
{
return std::make_unique<NativeDarkModeChangeDetectorImpl>();
}
//============================================================================== //==============================================================================
class ScreenSaverDefeater : public Timer class ScreenSaverDefeater : public Timer
{ {
@@ -674,10 +741,4 @@ void Process::setDockIconVisible (bool isVisible)
ignoreUnused (err); ignoreUnused (err);
} }
bool Desktop::isOSXDarkModeActive()
{
return [[[NSUserDefaults standardUserDefaults] stringForKey: nsStringLiteral ("AppleInterfaceStyle")]
isEqualToString: nsStringLiteral ("Dark")];
}
} // namespace juce } // namespace juce

+ 91
- 1
modules/juce_gui_basics/native/juce_win32_Windowing.cpp View File

@@ -712,6 +712,8 @@ static void setWindowZOrder (HWND hwnd, HWND insertAfter)
} }
//============================================================================== //==============================================================================
extern RTL_OSVERSIONINFOW getWindowsVersionInfo();
double Desktop::getDefaultMasterScale() double Desktop::getDefaultMasterScale()
{ {
if (! JUCEApplicationBase::isStandaloneApp() || isPerMonitorDPIAwareProcess()) if (! JUCEApplicationBase::isStandaloneApp() || isPerMonitorDPIAwareProcess())
@@ -720,7 +722,95 @@ double Desktop::getDefaultMasterScale()
return getGlobalDPI() / USER_DEFAULT_SCREEN_DPI; return getGlobalDPI() / USER_DEFAULT_SCREEN_DPI;
} }
bool Desktop::canUseSemiTransparentWindows() noexcept { return true; }
bool Desktop::canUseSemiTransparentWindows() noexcept
{
return true;
}
class Desktop::NativeDarkModeChangeDetectorImpl
{
public:
NativeDarkModeChangeDetectorImpl()
{
const auto winVer = getWindowsVersionInfo();
if (winVer.dwMajorVersion >= 10 && winVer.dwBuildNumber >= 17763)
{
const auto uxtheme = "uxtheme.dll";
LoadLibraryA (uxtheme);
const auto uxthemeModule = GetModuleHandleA (uxtheme);
if (uxthemeModule != nullptr)
{
shouldAppsUseDarkMode = (ShouldAppsUseDarkModeFunc) GetProcAddress (uxthemeModule, MAKEINTRESOURCEA (132));
if (shouldAppsUseDarkMode != nullptr)
darkModeEnabled = shouldAppsUseDarkMode() && ! isHighContrast();
}
}
}
bool isDarkModeEnabled() const noexcept { return darkModeEnabled; }
private:
static bool isHighContrast()
{
HIGHCONTRASTW highContrast { 0 };
if (SystemParametersInfoW (SPI_GETHIGHCONTRAST, sizeof (highContrast), &highContrast, false))
return highContrast.dwFlags & HCF_HIGHCONTRASTON;
return false;
}
static LRESULT CALLBACK callWndProc (int nCode, WPARAM wParam, LPARAM lParam)
{
auto* params = reinterpret_cast<CWPSTRUCT*> (lParam);
if (nCode >= 0
&& params != nullptr
&& params->message == WM_SETTINGCHANGE
&& params->lParam != 0
&& CompareStringOrdinal (reinterpret_cast<LPWCH> (params->lParam), -1, L"ImmersiveColorSet", -1, true) == CSTR_EQUAL)
{
Desktop::getInstance().nativeDarkModeChangeDetectorImpl->colourSetChanged();
}
return CallNextHookEx ({}, nCode, wParam, lParam);
}
void colourSetChanged()
{
if (shouldAppsUseDarkMode != nullptr)
{
const auto wasDarkModeEnabled = std::exchange (darkModeEnabled, shouldAppsUseDarkMode() && ! isHighContrast());
if (darkModeEnabled != wasDarkModeEnabled)
Desktop::getInstance().darkModeChanged();
}
}
using ShouldAppsUseDarkModeFunc = bool (WINAPI*)();
ShouldAppsUseDarkModeFunc shouldAppsUseDarkMode = nullptr;
bool darkModeEnabled = false;
HHOOK hook { SetWindowsHookEx (WH_CALLWNDPROC,
callWndProc,
(HINSTANCE) juce::Process::getCurrentModuleInstanceHandle(),
GetCurrentThreadId()) };
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NativeDarkModeChangeDetectorImpl)
};
std::unique_ptr<Desktop::NativeDarkModeChangeDetectorImpl> Desktop::createNativeDarkModeChangeDetectorImpl()
{
return std::make_unique<NativeDarkModeChangeDetectorImpl>();
}
bool Desktop::isDarkModeActive() const
{
return nativeDarkModeChangeDetectorImpl->isDarkModeEnabled();
}
Desktop::DisplayOrientation Desktop::getCurrentOrientation() const Desktop::DisplayOrientation Desktop::getCurrentOrientation() const
{ {


Loading…
Cancel
Save