summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2023-02-06 20:53:55 +0000
committerCaolán McNamara <caolanm@redhat.com>2023-02-08 16:11:25 +0000
commitf7c03364e24da285ea95cea0cc688a7a120fc163 (patch)
treeb6dc20e02654f5144daea807303dbdd71a72bba0
parent68ab2e109edf8b81c48e953f7c8d43841e07365a (diff)
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>
-rw-r--r--cui/source/options/optgdlg.cxx33
-rw-r--r--cui/source/options/optgdlg.hxx2
-rw-r--r--cui/uiconfig/ui/optviewpage.ui106
-rw-r--r--include/vcl/settings.hxx3
-rw-r--r--officecfg/registry/schema/org/openoffice/Office/Common.xcs25
-rw-r--r--vcl/inc/osx/salframe.h1
-rw-r--r--vcl/inc/salframe.hxx2
-rw-r--r--vcl/inc/unx/gtk/gtkframe.hxx1
-rw-r--r--vcl/inc/win/salframe.h1
-rw-r--r--vcl/osx/salframe.cxx20
-rw-r--r--vcl/source/app/settings.cxx20
-rw-r--r--vcl/unx/gtk3/gtkframe.cxx48
-rw-r--r--vcl/win/gdi/salnativewidgets-luna.cxx49
-rw-r--r--vcl/win/window/salframe.cxx47
14 files changed, 300 insertions, 58 deletions
diff --git a/cui/source/options/optgdlg.cxx b/cui/source/options/optgdlg.cxx
index 4405fdb3e76b..5663d3912488 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"))
@@ -547,9 +549,14 @@ OfaViewTabPage::OfaViewTabPage(weld::Container* pPage, weld::DialogController* p
, m_xMoreIcons(m_xBuilder->weld_button("btnMoreIcons"))
, m_xRunGPTests(m_xBuilder->weld_button("btn_rungptest"))
{
- 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));
@@ -668,6 +675,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());
@@ -781,6 +789,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(
@@ -824,12 +838,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);
}
@@ -912,6 +934,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 a4c686cc2b27..870e3f39bccc 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 ac6b7fcde239..c0ea6b0f2bef 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">Automatic</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 | iconstyle">Specifies the icon style for icons in toolbars and dialogs.</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">iconstyle</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 9d865544bd51..de6a4b903c07 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 ced635fa4200..ea8fde42d833 100644
--- a/officecfg/registry/schema/org/openoffice/Office/Common.xcs
+++ b/officecfg/registry/schema/org/openoffice/Office/Common.xcs
@@ -5548,6 +5548,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 71b8eb45b772..af8783b96147 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 552d88eb2519..a78f9afe08c0 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 be82779142b1..27bbf77ffd54 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 dedac6906467..78f61945a311 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 02a3879648db..62eb7bbac341 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 (Application::GetSettings().GetMiscSettings().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.
diff --git a/vcl/source/app/settings.cxx b/vcl/source/app/settings.cxx
index c12a520ae025..9762c2164f92 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
@@ -2755,6 +2756,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 0a030c83b14b..5cf87a363bc0 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>
@@ -1358,20 +1359,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;
}
}
@@ -1380,9 +1381,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);
@@ -1423,16 +1445,18 @@ 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;
+ 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);
- m_nPortalSettingChangedSignalId = g_signal_connect(m_pSettingsPortal, "g-signal", G_CALLBACK(settings_portal_changed_cb), this);
}
#if GTK_CHECK_VERSION(4,0,0)
diff --git a/vcl/win/gdi/salnativewidgets-luna.cxx b/vcl/win/gdi/salnativewidgets-luna.cxx
index 1cd6245658d6..a0379baa7c6c 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 (Application::GetSettings().GetMiscSettings().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 8c43b8448d93..847156f5b2df 100644
--- a/vcl/win/window/salframe.cxx
+++ b/vcl/win/window/salframe.cxx
@@ -261,6 +261,13 @@ void ImplSalGetWorkArea( HWND hWnd, RECT *pRect, const RECT *pParentRect )
}
}
+enum PreferredAppMode
+{
+ AllowDark = 1,
+ ForceDark = 2,
+ ForceLight = 3
+};
+
static void UpdateDarkMode(HWND hWnd)
{
static bool bOSSupportsDarkMode = OSSupportsDarkMode();
@@ -271,18 +278,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 (Application::GetSettings().GetMiscSettings().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,
@@ -3062,6 +3088,11 @@ void WinSalFrame::EndSetClipRegion()
}
}
+void WinSalFrame::UpdateDarkMode()
+{
+ ::UpdateDarkMode(mhWnd);
+}
+
static bool ImplHandleMouseMsg( HWND hWnd, UINT nMsg,
WPARAM wParam, LPARAM lParam )
{