include/unotools/options.hxx | 3 ++- 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 +++++++++++++++++++++++--------- 6 files changed, 77 insertions(+), 24 deletions(-)
New commits: commit a80b063ca9b9a1ae9c288ce1725d783953131559 Author: Caolán McNamara <caolan.mcnam...@collabora.com> AuthorDate: Mon Nov 27 10:34:56 2023 +0000 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Tue Nov 28 11:06:45 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/+/159992 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Miklos Vajna <vmik...@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 83bd972d4d0b..650cca1562d1 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(m_pColorConfig->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().getStr()); + + // 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 297f6f8f9e14..391ff8c72add 100644 --- a/sfx2/source/appl/appserv.cxx +++ b/sfx2/source/appl/appserv.cxx @@ -604,7 +604,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 e03e875f100a..a0a462631473 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> @@ -237,11 +238,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 580c6d484709..566e07b2d853 100644 --- a/svx/source/svdraw/svdpntv.cxx +++ b/svx/source/svdraw/svdpntv.cxx @@ -231,8 +231,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 ba92304518f2..75282391ab86 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/isethint.hxx> #include <svl/stritem.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> @@ -969,7 +972,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() ) { @@ -978,8 +981,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()) @@ -991,24 +994,35 @@ void SwModule::ConfigurationChanged( utl::ConfigurationBroadcaster* pBrdCst, Con aNewOptions.SetThemeName(m_pColorConfig->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().getStr()); pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_DOCUMENT_BACKGROUND_COLOR, aViewColors.m_aDocColor.AsRGBHexString().toUtf8().getStr()); } + + // 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 ); }