tdf#153229 add a switch to override honoring system dark mode
Change-Id: Iafb6182e05dc65d20d0809476ee58908f7426d39
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146597
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
(cherry picked from commit f7c03364e24da285ea95cea0cc688a7a120fc163)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146745
Reviewed-by: Sophie Gautier <sophi@libreoffice.org>
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
diff --git a/cui/source/options/optgdlg.cxx b/cui/source/options/optgdlg.cxx
index eea8868..3b1f652 100644
--- a/cui/source/options/optgdlg.cxx
+++ b/cui/source/options/optgdlg.cxx
@@ -528,6 +528,8 @@ OfaViewTabPage::OfaViewTabPage(weld::Container* pPage, weld::DialogController* p
, m_xIconSizeLB(m_xBuilder->weld_combo_box("iconsize"))
, m_xSidebarIconSizeLB(m_xBuilder->weld_combo_box("sidebariconsize"))
, m_xNotebookbarIconSizeLB(m_xBuilder->weld_combo_box("notebookbariconsize"))
, m_xDarkModeFrame(m_xBuilder->weld_widget("darkmode"))
, m_xAppearanceStyleLB(m_xBuilder->weld_combo_box("appearance"))
, m_xIconStyleLB(m_xBuilder->weld_combo_box("iconstyle"))
, m_xFontAntiAliasing(m_xBuilder->weld_check_button("aafont"))
, m_xAAPointLimitLabel(m_xBuilder->weld_label("aafrom"))
@@ -548,9 +550,14 @@ OfaViewTabPage::OfaViewTabPage(weld::Container* pPage, weld::DialogController* p
, m_xRunGPTests(m_xBuilder->weld_button("btn_rungptest"))
, m_sAutoStr(m_xIconStyleLB->get_text(0))
{
if (Application::GetToolkitName().startsWith("gtk"))
OUString sToolKitName(Application::GetToolkitName());
if (sToolKitName.startsWith("gtk"))
m_xMenuIconBox->hide();
const bool bHasDarkMode = sToolKitName.startsWith("gtk") || sToolKitName == "osx" || sToolKitName == "win";
if (!bHasDarkMode)
m_xDarkModeFrame->hide();
m_xFontAntiAliasing->connect_toggled( LINK( this, OfaViewTabPage, OnAntialiasingToggled ) );
m_xUseSkia->connect_toggled(LINK(this, OfaViewTabPage, OnUseSkiaToggled));
@@ -671,6 +678,7 @@ bool OfaViewTabPage::FillItemSet( SfxItemSet* )
{
bool bModified = false;
bool bMenuOptModified = false;
bool bDarkModeOptModified = false;
bool bRepaintWindows(false);
std::shared_ptr<comphelper::ConfigurationChanges> xChanges(comphelper::ConfigurationChanges::create());
@@ -784,6 +792,12 @@ bool OfaViewTabPage::FillItemSet( SfxItemSet* )
bAppearanceChanged = true;
}
if (m_xAppearanceStyleLB->get_value_changed_from_saved())
{
bDarkModeOptModified = true;
bModified = true;
}
if (m_xContextMenuShortcutsLB->get_value_changed_from_saved())
{
officecfg::Office::Common::View::Menu::ShortcutsInContextMenus::set(
@@ -827,12 +841,20 @@ bool OfaViewTabPage::FillItemSet( SfxItemSet* )
xChanges->commit();
if( bMenuOptModified )
if (bMenuOptModified || bDarkModeOptModified)
{
// Set changed settings to the application instance
AllSettings aAllSettings = Application::GetSettings();
StyleSettings aStyleSettings = aAllSettings.GetStyleSettings();
aAllSettings.SetStyleSettings(aStyleSettings);
if (bMenuOptModified)
{
StyleSettings aStyleSettings = aAllSettings.GetStyleSettings();
aAllSettings.SetStyleSettings(aStyleSettings);
}
if (bDarkModeOptModified)
MiscSettings::SetDarkMode(m_xAppearanceStyleLB->get_active());
Application::MergeSystemSettings( aAllSettings );
Application::SetSettings(aAllSettings);
}
@@ -918,6 +940,9 @@ void OfaViewTabPage::Reset( const SfxItemSet* )
m_xIconStyleLB->set_active(nStyleLB_InitialSelection);
m_xIconStyleLB->save_value();
m_xAppearanceStyleLB->set_active(officecfg::Office::Common::Misc::Appearance::get());
m_xAppearanceStyleLB->save_value();
// Mouse Snap
m_xMousePosLB->set_active(static_cast<sal_Int32>(pAppearanceCfg->GetSnapMode()));
m_xMousePosLB->save_value();
diff --git a/cui/source/options/optgdlg.hxx b/cui/source/options/optgdlg.hxx
index 0e0796e..e131022 100644
--- a/cui/source/options/optgdlg.hxx
+++ b/cui/source/options/optgdlg.hxx
@@ -87,6 +87,8 @@ private:
std::unique_ptr<weld::ComboBox> m_xIconSizeLB;
std::unique_ptr<weld::ComboBox> m_xSidebarIconSizeLB;
std::unique_ptr<weld::ComboBox> m_xNotebookbarIconSizeLB;
std::unique_ptr<weld::Widget> m_xDarkModeFrame;
std::unique_ptr<weld::ComboBox> m_xAppearanceStyleLB;
std::unique_ptr<weld::ComboBox> m_xIconStyleLB;
std::unique_ptr<weld::CheckButton> m_xFontAntiAliasing;
diff --git a/cui/uiconfig/ui/optviewpage.ui b/cui/uiconfig/ui/optviewpage.ui
index ac6b7fc..a371f83 100644
--- a/cui/uiconfig/ui/optviewpage.ui
+++ b/cui/uiconfig/ui/optviewpage.ui
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<!-- Generated with glade 3.40.0 -->
<interface domain="cui">
<requires lib="gtk+" version="3.20"/>
<object class="GtkAdjustment" id="adjustment2">
@@ -18,7 +18,7 @@
<property name="border-width">6</property>
<property name="column-spacing">24</property>
<child>
<!-- n-columns=1 n-rows=4 -->
<!-- n-columns=1 n-rows=5 -->
<object class="GtkGrid" id="grid2">
<property name="visible">True</property>
<property name="can-focus">False</property>
@@ -126,7 +126,7 @@
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">3</property>
<property name="top-attach">4</property>
</packing>
</child>
<child>
@@ -249,7 +249,7 @@
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
<property name="top-attach">3</property>
</packing>
</child>
<child>
@@ -390,7 +390,7 @@
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
<property name="top-attach">2</property>
</packing>
</child>
<child>
@@ -474,6 +474,76 @@
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkFrame" id="darkmode">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="hexpand">True</property>
<property name="label-xalign">0</property>
<property name="shadow-type">none</property>
<child>
<!-- n-columns=2 n-rows=1 -->
<object class="GtkGrid" id="refgrid2">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="margin-start">12</property>
<property name="margin-top">6</property>
<property name="hexpand">True</property>
<property name="column-spacing">6</property>
<child>
<object class="GtkComboBoxText" id="appearance">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="hexpand">True</property>
<property name="active">0</property>
<items>
<item translatable="yes" context="optviewpage|appearance">System</item>
<item translatable="yes" context="optviewpage|appearance">Light</item>
<item translatable="yes" context="optviewpage|appearance">Dark</item>
</items>
<child internal-child="accessible">
<object class="AtkObject" id="appearance-atkobject">
<property name="AtkObject::accessible-description" translatable="yes" context="extended_tip | appearance">Specifies whether to follow the system appearance mode or override Dark or Light.</property>
</object>
</child>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label7">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes" context="optviewpage|label7">Mode:</property>
<property name="use-underline">True</property>
<property name="mnemonic-widget">appearance</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label16">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes" context="optviewpage|label16">Appearance</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
@@ -757,26 +827,28 @@
</object>
<object class="GtkSizeGroup" id="sizegroupLabel">
<widgets>
<widget name="label6"/>
<widget name="label14"/>
<widget name="label8"/>
<widget name="label9"/>
<widget name="label13"/>
<widget name="label10"/>
<widget name="label11"/>
<widget name="label12"/>
<widget name="label13"/>
<widget name="label10"/>
<widget name="label8"/>
<widget name="label9"/>
<widget name="label14"/>
<widget name="label6"/>
<widget name="label7"/>
</widgets>
</object>
<object class="GtkSizeGroup" id="sizegroupWidget">
<widgets>
<widget name="iconstyle"/>
<widget name="iconsize"/>
<widget name="notebookbariconsize"/>
<widget name="sidebariconsize"/>
<widget name="menuicons"/>
<widget name="contextmenushortcuts"/>
<widget name="mousepos"/>
<widget name="mousemiddle"/>
<widget name="menuicons"/>
<widget name="contextmenushortcuts"/>
<widget name="notebookbariconsize"/>
<widget name="sidebariconsize"/>
<widget name="iconsize"/>
<widget name="iconstyle"/>
<widget name="appearance"/>
</widgets>
</object>
</interface>
diff --git a/include/vcl/settings.hxx b/include/vcl/settings.hxx
index 9d86554..de6a4b9 100644
--- a/include/vcl/settings.hxx
+++ b/include/vcl/settings.hxx
@@ -645,6 +645,9 @@ public:
bool GetDisablePrinting() const;
void SetEnableLocalizedDecimalSep( bool bEnable );
bool GetEnableLocalizedDecimalSep() const;
// 0 auto, 1 light, 2, dark
static void SetDarkMode(int nMode);
static int GetDarkMode();
bool operator ==( const MiscSettings& rSet ) const;
bool operator !=( const MiscSettings& rSet ) const;
diff --git a/officecfg/registry/schema/org/openoffice/Office/Common.xcs b/officecfg/registry/schema/org/openoffice/Office/Common.xcs
index ea175aa..24716e1 100644
--- a/officecfg/registry/schema/org/openoffice/Office/Common.xcs
+++ b/officecfg/registry/schema/org/openoffice/Office/Common.xcs
@@ -5416,6 +5416,31 @@
<info>
<desc>Determines the miscellaneous entries for the common group.</desc>
</info>
<prop oor:name="Appearance" oor:type="xs:short" oor:nillable="false">
<!-- UIHints: Tools Options - General View [Section] Appearance -->
<info>
<desc>Specifies the appearance of the user interface.</desc>
<label>Appearance</label>
</info>
<constraints>
<enumeration oor:value="0">
<info>
<desc>Automatic, from system settings</desc>
</info>
</enumeration>
<enumeration oor:value="1">
<info>
<desc>Light</desc>
</info>
</enumeration>
<enumeration oor:value="2">
<info>
<desc>Dark</desc>
</info>
</enumeration>
</constraints>
<value>0</value>
</prop>
<prop oor:name="MaxOpenDocuments" oor:type="xs:int">
<info>
<desc>Determines the maximum count of documents, which are allowed to
diff --git a/vcl/inc/osx/salframe.h b/vcl/inc/osx/salframe.h
index 71b8eb4..af8783b 100644
--- a/vcl/inc/osx/salframe.h
+++ b/vcl/inc/osx/salframe.h
@@ -163,6 +163,7 @@ public:
tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight ) override;
// done setting up the clipregion
virtual void EndSetClipRegion() override;
virtual void UpdateDarkMode() override;
void UpdateFrameGeometry();
diff --git a/vcl/inc/salframe.hxx b/vcl/inc/salframe.hxx
index 552d88e..a78f9af 100644
--- a/vcl/inc/salframe.hxx
+++ b/vcl/inc/salframe.hxx
@@ -299,6 +299,8 @@ public:
void SetModalHierarchyHdl(const Link<bool, void>& rLink) { m_aModalHierarchyHdl = rLink; }
void NotifyModalHierarchy(bool bModal) { m_aModalHierarchyHdl.Call(bModal); }
virtual void UpdateDarkMode() {}
// Call the callback set; this sometimes necessary for implementation classes
// that should not know more than necessary about the SalFrame implementation
// (e.g. input methods, printer update handlers).
diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx
index 5b2df74..bd5f4de 100644
--- a/vcl/inc/unx/gtk/gtkframe.hxx
+++ b/vcl/inc/unx/gtk/gtkframe.hxx
@@ -611,6 +611,7 @@ public:
virtual bool UpdatePopover(void* nId, const OUString& rHelpText, vcl::Window* pParent, const tools::Rectangle& rHelpArea) override;
virtual bool HidePopover(void* nId) override;
virtual weld::Window* GetFrameWeld() const override;
virtual void UpdateDarkMode() override;
static GtkSalFrame *getFromWindow( GtkWidget *pWindow );
diff --git a/vcl/inc/win/salframe.h b/vcl/inc/win/salframe.h
index dedac69..78f6194 100644
--- a/vcl/inc/win/salframe.h
+++ b/vcl/inc/win/salframe.h
@@ -139,6 +139,7 @@ public:
virtual void BeginSetClipRegion( sal_uInt32 nRects ) override;
virtual void UnionClipRegion( tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight ) override;
virtual void EndSetClipRegion() override;
virtual void UpdateDarkMode() override;
constexpr vcl::WindowState state() const { return m_eState; }
void UpdateFrameState();
diff --git a/vcl/osx/salframe.cxx b/vcl/osx/salframe.cxx
index 02a3879..bf2257b 100644
--- a/vcl/osx/salframe.cxx
+++ b/vcl/osx/salframe.cxx
@@ -1258,6 +1258,26 @@ void AquaSalFrame::getResolution( sal_Int32& o_rDPIX, sal_Int32& o_rDPIY )
mpGraphics->GetResolution( o_rDPIX, o_rDPIY );
}
void AquaSalFrame::UpdateDarkMode()
{
if (@available(macOS 10.14, iOS 13, *))
{
switch (MiscSettings::GetDarkMode())
{
case 0: // auto
default:
[NSApp setAppearance: nil];
break;
case 1: // light
[NSApp setAppearance: [NSAppearance appearanceNamed: NSAppearanceNameAqua]];
break;
case 2: // dark
[NSApp setAppearance: [NSAppearance appearanceNamed: NSAppearanceNameDarkAqua]];
break;
}
}
}
// on OSX-Aqua the style settings are independent of the frame, so it does
// not really belong here. Since the connection to the Appearance_Manager
// is currently done in salnativewidgets.cxx this would be a good place.
@@ -1289,11 +1309,11 @@ SAL_WNODEPRECATED_DECLARATIONS_POP
StyleSettings aStyleSettings = rSettings.GetStyleSettings();
bool bUseDarkMode(false);
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
if (userDefaults != nil)
if (@available(macOS 10.14, iOS 13, *))
{
NSString* setting = [userDefaults stringForKey: @"AppleInterfaceStyle"];
bUseDarkMode = (setting && [setting isEqual: @"Dark"]);
NSAppearanceName match = [mpNSView.effectiveAppearance bestMatchFromAppearancesWithNames: @[
NSAppearanceNameAqua, NSAppearanceNameDarkAqua]];
bUseDarkMode = [match isEqualToString: NSAppearanceNameDarkAqua];
}
// there is no sukapura_dark, at the time of writing at least, so whatever
// is considered the default dark icon set will be used
diff --git a/vcl/source/app/settings.cxx b/vcl/source/app/settings.cxx
index d6cf251..71d58a4 100644
--- a/vcl/source/app/settings.cxx
+++ b/vcl/source/app/settings.cxx
@@ -53,6 +53,7 @@
using namespace ::com::sun::star;
#include <salframe.hxx>
#include <svdata.hxx>
struct ImplMouseData
@@ -2766,6 +2767,25 @@ bool MiscSettings::GetEnableLocalizedDecimalSep() const
return mxData->mbEnableLocalizedDecimalSep;
}
int MiscSettings::GetDarkMode()
{
return officecfg::Office::Common::Misc::Appearance::get();
}
void MiscSettings::SetDarkMode(int nMode)
{
std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
officecfg::Office::Common::Misc::Appearance::set(nMode, batch);
batch->commit();
vcl::Window *pWin = Application::GetFirstTopLevelWindow();
while (pWin)
{
pWin->ImplGetFrame()->UpdateDarkMode();
pWin = Application::GetNextTopLevelWindow(pWin);
}
}
HelpSettings::HelpSettings()
: mxData(std::make_shared<ImplHelpData>())
{
diff --git a/vcl/unx/gtk3/gtkframe.cxx b/vcl/unx/gtk3/gtkframe.cxx
index 1d72e46..69dc11b 100644
--- a/vcl/unx/gtk3/gtkframe.cxx
+++ b/vcl/unx/gtk3/gtkframe.cxx
@@ -45,6 +45,7 @@
#include <window.h>
#include <basegfx/vector/b2ivector.hxx>
#include <officecfg/Office/Common.hxx>
#include <dlfcn.h>
@@ -1315,20 +1316,20 @@ namespace
PREFER_LIGHT
};
bool ReadColorScheme(GDBusProxy* proxy, GVariant** out)
void ReadColorScheme(GDBusProxy* proxy, GVariant** out)
{
g_autoptr (GVariant) ret =
g_dbus_proxy_call_sync(proxy, "Read",
g_variant_new ("(ss)", "org.freedesktop.appearance", "color-scheme"),
G_DBUS_CALL_FLAGS_NONE, G_MAXINT, nullptr, nullptr);
if (!ret)
return false;
return;
g_autoptr (GVariant) child = nullptr;
g_variant_get(ret, "(v)", &child);
g_variant_get(child, "v", out);
return true;
return;
}
}
@@ -1337,9 +1338,30 @@ void GtkSalFrame::SetColorScheme(GVariant* variant)
if (!m_pWindow)
return;
guint32 color_scheme = g_variant_get_uint32(variant);
if (color_scheme > PREFER_LIGHT)
color_scheme = DEFAULT;
guint32 color_scheme;
switch (officecfg::Office::Common::Misc::Appearance::get())
{
default:
case 0: // Auto
{
if (variant)
{
color_scheme = g_variant_get_uint32(variant);
if (color_scheme > PREFER_LIGHT)
color_scheme = DEFAULT;
}
else
color_scheme = DEFAULT;
break;
}
case 1: // Light
color_scheme = PREFER_LIGHT;
break;
case 2: // Dark
color_scheme = PREFER_DARK;
break;
}
bool bDarkIconTheme(color_scheme == PREFER_DARK);
GtkSettings* pSettings = gtk_widget_get_settings(m_pWindow);
@@ -1380,18 +1402,20 @@ void GtkSalFrame::ListenPortalSettings()
"org.freedesktop.portal.Settings",
nullptr,
nullptr);
if (!m_pSettingsPortal)
return;
g_autoptr (GVariant) value = nullptr;
UpdateDarkMode();
if (!ReadColorScheme(m_pSettingsPortal, &value))
return;
SetColorScheme(value);
m_nPortalSettingChangedSignalId = g_signal_connect(m_pSettingsPortal, "g-signal", G_CALLBACK(settings_portal_changed_cb), this);
}
void GtkSalFrame::UpdateDarkMode()
{
g_autoptr (GVariant) value = nullptr;
if (m_pSettingsPortal)
ReadColorScheme(m_pSettingsPortal, &value);
SetColorScheme(value);
}
#if GTK_CHECK_VERSION(4,0,0)
static void PopoverClosed(GtkPopover*, GtkSalFrame* pThis)
{
diff --git a/vcl/win/gdi/salnativewidgets-luna.cxx b/vcl/win/gdi/salnativewidgets-luna.cxx
index 1cd6245..c837cb7 100644
--- a/vcl/win/gdi/salnativewidgets-luna.cxx
+++ b/vcl/win/gdi/salnativewidgets-luna.cxx
@@ -402,16 +402,30 @@ bool UseDarkMode()
if (!bOSSupportsDarkMode)
return false;
HINSTANCE hUxthemeLib = LoadLibraryExW(L"uxtheme.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
if (!hUxthemeLib)
return false;
bool bRet(false);
switch (MiscSettings::GetDarkMode())
{
case 0: // auto
default:
{
HINSTANCE hUxthemeLib = LoadLibraryExW(L"uxtheme.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
if (!hUxthemeLib)
return false;
bool bRet = false;
typedef bool(WINAPI* ShouldAppsUseDarkMode_t)();
if (auto ShouldAppsUseDarkMode = reinterpret_cast<ShouldAppsUseDarkMode_t>(GetProcAddress(hUxthemeLib, MAKEINTRESOURCEA(132))))
bRet = ShouldAppsUseDarkMode();
typedef bool(WINAPI* ShouldAppsUseDarkMode_t)();
if (auto ShouldAppsUseDarkMode = reinterpret_cast<ShouldAppsUseDarkMode_t>(GetProcAddress(hUxthemeLib, MAKEINTRESOURCEA(132))))
bRet = ShouldAppsUseDarkMode();
FreeLibrary(hUxthemeLib);
FreeLibrary(hUxthemeLib);
break;
}
case 1: // light
bRet = false;
break;
case 2: // dark
bRet = true;
break;
}
return bRet;
}
@@ -421,7 +435,8 @@ static bool ImplDrawNativeControl( HDC hDC, HTHEME hTheme, RECT rc,
ControlPart nPart,
ControlState nState,
const ImplControlValue& aValue,
OUString const & aCaption )
OUString const & aCaption,
bool bUseDarkMode )
{
// a listbox dropdown is actually a combobox dropdown
if( nType == ControlType::Listbox )
@@ -767,7 +782,7 @@ static bool ImplDrawNativeControl( HDC hDC, HTHEME hTheme, RECT rc,
{
// tabpane in tabcontrols gets drawn in "darkmode" as if it was a
// a "light" theme, so bodge this by drawing a frame directly
if (UseDarkMode())
if (bUseDarkMode)
{
Color aColor(Application::GetSettings().GetStyleSettings().GetDisableColor());
ScopedHBRUSH hbrush(CreateSolidBrush(RGB(aColor.GetRed(),
@@ -783,7 +798,7 @@ static bool ImplDrawNativeControl( HDC hDC, HTHEME hTheme, RECT rc,
if( nType == ControlType::TabBody )
{
// tabbody in main window gets drawn in white in "darkmode", so bodge this here
if (UseDarkMode())
if (bUseDarkMode)
{
Color aColor(Application::GetSettings().GetStyleSettings().GetWindowColor());
ScopedHBRUSH hbrush(CreateSolidBrush(RGB(aColor.GetRed(),
@@ -843,7 +858,7 @@ static bool ImplDrawNativeControl( HDC hDC, HTHEME hTheme, RECT rc,
// tabitem in tabcontrols gets drawn in "darkmode" as if it was a
// a "light" theme, so bodge this by drawing with a button instead
if (UseDarkMode())
if (bUseDarkMode)
{
Color aColor;
if (iState == TILES_SELECTED)
@@ -911,7 +926,7 @@ static bool ImplDrawNativeControl( HDC hDC, HTHEME hTheme, RECT rc,
}
// toolbar in main window gets drawn in white in "darkmode", so bodge this here
if (UseDarkMode())
if (bUseDarkMode)
{
Color aColor(Application::GetSettings().GetStyleSettings().GetWindowColor());
ScopedHBRUSH hbrush(CreateSolidBrush(RGB(aColor.GetRed(),
@@ -943,7 +958,7 @@ static bool ImplDrawNativeControl( HDC hDC, HTHEME hTheme, RECT rc,
rc.bottom += pValue->maTopDockingAreaHeight; // extend potential gradient to cover docking area as well
// menubar in main window gets drawn in white in "darkmode", so bodge this here
if (UseDarkMode())
if (bUseDarkMode)
{
Color aColor(Application::GetSettings().GetStyleSettings().GetWindowColor());
ScopedHBRUSH hbrush(CreateSolidBrush(RGB(aColor.GetRed(),
@@ -1302,7 +1317,7 @@ bool WinSalGraphics::drawNativeControl( ControlType nType,
// set default text alignment
int ta = SetTextAlign(getHDC(), TA_LEFT|TA_TOP|TA_NOUPDATECP);
bOk = ImplDrawNativeControl(getHDC(), hTheme, rc, nType, nPart, nState, aValue, aCaptionStr);
bOk = ImplDrawNativeControl(getHDC(), hTheme, rc, nType, nPart, nState, aValue, aCaptionStr, bUseDarkMode);
// restore alignment
SetTextAlign(getHDC(), ta);
@@ -1318,8 +1333,8 @@ bool WinSalGraphics::drawNativeControl( ControlType nType,
SetTextAlign(aWhiteDC->getCompatibleHDC(), TA_LEFT|TA_TOP|TA_NOUPDATECP);
aWhiteDC->fill(RGB(0xff, 0xff, 0xff));
if (ImplDrawNativeControl(aBlackDC->getCompatibleHDC(), hTheme, rc, nType, nPart, nState, aValue, aCaptionStr) &&
ImplDrawNativeControl(aWhiteDC->getCompatibleHDC(), hTheme, rc, nType, nPart, nState, aValue, aCaptionStr))
if (ImplDrawNativeControl(aBlackDC->getCompatibleHDC(), hTheme, rc, nType, nPart, nState, aValue, aCaptionStr, bUseDarkMode) &&
ImplDrawNativeControl(aWhiteDC->getCompatibleHDC(), hTheme, rc, nType, nPart, nState, aValue, aCaptionStr, bUseDarkMode))
{
bOk = pImpl->RenderAndCacheNativeControl(*aWhiteDC, *aBlackDC, cacheRect.Left(), cacheRect.Top(), aControlCacheKey);
}
diff --git a/vcl/win/window/salframe.cxx b/vcl/win/window/salframe.cxx
index e6c8f8a..3a094c0 100644
--- a/vcl/win/window/salframe.cxx
+++ b/vcl/win/window/salframe.cxx
@@ -261,6 +261,17 @@ void ImplSalGetWorkArea( HWND hWnd, RECT *pRect, const RECT *pParentRect )
}
}
namespace {
enum PreferredAppMode
{
AllowDark = 1,
ForceDark = 2,
ForceLight = 3
};
}
static void UpdateDarkMode(HWND hWnd)
{
static bool bOSSupportsDarkMode = OSSupportsDarkMode();
@@ -271,18 +282,37 @@ static void UpdateDarkMode(HWND hWnd)
if (!hUxthemeLib)
return;
typedef void(WINAPI* AllowDarkModeForWindow_t)(HWND, BOOL);
if (auto AllowDarkModeForWindow = reinterpret_cast<AllowDarkModeForWindow_t>(GetProcAddress(hUxthemeLib, MAKEINTRESOURCEA(133))))
AllowDarkModeForWindow(hWnd, TRUE);
typedef bool(WINAPI* ShouldAppsUseDarkMode_t)();
if (auto ShouldAppsUseDarkMode = reinterpret_cast<ShouldAppsUseDarkMode_t>(GetProcAddress(hUxthemeLib, MAKEINTRESOURCEA(132))))
typedef PreferredAppMode(WINAPI* SetPreferredAppMode_t)(PreferredAppMode);
auto SetPreferredAppMode = reinterpret_cast<SetPreferredAppMode_t>(GetProcAddress(hUxthemeLib, MAKEINTRESOURCEA(135)));
if (SetPreferredAppMode)
{
BOOL bDarkMode = ShouldAppsUseDarkMode();
DwmSetWindowAttribute(hWnd, 20, &bDarkMode, sizeof(bDarkMode));
switch (MiscSettings::GetDarkMode())
{
case 0:
SetPreferredAppMode(AllowDark);
break;
case 1:
SetPreferredAppMode(ForceLight);
break;
case 2:
SetPreferredAppMode(ForceDark);
break;
}
}
BOOL bDarkMode = UseDarkMode();
typedef void(WINAPI* AllowDarkModeForWindow_t)(HWND, BOOL);
auto AllowDarkModeForWindow = reinterpret_cast<AllowDarkModeForWindow_t>(GetProcAddress(hUxthemeLib, MAKEINTRESOURCEA(133)));
if (AllowDarkModeForWindow)
AllowDarkModeForWindow(hWnd, bDarkMode);
FreeLibrary(hUxthemeLib);
if (!AllowDarkModeForWindow)
return;
DwmSetWindowAttribute(hWnd, 20, &bDarkMode, sizeof(bDarkMode));
}
SalFrame* ImplSalCreateFrame( WinSalInstance* pInst,
@@ -3076,6 +3106,11 @@ void WinSalFrame::EndSetClipRegion()
}
}
void WinSalFrame::UpdateDarkMode()
{
::UpdateDarkMode(mhWnd);
}
static bool ImplHandleMouseMsg( HWND hWnd, UINT nMsg,
WPARAM wParam, LPARAM lParam )
{