1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

Linux: Implement dark mode detection

This commit is contained in:
ed 2021-08-24 12:48:58 +01:00
parent 3d282c1078
commit 70d36f06db
3 changed files with 75 additions and 5 deletions

View file

@ -534,16 +534,53 @@ bool Desktop::canUseSemiTransparentWindows() noexcept
return XWindowSystem::getInstance()->canUseSemiTransparentWindows();
}
bool Desktop::isDarkModeActive() const
class Desktop::NativeDarkModeChangeDetectorImpl : private XWindowSystemUtilities::XSettings::Listener
{
return false;
}
public:
NativeDarkModeChangeDetectorImpl()
{
const auto* windowSystem = XWindowSystem::getInstance();
class Desktop::NativeDarkModeChangeDetectorImpl { public: NativeDarkModeChangeDetectorImpl() = default; };
if (auto* xSettings = windowSystem->getXSettings())
xSettings->addListener (this);
darkModeEnabled = windowSystem->isDarkModeActive();
}
~NativeDarkModeChangeDetectorImpl() override
{
if (auto* windowSystem = XWindowSystem::getInstanceWithoutCreating())
if (auto* xSettings = windowSystem->getXSettings())
xSettings->removeListener (this);
}
bool isDarkModeEnabled() const noexcept { return darkModeEnabled; }
private:
void settingChanged (const XWindowSystemUtilities::XSetting& settingThatHasChanged) override
{
if (settingThatHasChanged.name == XWindowSystem::getThemeNameSettingName())
{
const auto wasDarkModeEnabled = std::exchange (darkModeEnabled, XWindowSystem::getInstance()->isDarkModeActive());
if (darkModeEnabled != wasDarkModeEnabled)
Desktop::getInstance().darkModeChanged();
}
}
bool darkModeEnabled = false;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NativeDarkModeChangeDetectorImpl)
};
std::unique_ptr<Desktop::NativeDarkModeChangeDetectorImpl> Desktop::createNativeDarkModeChangeDetectorImpl()
{
return nullptr;
return std::make_unique<NativeDarkModeChangeDetectorImpl>();
}
bool Desktop::isDarkModeActive() const
{
return nativeDarkModeChangeDetectorImpl->isDarkModeEnabled();
}
static bool screenSaverAllowed = true;

View file

@ -2018,6 +2018,37 @@ bool XWindowSystem::canUseARGBImages() const
return canUseARGB;
}
bool XWindowSystem::isDarkModeActive() const
{
const auto themeName = [this]() -> String
{
if (xSettings != nullptr)
{
const auto themeNameSetting = xSettings->getSetting (getThemeNameSettingName());
if (themeNameSetting.isValid()
&& themeNameSetting.stringValue.isNotEmpty())
{
return themeNameSetting.stringValue;
}
}
ChildProcess gsettings;
if (File ("/usr/bin/gsettings").existsAsFile()
&& gsettings.start ("/usr/bin/gsettings get org.gnome.desktop.interface gtk-theme", ChildProcess::wantStdOut))
{
if (gsettings.waitForProcessToFinish (200))
return gsettings.readAllProcessOutput();
}
return {};
}();
return (themeName.isNotEmpty()
&& (themeName.containsIgnoreCase ("dark") || themeName.containsIgnoreCase ("black")));
}
Image XWindowSystem::createImage (bool isSemiTransparent, int width, int height, bool argb) const
{
auto visualAndDepth = displayVisuals->getBestVisualForWindow (isSemiTransparent);

View file

@ -197,6 +197,7 @@ public:
bool canUseSemiTransparentWindows() const;
bool canUseARGBImages() const;
bool isDarkModeActive() const;
int getNumPaintsPendingForWindow (::Window);
void processPendingPaintsForWindow (::Window);
@ -238,6 +239,7 @@ public:
bool isX11Available() const noexcept { return xIsAvailable; }
static String getWindowScalingFactorSettingName() { return "Gdk/WindowScalingFactor"; }
static String getThemeNameSettingName() { return "Net/ThemeName"; }
//==============================================================================
void handleWindowMessage (LinuxComponentPeer*, XEvent&) const;