diff options
author | Caolán McNamara <caolanm@redhat.com> | 2023-02-06 20:53:55 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2023-02-08 16:11:25 +0000 |
commit | f7c03364e24da285ea95cea0cc688a7a120fc163 (patch) | |
tree | b6dc20e02654f5144daea807303dbdd71a72bba0 | |
parent | 68ab2e109edf8b81c48e953f7c8d43841e07365a (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.cxx | 33 | ||||
-rw-r--r-- | cui/source/options/optgdlg.hxx | 2 | ||||
-rw-r--r-- | cui/uiconfig/ui/optviewpage.ui | 106 | ||||
-rw-r--r-- | include/vcl/settings.hxx | 3 | ||||
-rw-r--r-- | officecfg/registry/schema/org/openoffice/Office/Common.xcs | 25 | ||||
-rw-r--r-- | vcl/inc/osx/salframe.h | 1 | ||||
-rw-r--r-- | vcl/inc/salframe.hxx | 2 | ||||
-rw-r--r-- | vcl/inc/unx/gtk/gtkframe.hxx | 1 | ||||
-rw-r--r-- | vcl/inc/win/salframe.h | 1 | ||||
-rw-r--r-- | vcl/osx/salframe.cxx | 20 | ||||
-rw-r--r-- | vcl/source/app/settings.cxx | 20 | ||||
-rw-r--r-- | vcl/unx/gtk3/gtkframe.cxx | 48 | ||||
-rw-r--r-- | vcl/win/gdi/salnativewidgets-luna.cxx | 49 | ||||
-rw-r--r-- | vcl/win/window/salframe.cxx | 47 |
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 ) { |