include/unotools/options.hxx       |    3 ++-
 sc/source/core/tool/viewopti.cxx   |    1 +
 sc/source/ui/app/scmod.cxx         |   33 +++++++++++++++++++++++----------
 sfx2/source/appl/appserv.cxx       |    7 ++++++-
 svtools/source/config/colorcfg.cxx |   22 ++++++++++++++++++++--
 svx/source/svdraw/svdpntv.cxx      |    4 +++-
 sw/source/uibase/app/apphdl.cxx    |   32 +++++++++++++++++++++++---------
 7 files changed, 78 insertions(+), 24 deletions(-)

New commits:
commit 8c727d1a9a8cfdc309896ed02c546e192e006575
Author:     Caolán McNamara <caolan.mcnam...@collabora.com>
AuthorDate: Mon Nov 27 10:34:56 2023 +0000
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Tue Nov 28 09:36:08 2023 +0100

    Always send theme-change in kit-mode even if the global theme is the same
    
    Kit explicitly ignores changes to the global color scheme, except for the 
current ViewShell,
    so an attempted change to the same global color scheme when the now current 
ViewShell ignored
    the last change requires re-sending the change. In which case individual 
shells will have to
    decide if this color-scheme change is a change from their perspective to 
avoid unnecessary
    invalidations.
    
    Add ConfigurationHints::OnlyCurrentDocumentColorScheme as the hint that
    only the document color scheme has changed, so individual shells can see
    if their document color scheme is different to this new color scheme and
    not invalidate if unnecessary. So dark/light mode changes work properly
    without reintroducing unwanted invalidations.
    
    Change-Id: I5ebb4878694ceb6b9afe26286a30da06ea6ff3ef
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160002
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/include/unotools/options.hxx b/include/unotools/options.hxx
index 4e0206ace017..7121848226c8 100644
--- a/include/unotools/options.hxx
+++ b/include/unotools/options.hxx
@@ -35,10 +35,11 @@ enum class ConfigurationHints {
     DecSep             = 0x0008,
     DatePatterns       = 0x0010,
     IgnoreLang         = 0x0020,
+    OnlyCurrentDocumentColorScheme = 0x0040,
     CtlSettingsChanged = 0x2000,
 };
 namespace o3tl {
-    template<> struct typed_flags<ConfigurationHints> : 
is_typed_flags<ConfigurationHints, 0x203f> {};
+    template<> struct typed_flags<ConfigurationHints> : 
is_typed_flags<ConfigurationHints, 0x207f> {};
 }
 
 /*
diff --git a/sc/source/ui/app/scmod.cxx b/sc/source/ui/app/scmod.cxx
index d15c891a2f62..3fa3a7849b22 100644
--- a/sc/source/ui/app/scmod.cxx
+++ b/sc/source/ui/app/scmod.cxx
@@ -174,7 +174,7 @@ ScModule::~ScModule()
     DeleteCfg(); // Called from Exit()
 }
 
-void ScModule::ConfigurationChanged( utl::ConfigurationBroadcaster* p, 
ConfigurationHints )
+void ScModule::ConfigurationChanged(utl::ConfigurationBroadcaster* p, 
ConfigurationHints eHints)
 {
     if ( p == m_pColorConfig.get() || p == m_pAccessOptions.get() )
     {
@@ -208,7 +208,10 @@ void ScModule::ConfigurationChanged( 
utl::ConfigurationBroadcaster* p, Configura
             }
         }
 
-        if (comphelper::LibreOfficeKit::isActive() && m_pColorConfig)
+        bool bSkipInvalidate = false;
+
+        const bool bKit = comphelper::LibreOfficeKit::isActive();
+        if (bKit && p == m_pColorConfig.get())
         {
             SfxViewShell* pSfxViewShell = SfxViewShell::Current();
             ScTabViewShell* pViewShell = 
dynamic_cast<ScTabViewShell*>(pSfxViewShell);
@@ -220,26 +223,34 @@ void ScModule::ConfigurationChanged( 
utl::ConfigurationBroadcaster* p, Configura
                 Color 
aFillColor(m_pColorConfig->GetColorValue(svtools::DOCCOLOR).nColor);
                 aViewOptions.SetDocColor(aFillColor);
                 
aViewOptions.SetColorSchemeName(svtools::ColorConfig::GetCurrentSchemeName());
-                pViewData.SetOptions(aViewOptions);
+                const bool bChanged(aViewOptions != pViewData.GetOptions());
+                if (bChanged)
+                    pViewData.SetOptions(aViewOptions);
                 ScModelObj* pScModelObj = 
comphelper::getFromUnoTunnel<ScModelObj>(SfxObjectShell::Current()->GetModel());
                 SfxLokHelper::notifyViewRenderState(SfxViewShell::Current(), 
pScModelObj);
                 // In Online, the document color is the one used for the 
background, contrary to
                 // Writer and Draw that use the application background color.
                 
pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_APPLICATION_BACKGROUND_COLOR,
                         aFillColor.AsRGBHexString().toUtf8());
+
+                // if nothing changed, and the hint was 
OnlyCurrentDocumentColorScheme we can skip invalidate
+                bSkipInvalidate = !bChanged && eHints == 
ConfigurationHints::OnlyCurrentDocumentColorScheme;
             }
         }
 
-        // force all views to repaint, using the new options
-        SfxViewShell* pViewShell = SfxViewShell::GetFirst();
-        while(pViewShell)
+        //invalidate only the current view in tiled rendering mode, or all 
views otherwise
+        SfxViewShell* pViewShell = bKit ? SfxViewShell::Current() : 
SfxViewShell::GetFirst();
+        while (pViewShell)
         {
             if (ScTabViewShell* pViewSh = 
dynamic_cast<ScTabViewShell*>(pViewShell))
             {
-                pViewSh->PaintGrid();
-                pViewSh->PaintTop();
-                pViewSh->PaintLeft();
-                pViewSh->PaintExtras();
+                if (!bSkipInvalidate)
+                {
+                    pViewSh->PaintGrid();
+                    pViewSh->PaintTop();
+                    pViewSh->PaintLeft();
+                    pViewSh->PaintExtras();
+                }
 
                 ScInputHandler* pHdl = pViewSh->GetInputHandler();
                 if ( pHdl )
@@ -251,6 +262,8 @@ void ScModule::ConfigurationChanged( 
utl::ConfigurationBroadcaster* p, Configura
                 if (pWin)
                     pWin->Invalidate();
             }
+            if (bKit)
+                break;
             pViewShell = SfxViewShell::GetNext( *pViewShell );
         }
     }
diff --git a/sfx2/source/appl/appserv.cxx b/sfx2/source/appl/appserv.cxx
index 9c1b3c9d2a57..aa0699e78137 100644
--- a/sfx2/source/appl/appserv.cxx
+++ b/sfx2/source/appl/appserv.cxx
@@ -594,7 +594,12 @@ void SfxApplication::MiscExec_Impl( SfxRequest& rReq )
             }
             const OUString& rSchemeName = pNewThemeArg->GetValue();
             svtools::EditableColorConfig aEditableConfig;
-            if (aEditableConfig.GetCurrentSchemeName() != rSchemeName)
+            // kit explicitly ignores changes to the global color scheme, 
except for the current ViewShell,
+            // so an attempted change to the same global color scheme when the 
now current ViewShell ignored
+            // the last change requires re-sending the change. In which case 
individual shells will have to
+            // decide if this color-scheme change is a change from their 
perspective to avoid unnecessary
+            // invalidations.
+            if (aEditableConfig.GetCurrentSchemeName() != rSchemeName || 
comphelper::LibreOfficeKit::isActive())
                 aEditableConfig.LoadScheme(rSchemeName);
             break;
         }
diff --git a/svtools/source/config/colorcfg.cxx 
b/svtools/source/config/colorcfg.cxx
index f2f142071a43..167dfa3337ad 100644
--- a/svtools/source/config/colorcfg.cxx
+++ b/svtools/source/config/colorcfg.cxx
@@ -25,6 +25,7 @@
 #include <com/sun/star/uno/Any.hxx>
 #include <com/sun/star/uno/Sequence.hxx>
 #include <com/sun/star/beans/PropertyValue.hpp>
+#include <comphelper/lok.hxx>
 #include <comphelper/processfactory.hxx>
 #include <unotools/configitem.hxx>
 #include <unotools/confignode.hxx>
@@ -241,11 +242,28 @@ void ColorConfig_Impl::Load(const OUString& rScheme)
     }
 }
 
-void    ColorConfig_Impl::Notify( const uno::Sequence<OUString>& )
+void ColorConfig_Impl::Notify(const uno::Sequence<OUString>& rProperties)
 {
+    const bool bOnlyChangingCurrentColorScheme = rProperties.getLength() == 1 
&& rProperties[0] == "CurrentColorScheme";
+    const OUString sOldLoadedScheme = m_sLoadedScheme;
+
     //loading via notification always uses the default setting
     Load(OUString());
-    NotifyListeners(ConfigurationHints::NONE);
+
+    // If the name of the scheme hasn't changed, then there is no change to the
+    // global color scheme name, but Kit deliberately only changed the then
+    // current document when it last changed, so there are typically a mixture
+    // of documents with the original 'light' color scheme and the last changed
+    // color scheme 'dark'. Kit then tries to set the color scheme again to the
+    // last changed color scheme 'dark' to try and update a 'light' document
+    // that had opted out of the last change to 'dark'. So tag such an apparent
+    // null change attempt with 'OnlyCurrentDocumentColorScheme' to allow it to
+    // go through, but identify what that change is for, so the other color
+    // config listeners for whom it doesn't matter, can ignore it as an
+    // optimization.
+    const bool bOnlyCurrentDocumentColorScheme = 
bOnlyChangingCurrentColorScheme && sOldLoadedScheme == m_sLoadedScheme &&
+                                                 
comphelper::LibreOfficeKit::isActive();
+    NotifyListeners(bOnlyCurrentDocumentColorScheme ? 
ConfigurationHints::OnlyCurrentDocumentColorScheme : ConfigurationHints::NONE);
 }
 
 void ColorConfig_Impl::ImplCommit()
diff --git a/svx/source/svdraw/svdpntv.cxx b/svx/source/svdraw/svdpntv.cxx
index 436b2998e810..4584e7f83174 100644
--- a/svx/source/svdraw/svdpntv.cxx
+++ b/svx/source/svdraw/svdpntv.cxx
@@ -230,8 +230,10 @@ void SdrPaintView::Notify(SfxBroadcaster& rBC, const 
SfxHint& rHint)
     }
 }
 
-void SdrPaintView::ConfigurationChanged( ::utl::ConfigurationBroadcaster* , 
ConfigurationHints )
+void SdrPaintView::ConfigurationChanged( ::utl::ConfigurationBroadcaster* , 
ConfigurationHints eHint)
 {
+    if (eHint == ConfigurationHints::OnlyCurrentDocumentColorScheme)
+        return;
     onChangeColorConfig();
     InvalidateAllWin();
 }
diff --git a/sw/source/uibase/app/apphdl.cxx b/sw/source/uibase/app/apphdl.cxx
index cd073097f771..cfb431092064 100644
--- a/sw/source/uibase/app/apphdl.cxx
+++ b/sw/source/uibase/app/apphdl.cxx
@@ -22,6 +22,7 @@
 #include <config_wasm_strip.h>
 
 #include <comphelper/propertysequence.hxx>
+#include <comphelper/servicehelper.hxx>
 #include <sfx2/dispatch.hxx>
 #include <sfx2/event.hxx>
 #include <sfx2/objitem.hxx>
@@ -31,6 +32,7 @@
 #include <svl/whiter.hxx>
 #include <svl/stritem.hxx>
 #include <svl/voiditem.hxx>
+#include <sfx2/lokhelper.hxx>
 #include <sfx2/request.hxx>
 #include <sfx2/fcontnr.hxx>
 #include <svl/ctloptions.hxx>
@@ -70,6 +72,7 @@
 #include <dbconfig.hxx>
 #include <mmconfigitem.hxx>
 #include <strings.hrc>
+#include <unotxdoc.hxx>
 #include <com/sun/star/container/XChild.hpp>
 #include <com/sun/star/sdbc/XConnection.hpp>
 #include <com/sun/star/sdb/TextConnectionSettings.hpp>
@@ -959,7 +962,7 @@ void SwModule::Notify( SfxBroadcaster& /*rBC*/, const 
SfxHint& rHint )
     }
 }
 
-void SwModule::ConfigurationChanged( utl::ConfigurationBroadcaster* pBrdCst, 
ConfigurationHints )
+void SwModule::ConfigurationChanged(utl::ConfigurationBroadcaster* pBrdCst, 
ConfigurationHints eHints)
 {
     if( pBrdCst == m_pUserOptions.get() )
     {
@@ -968,8 +971,8 @@ void SwModule::ConfigurationChanged( 
utl::ConfigurationBroadcaster* pBrdCst, Con
     else if ( pBrdCst == m_pColorConfig.get() )
     {
         //invalidate only the current view in tiled rendering mode, or all 
views otherwise
-        bool bOnlyInvalidateCurrentView = 
comphelper::LibreOfficeKit::isActive();
-        SfxViewShell* pViewShell = bOnlyInvalidateCurrentView ? 
SfxViewShell::Current() : SfxViewShell::GetFirst();
+        const bool bKit = comphelper::LibreOfficeKit::isActive();
+        SfxViewShell* pViewShell = bKit ? SfxViewShell::Current() : 
SfxViewShell::GetFirst();
         while(pViewShell)
         {
             if(pViewShell->GetWindow())
@@ -981,24 +984,35 @@ void SwModule::ConfigurationChanged( 
utl::ConfigurationBroadcaster* pBrdCst, Con
                     
aNewOptions.SetThemeName(svtools::ColorConfig::GetCurrentSchemeName());
                     SwViewColors aViewColors(*m_pColorConfig);
                     aNewOptions.SetColorConfig(aViewColors);
-                    pSwView->GetWrtShell().ApplyViewOptions(aNewOptions);
+                    const bool bChanged(aNewOptions != 
*pSwView->GetWrtShell().GetViewOptions());
+                    if (bChanged)
+                        pSwView->GetWrtShell().ApplyViewOptions(aNewOptions);
+                    else if (bKit)
+                    {
+                        SwXTextDocument* pModel = 
comphelper::getFromUnoTunnel<SwXTextDocument>(pViewShell->GetCurrentDocument());
+                        SfxLokHelper::notifyViewRenderState(pViewShell, 
pModel);
+                    }
 
-                    if (bOnlyInvalidateCurrentView)
+                    if (bKit)
                     {
                         
pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_APPLICATION_BACKGROUND_COLOR,
                             
aViewColors.m_aAppBackgroundColor.AsRGBHexString().toUtf8());
                         
pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_DOCUMENT_BACKGROUND_COLOR,
                             
aViewColors.m_aAppBackgroundColor.AsRGBHexString().toUtf8());
                     }
+
+                    // if nothing changed, and the hint was 
OnlyCurrentDocumentColorScheme we can skip invalidate
+                    const bool bSkipInvalidate = !bChanged && bKit && eHints 
== ConfigurationHints::OnlyCurrentDocumentColorScheme;
+                    if (!bSkipInvalidate)
+                        pViewShell->GetWindow()->Invalidate();
                 }
-                if(pSwView !=  nullptr ||
-                   dynamic_cast< const SwPagePreview *>( pViewShell ) !=  
nullptr ||
-                   dynamic_cast< const SwSrcView *>( pViewShell ) !=  nullptr)
+                else if (dynamic_cast< const SwPagePreview *>( pViewShell ) != 
nullptr ||
+                         dynamic_cast< const SwSrcView *>( pViewShell ) !=  
nullptr)
                 {
                     pViewShell->GetWindow()->Invalidate();
                 }
             }
-            if (bOnlyInvalidateCurrentView)
+            if (bKit)
                 break;
             pViewShell = SfxViewShell::GetNext( *pViewShell );
         }
commit cd2ba8cd78c1cd66d5c74e5d35acdcda1bf5abbc
Author:     Caolán McNamara <caolan.mcnam...@collabora.com>
AuthorDate: Mon Nov 27 14:38:19 2023 +0000
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Tue Nov 28 09:35:54 2023 +0100

    ScViewOptions::operator== doesn't compare sColorSchemeName
    
    Change-Id: I21e6630deb9a5329092c88651e4ba0a3715ce616
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159997
    Tested-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/sc/source/core/tool/viewopti.cxx b/sc/source/core/tool/viewopti.cxx
index a91f0cef8bf9..41394ded9a16 100644
--- a/sc/source/core/tool/viewopti.cxx
+++ b/sc/source/core/tool/viewopti.cxx
@@ -142,6 +142,7 @@ bool ScViewOptions::operator==( const ScViewOptions& rOpt ) 
const
     bEqual = bEqual && (aGridCol       == rOpt.aGridCol);
     bEqual = bEqual && (aGridColName   == rOpt.aGridColName);
     bEqual = bEqual && (aGridOpt       == rOpt.aGridOpt);
+    bEqual = bEqual && (sColorSchemeName == rOpt.sColorSchemeName);
     bEqual = bEqual && (aDocCol        == rOpt.aDocCol);
 
     return bEqual;

Reply via email to