[Libreoffice-commits] core.git: Branch 'feature/new-vcl-scheduler' - 72 commits - avmedia/source basctl/source connectivity/source cui/source cui/uiconfig dbaccess/source desktop/qa filter/source forms/source formula/source fpicker/source framework/source helpcompiler/source helpcontent2 hwpfilter/source i18nutil/source idlc/source idl/inc idl/source include/rtl include/svx include/vcl ios/experimental jvmfwk/plugins lotuswordpro/source officecfg/registry oox/source reportdesign/source rsc/source sal/cppunittester sc/inc sc/qa sc/source sd/qa sd/source sd/uiconfig sfx2/source shell/source solenv/bin solenv/gdb soltools/cpp soltools/mkdepend starmath/inc starmath/source svl/source svtools/source svx/source sw/inc sw/Library_sw.mk sw/qa sw/source sw/uiconfig toolkit/source tools/source vcl/headless vcl/inc vcl/Module_vcl.mk vcl/osx vcl/qa vcl/source vcl/unx vcl/win writerfilter/source xmloff/source xmlsecurity/source

Jan-Marek Glogowski glogow at fbihome.de
Thu Mar 23 14:35:11 UTC 2017


Rebased ref, commits from common ancestor:
commit c17f07713ce3bfd71d37380816b8722e4f664f57
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Wed Sep 14 18:17:18 2016 +0200

    Don't poll busy documents via idle task
    
    Creates a very busy idle-loop, for non-task work like mail merge.
    
    Change-Id: If7be82e4675008f23e6f4f6be5c40df40a231a8b

diff --git a/sw/source/core/doc/DocumentTimerManager.cxx b/sw/source/core/doc/DocumentTimerManager.cxx
index 83ce6fe2dce9..4a9855570bd6 100644
--- a/sw/source/core/doc/DocumentTimerManager.cxx
+++ b/sw/source/core/doc/DocumentTimerManager.cxx
@@ -40,44 +40,44 @@ namespace sw
 DocumentTimerManager::DocumentTimerManager( SwDoc& i_rSwdoc ) : m_rDoc( i_rSwdoc ),
                                                                 mbStartIdleTimer( false ),
                                                                 mIdleBlockCount( 0 ),
-                                                                maIdle("DocumentTimerManagerIdleTimer")
+                                                                maDocIdle( i_rSwdoc )
 {
-    maIdle.SetPriority( TaskPriority::LOWEST );
-    maIdle.SetInvokeHandler( LINK( this, DocumentTimerManager, DoIdleJobs) );
-    maIdle.SetDebugName( "sw::DocumentTimerManager maIdle" );
+    maDocIdle.SetPriority( TaskPriority::LOWEST );
+    maDocIdle.SetInvokeHandler( LINK( this, DocumentTimerManager, DoIdleJobs) );
+    maDocIdle.SetDebugName( "sw::DocumentTimerManager maDocIdle" );
 }
 
 void DocumentTimerManager::StartIdling()
 {
     mbStartIdleTimer = true;
     if( !mIdleBlockCount )
-        maIdle.Start();
+        maDocIdle.Start();
 }
 
 void DocumentTimerManager::StopIdling()
 {
     mbStartIdleTimer = false;
-    maIdle.Stop();
+    maDocIdle.Stop();
 }
 
 void DocumentTimerManager::BlockIdling()
 {
-    maIdle.Stop();
+    maDocIdle.Stop();
     ++mIdleBlockCount;
 }
 
 void DocumentTimerManager::UnblockIdling()
 {
     --mIdleBlockCount;
-    if( !mIdleBlockCount && mbStartIdleTimer && !maIdle.IsActive() )
-        maIdle.Start();
+    if( !mIdleBlockCount && mbStartIdleTimer && !maDocIdle.IsActive() )
+        maDocIdle.Start();
 }
 
 void DocumentTimerManager::StartBackgroundJobs()
 {
     // Trigger DoIdleJobs(), asynchronously.
-    if (!maIdle.IsActive()) //fdo#73165 if the timer is already running don't restart from 0
-        maIdle.Start();
+    if (!maDocIdle.IsActive()) //fdo#73165 if the timer is already running don't restart from 0
+        maDocIdle.Start();
 }
 
 IMPL_LINK( DocumentTimerManager, DoIdleJobs, Timer*, pIdle, void )
@@ -96,10 +96,7 @@ IMPL_LINK( DocumentTimerManager, DoIdleJobs, Timer*, pIdle, void )
         for(SwViewShell& rSh : pShell->GetRingContainer())
         {
             if( rSh.ActionPend() )
-            {
-                pIdle->Start();
                 return;
-            }
         }
 
         if( pTmpRoot->IsNeedGrammarCheck() )
@@ -119,9 +116,7 @@ IMPL_LINK( DocumentTimerManager, DoIdleJobs, Timer*, pIdle, void )
             if ((*pLayIter)->IsIdleFormat())
             {
                 (*pLayIter)->GetCurrShell()->LayoutIdle();
-
                 // Defer the remaining work.
-                pIdle->Start();
                 return;
             }
         }
@@ -135,11 +130,8 @@ IMPL_LINK( DocumentTimerManager, DoIdleJobs, Timer*, pIdle, void )
                 /* && !pStartSh->GetViewOptions()->IsFieldName()*/ )
         {
             if ( m_rDoc.getIDocumentFieldsAccess().GetUpdateFields().IsInUpdateFields() ||
-                 m_rDoc.getIDocumentFieldsAccess().IsExpFieldsLocked() )
-            {
-                pIdle->Start();
+                      m_rDoc.getIDocumentFieldsAccess().IsExpFieldsLocked() )
                 return;
-            }
 
             //  Action brackets!
             m_rDoc.getIDocumentFieldsAccess().GetUpdateFields().SetInUpdateFields( true );
@@ -167,6 +159,7 @@ IMPL_LINK( DocumentTimerManager, DoIdleJobs, Timer*, pIdle, void )
     if( pModLogFile && 1 != (long)pModLogFile )
         delete pModLogFile, static_cast<long&>(pModLogFile) = 1;
 #endif
+    pIdle->Stop();
 }
 
 DocumentTimerManager::~DocumentTimerManager() {}
diff --git a/sw/source/core/inc/DocumentTimerManager.hxx b/sw/source/core/inc/DocumentTimerManager.hxx
index da4b9e4b30fd..698762ab087e 100644
--- a/sw/source/core/inc/DocumentTimerManager.hxx
+++ b/sw/source/core/inc/DocumentTimerManager.hxx
@@ -21,8 +21,8 @@
 #define INCLUDED_SW_SOURCE_CORE_INC_DOCUMENTTIMERMANAGER_HXX
 
 #include <IDocumentTimerAccess.hxx>
+#include <SwDocIdle.hxx>
 
-#include <vcl/idle.hxx>
 #include <sal/types.h>
 #include <tools/link.hxx>
 
@@ -47,7 +47,6 @@ public:
 
     void StartBackgroundJobs() override;
 
-    // Our own 'IdleTimer' calls the following method
     DECL_LINK( DoIdleJobs, Timer *, void );
 
     virtual ~DocumentTimerManager() override;
@@ -61,7 +60,7 @@ private:
 
     bool mbStartIdleTimer; //< idle timer mode start/stop
     sal_Int32 mIdleBlockCount;
-    Idle  maIdle;
+    SwDocIdle maDocIdle;
 };
 
 }
commit 786cf0d8f05160d1d98e3f491b9c378e80bae98c
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Sun Jul 31 16:35:49 2016 +0200

    Don't update document stats for non-idle views
    
    This functionality should be merged into the DocumentTimerManager,
    which itself should run the different document idle tasks via
    seperate jobs instead of a single idle, if they don't depend on
    each other.
    
    To implement a non-busy, suspendable Idle, this adds an AutoIdle
    class, which is automatically re-scheduled after being processed.
    
    It also adds a SwDocIdle, which isn't ready to schedule for busy
    documents.
    
    Change-Id: I185137ed3423ecaae0f7edb39018d26c4244d359

diff --git a/sw/Library_sw.mk b/sw/Library_sw.mk
index 811c8c629ef6..9c1363063fc4 100644
--- a/sw/Library_sw.mk
+++ b/sw/Library_sw.mk
@@ -159,6 +159,7 @@ $(eval $(call gb_Library_add_exception_objects,sw,\
     sw/source/core/crsr/trvltbl \
     sw/source/core/crsr/viscrs \
     sw/source/core/crsr/overlayrangesoutline \
+    sw/source/core/doc/SwDocIdle \
     sw/source/core/doc/SwStyleNameMapper \
     sw/source/core/doc/acmplwrd \
     sw/source/core/doc/CntntIdxStore \
diff --git a/sw/inc/SwDocIdle.hxx b/sw/inc/SwDocIdle.hxx
new file mode 100644
index 000000000000..6bc65e24766c
--- /dev/null
+++ b/sw/inc/SwDocIdle.hxx
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_SW_INC_SWDOCIDLE_HXX
+#define INCLUDED_SW_INC_SWDOCIDLE_HXX
+
+#include <doc.hxx>
+#include <vcl/idle.hxx>
+
+namespace sw {
+
+/**
+ * An Idle, which is just ready to be scheduled for idle documents.
+ *
+ * Currently it's missing the notification, when busy documents become idle
+ * again, so it relies on any task being triggered to recheck, which is
+ * quite probably not a problem, as busy documents have a high chance to have
+ * generated idle tasks.
+ */
+class SwDocIdle : public AutoIdle
+{
+private:
+    SwDoc &m_rDoc;
+
+protected:
+    virtual sal_uInt64 UpdateMinPeriod(
+        sal_uInt64 nMinPeriod, sal_uInt64 nTimeNow ) const override;
+
+public:
+    SwDocIdle( SwDoc &doc );
+    virtual ~SwDocIdle() override;
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/doc/DocumentStatisticsManager.cxx b/sw/source/core/doc/DocumentStatisticsManager.cxx
index f529d5483417..9d050e0c77a0 100644
--- a/sw/source/core/doc/DocumentStatisticsManager.cxx
+++ b/sw/source/core/doc/DocumentStatisticsManager.cxx
@@ -34,6 +34,8 @@
 #include <vector>
 #include <viewsh.hxx>
 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <wrtsh.hxx>
+#include <viewopt.hxx>
 
 using namespace ::com::sun::star;
 
@@ -71,12 +73,13 @@ namespace sw
 
 DocumentStatisticsManager::DocumentStatisticsManager( SwDoc& i_rSwdoc ) : m_rDoc( i_rSwdoc ),
                                                                           mpDocStat( new SwDocStat ),
-                                                                          mbInitialized( false )
+                                                                          mbInitialized( false ),
+                                                                          maStatsUpdateIdle( i_rSwdoc )
+
 {
-    maStatsUpdateTimer.SetTimeout( 1 );
-    maStatsUpdateTimer.SetPriority( TaskPriority::LOWEST );
-    maStatsUpdateTimer.SetInvokeHandler( LINK( this, DocumentStatisticsManager, DoIdleStatsUpdate ) );
-    maStatsUpdateTimer.SetDebugName( "sw::DocumentStatisticsManager maStatsUpdateTimer" );
+    maStatsUpdateIdle.SetPriority( TaskPriority::LOWEST );
+    maStatsUpdateIdle.SetInvokeHandler( LINK( this, DocumentStatisticsManager, DoIdleStatsUpdate ) );
+    maStatsUpdateIdle.SetDebugName( "sw::DocumentStatisticsManager maStatsUpdateIdle" );
 }
 
 void DocumentStatisticsManager::DocInfoChgd(bool const isEnableSetModified)
@@ -120,14 +123,15 @@ void DocumentStatisticsManager::UpdateDocStat( bool bCompleteAsync, bool bFields
     {
         if (!bCompleteAsync)
         {
+            maStatsUpdateIdle.Stop();
             while (IncrementalDocStatCalculate(
                         std::numeric_limits<long>::max(), bFields)) {}
-            maStatsUpdateTimer.Stop();
         }
-        else if (IncrementalDocStatCalculate(5000, bFields))
-            maStatsUpdateTimer.Start();
         else
-            maStatsUpdateTimer.Stop();
+        {
+            if (!maStatsUpdateIdle.IsActive() && IncrementalDocStatCalculate(5000, bFields))
+                maStatsUpdateIdle.Start();
+        }
     }
 }
 
@@ -178,7 +182,7 @@ bool DocumentStatisticsManager::IncrementalDocStatCalculate(long nChars, bool bF
     }
 
     mpDocStat->nPage     = m_rDoc.getIDocumentLayoutAccess().GetCurrentLayout() ? m_rDoc.getIDocumentLayoutAccess().GetCurrentLayout()->GetPageNum() : 0;
-    mpDocStat->bModified = false;
+    SetDocStatModified( false );
 
     css::uno::Sequence < css::beans::NamedValue > aStat( mpDocStat->nPage ? 8 : 7);
     sal_Int32 n=0;
@@ -233,11 +237,10 @@ bool DocumentStatisticsManager::IncrementalDocStatCalculate(long nChars, bool bF
     return nChars < 0;
 }
 
-IMPL_LINK_NOARG( DocumentStatisticsManager, DoIdleStatsUpdate, Timer *, void )
+IMPL_LINK( DocumentStatisticsManager, DoIdleStatsUpdate, Timer *, pIdle, void )
 {
-    if (IncrementalDocStatCalculate(32000))
-        maStatsUpdateTimer.Start();
-
+    if (!IncrementalDocStatCalculate(32000))
+        pIdle->Stop();
     SwView* pView = m_rDoc.GetDocShell() ? m_rDoc.GetDocShell()->GetView() : nullptr;
     if( pView )
         pView->UpdateDocStats();
@@ -245,7 +248,7 @@ IMPL_LINK_NOARG( DocumentStatisticsManager, DoIdleStatsUpdate, Timer *, void )
 
 DocumentStatisticsManager::~DocumentStatisticsManager()
 {
-    maStatsUpdateTimer.Stop();
+    maStatsUpdateIdle.Stop();
     delete mpDocStat;
 }
 
diff --git a/sw/source/core/doc/SwDocIdle.cxx b/sw/source/core/doc/SwDocIdle.cxx
new file mode 100644
index 000000000000..9461807943d8
--- /dev/null
+++ b/sw/source/core/doc/SwDocIdle.cxx
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <view.hxx>
+#include <wrtsh.hxx>
+#include <docsh.hxx>
+#include <viewopt.hxx>
+#include <vcl/scheduler.hxx>
+
+#include "SwDocIdle.hxx"
+
+namespace sw
+{
+
+sal_uInt64 SwDocIdle::UpdateMinPeriod( sal_uInt64 /* nMinPeriod */, sal_uInt64 /* nTimeNow */ ) const
+{
+    bool bReadyForSchedule = true;
+    SwView* pView = m_rDoc.GetDocShell() ? m_rDoc.GetDocShell()->GetView() : nullptr;
+    if( pView )
+    {
+        SwWrtShell& rWrtShell = pView->GetWrtShell();
+        bReadyForSchedule = rWrtShell.GetViewOptions()->IsIdle();
+    }
+    return bReadyForSchedule
+        ? Scheduler::ImmediateTimeoutMs : Scheduler::InfiniteTimeoutMs;
+}
+
+SwDocIdle::SwDocIdle( SwDoc &doc )
+    : m_rDoc( doc )
+{
+}
+
+SwDocIdle::~SwDocIdle()
+{
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/inc/DocumentStatisticsManager.hxx b/sw/source/core/inc/DocumentStatisticsManager.hxx
index b21e8ec9ef99..41b961f9cae5 100644
--- a/sw/source/core/inc/DocumentStatisticsManager.hxx
+++ b/sw/source/core/inc/DocumentStatisticsManager.hxx
@@ -20,11 +20,10 @@
 #define INCLUDED_SW_SOURCE_CORE_INC_DOCUMENTSTATISTICSMANAGER_HXX
 
 #include <IDocumentStatistics.hxx>
-#include <vcl/timer.hxx>
+#include <SwDocIdle.hxx>
 
 class SwDoc;
 struct SwDocStat;
-class Timer;
 
 namespace sw {
 
@@ -61,10 +60,9 @@ private:
     // Our own 'StatsUpdateTimer' calls the following method
     DECL_LINK( DoIdleStatsUpdate, Timer *, void );
 
-
-    SwDocStat       *mpDocStat;          //< Statistics information.
-    bool            mbInitialized;       // allow first time update
-    Timer       maStatsUpdateTimer;      //< Timer for asynchronous stats calculation
+    SwDocStat       *mpDocStat;          //< Statistics information
+    bool             mbInitialized;      //< allow first time update
+    SwDocIdle        maStatsUpdateIdle;  //< Idle for asynchronous stats calculation
 };
 
 }
commit b5181407ef07a305da468d9a0a9b8ff593a279b0
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Wed Aug 10 12:00:53 2016 +0200

    Reorganize Scheduler priority classes
    
    This is based on glibs classification of tasks, but while glib uses
    an int for more fine grained priority, we stay with our enum.
    
    1. Timers start with DEFAULT priority, which directly corresponds
       with the previous HIGH priority
    2. Idles start with DEFAULT_IDLE priority instead of the previous
       HIGH priority, so idle default becomes "really run when idle".
    
    As RESIZE and REPAINT are special, and the DEFAULTS are set, there
    is just one primary decision for the programmer: should my idle
    run before paint (AKA HIGH_IDLE)?
    
    If we really need a more fine-grained classification, we can add it
    later, or also switch to a real int. As a result, this drops many
    classifications from the code and drastically changes behaviour,
    AKA a mail merge from KDE is now as fast as Gtk+ again.
    
    Change-Id: I498a73fd02d5fb6f5d7e9f742f3bce972de9b1f9

diff --git a/avmedia/source/framework/mediacontrol.cxx b/avmedia/source/framework/mediacontrol.cxx
index 18d4f5599618..c44a12fd872c 100644
--- a/avmedia/source/framework/mediacontrol.cxx
+++ b/avmedia/source/framework/mediacontrol.cxx
@@ -114,7 +114,7 @@ MediaControl::MediaControl( vcl::Window* pParent, MediaControlStyle eControlStyl
         mpZoomToolBox->SetPaintTransparent( true );
     }
 
-    maIdle.SetPriority( TaskPriority::LOW );
+    maIdle.SetPriority( TaskPriority::HIGH_IDLE );
     maIdle.SetInvokeHandler( LINK( this, MediaControl, implTimeoutHdl ) );
     maIdle.Start();
 }
diff --git a/avmedia/source/framework/soundhandler.cxx b/avmedia/source/framework/soundhandler.cxx
index 45f1b61132f7..a2ea3ed52ac0 100644
--- a/avmedia/source/framework/soundhandler.cxx
+++ b/avmedia/source/framework/soundhandler.cxx
@@ -221,7 +221,7 @@ void SAL_CALL SoundHandler::dispatchWithNotification(const css::util::URL&
         // Count this request and initialize self-holder against dying by uno ref count ...
         m_xSelfHold.set(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
         m_xPlayer->start();
-        m_aUpdateIdle.SetPriority( TaskPriority::LOWER );
+        m_aUpdateIdle.SetPriority( TaskPriority::HIGH_IDLE );
         m_aUpdateIdle.Start();
     }
     catch( css::uno::Exception& e )
diff --git a/avmedia/source/opengl/oglplayer.cxx b/avmedia/source/opengl/oglplayer.cxx
index 18b4e9437d66..b44f77de6caf 100644
--- a/avmedia/source/opengl/oglplayer.cxx
+++ b/avmedia/source/opengl/oglplayer.cxx
@@ -123,7 +123,7 @@ bool OGLPlayer::create( const OUString& rURL )
 
     // Set timer
     m_aTimer.SetTimeout(8); // is 125fps enough for anyone ?
-    m_aTimer.SetPriority(TaskPriority::LOW);
+    m_aTimer.SetPriority(TaskPriority::HIGH_IDLE);
     m_aTimer.SetInvokeHandler(LINK(this,OGLPlayer,TimerHandler));
 
     return true;
diff --git a/basctl/source/basicide/baside2b.cxx b/basctl/source/basicide/baside2b.cxx
index c02bac26d0f2..bdffe0152bed 100644
--- a/basctl/source/basicide/baside2b.cxx
+++ b/basctl/source/basicide/baside2b.cxx
@@ -960,7 +960,6 @@ void EditorWindow::CreateEditEngine()
 
     ImplSetFont();
 
-    aSyntaxIdle.SetPriority( TaskPriority::LOWER );
     aSyntaxIdle.SetInvokeHandler( LINK( this, EditorWindow, SyntaxTimerHdl ) );
 
     bool bWasDoSyntaxHighlight = bDoSyntaxHighlight;
diff --git a/basctl/source/dlged/dlged.cxx b/basctl/source/dlged/dlged.cxx
index ecdbdf540ad1..6568ac9e4ba7 100644
--- a/basctl/source/dlged/dlged.cxx
+++ b/basctl/source/dlged/dlged.cxx
@@ -217,7 +217,6 @@ DlgEditor::DlgEditor (
     m_ClipboardDataFlavorsResource[1].HumanPresentableName = "Dialog 8.0" ;
     m_ClipboardDataFlavorsResource[1].DataType =             cppu::UnoType<Sequence< sal_Int8 >>::get();
 
-    aMarkIdle.SetPriority(TaskPriority::LOW);
     aMarkIdle.SetInvokeHandler( LINK( this, DlgEditor, MarkTimeout ) );
 
     rWindow.SetMapMode( MapMode( MapUnit::Map100thMM ) );
diff --git a/cui/source/options/optjava.cxx b/cui/source/options/optjava.cxx
index f7a90976eb39..772db822eb49 100644
--- a/cui/source/options/optjava.cxx
+++ b/cui/source/options/optjava.cxx
@@ -186,7 +186,6 @@ SvxJavaOptionsPage::SvxJavaOptionsPage( vcl::Window* pParent, const SfxItemSet&
     m_pParameterBtn->SetClickHdl( LINK( this, SvxJavaOptionsPage, ParameterHdl_Impl ) );
     m_pClassPathBtn->SetClickHdl( LINK( this, SvxJavaOptionsPage, ClassPathHdl_Impl ) );
     m_aResetIdle.SetInvokeHandler( LINK( this, SvxJavaOptionsPage, ResetHdl_Impl ) );
-    m_aResetIdle.SetPriority(TaskPriority::LOWER);
 
     m_pExpertConfigBtn->SetClickHdl( LINK( this, SvxJavaOptionsPage, ExpertConfigHdl_Impl) );
     if (!officecfg::Office::Common::Security::EnableExpertConfiguration::get())
diff --git a/dbaccess/source/ui/querydesign/JoinTableView.cxx b/dbaccess/source/ui/querydesign/JoinTableView.cxx
index 6f383c341841..00676828f05b 100644
--- a/dbaccess/source/ui/querydesign/JoinTableView.cxx
+++ b/dbaccess/source/ui/querydesign/JoinTableView.cxx
@@ -1063,7 +1063,7 @@ void OJoinTableView::ScrollWhileDragging()
     // resetting timer, if still necessary
     if (bNeedScrollTimer)
     {
-        m_aDragScrollIdle.SetPriority(TaskPriority::LOW);
+        m_aDragScrollIdle.SetPriority( TaskPriority::HIGH_IDLE );
         m_aDragScrollIdle.Start();
     }
 
diff --git a/formula/source/ui/dlg/formula.cxx b/formula/source/ui/dlg/formula.cxx
index d795395884f7..a9e4ef33b0bc 100644
--- a/formula/source/ui/dlg/formula.cxx
+++ b/formula/source/ui/dlg/formula.cxx
@@ -1801,7 +1801,6 @@ OUString FormulaDlg::GetMeText() const
 void FormulaDlg::Update()
 {
     m_pImpl->Update();
-    m_pImpl->aIdle.SetPriority(TaskPriority::LOWER);
     m_pImpl->aIdle.SetInvokeHandler(LINK( this, FormulaDlg, UpdateFocusHdl));
     m_pImpl->aIdle.Start();
 }
diff --git a/formula/source/ui/dlg/funcutl.cxx b/formula/source/ui/dlg/funcutl.cxx
index 685381fadb1c..35c8312a17d1 100644
--- a/formula/source/ui/dlg/funcutl.cxx
+++ b/formula/source/ui/dlg/funcutl.cxx
@@ -409,7 +409,6 @@ RefEdit::RefEdit( vcl::Window* _pParent, vcl::Window* pShrinkModeLabel, WinBits
     , pLabelWidget(pShrinkModeLabel)
 {
     aIdle.SetInvokeHandler( LINK( this, RefEdit, UpdateHdl ) );
-    aIdle.SetPriority( TaskPriority::LOW );
 }
 
 VCL_BUILDER_DECL_FACTORY(RefEdit)
@@ -478,7 +477,6 @@ void RefEdit::SetReferences( IControlReferenceHandler* pDlg, vcl::Window* pLabel
     if( pDlg )
     {
         aIdle.SetInvokeHandler( LINK( this, RefEdit, UpdateHdl ) );
-        aIdle.SetPriority( TaskPriority::LOW );
     }
     else
     {
diff --git a/framework/source/layoutmanager/layoutmanager.cxx b/framework/source/layoutmanager/layoutmanager.cxx
index 1243f2d88205..3b64726de2e7 100644
--- a/framework/source/layoutmanager/layoutmanager.cxx
+++ b/framework/source/layoutmanager/layoutmanager.cxx
@@ -138,6 +138,7 @@ LayoutManager::LayoutManager( const Reference< XComponentContext >& xContext ) :
         m_xToolbarManager = new ToolbarLayoutManager( xContext, Reference<XUIElementFactory>(m_xUIElementFactoryManager, UNO_QUERY_THROW), this );
     }
 
+    m_aAsyncLayoutTimer.SetPriority( TaskPriority::HIGH_IDLE );
     m_aAsyncLayoutTimer.SetTimeout( 50 );
     m_aAsyncLayoutTimer.SetInvokeHandler( LINK( this, LayoutManager, AsyncLayoutHdl ) );
     m_aAsyncLayoutTimer.SetDebugName( "framework::LayoutManager m_aAsyncLayoutTimer" );
diff --git a/include/vcl/task.hxx b/include/vcl/task.hxx
index 573ee5db92d1..c955fb812e7f 100644
--- a/include/vcl/task.hxx
+++ b/include/vcl/task.hxx
@@ -29,16 +29,14 @@ struct ImplSchedulerData;
 
 enum class TaskPriority
 {
-    HIGHEST      = 0,
-    HIGH         = 1,
-    RESIZE       = 2,
-    REPAINT      = 3,
-    MEDIUM       = 3,
-    POST_PAINT   = 4,
-    DEFAULT_IDLE = 5,
-    LOW          = 6,
-    LOWER        = 7,
-    LOWEST       = 8
+    HIGHEST,       ///< These events should run very fast!
+    DEFAULT,       ///< Default priority used, e.g. the default timer priority
+    HIGH_IDLE,     ///< Important idle events to be run before processing drawing events
+    RESIZE,        ///< Resize runs before repaint, so we won't paint twice
+    REPAINT,       ///< All repaint events should go in here
+    POST_PAINT,    ///< Everything running directly after painting
+    DEFAULT_IDLE,  ///< Default idle priority
+    LOWEST         ///< Low, very idle cleanup tasks
 };
 
 class VCL_DLLPUBLIC Task
diff --git a/reportdesign/source/ui/report/DesignView.cxx b/reportdesign/source/ui/report/DesignView.cxx
index 177d87daa111..b441ab436eab 100644
--- a/reportdesign/source/ui/report/DesignView.cxx
+++ b/reportdesign/source/ui/report/DesignView.cxx
@@ -116,7 +116,6 @@ ODesignView::ODesignView(   vcl::Window* pParent,
     m_aSplitWin->SetAlign(WindowAlign::Left);
     m_aSplitWin->Show();
 
-    m_aMarkIdle.SetPriority( TaskPriority::LOW );
     m_aMarkIdle.SetInvokeHandler( LINK( this, ODesignView, MarkTimeout ) );
 }
 
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index d9149ff1788f..217f076a2f62 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -250,7 +250,6 @@ ScDocument::ScDocument( ScDocumentMode eMode, SfxObjectShell* pDocShell ) :
     SetLanguage( ScGlobal::eLnge, ScGlobal::eLnge, ScGlobal::eLnge );
 
     aTrackIdle.SetInvokeHandler( LINK( this, ScDocument, TrackTimeHdl ) );
-    aTrackIdle.SetPriority( TaskPriority::LOW );
 }
 
 sfx2::LinkManager* ScDocument::GetLinkManager()
diff --git a/sc/source/ui/app/scmod.cxx b/sc/source/ui/app/scmod.cxx
index 580c34ac906c..c67b70e4ed5f 100644
--- a/sc/source/ui/app/scmod.cxx
+++ b/sc/source/ui/app/scmod.cxx
@@ -179,7 +179,6 @@ ScModule::ScModule( SfxObjectFactory* pFact ) :
                                         ERRCODE_AREA_APP2-1,
                                         GetResMgr() );
 
-    aSpellIdle.SetPriority(TaskPriority::LOWER);
     aSpellIdle.SetInvokeHandler( LINK( this, ScModule, SpellTimerHdl ) );
     aSpellIdle.SetDebugName( "sc::ScModule aSpellIdle" );
 
diff --git a/sc/source/ui/miscdlgs/acredlin.cxx b/sc/source/ui/miscdlgs/acredlin.cxx
index ac5d9b5ad413..81d841efa8ec 100644
--- a/sc/source/ui/miscdlgs/acredlin.cxx
+++ b/sc/source/ui/miscdlgs/acredlin.cxx
@@ -109,13 +109,11 @@ ScAcceptChgDlg::ScAcceptChgDlg(SfxBindings* pB, SfxChildWindow* pCW, vcl::Window
     m_pAcceptChgCtr = VclPtr<SvxAcceptChgCtr>::Create(get_content_area(), this);
     nAcceptCount=0;
     nRejectCount=0;
-    aReOpenIdle.SetPriority(TaskPriority::MEDIUM);
     aReOpenIdle.SetInvokeHandler(LINK( this, ScAcceptChgDlg, ReOpenTimerHdl ));
 
     pTPFilter=m_pAcceptChgCtr->GetFilterPage();
     pTPView=m_pAcceptChgCtr->GetViewPage();
     pTheView=pTPView->GetTableControl();
-    aSelectionIdle.SetPriority(TaskPriority::LOW);
     aSelectionIdle.SetInvokeHandler(LINK( this, ScAcceptChgDlg, UpdateSelectionHdl ));
     aSelectionIdle.SetDebugName( "ScAcceptChgDlg  aSelectionIdle" );
 
diff --git a/sc/source/ui/miscdlgs/anyrefdg.cxx b/sc/source/ui/miscdlgs/anyrefdg.cxx
index 54425e0fee65..611aea256004 100644
--- a/sc/source/ui/miscdlgs/anyrefdg.cxx
+++ b/sc/source/ui/miscdlgs/anyrefdg.cxx
@@ -764,7 +764,6 @@ ScRefHandler::ScRefHandler( vcl::Window &rWindow, SfxBindings* pB, bool bBindRef
         pActiveWin(nullptr)
 {
     m_aHelper.SetWindow(m_rWindow.get());
-    aIdle.SetPriority(TaskPriority::LOWER);
     aIdle.SetInvokeHandler(LINK( this, ScRefHandler, UpdateFocusHdl));
 
     if( bBindRef ) EnterRefMode();
diff --git a/sc/source/ui/miscdlgs/conflictsdlg.cxx b/sc/source/ui/miscdlgs/conflictsdlg.cxx
index a6c7104e9271..772f3a893493 100644
--- a/sc/source/ui/miscdlgs/conflictsdlg.cxx
+++ b/sc/source/ui/miscdlgs/conflictsdlg.cxx
@@ -421,7 +421,6 @@ ScConflictsDlg::ScConflictsDlg( vcl::Window* pParent, ScViewData* pViewData, ScD
     m_pLbConflicts->SetSelectionMode( SelectionMode::Multiple );
     m_pLbConflicts->SetHighlightRange();
 
-    maSelectionIdle.SetPriority( TaskPriority::LOW );
     maSelectionIdle.SetInvokeHandler( LINK( this, ScConflictsDlg, UpdateSelectionHdl ) );
     maSelectionIdle.SetDebugName( "ScConflictsDlg maSelectionIdle" );
 
diff --git a/sd/source/ui/dlg/filedlg.cxx b/sd/source/ui/dlg/filedlg.cxx
index 7799458da69f..d97cf7923133 100644
--- a/sd/source/ui/dlg/filedlg.cxx
+++ b/sd/source/ui/dlg/filedlg.cxx
@@ -130,7 +130,6 @@ IMPL_LINK_NOARG(SdFileDialog_Imp, PlayMusicHdl, void*, void)
             {
                 mxPlayer.set( avmedia::MediaWindow::createPlayer( aUrl, "" ), css::uno::UNO_QUERY_THROW );
                 mxPlayer->start();
-                maUpdateIdle.SetPriority( TaskPriority::LOW );
                 maUpdateIdle.Start();
             }
             catch (const css::uno::Exception&)
diff --git a/sd/source/ui/framework/module/ShellStackGuard.cxx b/sd/source/ui/framework/module/ShellStackGuard.cxx
index 2372158fe950..79171d026bd2 100644
--- a/sd/source/ui/framework/module/ShellStackGuard.cxx
+++ b/sd/source/ui/framework/module/ShellStackGuard.cxx
@@ -72,7 +72,6 @@ ShellStackGuard::ShellStackGuard (Reference<frame::XController>& rxController)
 
         // Prepare the printer polling.
         maPrinterPollingIdle.SetInvokeHandler(LINK(this,ShellStackGuard,TimeoutHandler));
-        maPrinterPollingIdle.SetPriority(TaskPriority::LOWER);
     }
 }
 
diff --git a/sd/source/ui/view/sdview.cxx b/sd/source/ui/view/sdview.cxx
index 34d3ae3cf4bc..f9069f44624b 100644
--- a/sd/source/ui/view/sdview.cxx
+++ b/sd/source/ui/view/sdview.cxx
@@ -143,9 +143,7 @@ View::View(SdDrawDocument& rDrawDoc, OutputDevice* pOutDev,
 
     // Timer for delayed drop (has to be for MAC)
     maDropErrorIdle.SetInvokeHandler( LINK(this, View, DropErrorHdl) );
-    maDropErrorIdle.SetPriority(TaskPriority::MEDIUM);
     maDropInsertFileIdle.SetInvokeHandler( LINK(this, View, DropInsertFileHdl) );
-    maDropInsertFileIdle.SetPriority(TaskPriority::MEDIUM);
 }
 
 void View::ImplClearDrawDropMarker()
diff --git a/sfx2/source/appl/appcfg.cxx b/sfx2/source/appl/appcfg.cxx
index 03ae9db916aa..9fba4de005c7 100644
--- a/sfx2/source/appl/appcfg.cxx
+++ b/sfx2/source/appl/appcfg.cxx
@@ -109,7 +109,7 @@ SfxEventAsyncer_Impl::SfxEventAsyncer_Impl( const SfxEventHint& rHint )
         StartListening( *rHint.GetObjShell() );
     pIdle.reset( new Idle("SfxEventASyncer") );
     pIdle->SetInvokeHandler( LINK(this, SfxEventAsyncer_Impl, IdleHdl) );
-    pIdle->SetPriority( TaskPriority::HIGHEST );
+    pIdle->SetPriority( TaskPriority::HIGH_IDLE );
     pIdle->SetDebugName( "sfx::SfxEventAsyncer_Impl pIdle" );
     pIdle->Start();
 }
diff --git a/sfx2/source/appl/newhelp.cxx b/sfx2/source/appl/newhelp.cxx
index 1ac1ce28c709..92f2c40a4651 100644
--- a/sfx2/source/appl/newhelp.cxx
+++ b/sfx2/source/appl/newhelp.cxx
@@ -551,7 +551,6 @@ IndexTabPage_Impl::IndexTabPage_Impl(vcl::Window* pParent, SfxHelpIndexWindow_Im
 
     m_pOpenBtn->SetClickHdl( LINK( this, IndexTabPage_Impl, OpenHdl ) );
     aFactoryIdle.SetInvokeHandler( LINK(this, IndexTabPage_Impl, IdleHdl ));
-    aFactoryIdle.SetPriority(TaskPriority::LOWER);
     aKeywordTimer.SetInvokeHandler( LINK( this, IndexTabPage_Impl, TimeoutHdl ) );
 }
 
@@ -1431,7 +1430,6 @@ SfxHelpIndexWindow_Impl::SfxHelpIndexWindow_Impl(SfxHelpWindow_Impl* _pParent)
     nMinWidth = ( m_pActiveLB->GetSizePixel().Width() / 2 );
 
     aIdle.SetInvokeHandler( LINK( this, SfxHelpIndexWindow_Impl, InitHdl ) );
-    aIdle.SetPriority( TaskPriority::LOWER );
     aIdle.Start();
 
     Show();
diff --git a/sfx2/source/control/dispatch.cxx b/sfx2/source/control/dispatch.cxx
index f6d19173b3c7..09d9cc6d89a5 100644
--- a/sfx2/source/control/dispatch.cxx
+++ b/sfx2/source/control/dispatch.cxx
@@ -450,7 +450,7 @@ void SfxDispatcher::Construct_Impl()
 
     xImp->xPoster = new SfxHintPoster(aGenLink);
 
-    xImp->aIdle.SetPriority(TaskPriority::MEDIUM);
+    xImp->aIdle.SetPriority(TaskPriority::HIGH_IDLE );
     xImp->aIdle.SetInvokeHandler( LINK(this, SfxDispatcher, EventHdl_Impl ) );
     xImp->aIdle.SetDebugName( "sfx::SfxDispatcher_Impl aIdle" );
 }
@@ -574,8 +574,6 @@ void SfxDispatcher::Pop(SfxShell& rShell, SfxDispatcherPopFlags nMode)
     if(!pSfxApp->IsDowning() && !xImp->aToDoStack.empty())
     {
         // No immediate update is requested
-        xImp->aIdle.SetPriority(TaskPriority::MEDIUM);
-        xImp->aIdle.SetInvokeHandler( LINK(this, SfxDispatcher, EventHdl_Impl ) );
         xImp->aIdle.Start();
     }
     else
@@ -770,8 +768,6 @@ void SfxDispatcher::DoActivate_Impl(bool bMDI)
     if(!xImp->aToDoStack.empty())
     {
         // No immediate update is requested
-        xImp->aIdle.SetPriority(TaskPriority::MEDIUM);
-        xImp->aIdle.SetInvokeHandler( LINK(this, SfxDispatcher, EventHdl_Impl ) );
         xImp->aIdle.Start();
     }
 }
diff --git a/svtools/source/contnr/imivctl1.cxx b/svtools/source/contnr/imivctl1.cxx
index 40933e230955..e0d599cb4e5a 100644
--- a/svtools/source/contnr/imivctl1.cxx
+++ b/svtools/source/contnr/imivctl1.cxx
@@ -143,7 +143,7 @@ SvxIconChoiceCtrl_Impl::SvxIconChoiceCtrl_Impl(
     aEditIdle.SetInvokeHandler(LINK(this,SvxIconChoiceCtrl_Impl,EditTimeoutHdl));
     aEditIdle.SetDebugName( "svtools::SvxIconChoiceCtrl_Impl aEditIdle" );
 
-    aAutoArrangeIdle.SetPriority( TaskPriority::LOW );
+    aAutoArrangeIdle.SetPriority( TaskPriority::HIGH_IDLE );
     aAutoArrangeIdle.SetInvokeHandler(LINK(this,SvxIconChoiceCtrl_Impl,AutoArrangeHdl));
     aAutoArrangeIdle.SetDebugName( "svtools::SvxIconChoiceCtrl_Impl aAutoArrangeIdle" );
 
@@ -151,11 +151,11 @@ SvxIconChoiceCtrl_Impl::SvxIconChoiceCtrl_Impl(
     aCallSelectHdlIdle.SetInvokeHandler( LINK(this,SvxIconChoiceCtrl_Impl,CallSelectHdlHdl));
     aCallSelectHdlIdle.SetDebugName( "svtools::SvxIconChoiceCtrl_Impl aCallSelectHdlIdle" );
 
-    aDocRectChangedIdle.SetPriority( TaskPriority::MEDIUM );
+    aDocRectChangedIdle.SetPriority( TaskPriority::HIGH_IDLE );
     aDocRectChangedIdle.SetInvokeHandler(LINK(this,SvxIconChoiceCtrl_Impl,DocRectChangedHdl));
     aDocRectChangedIdle.SetDebugName( "svtools::SvxIconChoiceCtrl_Impl aDocRectChangedIdle" );
 
-    aVisRectChangedIdle.SetPriority( TaskPriority::MEDIUM );
+    aVisRectChangedIdle.SetPriority( TaskPriority::HIGH_IDLE );
     aVisRectChangedIdle.SetInvokeHandler(LINK(this,SvxIconChoiceCtrl_Impl,VisRectChangedHdl));
     aVisRectChangedIdle.SetDebugName( "svtools::SvxIconChoiceCtrl_Impl aVisRectChangedIdle" );
 
diff --git a/svx/source/dialog/_contdlg.cxx b/svx/source/dialog/_contdlg.cxx
index 4ae00bfa5624..41616ad74463 100644
--- a/svx/source/dialog/_contdlg.cxx
+++ b/svx/source/dialog/_contdlg.cxx
@@ -286,7 +286,6 @@ SvxSuperContourDlg::SvxSuperContourDlg(SfxBindings *_pBindings, SfxChildWindow *
 
     Resize();
 
-    aUpdateIdle.SetPriority( TaskPriority::LOW );
     aUpdateIdle.SetInvokeHandler( LINK( this, SvxSuperContourDlg, UpdateHdl ) );
 
     aCreateIdle.SetPriority( TaskPriority::RESIZE );
diff --git a/svx/source/dialog/imapdlg.cxx b/svx/source/dialog/imapdlg.cxx
index dcd1e5242e95..2b8def32b699 100644
--- a/svx/source/dialog/imapdlg.cxx
+++ b/svx/source/dialog/imapdlg.cxx
@@ -204,7 +204,6 @@ SvxIMapDlg::SvxIMapDlg(SfxBindings *_pBindings, SfxChildWindow *pCW, vcl::Window
     m_pCbbTarget->Disable();
     pOwnData->bExecState = false;
 
-    pOwnData->aIdle.SetPriority( TaskPriority::LOW );
     pOwnData->aIdle.SetInvokeHandler( LINK( this, SvxIMapDlg, UpdateHdl ) );
 
     m_pTbxIMapDlg1->EnableItem( mnActiveId, false );
diff --git a/svx/source/sdr/contact/objectcontactofpageview.cxx b/svx/source/sdr/contact/objectcontactofpageview.cxx
index 0e81e850a727..a2847646dd6a 100644
--- a/svx/source/sdr/contact/objectcontactofpageview.cxx
+++ b/svx/source/sdr/contact/objectcontactofpageview.cxx
@@ -61,7 +61,7 @@ namespace sdr
             setPreviewRenderer(((SdrPaintView&)rPageWindow.GetPageView().GetView()).IsPreviewRenderer());
 
             // init timer
-            SetPriority(TaskPriority::HIGH);
+            SetPriority(TaskPriority::HIGH_IDLE);
             Stop();
         }
 
diff --git a/svx/source/sdr/contact/viewobjectcontactofpageobj.cxx b/svx/source/sdr/contact/viewobjectcontactofpageobj.cxx
index dfe57ea6e18b..6a4756c21a14 100644
--- a/svx/source/sdr/contact/viewobjectcontactofpageobj.cxx
+++ b/svx/source/sdr/contact/viewobjectcontactofpageobj.cxx
@@ -84,7 +84,7 @@ PagePrimitiveExtractor::PagePrimitiveExtractor(
     setPreviewRenderer(true);
 
     // init timer
-    SetPriority(TaskPriority::HIGH);
+    SetPriority(TaskPriority::HIGH_IDLE);
     Stop();
 }
 
diff --git a/svx/source/sdr/event/eventhandler.cxx b/svx/source/sdr/event/eventhandler.cxx
index 9511c623a1a2..8d0e29592c92 100644
--- a/svx/source/sdr/event/eventhandler.cxx
+++ b/svx/source/sdr/event/eventhandler.cxx
@@ -81,7 +81,7 @@ namespace sdr
 
         TimerEventHandler::TimerEventHandler()
         {
-            SetPriority(TaskPriority::HIGH);
+            SetPriority(TaskPriority::HIGH_IDLE);
             Stop();
         }
 
diff --git a/svx/source/svdraw/svdibrow.cxx b/svx/source/svdraw/svdibrow.cxx
index 41407b648f61..e848fb66f6ea 100644
--- a/svx/source/svdraw/svdibrow.cxx
+++ b/svx/source/svdraw/svdibrow.cxx
@@ -1100,7 +1100,7 @@ void SdrItemBrowser::SetDirty()
 {
     if (!bDirty) {
         bDirty = true;
-        aIdle.SetPriority(TaskPriority::HIGH);
+        aIdle.SetPriority(TaskPriority::HIGH_IDLE);
         aIdle.Start();
     }
 }
diff --git a/svx/source/tbxctrls/grafctrl.cxx b/svx/source/tbxctrls/grafctrl.cxx
index 9a8e4e419ab5..34642fb25d1a 100644
--- a/svx/source/tbxctrls/grafctrl.cxx
+++ b/svx/source/tbxctrls/grafctrl.cxx
@@ -121,7 +121,6 @@ ImplGrafMetricField::ImplGrafMetricField( vcl::Window* pParent, const OUString&
         SetSpinSize( 1 );
     }
 
-    maIdle.SetPriority( TaskPriority::LOW );
     maIdle.SetInvokeHandler( LINK( this, ImplGrafMetricField, ImplModifyHdl ) );
 }
 
diff --git a/sw/source/uibase/docvw/srcedtw.cxx b/sw/source/uibase/docvw/srcedtw.cxx
index 71922d57bfe8..24eadb595cea 100644
--- a/sw/source/uibase/docvw/srcedtw.cxx
+++ b/sw/source/uibase/docvw/srcedtw.cxx
@@ -534,7 +534,6 @@ void SwSrcEditWindow::CreateTextEngine()
     m_pOutWin->SetFont( aFont );
     m_pTextEngine->SetFont( aFont );
 
-    m_aSyntaxIdle.SetPriority( TaskPriority::LOWER );
     m_aSyntaxIdle.SetInvokeHandler( LINK( this, SwSrcEditWindow, SyntaxTimerHdl ) );
 
     m_pTextEngine->EnableUndo( true );
diff --git a/sw/source/uibase/utlui/unotools.cxx b/sw/source/uibase/utlui/unotools.cxx
index 260a02176a07..89c7f3a80928 100644
--- a/sw/source/uibase/utlui/unotools.cxx
+++ b/sw/source/uibase/utlui/unotools.cxx
@@ -83,7 +83,7 @@ SwOneExampleFrame::SwOneExampleFrame( vcl::Window& rWin,
 
     // the controller is asynchronously set
     aLoadedIdle.SetInvokeHandler(LINK(this, SwOneExampleFrame, TimeoutHdl));
-    aLoadedIdle.SetPriority(TaskPriority::HIGH);
+    aLoadedIdle.SetPriority(TaskPriority::HIGH_IDLE);
 
     CreateControl();
 
diff --git a/vcl/osx/salinst.cxx b/vcl/osx/salinst.cxx
index 13aa712a99ac..633ba4684c75 100644
--- a/vcl/osx/salinst.cxx
+++ b/vcl/osx/salinst.cxx
@@ -109,7 +109,6 @@ void AquaSalInstance::delayedSettingsChanged( bool bInvalidate )
 {
     osl::Guard< comphelper::SolarMutex > aGuard( *mpSalYieldMutex );
     AquaDelayedSettingsChanged* pIdle = new AquaDelayedSettingsChanged( bInvalidate );
-    pIdle->SetPriority( TaskPriority::MEDIUM );
     pIdle->Start();
 }
 
diff --git a/vcl/source/app/idle.cxx b/vcl/source/app/idle.cxx
index 78c114801868..0eca28c52306 100644
--- a/vcl/source/app/idle.cxx
+++ b/vcl/source/app/idle.cxx
@@ -42,8 +42,7 @@ void Idle::Start()
     {
         switch ( GetPriority() )
         {
-            case TaskPriority::LOW:
-            case TaskPriority::LOWER:
+            case TaskPriority::DEFAULT_IDLE:
             case TaskPriority::LOWEST:
                 nPeriod = Scheduler::InfiniteTimeoutMs;
                 break;
diff --git a/vcl/source/app/scheduler.cxx b/vcl/source/app/scheduler.cxx
index 25e43baf9b44..b8fcc6756f7f 100644
--- a/vcl/source/app/scheduler.cxx
+++ b/vcl/source/app/scheduler.cxx
@@ -474,7 +474,7 @@ Task::~Task()
 TaskImpl::TaskImpl( const sal_Char *pDebugName )
     : mpSchedulerData( nullptr )
     , mpDebugName( pDebugName )
-    , mePriority( TaskPriority::HIGH )
+    , mePriority( TaskPriority::DEFAULT )
     , mbActive( false )
 {
 }
diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx
index b31c0b9c7537..296dad56c6cd 100644
--- a/vcl/source/app/svapp.cxx
+++ b/vcl/source/app/svapp.cxx
@@ -461,7 +461,7 @@ void Application::Execute()
         pSVData->maAppData.mnEventTestLimit = 50;
         pSVData->maAppData.mpEventTestingIdle = new Idle("eventtesting");
         pSVData->maAppData.mpEventTestingIdle->SetInvokeHandler(LINK(&(pSVData->maAppData), ImplSVAppData, VclEventTestingHdl));
-        pSVData->maAppData.mpEventTestingIdle->SetPriority(TaskPriority::MEDIUM);
+        pSVData->maAppData.mpEventTestingIdle->SetPriority(TaskPriority::HIGH_IDLE);
         pSVData->maAppData.mpEventTestInput = new SvFileStream("eventtesting", StreamMode::READ);
         pSVData->maAppData.mpEventTestingIdle->Start();
     }
diff --git a/vcl/source/app/timer.cxx b/vcl/source/app/timer.cxx
index 6cba9e2f2b2f..f615c9f732e6 100644
--- a/vcl/source/app/timer.cxx
+++ b/vcl/source/app/timer.cxx
@@ -42,7 +42,7 @@ Timer::Timer( bool bAuto, const sal_Char *pDebugName )
     , mnTimeout( Scheduler::ImmediateTimeoutMs )
     , mbAuto( bAuto )
 {
-    SetPriority( TaskPriority::HIGHEST );
+    SetPriority( TaskPriority::DEFAULT );
 }
 
 Timer::Timer( const sal_Char *pDebugName )
diff --git a/vcl/source/edit/textdata.cxx b/vcl/source/edit/textdata.cxx
index 4705386be87e..e5de47c77b96 100644
--- a/vcl/source/edit/textdata.cxx
+++ b/vcl/source/edit/textdata.cxx
@@ -279,7 +279,7 @@ IdleFormatter::IdleFormatter()
 {
     mpView = nullptr;
     mnRestarts = 0;
-    SetPriority(TaskPriority::HIGH);
+    SetPriority(TaskPriority::HIGH_IDLE);
 }
 
 IdleFormatter::~IdleFormatter()
diff --git a/vcl/source/uitest/uno/uiobject_uno.cxx b/vcl/source/uitest/uno/uiobject_uno.cxx
index 594471a8fbcb..ce78590f747a 100644
--- a/vcl/source/uitest/uno/uiobject_uno.cxx
+++ b/vcl/source/uitest/uno/uiobject_uno.cxx
@@ -114,7 +114,7 @@ void SAL_CALL UIObjectUnoObj::executeAction(const OUString& rAction, const css::
     mReady = false;
     Idle aIdle;
     aIdle.SetDebugName("UI Test Idle Handler");
-    aIdle.SetPriority(TaskPriority::HIGH);
+    aIdle.SetPriority(TaskPriority::DEFAULT);
 
     std::function<void()> func = [this](){
 
diff --git a/vcl/source/window/dockmgr.cxx b/vcl/source/window/dockmgr.cxx
index 7871b539e207..56b42a83a729 100644
--- a/vcl/source/window/dockmgr.cxx
+++ b/vcl/source/window/dockmgr.cxx
@@ -88,11 +88,11 @@ ImplDockFloatWin2::ImplDockFloatWin2( vcl::Window* pParent, WinBits nWinBits,
     SetBackground( GetSettings().GetStyleSettings().GetFaceColor() );
 
     maDockIdle.SetInvokeHandler( LINK( this, ImplDockFloatWin2, DockTimerHdl ) );
-    maDockIdle.SetPriority( TaskPriority::MEDIUM );
+    maDockIdle.SetPriority( TaskPriority::HIGH_IDLE );
     maDockIdle.SetDebugName( "vcl::ImplDockFloatWin2 maDockIdle" );
 
     maEndDockIdle.SetInvokeHandler( LINK( this, ImplDockFloatWin2, EndDockTimerHdl ) );
-    maEndDockIdle.SetPriority( TaskPriority::MEDIUM );
+    maDockIdle.SetPriority( TaskPriority::HIGH_IDLE );
     maEndDockIdle.SetDebugName( "vcl::ImplDockFloatWin2 maEndDockIdle" );
 }
 
diff --git a/vcl/source/window/dockwin.cxx b/vcl/source/window/dockwin.cxx
index ced4ec955b36..88e1d1d305a2 100644
--- a/vcl/source/window/dockwin.cxx
+++ b/vcl/source/window/dockwin.cxx
@@ -98,7 +98,7 @@ ImplDockFloatWin::ImplDockFloatWin( vcl::Window* pParent, WinBits nWinBits,
     SetBackground();
 
     maDockIdle.SetInvokeHandler( LINK( this, ImplDockFloatWin, DockTimerHdl ) );
-    maDockIdle.SetPriority( TaskPriority::MEDIUM );
+    maDockIdle.SetPriority( TaskPriority::HIGH_IDLE );
     maDockIdle.SetDebugName( "vcl::ImplDockFloatWin maDockIdle" );
 }
 
commit 09f755fdf0728a627fc4650b1d29598c1eea14e1
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Sun Jan 29 17:12:25 2017 +0100

    Drop Task::ReadyForSchedule
    
    All relevant information is also provided by UpdateMinPeriod and
    the calculations were even duplicated. This also includes dropping
    Scheduler::UpdateMinPeriod, as this is now reduced to a simple
    comparison and assignment, as we simply ignore larger returned
    sleep times.
    
    Change-Id: I13852e3e63daead451bf7fcb98be9b1d44bd7abd

diff --git a/include/vcl/idle.hxx b/include/vcl/idle.hxx
index cb96c09864c5..18d4e8abaab7 100644
--- a/include/vcl/idle.hxx
+++ b/include/vcl/idle.hxx
@@ -35,8 +35,8 @@ private:
     sal_uInt64    GetTimeout() const = delete;
 
 protected:
-    virtual bool ReadyForSchedule( sal_uInt64 nTimeNow ) const override;
-    virtual sal_uInt64 UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 nTimeNow ) const override;
+    virtual sal_uInt64 UpdateMinPeriod(
+        sal_uInt64 nMinPeriod, sal_uInt64 nTimeNow ) const override;
 
     Idle( bool bAuto, const sal_Char *pDebugName = nullptr );
 
diff --git a/include/vcl/scheduler.hxx b/include/vcl/scheduler.hxx
index 669a402f73d6..ff5885edb36f 100644
--- a/include/vcl/scheduler.hxx
+++ b/include/vcl/scheduler.hxx
@@ -35,9 +35,6 @@ class VCL_DLLPUBLIC Scheduler final
     static inline bool HasPendingTasks( const ImplSchedulerContext &rSchedCtx,
                                         const sal_uInt64 nTime );
 
-    static inline void UpdateMinPeriod( ImplSchedulerData *pSchedulerData,
-                                        sal_uInt64 nTime, sal_uInt64 &nMinPeriod );
-
     static inline void UpdateSystemTimer( ImplSchedulerContext &rSchedCtx,
                                           sal_uInt64 nMinPeriod,
                                           bool bForce, sal_uInt64 nTime );
diff --git a/include/vcl/task.hxx b/include/vcl/task.hxx
index 75812c4e8622..573ee5db92d1 100644
--- a/include/vcl/task.hxx
+++ b/include/vcl/task.hxx
@@ -54,11 +54,18 @@ protected:
     const ImplSchedulerData* GetSchedulerData() const;
 
     virtual void SetDeletionFlags();
-    /// Is this item ready to be dispatched at nTimeNow
-    virtual bool ReadyForSchedule( sal_uInt64 nTimeNow ) const = 0;
+
     /**
-     * Adjust nMinPeriod downwards if we want to be notified before
-     * then, nTimeNow is the current time.
+     * How long (in MS) until the Task is ready to be dispatched?
+     *
+     * Simply return Scheduler::ImmediateTimeoutMs if you're ready, like an
+     * Idle. If you have to return Scheduler::InfiniteTimeoutMs, you probably
+     * need an other mechanism to wake up the Scheduler or rely on other
+     * Tasks to be scheduled, or simply use a polling Timer.
+     *
+     * @param nMinPeriod the currently expected sleep time
+     * @param nTimeNow the current time
+     * @return the sleep time of the Task to become ready
      */
     virtual sal_uInt64 UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 nTimeNow ) const = 0;
 
diff --git a/include/vcl/timer.hxx b/include/vcl/timer.hxx
index 5be766cb6aa7..d26004cc5312 100644
--- a/include/vcl/timer.hxx
+++ b/include/vcl/timer.hxx
@@ -31,8 +31,8 @@ class VCL_DLLPUBLIC Timer : public Task
 
 protected:
     virtual void SetDeletionFlags() override;
-    virtual bool ReadyForSchedule( sal_uInt64 nTimeNow ) const override;
-    virtual sal_uInt64 UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 nTimeNow ) const override;
+    virtual sal_uInt64 UpdateMinPeriod(
+        sal_uInt64 nMinPeriod, sal_uInt64 nTimeNow ) const override;
 
     Timer( bool bAuto, const sal_Char *pDebugName = nullptr );
 
diff --git a/vcl/source/app/idle.cxx b/vcl/source/app/idle.cxx
index 4cbd3f8c0ed6..78c114801868 100644
--- a/vcl/source/app/idle.cxx
+++ b/vcl/source/app/idle.cxx
@@ -55,11 +55,6 @@ void Idle::Start()
     Task::StartTimer(nPeriod);
 }
 
-bool Idle::ReadyForSchedule( sal_uInt64 /* nTimeNow */ ) const
-{
-    return true;
-}
-
 sal_uInt64 Idle::UpdateMinPeriod( sal_uInt64 /* nMinPeriod */, sal_uInt64 /* nTimeNow */ ) const
 {
     return Scheduler::ImmediateTimeoutMs;
diff --git a/vcl/source/app/scheduler.cxx b/vcl/source/app/scheduler.cxx
index b91ac191e564..25e43baf9b44 100644
--- a/vcl/source/app/scheduler.cxx
+++ b/vcl/source/app/scheduler.cxx
@@ -171,19 +171,6 @@ bool Scheduler::GetDeterministicMode()
     return g_bDeterministicMode;
 }
 
-inline void Scheduler::UpdateMinPeriod( ImplSchedulerData * const pSchedulerData,
-                                        const sal_uInt64 nTime, sal_uInt64 &nMinPeriod )
-{
-    if ( nMinPeriod > ImmediateTimeoutMs )
-    {
-        sal_uInt64 nCurPeriod = nMinPeriod;
-        nMinPeriod = pSchedulerData->mpTask->UpdateMinPeriod( nCurPeriod, nTime );
-        assert( nMinPeriod <= nCurPeriod );
-        if ( nCurPeriod < nMinPeriod )
-            nMinPeriod = nCurPeriod;
-    }
-}
-
 inline void Scheduler::UpdateSystemTimer( ImplSchedulerContext &rSchedCtx,
                                           const sal_uInt64 nMinPeriod,
                                           const bool bForce, const sal_uInt64 nTime )
@@ -253,6 +240,8 @@ bool Scheduler::ProcessTaskScheduling()
     ImplSchedulerData *pMostUrgent = nullptr;
     ImplSchedulerData *pPrevMostUrgent = nullptr;
     sal_uInt64         nMinPeriod = InfiniteTimeoutMs;
+    sal_uInt64         nMostUrgentPeriod = InfiniteTimeoutMs;
+    sal_uInt64         nReadyPeriod = InfiniteTimeoutMs;
 
     DBG_TESTSOLARMUTEX();
 
@@ -297,16 +286,18 @@ bool Scheduler::ProcessTaskScheduling()
             goto next_entry;
 
         // skip ready tasks with lower priority than the most urgent (numerical lower is higher)
-        if ( pSchedulerData->mpTask->ReadyForSchedule( nTime ) &&
+        nReadyPeriod = pSchedulerData->mpTask->UpdateMinPeriod( nMinPeriod, nTime );
+        if ( ImmediateTimeoutMs == nReadyPeriod &&
              (!pMostUrgent || (pSchedulerData->mpTask->GetPriority() < pMostUrgent->mpTask->GetPriority())) )
         {
-            if ( pMostUrgent )
-                UpdateMinPeriod( pMostUrgent, nTime, nMinPeriod );
+            if ( pMostUrgent && nMinPeriod > nMostUrgentPeriod )
+                nMinPeriod = nMostUrgentPeriod;
             pPrevMostUrgent = pPrevSchedulerData;
             pMostUrgent = pSchedulerData;
+            nMostUrgentPeriod = nReadyPeriod;
         }
-        else
-            UpdateMinPeriod( pSchedulerData, nTime, nMinPeriod );
+        else if ( nMinPeriod > nReadyPeriod )
+            nMinPeriod = nReadyPeriod;
 
 next_entry:
         pPrevSchedulerData = pSchedulerData;
@@ -357,7 +348,9 @@ next_entry:
             if ( pMostUrgent->mpTask && pMostUrgent->mpTask->IsActive() )
             {
                 pMostUrgent->mnUpdateTime = nTime;
-                UpdateMinPeriod( pMostUrgent, nTime, nMinPeriod );
+                nReadyPeriod = pMostUrgent->mpTask->UpdateMinPeriod( nMinPeriod, nTime );
+                if ( nMinPeriod > nReadyPeriod )
+                    nMinPeriod = nReadyPeriod;
                 UpdateSystemTimer( rSchedCtx, nMinPeriod, false, nTime );
             }
         }
diff --git a/vcl/source/app/timer.cxx b/vcl/source/app/timer.cxx
index 18796806a318..6cba9e2f2b2f 100644
--- a/vcl/source/app/timer.cxx
+++ b/vcl/source/app/timer.cxx
@@ -30,21 +30,11 @@ void Timer::SetDeletionFlags()
         Task::SetDeletionFlags();
 }
 
-bool Timer::ReadyForSchedule( sal_uInt64 nTimeNow ) const
-{
-    return (GetSchedulerData()->mnUpdateTime + mnTimeout) <= nTimeNow;
-}
-
-sal_uInt64 Timer::UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 nTimeNow ) const
+sal_uInt64 Timer::UpdateMinPeriod( sal_uInt64, sal_uInt64 nTimeNow ) const
 {
     sal_uInt64 nWakeupTime = GetSchedulerData()->mnUpdateTime + mnTimeout;
-    if( nWakeupTime <= nTimeNow )
-        return Scheduler::ImmediateTimeoutMs;
-    else
-    {
-        sal_uInt64 nSleepTime = nWakeupTime - nTimeNow;
-        return ( nSleepTime < nMinPeriod ) ? nSleepTime : nMinPeriod;
-    }
+    return ( nWakeupTime <= nTimeNow )
+        ? Scheduler::ImmediateTimeoutMs : nWakeupTime - nTimeNow;
 }
 
 Timer::Timer( bool bAuto, const sal_Char *pDebugName )
commit 15a74133877f5aa9ee6265f058cf2d0ffeacb2ef
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Sat Jan 28 00:54:33 2017 +0100

    Remove duplicated delete information
    
    Task::mbActive already stores the inverse information of
    ImplSchedulerData::mbDelete, so we can drop the latter one.
    
    Change-Id: I57f8c23ca1eebdeed780a644c83fcbeb9b92cd66

diff --git a/vcl/inc/schedulerimpl.hxx b/vcl/inc/schedulerimpl.hxx
index f51d56870d3a..9706b8a875b6 100644
--- a/vcl/inc/schedulerimpl.hxx
+++ b/vcl/inc/schedulerimpl.hxx
@@ -30,7 +30,6 @@ struct ImplSchedulerData final
 {
     ImplSchedulerData* mpNext;        ///< Pointer to the next element in list
     Task*              mpTask;        ///< Pointer to VCL Task instance
-    bool               mbDelete;      ///< Destroy this task?
     bool               mbInScheduler; ///< Task currently processed?
     sal_uInt64         mnUpdateTime;  ///< Last Update Time
 
diff --git a/vcl/source/app/scheduler.cxx b/vcl/source/app/scheduler.cxx
index e1042fffd9fe..b91ac191e564 100644
--- a/vcl/source/app/scheduler.cxx
+++ b/vcl/source/app/scheduler.cxx
@@ -76,8 +76,7 @@ template< typename charT, typename traits >
 inline std::basic_ostream<charT, traits> & operator <<(
     std::basic_ostream<charT, traits> & stream, const ImplSchedulerData& data )
 {
-    stream << " i: " << data.mbInScheduler
-           << " d: " << data.mbDelete;
+    stream << " i: " << data.mbInScheduler;
     return stream;
 }
 
@@ -273,7 +272,8 @@ bool Scheduler::ProcessTaskScheduling()
                 << pSchedulerData << " " << *pSchedulerData << " (to be deleted)" );
 
         // Should the Task be released from scheduling or stacked?
-        if ( pSchedulerData->mbDelete || !pSchedulerData->mpTask || pSchedulerData->mbInScheduler )
+        if ( !pSchedulerData->mpTask || !pSchedulerData->mpTask->IsActive()
+            || pSchedulerData->mbInScheduler )
         {
             ImplSchedulerData * const pSchedulerDataNext =
                 DropSchedulerData( rSchedCtx, pPrevSchedulerData, pSchedulerData );
@@ -354,7 +354,7 @@ next_entry:
                 AppendSchedulerData( rSchedCtx, pMostUrgent );
             }
 
-            if ( pMostUrgent->mpTask && !pMostUrgent->mbDelete )
+            if ( pMostUrgent->mpTask && pMostUrgent->mpTask->IsActive() )
             {
                 pMostUrgent->mnUpdateTime = nTime;
                 UpdateMinPeriod( pMostUrgent, nTime, nMinPeriod );
@@ -378,7 +378,6 @@ void Task::StartTimer( sal_uInt64 nMS )
 
 void Task::SetDeletionFlags()
 {
-    mpImpl->mpSchedulerData->mbDelete = true;
     mpImpl->mbActive = false;
 }
 
@@ -432,7 +431,6 @@ void Task::Start()
         SAL_INFO( "vcl.schedule", tools::Time::GetSystemTicks()
                   << " " << mpImpl->mpSchedulerData << "  restarted  " << *this );
 
-    mpImpl->mpSchedulerData->mbDelete      = false;
     mpImpl->mpSchedulerData->mnUpdateTime  = tools::Time::GetSystemTicks();
 }
 
@@ -441,8 +439,6 @@ void Task::Stop()
     SAL_INFO_IF( mpImpl->mbActive, "vcl.schedule", tools::Time::GetSystemTicks()
                   << " " << mpImpl->mpSchedulerData << "  stopped    " << *this );
     mpImpl->mbActive = false;
-    if ( mpImpl->mpSchedulerData )
-        mpImpl->mpSchedulerData->mbDelete = true;
 }
 
 Task& Task::operator=( const Task& rTask )
@@ -479,10 +475,7 @@ Task::Task( const Task& rTask )
 Task::~Task()
 {
     if ( mpImpl->mpSchedulerData )
-    {
-        mpImpl->mpSchedulerData->mbDelete = true;
         mpImpl->mpSchedulerData->mpTask = nullptr;
-    }
 }
 
 TaskImpl::TaskImpl( const sal_Char *pDebugName )
commit bf35c0440d205db05a417f6842675b3ba62cddd2
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Fri Jan 27 23:40:11 2017 +0100

    Run LO scheduler only via system timer
    
    Change-Id: I5283f18aebcd6797ad35771ae8fc4a0f425ff924

diff --git a/include/vcl/scheduler.hxx b/include/vcl/scheduler.hxx
index 5c5617cd0c8b..669a402f73d6 100644
--- a/include/vcl/scheduler.hxx
+++ b/include/vcl/scheduler.hxx
@@ -52,8 +52,6 @@ public:
 
     /// Process one pending Timer with highhest priority
     static void       CallbackTaskScheduling();
-    /// Are there any pending tasks to process?
-    static bool       HasPendingTasks();
     /// Process one pending task ahead of time with highest priority.
     static bool       ProcessTaskScheduling();
     /// Process all events until we are idle
diff --git a/vcl/inc/svdata.hxx b/vcl/inc/svdata.hxx
index f1a8c40afccb..ec1010370853 100644
--- a/vcl/inc/svdata.hxx
+++ b/vcl/inc/svdata.hxx
@@ -316,7 +316,6 @@ struct ImplSchedulerContext
     SalTimer*               mpSalTimer = nullptr;           ///< interface to sal event loop / system timer
     sal_uInt64              mnTimerStart = 0;               ///< start time of the timer
     sal_uInt64              mnTimerPeriod = SAL_MAX_UINT64; ///< current timer period
-    bool                    mbNeedsReschedule = false;      ///< we need to reschedule
 };
 
 struct ImplSVData
diff --git a/vcl/source/app/idle.cxx b/vcl/source/app/idle.cxx
index 8038005a7d4f..4cbd3f8c0ed6 100644
--- a/vcl/source/app/idle.cxx
+++ b/vcl/source/app/idle.cxx
@@ -57,8 +57,6 @@ void Idle::Start()
 
 bool Idle::ReadyForSchedule( sal_uInt64 /* nTimeNow */ ) const
 {
-    ImplSVData *pSVData = ImplGetSVData();
-    pSVData->maSchedCtx.mbNeedsReschedule = true;
     return true;
 }
 
diff --git a/vcl/source/app/scheduler.cxx b/vcl/source/app/scheduler.cxx
index 4cbc94e098b6..e1042fffd9fe 100644
--- a/vcl/source/app/scheduler.cxx
+++ b/vcl/source/app/scheduler.cxx
@@ -172,13 +172,6 @@ bool Scheduler::GetDeterministicMode()
     return g_bDeterministicMode;
 }
 
-bool Scheduler::HasPendingTasks()
-{
-    const ImplSchedulerContext &rSchedCtx = ImplGetSVData()->maSchedCtx;
-    return ( rSchedCtx.mbNeedsReschedule || ((rSchedCtx.mnTimerPeriod != InfiniteTimeoutMs)
-        && (tools::Time::GetSystemTicks() >= rSchedCtx.mnTimerStart + rSchedCtx.mnTimerPeriod )) );
-}
-
 inline void Scheduler::UpdateMinPeriod( ImplSchedulerData * const pSchedulerData,
                                         const sal_uInt64 nTime, sal_uInt64 &nMinPeriod )
 {
@@ -246,7 +239,6 @@ bool Scheduler::ProcessTaskScheduling()
     sal_uInt64 nTime = tools::Time::GetSystemTicks();
     if ( pSVData->mbDeInit || InfiniteTimeoutMs == rSchedCtx.mnTimerPeriod )
         return false;
-    rSchedCtx.mbNeedsReschedule = false;
 
     if ( nTime < rSchedCtx.mnTimerStart + rSchedCtx.mnTimerPeriod )
     {
@@ -442,7 +434,6 @@ void Task::Start()
 
     mpImpl->mpSchedulerData->mbDelete      = false;
     mpImpl->mpSchedulerData->mnUpdateTime  = tools::Time::GetSystemTicks();
-    rSchedCtx.mbNeedsReschedule            = true;
 }
 
 void Task::Stop()
diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx
index 8f3b317beba5..b31c0b9c7537 100644
--- a/vcl/source/app/svapp.cxx
+++ b/vcl/source/app/svapp.cxx
@@ -479,10 +479,6 @@ inline bool ImplYield(bool i_bWait, bool i_bAllEvents, sal_uLong const nReleased
     SAL_INFO("vcl.schedule", "Enter ImplYield: " << (i_bWait ? "wait" : "no wait") <<
              ": " << (i_bAllEvents ? "all events" : "one event") << ": " << nReleased);
 
-    // we handle pending task outside the system event loop, so don't wait
-    if (i_bWait && Scheduler::HasPendingTasks())
-        i_bWait = false;
-
     // TODO: there's a data race here on WNT only because ImplYield may be
     // called without SolarMutex; if we can get rid of LazyDelete (with VclPtr)
     // then the only remaining use of mnDispatchLevel is in OSX specific code
@@ -496,24 +492,16 @@ inline bool ImplYield(bool i_bWait, bool i_bAllEvents, sal_uLong const nReleased
             i_bWait && !pSVData->maAppData.mbAppQuit,
             i_bAllEvents, nReleased);
 
-    SAL_INFO("vcl.schedule", "DoYield returns: " << bProcessedEvent );
-
     pSVData->maAppData.mnDispatchLevel--;
 
     DBG_TESTSOLARMUTEX(); // must be locked on return from Yield
 
-    if (nReleased == 0) // tdf#99383 don't run stuff from ReAcquireSolarMutex
-    {
-        // Process all Tasks
-        bProcessedEvent = Scheduler::ProcessTaskScheduling() || bProcessedEvent;
-    }
-
     // flush lazy deleted objects
     if( pSVData->maAppData.mnDispatchLevel == 0 )
         vcl::LazyDelete::flush();
 
     SAL_INFO("vcl.schedule", "Leave ImplYield with return " << bProcessedEvent );
-    return bProcessedEvent || Scheduler::HasPendingTasks();
+    return bProcessedEvent;
 }
 
 bool Application::Reschedule( bool i_bAllEvents )
commit 89163794f9ed43b225796b69dc449b6db6b5cdb6
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Tue Mar 21 13:32:47 2017 +0100

    OSX fix empty message queue handling
    
    For some (unknown) reason [NSApp postEvent: ... atStart: NO]
    doesn't append the event, if the message queue is empty
    (AKA [NSApp nextEventMatchingMask .. ] returns nil).
    Due to nextEventMatchingMask usage, these postEvents have to
    run in the main thread.
    
    Using performSelectorOnMainThread deadlocks, since the calling
    thread may have locked the Yield mutex, so we simply defer the
    call using an NSEvent, like the Windows backend.
    
    So we have to peek at the queue and if it's empty simply prepend
    the event using [.. atStart: YES].
    
    In the end this make the vcl_timer unit test pass on OSX.
    
    Change-Id: Ib41186425b2f76faa0e9f116f47fdcd60d878099

diff --git a/vcl/Module_vcl.mk b/vcl/Module_vcl.mk
index 52f93e060551..c006ee1860b0 100644
--- a/vcl/Module_vcl.mk
+++ b/vcl/Module_vcl.mk
@@ -171,6 +171,12 @@ $(eval $(call gb_Module_add_check_targets,vcl,\
 ))
 endif
 
+ifeq ($(OS),MACOSX)
+$(eval $(call gb_Module_add_check_targets,vcl,\
+	CppunitTest_vcl_timer \
+))
+endif
+
 # screenshots
 $(eval $(call gb_Module_add_screenshot_targets,vcl,\
     CppunitTest_vcl_dialogs_test \
diff --git a/vcl/inc/osx/saltimer.h b/vcl/inc/osx/saltimer.h
index f9a6acb7a02f..86964115d648 100644
--- a/vcl/inc/osx/saltimer.h
+++ b/vcl/inc/osx/saltimer.h
@@ -26,10 +26,24 @@
 
 #include "saltimer.hxx"
 
-class AquaSalTimer : public SalTimer
+/**
+ * if NO == bAtStart, then it has to be run in the main thread,
+ * e.g. via performSelectorOnMainThread!
+ **/
+void ImplNSAppPostEvent( short nEventId, BOOL bAtStart, int nUserData = 0 );
+
+class ReleasePoolHolder
 {
-  public:
+    NSAutoreleasePool* mpPool;
+
+public:
+    ReleasePoolHolder() : mpPool( [[NSAutoreleasePool alloc] init] ) {}
+    ~ReleasePoolHolder() { [mpPool release]; }
+};
 
+class AquaSalTimer : public SalTimer
+{
+public:
     AquaSalTimer();
     virtual ~AquaSalTimer() override;
 
diff --git a/vcl/osx/salinst.cxx b/vcl/osx/salinst.cxx
index cecd7c0d87fb..13aa712a99ac 100644
--- a/vcl/osx/salinst.cxx
+++ b/vcl/osx/salinst.cxx
@@ -370,23 +370,7 @@ void AquaSalInstance::wakeupYield()
 {
     // wakeup :Yield
     if( mbWaitingYield )
-    {
-        SalData::ensureThreadAutoreleasePool();
-SAL_WNODEPRECATED_DECLARATIONS_PUSH
-    // 'NSApplicationDefined' is deprecated: first deprecated in macOS 10.12
-        NSEvent* pEvent = [NSEvent otherEventWithType: NSApplicationDefined
-                                   location: NSZeroPoint
-                                   modifierFlags: 0
-                                   timestamp: 0
-                                   windowNumber: 0
-                                   context: nil
-                                   subtype: AquaSalInstance::YieldWakeupEvent
-                                   data1: 0
-                                   data2: 0 ];
-SAL_WNODEPRECATED_DECLARATIONS_POP
-        if( pEvent )
-            [NSApp postEvent: pEvent atStart: NO];
-    }
+        ImplNSAppPostEvent( AquaSalInstance::YieldWakeupEvent, YES );
 }
 
 void AquaSalInstance::PostUserEvent( AquaSalFrame* pFrame, SalEvent nType, void* pData )
@@ -556,14 +540,6 @@ void AquaSalInstance::handleAppDefinedEvent( NSEvent* pEvent )
     };
 }
 
-class ReleasePoolHolder
-{
-    NSAutoreleasePool* mpPool;
-    public:
-    ReleasePoolHolder() : mpPool( [[NSAutoreleasePool alloc] init] ) {}
-    ~ReleasePoolHolder() { [mpPool release]; }
-};
-
 bool AquaSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents, sal_uLong const nReleased)
 {
     (void) nReleased;
@@ -629,9 +605,11 @@ bool AquaSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents, sal_uLon
 
 SAL_WNODEPRECATED_DECLARATIONS_PUSH
     // 'NSAnyEventMask' is deprecated: first deprecated in macOS 10.12
-            pEvent = [NSApp nextEventMatchingMask: NSAnyEventMask untilDate: nil
+            pEvent = [NSApp nextEventMatchingMask: NSAnyEventMask
 SAL_WNODEPRECATED_DECLARATIONS_POP
-                            inMode: NSDefaultRunLoopMode dequeue: YES];
+                            untilDate: nil
+                            inMode: NSDefaultRunLoopMode
+                            dequeue: YES];
             if( pEvent )
             {
                 [NSApp sendEvent: pEvent];
@@ -650,9 +628,11 @@ SAL_WNODEPRECATED_DECLARATIONS_POP
             NSDate* pDt = AquaSalTimer::pRunningTimer ? [AquaSalTimer::pRunningTimer fireDate] : [NSDate distantFuture];
 SAL_WNODEPRECATED_DECLARATIONS_PUSH
     // 'NSAnyEventMask' is deprecated: first deprecated in macOS 10.12
-            pEvent = [NSApp nextEventMatchingMask: NSAnyEventMask untilDate: pDt
+            pEvent = [NSApp nextEventMatchingMask: NSAnyEventMask
 SAL_WNODEPRECATED_DECLARATIONS_POP
-                            inMode: NSDefaultRunLoopMode dequeue: YES];
+                            untilDate: pDt
+                            inMode: NSDefaultRunLoopMode
+                            dequeue: YES];
             if( pEvent )
                 [NSApp sendEvent: pEvent];
             [NSApp updateWindows];
@@ -734,7 +714,7 @@ bool AquaSalInstance::AnyInput( VclInputFlags nType )
         }
     }
 
-    if (![NSThread isMainThread])
+    if (!isNSAppThread())
         return false;
 
     unsigned/*NSUInteger*/ nEventMask = 0;
diff --git a/vcl/osx/salnstimer.mm b/vcl/osx/salnstimer.mm
index 9c3264295d60..c9867cf7a79e 100644
--- a/vcl/osx/salnstimer.mm
+++ b/vcl/osx/salnstimer.mm
@@ -26,24 +26,13 @@
 #include "svdata.hxx"
 
 @implementation TimerCallbackCaller
+
 -(void)timerElapsed:(NSTimer*)pTimer
 {
     (void)pTimer;
-SAL_WNODEPRECATED_DECLARATIONS_PUSH
-// 'NSApplicationDefined' is deprecated: first deprecated in macOS 10.12
-    NSEvent* pEvent = [NSEvent otherEventWithType: NSApplicationDefined
-SAL_WNODEPRECATED_DECLARATIONS_POP
-                               location: NSZeroPoint
-                               modifierFlags: 0
-                               timestamp: [NSDate timeIntervalSinceReferenceDate]
-                               windowNumber: 0
-                               context: nil
-                               subtype: AquaSalInstance::DispatchTimerEvent
-                               data1: 0
-                               data2: 0 ];
-    assert( pEvent );
-    [NSApp postEvent: pEvent atStart: YES];
+    ImplNSAppPostEvent( AquaSalInstance::DispatchTimerEvent, YES );
 }
+
 @end
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/osx/saltimer.cxx b/vcl/osx/saltimer.cxx
index 523f46c7d0ce..514c9fbe4619 100644
--- a/vcl/osx/saltimer.cxx
+++ b/vcl/osx/saltimer.cxx
@@ -31,22 +31,45 @@ NSTimer* AquaSalTimer::pRunningTimer = nil;
 
 static void ImplSalStopTimer();
 
-static inline void ImplPostEvent( short nEventId, bool bAtStart, int nUserData = 0 )
+void ImplNSAppPostEvent( short nEventId, BOOL bAtStart, int nUserData )
 {
-    SalData::ensureThreadAutoreleasePool();
+    ReleasePoolHolder aPool;
 SAL_WNODEPRECATED_DECLARATIONS_PUSH
 // 'NSApplicationDefined' is deprecated: first deprecated in macOS 10.12
     NSEvent* pEvent = [NSEvent otherEventWithType: NSApplicationDefined
 SAL_WNODEPRECATED_DECLARATIONS_POP
                                location: NSZeroPoint
                                modifierFlags: 0
-                               timestamp: [NSDate timeIntervalSinceReferenceDate]
+                               timestamp: 0
                                windowNumber: 0
                                context: nil
                                subtype: nEventId
                                data1: nUserData
-                               data2: 0 ];
+                               data2: 0];
     assert( pEvent );
+    if ( nil == pEvent )
+        return;
+    if ( NO == bAtStart )
+    {
+        // nextEventMatchingMask has to run in the main thread!
+        assert([NSThread isMainThread]);
+
+        // Posting an event to the end of an empty queue fails,
+        // so we peek the queue and post to the start, if empty.
+        // Some Qt bugs even indicate nextEvent without dequeue
+        // sometimes blocks, so we dequeue and re-add the event.
+SAL_WNODEPRECATED_DECLARATIONS_PUSH
+// 'NSAnyEventMask' is deprecated: first deprecated in macOS 10.12
+        NSEvent* pPeekEvent = [NSApp nextEventMatchingMask: NSAnyEventMask
+SAL_WNODEPRECATED_DECLARATIONS_POP
+                               untilDate: nil
+                               inMode: NSDefaultRunLoopMode
+                               dequeue: YES];
+        if ( nil == pPeekEvent )
+            bAtStart = YES;
+        else
+            [NSApp postEvent: pPeekEvent atStart: YES];
+    }
     [NSApp postEvent: pEvent atStart: bAtStart];
 }
 
@@ -54,14 +77,18 @@ static void ImplSalStartTimer( sal_uLong nMS )
 {
     SalData* pSalData = GetSalData();
 
-    if ( 0 == nMS )
+    if( !pSalData->mpFirstInstance->isNSAppThread() )
     {
-        ImplSalStopTimer();
-        ImplPostEvent( AquaSalInstance::DispatchTimerEvent, false );
+        ImplNSAppPostEvent( AquaSalInstance::AppStartTimerEvent, YES, nMS );
         return;
     }
 
-    if( pSalData->mpFirstInstance->isNSAppThread() )
+    if ( 0 == nMS )
+    {
+        ImplSalStopTimer();
+        ImplNSAppPostEvent( AquaSalInstance::DispatchTimerEvent, NO );
+    }
+    else
     {
         NSTimeInterval aTI = double(nMS) / 1000.0;
         if( AquaSalTimer::pRunningTimer != nil )
@@ -89,8 +116,6 @@ static void ImplSalStartTimer( sal_uLong nMS )
             [[NSRunLoop currentRunLoop] addTimer: AquaSalTimer::pRunningTimer forMode: NSEventTrackingRunLoopMode];
         }
     }
-    else
-        ImplPostEvent( AquaSalInstance::AppStartTimerEvent, true, nMS );
 }
 
 static void ImplSalStopTimer()
commit 7d95532079824bbb774c2cb801e629f0ade9c074
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Fri Feb 24 18:27:49 2017 +0100

    OSX change to run LO via a single shot timer
    
    As all other backends, this runs the LO main loop just via the
    OSX main loop.
    
    Change-Id: Ie7562444951e16ff58edcaf6409f32809314c2fa

diff --git a/vcl/inc/osx/salinst.h b/vcl/inc/osx/salinst.h
index c0a4491207bc..3f299909745d 100644
--- a/vcl/inc/osx/salinst.h
+++ b/vcl/inc/osx/salinst.h
@@ -152,6 +152,7 @@ public:
     static const short AppEndLoopEvent    = 1;
     static const short AppStartTimerEvent = 10;
     static const short YieldWakeupEvent   = 20;
+    static const short DispatchTimerEvent = 30;
 
     static NSMenu* GetDynamicDockMenu();
 };
diff --git a/vcl/inc/osx/saltimer.h b/vcl/inc/osx/saltimer.h
index 94b58f82fd8b..f9a6acb7a02f 100644
--- a/vcl/inc/osx/saltimer.h
+++ b/vcl/inc/osx/saltimer.h
@@ -37,6 +37,7 @@ class AquaSalTimer : public SalTimer
     void Stop() override;
 
     static void handleStartTimerEvent( NSEvent* pEvent );
+    static void handleDispatchTimerEvent();
 
     static NSTimer* pRunningTimer;
     static bool bDispatchTimer;
diff --git a/vcl/osx/salinst.cxx b/vcl/osx/salinst.cxx
index a05a4dd4f93b..cecd7c0d87fb 100644
--- a/vcl/osx/salinst.cxx
+++ b/vcl/osx/salinst.cxx
@@ -475,8 +475,11 @@ void AquaSalInstance::handleAppDefinedEvent( NSEvent* pEvent )
             [pDockMenu release];
             pDockMenu = nil;
         }
+        break;
     }
-    break;
+    case DispatchTimerEvent:
+        AquaSalTimer::handleDispatchTimerEvent();
+        break;
 #if !HAVE_FEATURE_MACOSX_SANDBOX
     case AppleRemoteControlEvent: // Defined in <apple_remote/RemoteMainController.h>
     {
@@ -565,6 +568,7 @@ bool AquaSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents, sal_uLon
 {
     (void) nReleased;
     assert(nReleased == 0); // not implemented
+    bool bHadEvent = false;
 
     // ensure that the per thread autorelease pool is top level and
     // will therefore not be destroyed by cocoa implicitly
@@ -589,6 +593,7 @@ bool AquaSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents, sal_uLon
             {
                 aEvent = maUserEvents.front();
                 maUserEvents.pop_front();
+                bHadEvent = true;
             }
             else
                 bDispatchUser = false;
@@ -600,15 +605,15 @@ bool AquaSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents, sal_uLon
         {
             aEvent.mpFrame->CallCallback( aEvent.mnType, aEvent.mpData );
             maWaitingYieldCond.set();
-            // return if only one event is asked for
-            if( ! bHandleAllCurrentEvents )
-                return true;
         }
+
+        // return if only one event is asked for
+        if( !bHandleAllCurrentEvents && bDispatchUser )
+            return true;
     }
 
     // handle cocoa event queue
     // cocoa events may be only handled in the thread the NSApp was created
-    bool bHadEvent = false;
     if( isNSAppThread() && mnActivePrintJobs == 0 )
     {
         // we need to be woken up by a cocoa-event
@@ -653,18 +658,6 @@ SAL_WNODEPRECATED_DECLARATIONS_POP
             [NSApp updateWindows];
 
             AcquireYieldMutex( nCount );
-
-            // #i86581#
-            // FIXME: sometimes the NSTimer will never fire. Firing it by hand then
-            // fixes the problem even seems to set the correct next firing date
-            // Why oh why?
-            if( ! pEvent && AquaSalTimer::pRunningTimer )
-            {
-                // this cause crashes on MacOSX 10.4
-                // [AquaSalTimer::pRunningTimer fire];
-                if (ImplGetSVData()->maSchedCtx.mpSalTimer != nullptr)
-                    ImplGetSVData()->maSchedCtx.mpSalTimer->CallCallback();
-            }
         }
 
         mbWaitingYield = bOldWaitingYield;
diff --git a/vcl/osx/salnstimer.mm b/vcl/osx/salnstimer.mm
index 00f67e52cd26..9c3264295d60 100644
--- a/vcl/osx/salnstimer.mm
+++ b/vcl/osx/salnstimer.mm
@@ -29,19 +29,20 @@
 -(void)timerElapsed:(NSTimer*)pTimer
 {
     (void)pTimer;
-    if( AquaSalTimer::bDispatchTimer )
-    {
-        SolarMutexGuard aGuard;
-        ImplSVData* pSVData = ImplGetSVData();
-        if( pSVData->maSchedCtx.mpSalTimer )
-        {
-            pSVData->maSchedCtx.mpSalTimer->CallCallback();
-
-            // NSTimer does not end nextEventMatchingMask of NSApplication
-            // so we need to wakeup a waiting Yield to inform it something happened
-            GetSalData()->mpFirstInstance->wakeupYield();
-        }
-    }
+SAL_WNODEPRECATED_DECLARATIONS_PUSH
+// 'NSApplicationDefined' is deprecated: first deprecated in macOS 10.12
+    NSEvent* pEvent = [NSEvent otherEventWithType: NSApplicationDefined
+SAL_WNODEPRECATED_DECLARATIONS_POP
+                               location: NSZeroPoint
+                               modifierFlags: 0
+                               timestamp: [NSDate timeIntervalSinceReferenceDate]
+                               windowNumber: 0
+                               context: nil
+                               subtype: AquaSalInstance::DispatchTimerEvent
+                               data1: 0
+                               data2: 0 ];
+    assert( pEvent );
+    [NSApp postEvent: pEvent atStart: YES];
 }
 @end
 
diff --git a/vcl/osx/saltimer.cxx b/vcl/osx/saltimer.cxx
index 5d36de526aa2..523f46c7d0ce 100644
--- a/vcl/osx/saltimer.cxx
+++ b/vcl/osx/saltimer.cxx
@@ -28,15 +28,42 @@
 #include "osx/salinst.h"
 
 NSTimer* AquaSalTimer::pRunningTimer = nil;
-bool AquaSalTimer::bDispatchTimer = false;
 
-void ImplSalStartTimer( sal_uLong nMS )
+static void ImplSalStopTimer();
+
+static inline void ImplPostEvent( short nEventId, bool bAtStart, int nUserData = 0 )
+{
+    SalData::ensureThreadAutoreleasePool();
+SAL_WNODEPRECATED_DECLARATIONS_PUSH
+// 'NSApplicationDefined' is deprecated: first deprecated in macOS 10.12
+    NSEvent* pEvent = [NSEvent otherEventWithType: NSApplicationDefined
+SAL_WNODEPRECATED_DECLARATIONS_POP
+                               location: NSZeroPoint
+                               modifierFlags: 0
+                               timestamp: [NSDate timeIntervalSinceReferenceDate]
+                               windowNumber: 0
+                               context: nil
+                               subtype: nEventId
+                               data1: nUserData
+                               data2: 0 ];
+    assert( pEvent );
+    [NSApp postEvent: pEvent atStart: bAtStart];
+}
+
+static void ImplSalStartTimer( sal_uLong nMS )
 {
     SalData* pSalData = GetSalData();
+
+    if ( 0 == nMS )
+    {
+        ImplSalStopTimer();
+        ImplPostEvent( AquaSalInstance::DispatchTimerEvent, false );
+        return;
+    }
+
     if( pSalData->mpFirstInstance->isNSAppThread() )
     {
-        AquaSalTimer::bDispatchTimer = true;
-        NSTimeInterval aTI = double(nMS)/1000.0;
+        NSTimeInterval aTI = double(nMS) / 1000.0;
         if( AquaSalTimer::pRunningTimer != nil )
         {
             if (rtl::math::approxEqual(
@@ -46,18 +73,16 @@ void ImplSalStartTimer( sal_uLong nMS )
                 [AquaSalTimer::pRunningTimer setFireDate: [NSDate dateWithTimeIntervalSinceNow: aTI]];
             }
             else
-            {
-                [AquaSalTimer::pRunningTimer invalidate];
-                AquaSalTimer::pRunningTimer = nil;
-            }
+                ImplSalStopTimer();
         }
         if( AquaSalTimer::pRunningTimer == nil )
         {
-            AquaSalTimer::pRunningTimer = [NSTimer scheduledTimerWithTimeInterval: aTI
-                                                   target: [[[TimerCallbackCaller alloc] init] autorelease]
-                                                   selector: @selector(timerElapsed:)
-                                                   userInfo: nil
-                                                   repeats: YES];
+            AquaSalTimer::pRunningTimer = [[NSTimer scheduledTimerWithTimeInterval: aTI
+                                                    target: [[[TimerCallbackCaller alloc] init] autorelease]
+                                                    selector: @selector(timerElapsed:)
+                                                    userInfo: nil
+                                                    repeats: NO
+                                           ] retain];
             /* #i84055# add timer to tracking run loop mode,
                so they also elapse while e.g. life resize
             */
@@ -65,29 +90,25 @@ void ImplSalStartTimer( sal_uLong nMS )
         }
     }
     else
+        ImplPostEvent( AquaSalInstance::AppStartTimerEvent, true, nMS );
+}
+
+static void ImplSalStopTimer()
+{
+    if( AquaSalTimer::pRunningTimer != nil )
     {
-        SalData::ensureThreadAutoreleasePool();
-        // post an event so we can get into the main thread
-SAL_WNODEPRECATED_DECLARATIONS_PUSH
-    // 'NSApplicationDefined' is deprecated: first deprecated in macOS 10.12
-        NSEvent* pEvent = [NSEvent otherEventWithType: NSApplicationDefined
-                                   location: NSZeroPoint
-                                   modifierFlags: 0
-                                   timestamp: [NSDate timeIntervalSinceReferenceDate]
-                                   windowNumber: 0
-                                   context: nil
-                                   subtype: AquaSalInstance::AppStartTimerEvent
-                                   data1: (int)nMS
-                                   data2: 0 ];
-SAL_WNODEPRECATED_DECLARATIONS_POP
-        if( pEvent )
-            [NSApp postEvent: pEvent atStart: YES];
+        [AquaSalTimer::pRunningTimer invalidate];
+        [AquaSalTimer::pRunningTimer release];
+        AquaSalTimer::pRunningTimer = nil;
     }
 }
 
-void ImplSalStopTimer()
+void AquaSalTimer::handleDispatchTimerEvent()
 {
-    AquaSalTimer::bDispatchTimer = false;
+    ImplSVData* pSVData = ImplGetSVData();
+    SolarMutexGuard aGuard;
+    if( pSVData->maSchedCtx.mpSalTimer )
+        pSVData->maSchedCtx.mpSalTimer->CallCallback();
 }
 
 void AquaSalTimer::handleStartTimerEvent( NSEvent* pEvent )
@@ -98,14 +119,10 @@ void AquaSalTimer::handleStartTimerEvent( NSEvent* pEvent )
         NSTimeInterval posted = [pEvent timestamp] + NSTimeInterval([pEvent data1])/1000.0;
         NSTimeInterval current = [NSDate timeIntervalSinceReferenceDate];
         if( (posted - current) <= 0.0 )
-        {
-            SolarMutexGuard aGuard;
-            if( pSVData->maSchedCtx.mpSalTimer )
-                pSVData->maSchedCtx.mpSalTimer->CallCallback();
-        }
-        ImplSalStartTimer( sal_uLong( [pEvent data1] ) );
+            handleDispatchTimerEvent();
+        else
+            ImplSalStartTimer( sal_uLong( [pEvent data1] ) );
     }
-
 }
 
 AquaSalTimer::AquaSalTimer( )
diff --git a/vcl/osx/vclnsapp.mm b/vcl/osx/vclnsapp.mm
index 4c38466961b0..2add55ffde85 100644
--- a/vcl/osx/vclnsapp.mm
+++ b/vcl/osx/vclnsapp.mm
@@ -73,8 +73,8 @@ SAL_WNODEPRECATED_DECLARATIONS_PUSH
                                data1: 0
                                data2: 0 ];
 SAL_WNODEPRECATED_DECLARATIONS_POP
-    if( pEvent )
-        [NSApp postEvent: pEvent atStart: NO];
+    assert( pEvent );
+    [NSApp postEvent: pEvent atStart: NO];
 }
 
 -(void)sendEvent:(NSEvent*)pEvent
commit 8ef4ef7e778fdc3a5ac8d6d6944fb3d4297a03ec
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Sun Oct 30 02:02:10 2016 +0100

    WIN just wait for the Yield mutex in the timerout
    
    Don't re-schedule a timeout, simply wait in the timer callback.
    
    Change-Id: Ib46eb6dbf57f29c85ffdbd6492922020f7785d30

diff --git a/vcl/win/app/saltimer.cxx b/vcl/win/app/saltimer.cxx
index 2b7e90c46a3e..f994fd80044e 100644
--- a/vcl/win/app/saltimer.cxx
+++ b/vcl/win/app/saltimer.cxx
@@ -150,16 +150,9 @@ void EmitTimerCallback()
     if ( ! pSVData->maSchedCtx.mpSalTimer )
         return;
 
-    // Try to acquire the mutex. If we don't get the mutex then we
-    // try this a short time later again.
-    if (ImplSalYieldMutexTryToAcquire())
-    {
-        pSVData->maSchedCtx.mpSalTimer->CallCallback();
-
-        ImplSalYieldMutexRelease();
-    }
-    else
-        ImplSalStartTimer( 10 );
+    ImplSalYieldMutexAcquireWithWait();
+    pSVData->maSchedCtx.mpSalTimer->CallCallback();
+    ImplSalYieldMutexRelease();
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 1e3bdbab96526baf36be03e2724162dcd65a9983
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Sun Oct 30 00:14:18 2016 +0000

    WIN simplify system timer / LO event handling
    
    The system timer is supposed to have the following constraints:
    
    1. There is just one system timer, which drives LO event loop
    2. The timer has to run in the main window thread
    3. Messages are processed in order, so there is no real need for
       calling SendMessageW instead of PostMessageW
    4. LO event loop is supposed to be processed in the main window
       thread with the Solar mutex acquired
    5. The system timer is a single-shot timer
    6. The only one stopping the system timer is the scheduler, either
       when without tasks to process, or on VCL shutdown
    
    Following these constraints, we can remove quite a bit of timer
    handling code, which simplifies its handling.
    
    Drop the 16bit MAX duration limit, as CreateTimerQueueTimer uses
    a DWORD for the DueTime parameter, which is always UINT32.
    
    CreateTimerQueueTimer already sets the period to 0, which makes it
    a one-shot timer, but there is also the WT_EXECUTEONLYONCE, which
    enforces the Period parameter to be 0.
    
    Change-Id: I549142394334bdc098f053b42f222b23cf4fcecd

diff --git a/vcl/inc/win/saldata.hxx b/vcl/inc/win/saldata.hxx
index 2fb1b49d5177..b76dd0b02aed 100644
--- a/vcl/inc/win/saldata.hxx
+++ b/vcl/inc/win/saldata.hxx
@@ -80,10 +80,6 @@ public:
     long*                   mpDitherDiff;           // Dither mapping table
     BYTE*                   mpDitherLow;            // Dither mapping table
     BYTE*                   mpDitherHigh;           // Dither mapping table
-    sal_uLong               mnTimerMS;              // Current Time (in MS) of the Timer
-    sal_uLong               mnTimerOrgMS;           // Current Original Time (in MS)
-    DWORD                   mnNextTimerTime;
-    DWORD                   mnLastEventTime;
     HANDLE                  mnTimerId;              ///< Windows timer id
     HHOOK                   mhSalObjMsgHook;        // hook to get interesting msg for SalObject
     HWND                    mhWantLeaveMsg;         // window handle, that want a MOUSELEAVE message
@@ -206,7 +202,7 @@ int ImplSalWICompareAscii( const wchar_t* pStr1, const char* pStr2 );
 // wParam == bWait; lParam == 0
 #define SAL_MSG_THREADYIELD         (WM_USER+111)
 // wParam == 0; lParam == nMS
-#define SAL_MSG_STARTTIMER          (WM_USER+113)
+#define SAL_MSG_DEFERREDSTARTTIMER  (WM_USER+113)
 // wParam == nFrameStyle; lParam == pParent; lResult == pFrame
 #define SAL_MSG_CREATEFRAME         (WM_USER+114)
 // wParam == 0; lParam == 0
@@ -232,6 +228,7 @@ int ImplSalWICompareAscii( const wchar_t* pStr1, const char* pStr2 );
 #define SAL_MSG_MOUSELEAVE          (WM_USER+131)
 // NULL-Message, should not be processed
 #define SAL_MSG_DUMMY               (WM_USER+132)
+// Used for SETFOCUS and KILLFOCUS
 // wParam == 0; lParam == 0
 #define SAL_MSG_POSTFOCUS           (WM_USER+133)
 // wParam == wParam; lParam == lParam
@@ -258,18 +255,15 @@ int ImplSalWICompareAscii( const wchar_t* pStr1, const char* pStr2 );
 #define SAL_MSG_SETINPUTCONTEXT     (WM_USER+144)
 // wParam == nFlags; lParam == 0
 #define SAL_MSG_ENDEXTTEXTINPUT     (WM_USER+145)
-// POSTTIMER-Message; wparam = 0, lParam == time
-#define SAL_MSG_POSTTIMER        (WM_USER+161)
 
 // SysChild-ToTop; wParam = 0; lParam = 0
 #define SALOBJ_MSG_TOTOP            (WM_USER+160)
+// Used for SETFOCUS and KILLFOCUS
 // POSTFOCUS-Message; wParam == bFocus; lParam == 0
 #define SALOBJ_MSG_POSTFOCUS        (WM_USER+161)
 
 // Call the Timer's callback from the main thread
 #define SAL_MSG_TIMER_CALLBACK      (WM_USER+162)
-// Stop the timer from the main thread; wParam = 0, lParam = 0
-#define SAL_MSG_STOPTIMER           (WM_USER+163)
 
 inline void SetWindowPtr( HWND hWnd, WinSalFrame* pThis )
 {
diff --git a/vcl/inc/win/salinst.h b/vcl/inc/win/salinst.h
index 1466c48c7a1c..a1aa4c82efe1 100644
--- a/vcl/inc/win/salinst.h
+++ b/vcl/inc/win/salinst.h
@@ -82,8 +82,7 @@ public:
 SalFrame* ImplSalCreateFrame( WinSalInstance* pInst, HWND hWndParent, SalFrameStyleFlags nSalFrameStyle );
 SalObject* ImplSalCreateObject( WinSalInstance* pInst, WinSalFrame* pParent );
 HWND ImplSalReCreateHWND( HWND hWndParent, HWND oldhWnd, bool bAsChild );
-void ImplSalStartTimer( sal_uIntPtr nMS, bool bMutex = false );
-void ImplSalStopTimer();
+void ImplSalStartTimer( sal_uIntPtr nMS );
 
 #endif // INCLUDED_VCL_INC_WIN_SALINST_H
 
diff --git a/vcl/win/app/salinst.cxx b/vcl/win/app/salinst.cxx
index c6dfabf9d65c..7aa6c854880f 100644
--- a/vcl/win/app/salinst.cxx
+++ b/vcl/win/app/salinst.cxx
@@ -317,10 +317,6 @@ SalData::SalData()
     mpDitherDiff = nullptr;     // Dither mapping table
     mpDitherLow = nullptr;      // Dither mapping table
     mpDitherHigh = nullptr;     // Dither mapping table
-    mnTimerMS = 0;              // Current Time (in MS) of the Timer
-    mnTimerOrgMS = 0;           // Current Original Time (in MS)
-    mnNextTimerTime = 0;
-    mnLastEventTime = 0;
     mnTimerId = nullptr;        // windows timer id
     mhSalObjMsgHook = nullptr;  // hook to get interesting msg for SalObject
     mhWantLeaveMsg = nullptr;   // window handle, that want a MOUSELEAVE message
@@ -659,14 +655,17 @@ LRESULT CALLBACK SalComWndProc( HWND, UINT nMsg, WPARAM wParam, LPARAM lParam, i
             ImplSalYield( (bool)wParam, (bool)lParam );
             rDef = FALSE;
             break;
-        case SAL_MSG_STARTTIMER:
-            ImplSalStartTimer( (sal_uLong) lParam );
-            rDef = FALSE;
-            break;
-        case SAL_MSG_STOPTIMER:
-            ImplSalStopTimer();
+        case SAL_MSG_DEFERREDSTARTTIMER:
+        {
+            sal_uLong nTime = GetTickCount();
+            if ( nTime < (sal_uLong) lParam )
+                nTime = (sal_uLong) lParam - nTime;
+            else
+                nTime = 0;
+            ImplSalStartTimer( nTime );
             rDef = FALSE;
             break;
+        }
         case SAL_MSG_CREATEFRAME:
             nRet = reinterpret_cast<LRESULT>(ImplSalCreateFrame( GetSalData()->mpFirstInstance, reinterpret_cast<HWND>(lParam), (SalFrameStyleFlags)wParam ));
             rDef = FALSE;
@@ -711,23 +710,12 @@ LRESULT CALLBACK SalComWndProc( HWND, UINT nMsg, WPARAM wParam, LPARAM lParam, i
             ReleaseDC( reinterpret_cast<HWND>(wParam), reinterpret_cast<HDC>(lParam) );
             rDef = FALSE;
             break;
-        case SAL_MSG_POSTTIMER:
-            EmitTimerCallback();
-            break;
         case SAL_MSG_TIMER_CALLBACK:
-            EmitTimerCallback();
             MSG aMsg;
-            while (PeekMessageW(&aMsg, nullptr, SAL_MSG_TIMER_CALLBACK, SAL_MSG_TIMER_CALLBACK, PM_REMOVE))
-            {
-                // nothing; just remove all the SAL_MSG_TIMER_CALLBACKs that
-                // accumulated in the queue during the EmitTimerCallback(),
-                // otherwise it happens with short timeouts and long callbacks
-                // that no other events will ever be processed, as the queue
-                // is full of SAL_MSG_TIMER_CALLBACKs.
-                // It is impossible to limit the amount of them being emitted
-                // in the first place, as they are emitted asynchronously, but
-                // here we are already fully synchronized.
-            }
+            while ( PeekMessageW(&aMsg, nullptr, SAL_MSG_TIMER_CALLBACK,
+                                 SAL_MSG_TIMER_CALLBACK, PM_REMOVE) )
+                assert( "Multiple timer messages in queue" );
+            EmitTimerCallback();
             break;
     }
 
@@ -833,24 +821,6 @@ bool WinSalInstance::AnyInput( VclInputFlags nType )
     return false;
 }
 
-void SalTimer::Start( sal_uLong nMS )
-{
-    // to switch to Main-Thread
-    SalData* pSalData = GetSalData();
-    if ( pSalData->mpFirstInstance )
-    {
-        if ( pSalData->mnAppThreadId != GetCurrentThreadId() )
-        {
-            BOOL const ret = PostMessageW(pSalData->mpFirstInstance->mhComWnd, SAL_MSG_STARTTIMER, 0, (LPARAM)nMS);
-            SAL_WARN_IF(0 == ret, "vcl", "ERROR: PostMessage() failed!");
-        }
-        else
-            SendMessageW( pSalData->mpFirstInstance->mhComWnd, SAL_MSG_STARTTIMER, 0, (LPARAM)nMS );
-    }
-    else
-        ImplSalStartTimer( nMS );
-}
-
 SalFrame* WinSalInstance::CreateChildFrame( SystemParentData* pSystemParentData, SalFrameStyleFlags nSalFrameStyle )
 {
     // to switch to Main-Thread
diff --git a/vcl/win/app/saltimer.cxx b/vcl/win/app/saltimer.cxx
index 25412dcf6186..2b7e90c46a3e 100644
--- a/vcl/win/app/saltimer.cxx
+++ b/vcl/win/app/saltimer.cxx
@@ -22,8 +22,9 @@
 #include <win/saltimer.h>
 #include <win/salinst.h>
 
-// maximum period
-#define MAX_SYSPERIOD     65533
+#if defined ( __MINGW32__ )
+#include <sehandler.hxx>
+#endif
 
 void CALLBACK SalTimerProc(PVOID pParameter, BOOLEAN bTimerOrWaitFired);
 
@@ -34,67 +35,71 @@ void CALLBACK SalTimerProc(PVOID pParameter, BOOLEAN bTimerOrWaitFired);
 // deletion of timer (which is extremely likely, given that
 // INVALID_HANDLE_VALUE waits for the callback to run on the main thread),
 // this must run on the main thread too
-void ImplSalStopTimer()
+static void ImplSalStopTimer()
 {
     SalData *const pSalData = GetSalData();
+    assert( !pSalData->mpFirstInstance || pSalData->mnAppThreadId == GetCurrentThreadId() );
+
     HANDLE hTimer = pSalData->mnTimerId;
     if (hTimer)
     {
-        pSalData->mnTimerId = nullptr; // reset so it doesn't restart
+        pSalData->mnTimerId = nullptr;
         DeleteTimerQueueTimer(nullptr, hTimer, INVALID_HANDLE_VALUE);
-        pSalData->mnNextTimerTime = 0;
     }
+
+    // remove all pending SAL_MSG_TIMER_CALLBACK messages
+    // we always have to do this, since ImplSalStartTimer with 0ms just queues
+    // a new SAL_MSG_TIMER_CALLBACK message
     MSG aMsg;
-    // this needs to run on the main thread
-    while (PeekMessageW(&aMsg, nullptr, SAL_MSG_TIMER_CALLBACK, SAL_MSG_TIMER_CALLBACK, PM_REMOVE))
-    {
-        // just remove all the SAL_MSG_TIMER_CALLBACKs
-        // when the application end, this SAL_MSG_TIMER_CALLBACK start the timer again
-        // and then crashed in "SalTimerProc" when the object "SalData" was deleted
-    }
+    int nMsgCount = 0;
+    while ( PeekMessageW(&aMsg, nullptr, SAL_MSG_TIMER_CALLBACK,
+                         SAL_MSG_TIMER_CALLBACK, PM_REMOVE) )
+        nMsgCount++;
+    assert( nMsgCount <= 1 );
 }
 
-void ImplSalStartTimer( sal_uLong nMS, bool bMutex )
+void ImplSalStartTimer( sal_uLong nMS )
 {
     SalData* pSalData = GetSalData();
+    assert( !pSalData->mpFirstInstance || pSalData->mnAppThreadId == GetCurrentThreadId() );
 
-    // Remember the time of the timer
-    pSalData->mnTimerMS = nMS;
-    if (!bMutex)
-        pSalData->mnTimerOrgMS = nMS;
+    // DueTime parameter is a DWORD, which is always an unsigned 32bit
+    if (nMS > SAL_MAX_UINT32)
+        nMS = SAL_MAX_UINT32;
 
-    // duration has to fit into Window's sal_uInt16
-    if (nMS > MAX_SYSPERIOD)
-        nMS = MAX_SYSPERIOD;
+    // cannot change a one-shot timer, so delete it and create a new one
+    ImplSalStopTimer();
 
-    // cannot change a one-shot timer, so delete it and create new one
-    if (pSalData->mnTimerId)
+    // directly post a timer callback message for instant timers / idles
+    if ( 0 == nMS )
     {
-        DeleteTimerQueueTimer(nullptr, pSalData->mnTimerId, INVALID_HANDLE_VALUE);
-        pSalData->mnTimerId = nullptr;
+        BOOL const ret = PostMessageW(pSalData->mpFirstInstance->mhComWnd,
+                                      SAL_MSG_TIMER_CALLBACK, 0, 0);
+        SAL_WARN_IF(0 == ret, "vcl", "ERROR: PostMessage() failed!");
+    }
+    else
+    {
+        // probably WT_EXECUTEONLYONCE is not needed, but it enforces Period
+        // to be 0 and should not hurt; also see
+        // https://www.microsoft.com/msj/0499/pooling/pooling.aspx
+        CreateTimerQueueTimer(&pSalData->mnTimerId, nullptr, SalTimerProc, nullptr,
+                              nMS, 0, WT_EXECUTEINTIMERTHREAD | WT_EXECUTEONLYONCE);
     }
-    CreateTimerQueueTimer(&pSalData->mnTimerId, nullptr, SalTimerProc, nullptr, nMS, 0, WT_EXECUTEINTIMERTHREAD);
-
-    pSalData->mnNextTimerTime = pSalData->mnLastEventTime + nMS;
 }
 
 WinSalTimer::~WinSalTimer()
 {
+    Stop();
 }
 
 void WinSalTimer::Start( sal_uLong nMS )
 {
-    // switch to main thread
     SalData* pSalData = GetSalData();
-    if ( pSalData->mpFirstInstance )
+    if ( pSalData->mpFirstInstance && pSalData->mnAppThreadId != GetCurrentThreadId() )
     {
-        if ( pSalData->mnAppThreadId != GetCurrentThreadId() )
-        {
-            BOOL const ret = PostMessageW(pSalData->mpFirstInstance->mhComWnd, SAL_MSG_STARTTIMER, 0, (LPARAM)nMS);
-            SAL_WARN_IF(0 == ret, "vcl", "ERROR: PostMessage() failed!");
-        }
-        else
-            SendMessageW( pSalData->mpFirstInstance->mhComWnd, SAL_MSG_STARTTIMER, 0, (LPARAM)nMS );
+        BOOL const ret = PostMessageW(pSalData->mpFirstInstance->mhComWnd,
+            SAL_MSG_DEFERREDSTARTTIMER, 0, (LPARAM)GetTickCount() + nMS);
+        SAL_WARN_IF(0 == ret, "vcl", "ERROR: PostMessage() failed!");
     }
     else
         ImplSalStartTimer( nMS );
@@ -102,10 +107,7 @@ void WinSalTimer::Start( sal_uLong nMS )
 
 void WinSalTimer::Stop()
 {
-    SalData* pSalData = GetSalData();
-
-    assert(pSalData->mpFirstInstance);
-    SendMessageW(pSalData->mpFirstInstance->mhComWnd, SAL_MSG_STOPTIMER, 0, 0);
+    ImplSalStopTimer();
 }
 
 /** This gets invoked from a Timer Queue thread.
@@ -122,7 +124,8 @@ void CALLBACK SalTimerProc(PVOID, BOOLEAN)
         // always post message when the timer fires, we will remove the ones
         // that happened during execution of the callback later directly from
         // the message queue
-        BOOL const ret = PostMessageW(pSalData->mpFirstInstance->mhComWnd, SAL_MSG_TIMER_CALLBACK, 0, 0);
+        BOOL const ret = PostMessageW(pSalData->mpFirstInstance->mhComWnd,
+                                      SAL_MSG_TIMER_CALLBACK, 0, 0);
 #if OSL_DEBUG_LEVEL > 0
         if (0 == ret) // SEH prevents using SAL_WARN here?
             fputs("ERROR: PostMessage() failed!", stderr);
@@ -140,31 +143,23 @@ call then happens when the main thread gets SAL_MSG_TIMER_CALLBACK.
 */
 void EmitTimerCallback()
 {
-    SalData* pSalData = GetSalData();
-    ImplSVData* pSVData = ImplGetSVData();
-
     // Test for MouseLeave
     SalTestMouseLeave();
 
+    ImplSVData *pSVData = ImplGetSVData();
+    if ( ! pSVData->maSchedCtx.mpSalTimer )
+        return;
+
     // Try to acquire the mutex. If we don't get the mutex then we
     // try this a short time later again.
-    if (pSVData->maSchedCtx.mpSalTimer && ImplSalYieldMutexTryToAcquire())
+    if (ImplSalYieldMutexTryToAcquire())
     {
         pSVData->maSchedCtx.mpSalTimer->CallCallback();
 
         ImplSalYieldMutexRelease();
-
-        // Run the timer again if it was started before, and also
-        // Run the timer in the correct time, if we started this
-        // with a small timeout, because we didn't get the mutex
-        // - but not if mnTimerId is 0, which is set by ImplSalStopTimer()
-        if (pSalData->mnTimerId)
-            ImplSalStartTimer(pSalData->mnTimerOrgMS);
     }
     else
-    {
-        ImplSalStartTimer(10, true);
-    }
+        ImplSalStartTimer( 10 );
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/win/window/salframe.cxx b/vcl/win/window/salframe.cxx
index 40e561542ec0..5f1393c4f02d 100644
--- a/vcl/win/window/salframe.cxx
+++ b/vcl/win/window/salframe.cxx
@@ -5476,8 +5476,6 @@ LRESULT CALLBACK SalFrameWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lP
         return 0;
     }
 
-    bool bCheckTimers = false;
-
     switch( nMsg )
     {
         case WM_MOUSEMOVE:
@@ -5614,11 +5612,11 @@ LRESULT CALLBACK SalFrameWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lP
             rDef = FALSE;
             break;
         case WM_PAINT:
-            bCheckTimers = ImplHandlePaintMsg( hWnd );
+            ImplHandlePaintMsg( hWnd );
             rDef = FALSE;
             break;
         case SAL_MSG_POSTPAINT:
-            bCheckTimers = ImplHandlePostPaintMsg( hWnd, reinterpret_cast<RECT*>(wParam) );
+            ImplHandlePostPaintMsg( hWnd, reinterpret_cast<RECT*>(wParam) );
             rDef = FALSE;
             break;
 
@@ -5839,24 +5837,6 @@ LRESULT CALLBACK SalFrameWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lP
             break;
     }
 
-    if( bCheckTimers )
-    {
-        SalData* pSalData = GetSalData();
-        if( pSalData->mnNextTimerTime )
-        {
-            DWORD nCurTime = GetTickCount();
-            if( pSalData->mnNextTimerTime < nCurTime )
-            {
-                MSG aMsg;
-                if( ! PeekMessageW( &aMsg, nullptr, WM_PAINT, WM_PAINT, PM_NOREMOVE | PM_NOYIELD ) )
-                {
-                    BOOL const ret = PostMessageW(pSalData->mpFirstInstance->mhComWnd, SAL_MSG_POSTTIMER, 0, nCurTime);
-                    SAL_WARN_IF(0 == ret, "vcl", "ERROR: PostMessage() failed!");
-                }
-            }
-        }
-    }
-
     return nRet;
 }
 
commit 6fa827dee1088535ba3f21e2e9ad382c87087213
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Sat Oct 29 12:00:08 2016 +0200

    WIN unify deferred message handling
    
    Moves the common code into ProcessOrDeferMessage.
    
    All callers (try to) aquire the mutex before getting the
    WinSalFrame pointer, except for ImplHandleDeferredPaintMsg.
    
    This was probably an oversight, so this reverses the order in this

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list