sc/inc/document.hxx              |    2 +
 sc/inc/scmod.hxx                 |    2 -
 sc/source/core/data/document.cxx |    8 +++++++
 sc/source/core/data/table5.cxx   |    2 +
 sc/source/core/tool/ddelink.cxx  |    3 ++
 sc/source/ui/app/scmod.cxx       |   41 +++++++--------------------------------
 sc/source/ui/docshell/docsh.cxx  |    2 -
 sc/source/ui/view/gridwin.cxx    |    7 ++++--
 sc/source/ui/view/gridwin4.cxx   |    1 
 sc/source/ui/view/tabview4.cxx   |    2 -
 10 files changed, 32 insertions(+), 38 deletions(-)

New commits:
commit 0d3563ad4e49cc767862fae0d79f632103111180
Author:     seyoufi22 <[email protected]>
AuthorDate: Tue Feb 17 15:11:35 2026 +0200
Commit:     Caolán McNamara <[email protected]>
CommitDate: Fri Mar 6 21:58:24 2026 +0100

    tdf#166284 stop idle timer completely when no work is pending
    
    We can start the timer again when needed via a wrapper function
    on the document, cf. ScDocument::EnsureIdleUpdate() proxying
    to ScModule.
    
    Change-Id: I2341d6da92631a4615fd58f7e665e668bfe0a2b8
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199564
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <[email protected]>

diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 350c5e72c8fc..099918ac0ac4 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -668,6 +668,8 @@ public:
                                             ScDocShell* pDocShell = nullptr );
     SC_DLLPUBLIC                ~ScDocument();
 
+    static void       EnsureIdleUpdate(); // ensure that the idle handler is 
called when needed
+
     void              SetName( const OUString& r ) { aDocName = r; }
     const OUString&   GetCodeName() const { return aDocCodeName; }
     void              SetCodeName( const OUString& r ) { aDocCodeName = r; }
diff --git a/sc/inc/scmod.hxx b/sc/inc/scmod.hxx
index 5686f8c42d89..75fcd6cae08f 100644
--- a/sc/inc/scmod.hxx
+++ b/sc/inc/scmod.hxx
@@ -131,7 +131,7 @@ public:
     void                GetState( SfxItemSet& rSet );
     static void         HideDisabledSlots( SfxItemSet& rSet );
 
-    void                AnythingChanged();
+    void                EnsureIdleUpdate();
 
     //  Drag & Drop:
     const ScDragData*   GetDragData() const;
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index eeadfc52f19e..957876320ee3 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -6239,6 +6239,14 @@ void ScDocument::GetDocStat( ScDocStat& rDocStat )
     rDocStat.nCellCount  = GetCellCount();
 }
 
+void ScDocument::EnsureIdleUpdate()
+{
+    if (ScModule* pMod = ScModule::get())
+    {
+        pMod->EnsureIdleUpdate();
+    }
+}
+
 bool ScDocument::HasPrintRange()
 {
     bool bResult = false;
diff --git a/sc/source/core/data/table5.cxx b/sc/source/core/data/table5.cxx
index ceba143124e8..b430105efacf 100644
--- a/sc/source/core/data/table5.cxx
+++ b/sc/source/core/data/table5.cxx
@@ -953,6 +953,7 @@ void ScTable::InvalidateTextWidth(const ScAddress* 
pAdrFrom, const ScAddress* pA
             return;
 
         rCol.SetTextWidth(nRow, TEXTWIDTH_DIRTY);
+        ScDocument::EnsureIdleUpdate();
 
         if (bNumFormatChanged)
             rCol.SetScriptType(nRow, SvtScriptType::UNKNOWN);
@@ -1017,6 +1018,7 @@ void ScTable::InvalidateTextWidth(const ScAddress* 
pAdrFrom, const ScAddress* pA
             }
         }
     }
+    ScDocument::EnsureIdleUpdate();
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/tool/ddelink.cxx b/sc/source/core/tool/ddelink.cxx
index ffb1804cfe58..dfa6b0e955b1 100644
--- a/sc/source/core/tool/ddelink.cxx
+++ b/sc/source/core/tool/ddelink.cxx
@@ -247,7 +247,10 @@ void ScDdeLink::SetResult( const ScMatrixRef& pRes )
 void ScDdeLink::TryUpdate()
 {
     if (bIsInUpdate)
+    {
         bNeedUpdate = true;         // cannot be executed now
+        ScDocument::EnsureIdleUpdate();
+    }
     else
     {
         bIsInUpdate = true;
diff --git a/sc/source/ui/app/scmod.cxx b/sc/source/ui/app/scmod.cxx
index 4456f5da8d3a..28f53ab86cdb 100644
--- a/sc/source/ui/app/scmod.cxx
+++ b/sc/source/ui/app/scmod.cxx
@@ -98,12 +98,7 @@
 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
 #include <sfx2/lokhelper.hxx>
 
-#define SC_IDLE_MIN     150
-#define SC_IDLE_MAX     3000
-#define SC_IDLE_STEP    75
-#define SC_IDLE_COUNT   50
-
-static sal_uInt16 nIdleCount = 0;
+#define SC_IDLE_STEP     150
 
 SFX_IMPL_INTERFACE(ScModule, SfxShell)
 
@@ -145,7 +140,7 @@ ScModule::ScModule( SfxObjectFactory* pFact ) :
                                        GetResLocale()) );
 
     m_aIdleTimer.SetPriority(TaskPriority::DEFAULT_IDLE);
-    m_aIdleTimer.SetTimeout(SC_IDLE_MIN);
+    m_aIdleTimer.SetTimeout(SC_IDLE_STEP);
     m_aIdleTimer.SetInvokeHandler( LINK( this, ScModule, IdleHandler ) );
     m_aIdleTimer.Start();
 
@@ -1910,13 +1905,10 @@ void ScModule::EndReference()
 /**
  * Idle/OnlineSpelling
  */
-void ScModule::AnythingChanged()
+void ScModule::EnsureIdleUpdate()
 {
-    sal_uInt64 nOldTime = m_aIdleTimer.GetTimeout();
-    if ( nOldTime != SC_IDLE_MIN )
-        m_aIdleTimer.SetTimeout( SC_IDLE_MIN );
-
-    nIdleCount = 0;
+    if (!m_aIdleTimer.IsActive())
+        m_aIdleTimer.Start(); // Restart the timer.
 }
 
 static void lcl_CheckNeedsRepaint( const ScDocShell* pDocShell )
@@ -1936,7 +1928,7 @@ IMPL_LINK_NOARG(ScModule, IdleHandler, Timer *, void)
 {
     if ( Application::AnyInput( VclInputFlags::MOUSE | VclInputFlags::KEYBOARD 
) )
     {
-        m_aIdleTimer.Start(); // Timeout unchanged
+        m_aIdleTimer.Start();
         return;
     }
 
@@ -1958,31 +1950,14 @@ IMPL_LINK_NOARG(ScModule, IdleHandler, Timer *, void)
             lcl_CheckNeedsRepaint( pDocSh );
     }
 
-
-    sal_uInt64 nOldTime = m_aIdleTimer.GetTimeout();
-    sal_uInt64 nNewTime = nOldTime;
     if ( bMore )
     {
-        nNewTime = SC_IDLE_MIN;
-        nIdleCount = 0;
+        m_aIdleTimer.Start();
     }
     else
     {
-        // Set SC_IDLE_COUNT to initial Timeout - increase afterwards
-        if ( nIdleCount < SC_IDLE_COUNT )
-            ++nIdleCount;
-        else
-        {
-            nNewTime += SC_IDLE_STEP;
-            if ( nNewTime > SC_IDLE_MAX )
-                nNewTime = SC_IDLE_MAX;
-        }
+        m_aIdleTimer.Stop();
     }
-    if ( nNewTime != nOldTime )
-        m_aIdleTimer.SetTimeout( nNewTime );
-
-
-    m_aIdleTimer.Start();
 }
 
 /**
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index dced37e186ad..35f827def633 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -3085,7 +3085,7 @@ void ScDocShell::SetDrawModified()
         m_pDocument->UpdateChartListenerCollection();
         SfxGetpApp()->Broadcast(SfxHint( SfxHintId::ScDrawChanged ));    // 
Navigator
     }
-    ScModule::get()->AnythingChanged();
+    ScDocument::EnsureIdleUpdate();
 }
 
 void ScDocShell::SetInUndo(bool bSet)
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index eac8888919d9..7de7ba683661 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -5284,8 +5284,11 @@ void ScGridWindow::UpdateFormulas(SCCOL nX1, SCROW nY1, 
SCCOL nX2, SCROW nY2)
     {
         // Do not start, switched to paint
         //  (then at least the MapMode would no longer be right)
-
-        bNeedsRepaint = true;           // -> at end of paint run Invalidate 
on all
+        if (!bNeedsRepaint)
+        {
+            bNeedsRepaint = true;           // -> at end of paint run 
Invalidate on all
+            ScDocument::EnsureIdleUpdate();
+        }
         aRepaintPixel = tools::Rectangle();    // All
         return;
     }
diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx
index ecd1302b4153..94100b7c6d94 100644
--- a/sc/source/ui/view/gridwin4.cxx
+++ b/sc/source/ui/view/gridwin4.cxx
@@ -380,6 +380,7 @@ void ScGridWindow::Paint( vcl::RenderContext& 
/*rRenderContext*/, const tools::R
         {
             bNeedsRepaint = true;
             aRepaintPixel = LogicToPixel(rRect);    // only affected ranges
+            ScDocument::EnsureIdleUpdate();
         }
         return;
     }
diff --git a/sc/source/ui/view/tabview4.cxx b/sc/source/ui/view/tabview4.cxx
index 6dd77727d4a7..a7a4d7f64524 100644
--- a/sc/source/ui/view/tabview4.cxx
+++ b/sc/source/ui/view/tabview4.cxx
@@ -538,7 +538,7 @@ void ScTabView::UpdateScrollBars( HeaderType eHeaderType )
     if ( aViewData.IsActive() )
     {
         if (UpdateVisibleRange())
-            ScModule::get()->AnythingChanged(); // if visible area has changed
+            ScDocument::EnsureIdleUpdate(); // if visible area has changed
     }
 }
 

Reply via email to