Rebased ref, commits from common ancestor:
commit 29acdcdf561fc6412161f48714b1915c4119c622
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Wed Sep 27 16:42:57 2017 +0200

    DO NOT MERGE - error in clang static plugin
    
    vcl/unx/gtk/gtkdata.cxx:817:39: error: this parameter can be const 
[loplugin:constparams]
        static gboolean call_userEventFn( void *data )
                                          ^~~~~~~~~~
    1 error generated.
    /vcl/unx/gtk3/gtk3gtkdata.cxx:782:39: error: this parameter can be const 
[loplugin:constparams]
        static gboolean call_userEventFn( void *data )
                                          ^~~~~~~~~~
    1 error generated.
    
    Change-Id: Id8d42a0c14bfcc887ec1ecbf70f4c41c26e26efb

diff --git a/vcl/unx/gtk/gtkdata.cxx b/vcl/unx/gtk/gtkdata.cxx
index da70c0fbd62c..77abe724298d 100644
--- a/vcl/unx/gtk/gtkdata.cxx
+++ b/vcl/unx/gtk/gtkdata.cxx
@@ -816,12 +816,11 @@ void GtkSalTimer::Stop()
 extern "C" {
     static gboolean call_userEventFn( void *data )
     {
-        GtkSalData *pThis = static_cast<GtkSalData *>(data);
         SolarMutexGuard aGuard;
         const SalGenericDisplay *pDisplay = 
GetGenericUnixSalData()->GetDisplay();
         if ( pDisplay )
         {
-            GtkSalDisplay *pThisDisplay = pThis->GetGtkDisplay();
+            GtkSalDisplay *pThisDisplay = static_cast<GtkSalData 
*>(data)->GetGtkDisplay();
             assert(static_cast<const SalGenericDisplay *>(pThisDisplay) == 
pDisplay);
             pThisDisplay->DispatchInternalEvent();
         }
diff --git a/vcl/unx/gtk3/gtk3gtkdata.cxx b/vcl/unx/gtk3/gtk3gtkdata.cxx
index fbd449ef4ec6..f4d41a53d2c0 100644
--- a/vcl/unx/gtk3/gtk3gtkdata.cxx
+++ b/vcl/unx/gtk3/gtk3gtkdata.cxx
@@ -781,12 +781,11 @@ void GtkSalTimer::Stop()
 extern "C" {
     static gboolean call_userEventFn( void *data )
     {
-        GtkSalData *pThis = static_cast<GtkSalData *>(data);
         SolarMutexGuard aGuard;
         const SalGenericDisplay *pDisplay = 
GetGenericUnixSalData()->GetDisplay();
         if ( pDisplay )
         {
-            GtkSalDisplay *pThisDisplay = pThis->GetGtkDisplay();
+            GtkSalDisplay *pThisDisplay = static_cast<GtkSalData 
*>(data)->GetGtkDisplay();
             assert(static_cast<const SalGenericDisplay *>(pThisDisplay) == 
pDisplay);
             pThisDisplay->DispatchInternalEvent();
         }
commit 16f7daff659619d6c26749f828022694ac6a9340
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Tue Sep 26 19:06:51 2017 +0200

    tdf#112605 OSX refactor SalAquaTimer
    
    Drops all the static calls and variables from SalAquaTimer
    and moves all timer handling logic inside the class.
    
    This also fixes the leak in in timerElapsed.
    
    Change-Id: Ie7a1a8fffb70b8579ec6876eed10a275d2f06d27

diff --git a/vcl/inc/osx/saltimer.h b/vcl/inc/osx/saltimer.h
index 86964115d648..ad6adf9d00ed 100644
--- a/vcl/inc/osx/saltimer.h
+++ b/vcl/inc/osx/saltimer.h
@@ -43,6 +43,12 @@ public:
 
 class AquaSalTimer : public SalTimer
 {
+    NSTimer    *m_pRunningTimer;
+    sal_uInt32  m_nTimerStartTicks;  ///< system ticks at timer start % 
SAL_MAX_UINT32
+
+    void queueDispatchTimerEvent( bool bAtStart );
+    void callTimerCallback();
+
 public:
     AquaSalTimer();
     virtual ~AquaSalTimer() override;
@@ -50,13 +56,18 @@ public:
     void Start( sal_uLong nMS ) override;
     void Stop() override;
 
-    static void handleStartTimerEvent( NSEvent* pEvent );
-    static void handleDispatchTimerEvent();
+    void handleStartTimerEvent( NSEvent* pEvent );
+    void handleDispatchTimerEvent( NSEvent* pEvent );
+    void handleTimerElapsed();
 
-    static NSTimer* pRunningTimer;
-    static bool bDispatchTimer;
+    inline bool IsTimerElapsed() const;
 };
 
+inline bool AquaSalTimer::IsTimerElapsed() const
+{
+    return 0 != m_nTimerStartTicks;
+}
+
 #endif // INCLUDED_VCL_INC_OSX_SALTIMER_H
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/osx/salinst.cxx b/vcl/osx/salinst.cxx
index 89e3ae6d4e82..1b08a29461e6 100644
--- a/vcl/osx/salinst.cxx
+++ b/vcl/osx/salinst.cxx
@@ -426,11 +426,13 @@ bool AquaSalInstance::IsMainThread() const
 
 void AquaSalInstance::handleAppDefinedEvent( NSEvent* pEvent )
 {
+    AquaSalTimer *pTimer = static_cast<AquaSalTimer*>( 
ImplGetSVData()->maSchedCtx.mpSalTimer );
     int nSubtype = [pEvent subtype];
     switch( nSubtype )
     {
     case AppStartTimerEvent:
-        AquaSalTimer::handleStartTimerEvent( pEvent );
+        if ( pTimer )
+            pTimer->handleStartTimerEvent( pEvent );
         break;
     case AppEndLoopEvent:
         [NSApp stop: NSApp];
@@ -450,7 +452,8 @@ void AquaSalInstance::handleAppDefinedEvent( NSEvent* 
pEvent )
         break;
     }
     case DispatchTimerEvent:
-        AquaSalTimer::handleDispatchTimerEvent();
+        if ( pTimer )
+            pTimer->handleDispatchTimerEvent( pEvent );
         break;
 #if !HAVE_FEATURE_MACOSX_SANDBOX
     case AppleRemoteControlEvent: // Defined in 
<apple_remote/RemoteMainController.h>
@@ -598,12 +601,11 @@ SAL_WNODEPRECATED_DECLARATIONS_POP
         {
             SolarMutexReleaser aReleaser;
 
-            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
 SAL_WNODEPRECATED_DECLARATIONS_POP
-                            untilDate: pDt
+                            untilDate: [NSDate distantFuture]
                             inMode: NSDefaultRunLoopMode
                             dequeue: YES];
             if( pEvent )
@@ -682,14 +684,9 @@ bool AquaSalInstance::AnyInput( VclInputFlags nType )
 
     if( nType & VclInputFlags::TIMER )
     {
-        if( AquaSalTimer::pRunningTimer )
-        {
-            NSDate* pDt = [AquaSalTimer::pRunningTimer fireDate];
-            if( pDt && [pDt timeIntervalSinceNow] < 0 )
-            {
-                return true;
-            }
-        }
+        AquaSalTimer *pTimer = static_cast<AquaSalTimer*>( 
ImplGetSVData()->maSchedCtx.mpSalTimer );
+        if (pTimer && pTimer->IsTimerElapsed())
+            return true;
     }
 
     unsigned/*NSUInteger*/ nEventMask = 0;
diff --git a/vcl/osx/salnstimer.mm b/vcl/osx/salnstimer.mm
index c9b657dcd776..9647bb6b87c1 100644
--- a/vcl/osx/salnstimer.mm
+++ b/vcl/osx/salnstimer.mm
@@ -27,16 +27,12 @@
 
 @implementation TimerCallbackCaller
 
--(void)timerElapsed:(NSTimer*)pTimer
+-(void)timerElapsed:(NSTimer*)pNSTimer
 {
-    (void)pTimer;
-    // nil the timer, as it is just invalidated after the firing function
-    AquaSalTimer::pRunningTimer = nil;
-    const AquaSalInstance *pInst = GetSalData()->mpFirstInstance;
-    if (pInst->mbIsLiveResize)
-        AquaSalTimer::handleDispatchTimerEvent();
-    else
-        ImplNSAppPostEvent( AquaSalInstance::DispatchTimerEvent, YES );
+    (void) pNSTimer;
+    AquaSalTimer *pTimer = static_cast<AquaSalTimer*>( 
ImplGetSVData()->maSchedCtx.mpSalTimer );
+    if (pTimer)
+        pTimer->handleTimerElapsed();
 }
 
 @end
diff --git a/vcl/osx/saltimer.cxx b/vcl/osx/saltimer.cxx
index e442fcf05335..9c5bb7a7db9e 100644
--- a/vcl/osx/saltimer.cxx
+++ b/vcl/osx/saltimer.cxx
@@ -20,6 +20,7 @@
 #include <sal/config.h>
 
 #include <rtl/math.hxx>
+#include <tools/time.hxx>
 
 #include "osx/saltimer.h"
 #include "osx/salnstimer.h"
@@ -27,9 +28,6 @@
 #include "osx/salframe.h"
 #include "osx/salinst.h"
 
-NSTimer* AquaSalTimer::pRunningTimer = nil;
-
-static void ImplSalStopTimer();
 
 void ImplNSAppPostEvent( short nEventId, BOOL bAtStart, int nUserData )
 {
@@ -73,7 +71,16 @@ SAL_WNODEPRECATED_DECLARATIONS_POP
     [NSApp postEvent: pEvent atStart: bAtStart];
 }
 
-static void ImplSalStartTimer( sal_uLong nMS )
+void AquaSalTimer::queueDispatchTimerEvent( bool bAtStart )
+{
+    Stop();
+    m_nTimerStartTicks = tools::Time::GetMonotonicTicks() % SAL_MAX_UINT32;
+    if ( 0 == m_nTimerStartTicks )
+        m_nTimerStartTicks++;
+    ImplNSAppPostEvent( AquaSalInstance::DispatchTimerEvent, bAtStart, 
m_nTimerStartTicks );
+}
+
+void AquaSalTimer::Start( sal_uLong nMS )
 {
     SalData* pSalData = GetSalData();
 
@@ -84,27 +91,24 @@ static void ImplSalStartTimer( sal_uLong nMS )
     }
 
     if ( 0 == nMS && !pSalData->mpFirstInstance->mbIsLiveResize )
-    {
-        ImplSalStopTimer();
-        ImplNSAppPostEvent( AquaSalInstance::DispatchTimerEvent, NO );
-    }
+        queueDispatchTimerEvent( NO );
     else
     {
         NSTimeInterval aTI = double(nMS) / 1000.0;
-        if( AquaSalTimer::pRunningTimer != nil )
+        if( m_pRunningTimer != nil )
         {
-            if ([AquaSalTimer::pRunningTimer isValid] && 
rtl::math::approxEqual(
-                    [AquaSalTimer::pRunningTimer timeInterval], aTI))
+            if ([m_pRunningTimer isValid] && rtl::math::approxEqual(
+                    [m_pRunningTimer timeInterval], aTI))
             {
                 // set new fire date
-                [AquaSalTimer::pRunningTimer setFireDate: [NSDate 
dateWithTimeIntervalSinceNow: aTI]];
+                [m_pRunningTimer setFireDate: [NSDate 
dateWithTimeIntervalSinceNow: aTI]];
             }
             else
-                ImplSalStopTimer();
+                Stop();
         }
-        if( AquaSalTimer::pRunningTimer == nil )
+        if( m_pRunningTimer == nil )
         {
-            AquaSalTimer::pRunningTimer = [[NSTimer 
scheduledTimerWithTimeInterval: aTI
+            m_pRunningTimer = [[NSTimer scheduledTimerWithTimeInterval: aTI
                                                     target: 
[[[TimerCallbackCaller alloc] init] autorelease]
                                                     selector: 
@selector(timerElapsed:)
                                                     userInfo: nil
@@ -113,22 +117,23 @@ static void ImplSalStartTimer( sal_uLong nMS )
             /* #i84055# add timer to tracking run loop mode,
                so they also elapse while e.g. life resize
             */
-            [[NSRunLoop currentRunLoop] addTimer: AquaSalTimer::pRunningTimer 
forMode: NSEventTrackingRunLoopMode];
+            [[NSRunLoop currentRunLoop] addTimer: m_pRunningTimer forMode: 
NSEventTrackingRunLoopMode];
         }
     }
 }
 
-static void ImplSalStopTimer()
+void AquaSalTimer::Stop()
 {
-    if( AquaSalTimer::pRunningTimer != nil )
+    if( m_pRunningTimer != nil )
     {
-        [AquaSalTimer::pRunningTimer invalidate];
-        [AquaSalTimer::pRunningTimer release];
-        AquaSalTimer::pRunningTimer = nil;
+        [m_pRunningTimer invalidate];
+        [m_pRunningTimer release];
+        m_pRunningTimer = nil;
     }
+    m_nTimerStartTicks = 0;
 }
 
-void AquaSalTimer::handleDispatchTimerEvent()
+void AquaSalTimer::callTimerCallback()
 {
     ImplSVData* pSVData = ImplGetSVData();
     SolarMutexGuard aGuard;
@@ -136,6 +141,23 @@ void AquaSalTimer::handleDispatchTimerEvent()
         pSVData->maSchedCtx.mpSalTimer->CallCallback();
 }
 
+void AquaSalTimer::handleTimerElapsed()
+{
+    // Stop the timer, as it is just invalidated after the firing function
+    Stop();
+
+    if ( GetSalData()->mpFirstInstance->mbIsLiveResize )
+        callTimerCallback();
+    else
+        queueDispatchTimerEvent( YES );
+}
+
+void AquaSalTimer::handleDispatchTimerEvent( NSEvent *pEvent )
+{
+    if (m_nTimerStartTicks == [pEvent data1])
+        callTimerCallback();
+}
+
 void AquaSalTimer::handleStartTimerEvent( NSEvent* pEvent )
 {
     ImplSVData* pSVData = ImplGetSVData();
@@ -144,29 +166,21 @@ void AquaSalTimer::handleStartTimerEvent( NSEvent* pEvent 
)
         NSTimeInterval posted = [pEvent timestamp] + NSTimeInterval([pEvent 
data1])/1000.0;
         NSTimeInterval current = [NSDate timeIntervalSinceReferenceDate];
         if( (posted - current) <= 0.0 )
-            handleDispatchTimerEvent();
+            queueDispatchTimerEvent( YES );
         else
-            ImplSalStartTimer( sal_uLong( [pEvent data1] ) );
+            Start( sal_uLong( [pEvent data1] ) );
     }
 }
 
 AquaSalTimer::AquaSalTimer( )
+    : m_pRunningTimer( nullptr )
+    , m_nTimerStartTicks( 0 )
 {
 }
 
 AquaSalTimer::~AquaSalTimer()
 {
-    ImplSalStopTimer();
-}
-
-void AquaSalTimer::Start( sal_uLong nMS )
-{
-    ImplSalStartTimer( nMS );
-}
-
-void AquaSalTimer::Stop()
-{
-    ImplSalStopTimer();
+    Stop();
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit a24812abaa2d4c0294ed92c365070b40e93f53c6
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Mon Sep 4 17:40:13 2017 +0200

    Unify SalUserEvent handling
    
    Merges the various SalUserEvent structs and their handling into
    a single class. This includes a common SalFrame* hash map, as all
    backends use such a map to verify alive SalFrames.
    
    It also reverts the "FIXME: lousy workaround" for i#90083, which
    was part of commit d6f7c94e5c27ba02ff5c3229760c9808cc9b5bea.
    
    At least on my current OSX box application based window switching
    "just works" "out of the box", even without the code.
    
    Change-Id: I188b567e44fd79c162b2d9cabbd771d1f66c7dc4

diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 1aa3095d0a6c..5d62542e8b13 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -321,6 +321,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
     vcl/source/app/help \
     vcl/source/app/i18nhelp \
        vcl/source/app/idle \
+       vcl/source/app/salusereventlist \
     vcl/source/app/salvtables \
        vcl/source/app/scheduler \
     vcl/source/app/session \
diff --git a/vcl/headless/svpframe.cxx b/vcl/headless/svpframe.cxx
index 9a086c0b3d6a..7fc7c3a88eb0 100644
--- a/vcl/headless/svpframe.cxx
+++ b/vcl/headless/svpframe.cxx
@@ -94,10 +94,9 @@ SvpSalFrame::~SvpSalFrame()
         // pass focus to another frame, preferably a document style window
         if( s_pFocusFrame == nullptr )
         {
-            const std::list< SalFrame* >& rFrames( m_pInstance->getFrames() );
-            for( std::list< SalFrame* >::const_iterator it = rFrames.begin(); 
it != rFrames.end(); ++it )
+            for (auto pSalFrame : m_pInstance->getFrames() )
             {
-                SvpSalFrame* pFrame = static_cast<SvpSalFrame*>(*it);
+                SvpSalFrame* pFrame = static_cast<SvpSalFrame*>( pSalFrame );
                 if( pFrame->m_bVisible        &&
                     pFrame->m_pParent == nullptr &&
                     (pFrame->m_nStyle & (SalFrameStyleFlags::MOVEABLE |
diff --git a/vcl/headless/svpinst.cxx b/vcl/headless/svpinst.cxx
index ab8f91eac31f..5153c8952f4a 100644
--- a/vcl/headless/svpinst.cxx
+++ b/vcl/headless/svpinst.cxx
@@ -47,19 +47,6 @@
 // FIXME: remove when we re-work the svp mainloop
 #include "unx/salunxtime.h"
 
-bool SvpSalInstance::isFrameAlive( const SalFrame* pFrame ) const
-{
-    for( std::list< SalFrame* >::const_iterator it = m_aFrames.begin();
-         it != m_aFrames.end(); ++it )
-    {
-        if( *it == pFrame )
-        {
-            return true;
-        }
-    }
-    return false;
-}
-
 SvpSalInstance* SvpSalInstance::s_pDefaultInstance = nullptr;
 
 #if !defined(ANDROID) && !defined(IOS)
@@ -165,12 +152,8 @@ void SvpSalInstance::CreateWakeupPipe(bool log)
 
 #endif
 
-void SvpSalInstance::PostEvent(const SalFrame* pFrame, ImplSVEvent* pData, 
SalEvent nEvent)
+void SvpSalInstance::TriggerUserEventProcessing()
 {
-    {
-        osl::MutexGuard g(m_aEventGuard);
-        m_aUserEvents.emplace_back( pFrame, pData, nEvent );
-    }
     Wakeup();
 }
 
@@ -186,31 +169,6 @@ bool SvpSalInstance::PostedEventsInQueue()
 }
 #endif
 
-void SvpSalInstance::deregisterFrame( SalFrame* pFrame )
-{
-    m_aFrames.remove( pFrame );
-
-    osl::MutexGuard g(m_aEventGuard);
-    // cancel outstanding events for this frame
-    if( ! m_aUserEvents.empty() )
-    {
-        std::list< SalUserEvent >::iterator it = m_aUserEvents.begin();
-        do
-        {
-            if( it->m_pFrame == pFrame )
-            {
-                if (it->m_nEvent == SalEvent::UserEvent)
-                {
-                    delete it->m_pData;
-                }
-                it = m_aUserEvents.erase( it );
-            }
-            else
-                ++it;
-        } while( it != m_aUserEvents.end() );
-    }
-}
-
 void SvpSalInstance::Wakeup()
 {
 #ifndef IOS
@@ -304,44 +262,24 @@ SalBitmap* SvpSalInstance::CreateSalBitmap()
 #endif
 }
 
-bool SvpSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents)
+void SvpSalInstance::ProcessEvent( SalUserEvent aEvent )
 {
-    // first, check for already queued events.
-    std::list< SalUserEvent > aEvents;
+    aEvent.m_pFrame->CallCallback( aEvent.m_nEvent, aEvent.m_pData );
+    if( aEvent.m_nEvent == SalEvent::Resize )
     {
-        osl::MutexGuard g(m_aEventGuard);
-        if( ! m_aUserEvents.empty() )
-        {
-            if( bHandleAllCurrentEvents )
-            {
-                aEvents = m_aUserEvents;
-                m_aUserEvents.clear();
-            }
-            else
-            {
-                aEvents.push_back( m_aUserEvents.front() );
-                m_aUserEvents.pop_front();
-            }
-        }
+        // this would be a good time to post a paint
+        const SvpSalFrame* pSvpFrame = static_cast<const SvpSalFrame*>( 
aEvent.m_pFrame);
+        pSvpFrame->PostPaint();
     }
+}
 
-    bool bEvent = !aEvents.empty();
-    if( bEvent )
-    {
-        for( std::list<SalUserEvent>::const_iterator it = aEvents.begin(); it 
!= aEvents.end(); ++it )
-        {
-            if ( isFrameAlive( it->m_pFrame ) )
-            {
-                it->m_pFrame->CallCallback( it->m_nEvent, it->m_pData );
-                if( it->m_nEvent == SalEvent::Resize )
-                {
-                    // this would be a good time to post a paint
-                    const SvpSalFrame* pSvpFrame = static_cast<const 
SvpSalFrame*>(it->m_pFrame);
-                    pSvpFrame->PostPaint();
-                }
-            }
-        }
-    }
+
+bool SvpSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents)
+{
+    // first, process current user events
+    bool bEvent = DispatchUserEvents( bHandleAllCurrentEvents );
+    if ( !bHandleAllCurrentEvents &&bEvent )
+        return true;
 
     bEvent = CheckTimeout() || bEvent;
 
diff --git a/vcl/headless/svpprn.cxx b/vcl/headless/svpprn.cxx
index 488f17bb4084..2afb52502300 100644
--- a/vcl/headless/svpprn.cxx
+++ b/vcl/headless/svpprn.cxx
@@ -257,10 +257,9 @@ OUString SvpSalInstance::GetDefaultPrinter()
 
 void SvpSalInstance::PostPrintersChanged()
 {
-    const std::list< SalFrame* >& rList = 
SvpSalInstance::s_pDefaultInstance->getFrames();
-    for( std::list< SalFrame* >::const_iterator it = rList.begin();
-         it != rList.end(); ++it )
-        SvpSalInstance::s_pDefaultInstance->PostEvent( *it, nullptr, 
SalEvent::PrinterChanged );
+    SvpSalInstance *pInst = SvpSalInstance::s_pDefaultInstance;
+    for (auto pSalFrame : pInst->getFrames() )
+        pInst->PostEvent( pSalFrame, nullptr, SalEvent::PrinterChanged );
 }
 
 GenPspGraphics *SvpSalInstance::CreatePrintGraphics()
diff --git a/vcl/inc/headless/svpinst.hxx b/vcl/inc/headless/svpinst.hxx
index 0883981c4406..80566be18248 100644
--- a/vcl/inc/headless/svpinst.hxx
+++ b/vcl/inc/headless/svpinst.hxx
@@ -25,6 +25,7 @@
 #include <salinst.hxx>
 #include <salwtype.hxx>
 #include <saltimer.hxx>
+#include <salusereventlist.hxx>
 #include <unx/geninst.h>
 #include <unx/genprn.h>
 
@@ -57,35 +58,18 @@ class GenPspGraphics;
 
 SalInstance* svp_create_SalInstance();
 
-class VCL_DLLPUBLIC SvpSalInstance : public SalGenericInstance
+class VCL_DLLPUBLIC SvpSalInstance : public SalGenericInstance, public 
SalUserEventList
 {
     timeval                 m_aTimeout;
     sal_uLong               m_nTimeoutMS;
     int                     m_pTimeoutFDS[2];
 
-    // internal event queue
-    struct SalUserEvent
-    {
-        const SalFrame*     m_pFrame;
-        ImplSVEvent*        m_pData;
-        SalEvent            m_nEvent;
-
-        SalUserEvent( const SalFrame* pFrame, ImplSVEvent* pData, SalEvent 
nEvent )
-                : m_pFrame( pFrame ),
-                  m_pData( pData ),
-                  m_nEvent( nEvent )
-        {}
-    };
-
-    osl::Mutex              m_aEventGuard;
-    std::list< SalUserEvent > m_aUserEvents;
-
-    std::list< SalFrame* >  m_aFrames;
-
-    bool                    isFrameAlive( const SalFrame* pFrame ) const;
-
     void                    DoReleaseYield( int nTimeoutMS );
 
+    virtual void            TriggerUserEventProcessing() override;
+    virtual void            ProcessEvent( SalUserEvent aEvent ) override;
+    void                    Wakeup();
+
 public:
     static SvpSalInstance*  s_pDefaultInstance;
 
@@ -95,20 +79,15 @@ public:
     void                    CloseWakeupPipe(bool log);
     void                    CreateWakeupPipe(bool log);
 
-    void                    PostEvent(const SalFrame* pFrame, ImplSVEvent* 
pData, SalEvent nEvent);
-
 #ifdef ANDROID
     bool                    PostedEventsInQueue();
 #endif
 
     void                    StartTimer( sal_uLong nMS );
     void                    StopTimer();
-    void                    Wakeup();
 
-    void                    registerFrame( SalFrame* pFrame ) { 
m_aFrames.push_back( pFrame ); }
-    void                    deregisterFrame( SalFrame* pFrame );
-    const std::list< SalFrame* >&
-                            getFrames() const { return m_aFrames; }
+    inline void             registerFrame( SalFrame* pFrame );
+    inline void             deregisterFrame( SalFrame* pFrame );
 
     bool                    CheckTimeout( bool bExecuteTimers = true );
 
@@ -171,6 +150,16 @@ public:
     virtual GenPspGraphics *CreatePrintGraphics() override;
 };
 
+inline void SvpSalInstance::registerFrame( SalFrame* pFrame )
+{
+    insertFrame( pFrame );
+}
+
+inline void SvpSalInstance::deregisterFrame( SalFrame* pFrame )
+{
+    eraseFrame( pFrame );
+}
+
 #endif // INCLUDED_VCL_INC_HEADLESS_SVPINST_HXX
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/osx/saldata.hxx b/vcl/inc/osx/saldata.hxx
index fbc28e05391d..5ec684b83973 100644
--- a/vcl/inc/osx/saldata.hxx
+++ b/vcl/inc/osx/saldata.hxx
@@ -45,6 +45,7 @@
 
 #include "apple_remote/RemoteMainController.h"
 
+class AquaSalFrame;
 class AquaSalInstance;
 class SalObject;
 class SalFrame;
@@ -53,14 +54,6 @@ class SalPrinter;
 class SystemFontList;
 
 #define SAL_CLIPRECT_COUNT 16
-
-class AquaSalFrame;
-struct FrameHash : public std::hash<sal_IntPtr>
-{
-    size_t operator()(const AquaSalFrame* frame) const
-    { return std::hash<sal_IntPtr>::operator()( reinterpret_cast<const 
sal_IntPtr>(frame) ); }
-};
-
 #define INVALID_CURSOR_PTR reinterpret_cast<NSCursor*>(0xdeadbeef)
 
 // Singleton, instantiated from Application::Application() in
@@ -71,8 +64,6 @@ class SalData
 public:
     SALTIMERPROC                                  mpTimerProc;      // timer 
callback proc
     AquaSalInstance                              *mpFirstInstance;  // pointer 
of first instance
-    std::list<AquaSalFrame*>                      maFrames;         // list of 
all frames
-    std::unordered_set<const AquaSalFrame*,FrameHash>  maFrameCheck;// for 
fast check of frame existence
     std::list<AquaSalFrame*>                      maPresentationFrames;  // 
list of frames in presentation mode
     SalObject                                    *mpFirstObject;    // pointer 
of first object window
     SalVirtualDevice                             *mpFirstVD;        // first 
VirDev
diff --git a/vcl/inc/osx/salframe.h b/vcl/inc/osx/salframe.h
index e99a3175876d..f8cef1834106 100644
--- a/vcl/inc/osx/salframe.h
+++ b/vcl/inc/osx/salframe.h
@@ -26,6 +26,7 @@
 
 #include <vcl/sysdata.hxx>
 
+#include "osx/salinst.h"
 #include "osx/salmenu.h"
 #include "osx/saldata.hxx"
 #include "osx/osxvcltypes.h"
@@ -163,8 +164,7 @@ public:
     // trigger painting of the window
     void SendPaintEvent( const tools::Rectangle* pRect = nullptr );
 
-    static bool isAlive( const AquaSalFrame* pFrame )
-    { return GetSalData()->maFrameCheck.find( pFrame ) != 
GetSalData()->maFrameCheck.end(); }
+    static inline bool isAlive( const AquaSalFrame* pFrame );
 
     static AquaSalFrame* GetCaptureFrame() { return s_pCaptureFrame; }
 
@@ -204,6 +204,12 @@ private: // data
     AquaSalFrame& operator=(const AquaSalFrame&) = delete;
 };
 
+inline bool AquaSalFrame::isAlive( const AquaSalFrame* pFrame )
+{
+    AquaSalInstance *pInst = GetSalData()->mpFirstInstance;
+    return pInst && pInst->isFrameAlive( pFrame );
+}
+
 #endif // INCLUDED_VCL_INC_OSX_SALFRAME_H
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/osx/salinst.h b/vcl/inc/osx/salinst.h
index 0e30dfafb693..272cfc722d64 100644
--- a/vcl/inc/osx/salinst.h
+++ b/vcl/inc/osx/salinst.h
@@ -34,6 +34,8 @@
 
 #include "osx/runinmain.hxx"
 
+#include "salusereventlist.hxx"
+
 class AquaSalFrame;
 class SalFrame;
 class SalObject;
@@ -59,27 +61,18 @@ public:
     virtual bool IsCurrentThread() const override;
 };
 
-class AquaSalInstance : public SalInstance
+class AquaSalInstance : public SalInstance, public SalUserEventList
 {
-    struct SalUserEvent
-    {
-        AquaSalFrame*   mpFrame;
-        void*           mpData;
-        SalEvent        mnType;
-
-        SalUserEvent( AquaSalFrame* pFrame, void* pData, SalEvent nType ) :
-            mpFrame( pFrame ), mpData( pData ), mnType( nType )
-        {}
-    };
-
     bool RunInMainYield( bool bHandleAllCurrentEvents );
 
+    virtual void TriggerUserEventProcessing() override;
+    virtual void ProcessEvent( SalUserEvent aEvent ) override;
+
 public:
     SalYieldMutex*                          mpSalYieldMutex;        // 
Sal-Yield-Mutex
     OUString                                maDefaultPrinter;
     oslThreadIdentifier                     maMainThread;
     int                                     mnActivePrintJobs;
-    std::list< SalUserEvent >               maUserEvents;
     osl::Mutex                              maUserEventListMutex;
     osl::Condition                          maWaitingYieldCond;
     bool                                    mbIsLiveResize;
@@ -145,7 +138,6 @@ public:
 public:
     friend class AquaSalFrame;
 
-    void PostUserEvent( AquaSalFrame* pFrame, SalEvent nType, void* pData );
     void delayedSettingsChanged( bool bInvalidate );
 
     // Is this the NSAppThread?
diff --git a/vcl/inc/osx/vclnsapp.h b/vcl/inc/osx/vclnsapp.h
index c899ffce59d1..39bd3170abaf 100644
--- a/vcl/inc/osx/vclnsapp.h
+++ b/vcl/inc/osx/vclnsapp.h
@@ -61,8 +61,6 @@ class AquaSalFrame;
 #endif
 -(BOOL)applicationShouldHandleReopen: (NSApplication*)pApp hasVisibleWindows: 
(BOOL)bWinVisible;
 -(void)setDockIconClickHandler: (NSObject*)pHandler;
--(void)cycleFrameForward: (AquaSalFrame*)pCurFrame;
--(void)cycleFrameBackward: (AquaSalFrame*)pCurFrame;
 @end
 
 #endif // INCLUDED_VCL_INC_OSX_VCLNSAPP_H
diff --git a/vcl/inc/salusereventlist.hxx b/vcl/inc/salusereventlist.hxx
new file mode 100644
index 000000000000..1f689fb5cbf7
--- /dev/null
+++ b/vcl/inc/salusereventlist.hxx
@@ -0,0 +1,126 @@
+/* -*- 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_VCL_INC_SALUSEREVENTLIST_HXX
+#define INCLUDED_VCL_INC_SALUSEREVENTLIST_HXX
+
+#include <sal/config.h>
+#include <vcl/dllapi.h>
+#include <osl/mutex.hxx>
+
+#include <assert.h>
+
+#include <list>
+#include <unordered_set>
+
+class SalFrame;
+enum class SalEvent;
+
+struct SalFrameHash : public std::hash<sal_IntPtr>
+{
+    size_t operator()(const SalFrame* frame) const
+        { return std::hash<sal_IntPtr>::operator()( reinterpret_cast<const 
sal_IntPtr>(frame) ); }
+};
+
+typedef std::unordered_set< SalFrame*, SalFrameHash > SalFrameSet;
+
+class VCL_PLUGIN_PUBLIC SalUserEventList
+{
+public:
+    struct SalUserEvent
+    {
+        SalFrame*     m_pFrame;
+        void*         m_pData;
+        SalEvent      m_nEvent;
+
+        SalUserEvent( SalFrame* pFrame, void* pData, SalEvent nEvent )
+                : m_pFrame( pFrame ),
+                  m_pData( pData ),
+                  m_nEvent( nEvent )
+        {}
+
+        bool operator==(const SalUserEvent &aEvent) const
+        {
+            return m_pFrame == aEvent.m_pFrame
+                && m_pData == aEvent.m_pData
+                && m_nEvent== aEvent.m_nEvent;
+        }
+    };
+
+protected:
+    mutable osl::Mutex         m_aUserEventsMutex;
+    std::list< SalUserEvent >  m_aUserEvents;
+    std::list< SalUserEvent >  m_aProcessingUserEvents;
+    SalFrameSet                m_aFrames;
+
+    virtual void ProcessEvent( SalUserEvent aEvent ) = 0;
+    virtual void TriggerUserEventProcessing() = 0;
+    virtual void TriggerAllUserEventsProcessed() {};
+
+public:
+    SalUserEventList();
+    virtual ~SalUserEventList();
+
+    inline const SalFrameSet& getFrames() const;
+    inline SalFrame* anyFrame() const;
+    void insertFrame( SalFrame* pFrame );
+    void eraseFrame( SalFrame* pFrame );
+    inline bool isFrameAlive( const SalFrame* pFrame ) const;
+
+    void PostEvent( SalFrame* pFrame, void* pData, SalEvent nEvent );
+    bool RemoveEvent( SalFrame* pFrame, void* pData, SalEvent nEvent );
+    inline bool HasUserEvents() const;
+
+    bool DispatchUserEvents( bool bHandleAllCurrentEvents );
+};
+
+inline SalFrame* SalUserEventList::anyFrame() const
+{
+    if ( m_aFrames.empty() )
+        return nullptr;
+    return *m_aFrames.begin();
+}
+
+inline bool SalUserEventList::isFrameAlive( const SalFrame* pFrame ) const
+{
+    auto it = m_aFrames.find( const_cast<SalFrame*>( pFrame ) );
+    return it != m_aFrames.end();
+}
+
+inline bool SalUserEventList::HasUserEvents() const
+{
+    osl::MutexGuard aGuard( m_aUserEventsMutex );
+    return !(m_aUserEvents.empty() && m_aProcessingUserEvents.empty());
+}
+
+inline void SalUserEventList::PostEvent( SalFrame* pFrame, void* pData, 
SalEvent nEvent )
+{
+    osl::MutexGuard aGuard( m_aUserEventsMutex );
+    m_aUserEvents.push_back( SalUserEvent( pFrame, pData, nEvent ) );
+    TriggerUserEventProcessing();
+}
+
+inline const SalFrameSet& SalUserEventList::getFrames() const
+{
+    return m_aFrames;
+}
+
+#endif // INCLUDED_VCL_INC_SALUSEREVENTLIST_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/unx/gendisp.hxx b/vcl/inc/unx/gendisp.hxx
index 64564237a232..5c8f5113c300 100644
--- a/vcl/inc/unx/gendisp.hxx
+++ b/vcl/inc/unx/gendisp.hxx
@@ -27,45 +27,27 @@
 #include <vcl/dllapi.h>
 #include <list>
 #include <vector>
+#include <salusereventlist.hxx>
 
 class SalFrame;
-class VCL_DLLPUBLIC SalGenericDisplay
+class VCL_DLLPUBLIC SalGenericDisplay : public SalUserEventList
 {
-    mutable osl::Mutex m_aEventGuard;
-    struct SalUserEvent
-    {
-        SalFrame*  m_pFrame;
-        void*      m_pData;
-        SalEvent   m_nEvent;
-
-        SalUserEvent( SalFrame* pFrame, void* pData,
-                      SalEvent nEvent )
-                : m_pFrame( pFrame ),
-                  m_pData( pData ),
-                  m_nEvent( nEvent )
-        {}
-    };
-    std::list< SalUserEvent > m_aUserEvents;
 protected:
     SalFrame* m_pCapture;
-    std::list<SalFrame*> m_aFrames;
+
+    virtual void ProcessEvent( SalUserEvent aEvent ) override;
+
 public:
                  SalGenericDisplay();
-    virtual      ~SalGenericDisplay();
-
-    osl::Mutex& getEventGuardMutex() { return m_aEventGuard; }
+    virtual      ~SalGenericDisplay() override;
 
     void registerFrame( SalFrame* pFrame );
     virtual void deregisterFrame( SalFrame* pFrame );
     void emitDisplayChanged();
 
-    // Event handling
-    virtual void PostUserEvent() = 0;
-
     void SendInternalEvent( SalFrame* pFrame, void* pData, SalEvent nEvent = 
SalEvent::UserEvent );
-    void CancelInternalEvent( SalFrame const * pFrame, void const * pData, 
SalEvent nEvent );
+    void CancelInternalEvent( SalFrame* pFrame, void* pData, SalEvent nEvent );
     bool DispatchInternalEvent();
-    bool HasUserEvents() const;
 
     bool     MouseCaptured( const SalFrame *pFrameData ) const
                         { return m_pCapture == pFrameData; }
diff --git a/vcl/inc/unx/gtk/gtkdata.hxx b/vcl/inc/unx/gtk/gtkdata.hxx
index 4f4d520fc141..01b5c46b8dca 100644
--- a/vcl/inc/unx/gtk/gtkdata.hxx
+++ b/vcl/inc/unx/gtk/gtkdata.hxx
@@ -117,9 +117,9 @@ public:
     static void initNWF();
     static void deInitNWF();
 
-    static gboolean userEventFn( gpointer data );
+    void TriggerUserEventProcessing();
+    void TriggerAllUserEventsProcessed();
 
-    void PostUserEvent();
     bool Yield( bool bWait, bool bHandleAllCurrentEvents );
     inline GdkDisplay *GetGdkDisplay();
 
@@ -146,6 +146,7 @@ class GtkSalDisplay : public SalDisplay
 
     GdkCursor* getFromXBM( const unsigned char *pBitmap, const unsigned char 
*pMask,
                            int nWidth, int nHeight, int nXHot, int nYHot );
+
 public:
              GtkSalDisplay( GdkDisplay* pDisplay );
     virtual ~GtkSalDisplay() override;
@@ -180,7 +181,8 @@ public:
     void screenSizeChanged( GdkScreen const * );
     void monitorsChanged( GdkScreen const * );
 
-    virtual void PostUserEvent() override;
+    virtual void TriggerUserEventProcessing() override;
+    virtual void TriggerAllUserEventsProcessed() override;
 
 #if !GTK_CHECK_VERSION(3,0,0)
     virtual bool Dispatch( XEvent *pEvent ) override;
diff --git a/vcl/inc/unx/saldisp.hxx b/vcl/inc/unx/saldisp.hxx
index 0ec4e10e7d65..8f96e03630b0 100644
--- a/vcl/inc/unx/saldisp.hxx
+++ b/vcl/inc/unx/saldisp.hxx
@@ -168,7 +168,7 @@ public:
 
     virtual bool    Yield( bool bWait, bool bHandleAllCurrentEvents );
     virtual void    Wakeup();
-    virtual void    PostUserEvent();
+    void            TriggerUserEventProcessing();
 
     virtual void    Insert( int fd, void* data,
                             YieldFunc   pending,
@@ -371,12 +371,10 @@ public:
             { return getDataForScreen( nXScreen ).m_aRoot; }
     unsigned int GetXScreenCount() const { return m_aScreens.size(); }
 
-    const std::list< SalFrame* >& getFrames() const { return m_aFrames; }
+    const SalFrameSet& getFrames() const { return m_aFrames; }
     bool            IsNumLockFromXS() const { return bNumLockFromXS_; }
 
     std::list< SalObject* >& getSalObjects() { return m_aSalObjects; }
-
-    virtual void    PostUserEvent() override = 0;
 };
 
 inline  Display *SalColormap::GetXDisplay() const
@@ -390,7 +388,7 @@ public:
 
     virtual bool        Dispatch( XEvent *pEvent ) override;
     virtual void        Yield();
-    virtual void        PostUserEvent() override;
+    virtual void        TriggerUserEventProcessing() override;
 
     bool                IsEvent();
     void                SetupInput();
diff --git a/vcl/osx/salframe.cxx b/vcl/osx/salframe.cxx
index e54073cdf4f1..dcdfe6d9c936 100644
--- a/vcl/osx/salframe.cxx
+++ b/vcl/osx/salframe.cxx
@@ -87,8 +87,7 @@ AquaSalFrame::AquaSalFrame( SalFrame* pParent, 
SalFrameStyleFlags salFrameStyle
     initWindowAndView();
 
     SalData* pSalData = GetSalData();
-    pSalData->maFrames.push_front( this );
-    pSalData->maFrameCheck.insert( this );
+    pSalData->mpFirstInstance->insertFrame( this );
 }
 
 AquaSalFrame::~AquaSalFrame()
@@ -106,8 +105,7 @@ AquaSalFrame::~AquaSalFrame()
     [SalFrameView unsetMouseFrame: this];
 
     SalData* pSalData = GetSalData();
-    pSalData->maFrames.remove( this );
-    pSalData->maFrameCheck.erase( this );
+    pSalData->mpFirstInstance->eraseFrame( this );
     pSalData->maPresentationFrames.remove( this );
 
     SAL_WARN_IF( this == s_pCaptureFrame, "vcl", "capture frame destroyed" );
@@ -296,7 +294,7 @@ void AquaSalFrame::ReleaseGraphics( SalGraphics *pGraphics )
 
 bool AquaSalFrame::PostEvent(ImplSVEvent* pData)
 {
-    GetSalData()->mpFirstInstance->PostUserEvent( this, SalEvent::UserEvent, 
pData );
+    GetSalData()->mpFirstInstance->PostEvent( this, pData, SalEvent::UserEvent 
);
     return TRUE;
 }
 
diff --git a/vcl/osx/salinst.cxx b/vcl/osx/salinst.cxx
index 855dac645e41..89e3ae6d4e82 100644
--- a/vcl/osx/salinst.cxx
+++ b/vcl/osx/salinst.cxx
@@ -79,7 +79,8 @@ static bool bLeftMain = false;
 class AquaDelayedSettingsChanged : public Idle
 {
     bool            mbInvalidate;
-    public:
+
+public:
     AquaDelayedSettingsChanged( bool bInvalidate ) :
         mbInvalidate( bInvalidate )
     {
@@ -87,20 +88,20 @@ class AquaDelayedSettingsChanged : public Idle
 
     virtual void Invoke() override
     {
-        SalData* pSalData = GetSalData();
-        if( ! pSalData->maFrames.empty() )
-            pSalData->maFrames.front()->CallCallback( 
SalEvent::SettingsChanged, nullptr );
+        AquaSalInstance *pInst = GetSalData()->mpFirstInstance;
+        SalFrame *pAnyFrame = pInst->anyFrame();
+        if( pAnyFrame )
+            pAnyFrame->CallCallback( SalEvent::SettingsChanged, nullptr );
 
         if( mbInvalidate )
         {
-            for( std::list< AquaSalFrame* >::iterator it = 
pSalData->maFrames.begin();
-                it != pSalData->maFrames.end(); ++it )
+            for( auto pSalFrame : pInst->getFrames() )
             {
-                if( (*it)->mbShown )
-                    (*it)->SendPaintEvent();
+                AquaSalFrame* pFrame = static_cast<AquaSalFrame*>( 
const_cast<SalFrame*>( pSalFrame ) );
+                if( pFrame->mbShown )
+                    pFrame->SendPaintEvent();
             }
         }
-        Stop();
         delete this;
     }
 };
@@ -390,17 +391,19 @@ AquaSalInstance::~AquaSalInstance()
     delete mpSalYieldMutex;
 }
 
-void AquaSalInstance::PostUserEvent( AquaSalFrame* pFrame, SalEvent nType, 
void* pData )
+void AquaSalInstance::TriggerUserEventProcessing()
 {
-    {
-        osl::MutexGuard g( maUserEventListMutex );
-        maUserEvents.push_back( SalUserEvent( pFrame, pData, nType ) );
-    }
     dispatch_async(dispatch_get_main_queue(),^{
         ImplNSAppPostEvent( AquaSalInstance::YieldWakeupEvent, NO );
     });
 }
 
+void AquaSalInstance::ProcessEvent( SalUserEvent aEvent )
+{
+    aEvent.m_pFrame->CallCallback( aEvent.m_nEvent, aEvent.m_pData );
+    maWaitingYieldCond.set();
+}
+
 comphelper::SolarMutex* AquaSalInstance::GetYieldMutex()
 {
     return mpSalYieldMutex;
@@ -453,15 +456,17 @@ void AquaSalInstance::handleAppDefinedEvent( NSEvent* 
pEvent )
     case AppleRemoteControlEvent: // Defined in 
<apple_remote/RemoteMainController.h>
     {
         MediaCommand nCommand;
-        SalData* pSalData = GetSalData();
+        AquaSalInstance *pInst = GetSalData()->mpFirstInstance;
         bool bIsFullScreenMode = false;
 
-        std::list<AquaSalFrame*>::iterator it = pSalData->maFrames.begin();
-        while( it != pSalData->maFrames.end() )
+        for( auto pSalFrame : pInst->getFrames() )
         {
-            if ( (*it) && (*it)->mbFullScreen )
+            const AquaSalFrame* pFrame = static_cast<const AquaSalFrame*>( 
pSalFrame );
+            if ( pFrame->mbFullScreen )
+            {
                 bIsFullScreenMode = true;
-            ++it;
+                break;
+            }
         }
 
         switch ([pEvent data1])
@@ -497,9 +502,8 @@ void AquaSalInstance::handleAppDefinedEvent( NSEvent* 
pEvent )
             default:
                 break;
         }
-        AquaSalFrame* pFrame = pSalData->maFrames.front();
+        AquaSalFrame* pFrame = static_cast<AquaSalFrame*>( pInst->anyFrame() );
         vcl::Window* pWindow = pFrame ? pFrame->GetWindow() : nullptr;
-
         if( pWindow )
         {
             const Point aPoint;
@@ -532,6 +536,7 @@ bool AquaSalInstance::RunInMainYield( bool 
bHandleAllCurrentEvents )
     return false;
 
 }
+
 static bool isWakeupEvent( NSEvent *pEvent )
 {
 SAL_WNODEPRECATED_DECLARATIONS_PUSH
@@ -542,8 +547,6 @@ SAL_WNODEPRECATED_DECLARATIONS_POP
 
 bool AquaSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents)
 {
-    bool bHadEvent = false;
-
     // ensure that the per thread autorelease pool is top level and
     // will therefore not be destroyed by cocoa implicitly
     SalData::ensureThreadAutoreleasePool();
@@ -552,36 +555,10 @@ bool AquaSalInstance::DoYield(bool bWait, bool 
bHandleAllCurrentEvents)
     // an own pool for each yield level
     ReleasePoolHolder aReleasePool;
 
-    // Release all locks so that we don't deadlock when we pull pending
-    // events from the event queue
-    bool bDispatchUser = true;
-    while( bDispatchUser )
-    {
-        // get one user event
-        SalUserEvent aEvent( nullptr, nullptr, SalEvent::NONE );
-        {
-            osl::MutexGuard g( maUserEventListMutex );
-            if( ! maUserEvents.empty() )
-            {
-                aEvent = maUserEvents.front();
-                maUserEvents.pop_front();
-                bHadEvent = true;
-            }
-            else
-                bDispatchUser = false;
-        }
-
-        // dispatch it
-        if( aEvent.mpFrame && AquaSalFrame::isAlive( aEvent.mpFrame ) )
-        {
-            aEvent.mpFrame->CallCallback( aEvent.mnType, aEvent.mpData );
-            maWaitingYieldCond.set();
-        }
-
-        // return if only one event is asked for
-        if( !bHandleAllCurrentEvents && bDispatchUser )
-            return true;
-    }
+    // first, process current user events
+    bool bHadEvent = DispatchUserEvents( bHandleAllCurrentEvents );
+    if ( !bHandleAllCurrentEvents && bHadEvent )
+        return true;
 
     // handle cocoa event queue
     // cocoa events may be only handled in the thread the NSApp was created
@@ -639,13 +616,13 @@ SAL_WNODEPRECATED_DECLARATIONS_POP
         }
 
         // collect update rectangles
-        const std::list< AquaSalFrame* > rFrames( GetSalData()->maFrames );
-        for( std::list< AquaSalFrame* >::const_iterator it = rFrames.begin(); 
it != rFrames.end(); ++it )
+        for( auto pSalFrame : GetSalData()->mpFirstInstance->getFrames() )
         {
-            if( (*it)->mbShown && ! (*it)->maInvalidRect.IsEmpty() )
+            AquaSalFrame* pFrame = static_cast<AquaSalFrame*>( 
const_cast<SalFrame*>( pSalFrame ) );
+            if( pFrame->mbShown && ! pFrame->maInvalidRect.IsEmpty() )
             {
-                (*it)->Flush( (*it)->maInvalidRect );
-                (*it)->maInvalidRect.SetEmpty();
+                pFrame->Flush( pFrame->maInvalidRect );
+                pFrame->maInvalidRect.SetEmpty();
             }
         }
 
diff --git a/vcl/osx/vclnsapp.mm b/vcl/osx/vclnsapp.mm
index 651fa2a014cc..dafcdb97aca5 100644
--- a/vcl/osx/vclnsapp.mm
+++ b/vcl/osx/vclnsapp.mm
@@ -136,24 +136,6 @@ SAL_WNODEPRECATED_DECLARATIONS_PUSH
                 }
             }
 
-            // #i90083# handle frame switching
-            // FIXME: lousy workaround
-            if( (nModMask & (NSControlKeyMask|NSAlternateKeyMask)) == 0 )
-            {
-                if( [[pEvent characters] isEqualToString: @"<"] ||
-                    [[pEvent characters] isEqualToString: @"~"] )
-                {
-                    [self cycleFrameForward: pFrame];
-                    return;
-                }
-                else if( [[pEvent characters] isEqualToString: @">"] ||
-                         [[pEvent characters] isEqualToString: @"`"] )
-                {
-                    [self cycleFrameBackward: pFrame];
-                    return;
-                }
-            }
-
             // get information whether the event was handled; keyDown returns 
nothing
             GetSalData()->maKeyEventAnswer[ pEvent ] = false;
             bool bHandled = false;
@@ -245,84 +227,6 @@ SAL_WNODEPRECATED_DECLARATIONS_POP
     [super sendEvent: pEvent];
 }
 
--(void)cycleFrameForward: (AquaSalFrame*)pCurFrame
-{
-    // find current frame in list
-    std::list< AquaSalFrame* >& rFrames( GetSalData()->maFrames );
-    std::list< AquaSalFrame* >::iterator it = rFrames.begin();
-    for( ; it != rFrames.end() && *it != pCurFrame; ++it )
-        ;
-    if( it != rFrames.end() )
-    {
-        // now find the next frame (or end)
-        do
-        {
-            ++it;
-            if( it != rFrames.end() )
-            {
-                if( (*it)->mpDockMenuEntry != nullptr &&
-                    (*it)->mbShown )
-                {
-                    [(*it)->getNSWindow() makeKeyAndOrderFront: NSApp];
-                    return;
-                }
-            }
-        } while( it != rFrames.end() );
-        // cycle around, find the next up to pCurFrame
-        it = rFrames.begin();
-        while( *it != pCurFrame )
-        {
-            if( (*it)->mpDockMenuEntry != nullptr &&
-                (*it)->mbShown )
-            {
-                [(*it)->getNSWindow() makeKeyAndOrderFront: NSApp];
-                return;
-            }
-            ++it;
-        }
-    }
-}
-
--(void)cycleFrameBackward: (AquaSalFrame*)pCurFrame
-{
-    // do the same as cycleFrameForward only with a reverse iterator
-
-    // find current frame in list
-    std::list< AquaSalFrame* >& rFrames( GetSalData()->maFrames );
-    std::list< AquaSalFrame* >::reverse_iterator it = rFrames.rbegin();
-    for( ; it != rFrames.rend() && *it != pCurFrame; ++it )
-        ;
-    if( it != rFrames.rend() )
-    {
-        // now find the next frame (or end)
-        do
-        {
-            ++it;
-            if( it != rFrames.rend() )
-            {
-                if( (*it)->mpDockMenuEntry != nullptr &&
-                    (*it)->mbShown )
-                {
-                    [(*it)->getNSWindow() makeKeyAndOrderFront: NSApp];
-                    return;
-                }
-            }
-        } while( it != rFrames.rend() );
-        // cycle around, find the next up to pCurFrame
-        it = rFrames.rbegin();
-        while( *it != pCurFrame )
-        {
-            if( (*it)->mpDockMenuEntry != nullptr &&
-                (*it)->mbShown )
-            {
-                [(*it)->getNSWindow() makeKeyAndOrderFront: NSApp];
-                return;
-            }
-            ++it;
-        }
-    }
-}
-
 -(NSMenu*)applicationDockMenu:(NSApplication *)sender
 {
     (void)sender;
@@ -413,12 +317,13 @@ SAL_WNODEPRECATED_DECLARATIONS_POP
     {
         SolarMutexGuard aGuard;
 
-        SalData* pSalData = GetSalData();
-        if( ! pSalData->maFrames.empty() )
+        AquaSalInstance *pInst = GetSalData()->mpFirstInstance;
+        SalFrame *pAnyFrame = pInst->anyFrame();
+        if( pAnyFrame )
         {
             // the following QueryExit will likely present a message box, 
activate application
             [NSApp activateIgnoringOtherApps: YES];
-            aReply = pSalData->maFrames.front()->CallCallback( 
SalEvent::Shutdown, nullptr ) ? NSTerminateCancel : NSTerminateNow;
+            aReply = pAnyFrame->CallCallback( SalEvent::Shutdown, nullptr ) ? 
NSTerminateCancel : NSTerminateNow;
         }
 
         if( aReply == NSTerminateNow )
@@ -439,9 +344,10 @@ SAL_WNODEPRECATED_DECLARATIONS_POP
     (void)pNotification;
     SolarMutexGuard aGuard;
 
-    const SalData* pSalData = GetSalData();
-    if( !pSalData->maFrames.empty() )
-        pSalData->maFrames.front()->CallCallback( SalEvent::SettingsChanged, 
nullptr );
+    AquaSalInstance *pInst = GetSalData()->mpFirstInstance;
+    SalFrame *pAnyFrame = pInst->anyFrame();
+    if(  pAnyFrame )
+        pAnyFrame->CallCallback( SalEvent::SettingsChanged, nullptr );
 }
 
 -(void)screenParametersChanged: (NSNotification*) pNotification
@@ -449,11 +355,10 @@ SAL_WNODEPRECATED_DECLARATIONS_POP
     (void)pNotification;
     SolarMutexGuard aGuard;
 
-    SalData* pSalData = GetSalData();
-    std::list< AquaSalFrame* >::iterator it;
-    for( it = pSalData->maFrames.begin(); it != pSalData->maFrames.end(); ++it 
)
+    for( auto pSalFrame : GetSalData()->mpFirstInstance->getFrames() )
     {
-        (*it)->screenParametersChanged();
+        AquaSalFrame *pFrame = static_cast<AquaSalFrame*>( 
const_cast<SalFrame*>( pSalFrame ) );
+        pFrame->screenParametersChanged();
     }
 }
 
diff --git a/vcl/quartz/salvd.cxx b/vcl/quartz/salvd.cxx
index 3110398b8784..fe48f0b80326 100644
--- a/vcl/quartz/salvd.cxx
+++ b/vcl/quartz/salvd.cxx
@@ -255,19 +255,10 @@ bool AquaSalVirtualDevice::SetSize( long nDX, long nDY )
         AquaSalFrame* pSalFrame = mpGraphics->getGraphicsFrame();
         if( !pSalFrame || !AquaSalFrame::isAlive( pSalFrame ))
         {
-            if( !GetSalData()->maFrames.empty() )
-            {
-                // get the first matching frame
-                pSalFrame = *GetSalData()->maFrames.begin();
-            }
-            else
-            {
-                // ensure we don't reuse a dead AquaSalFrame on the very
-                // unlikely case of no other frame to use
-                pSalFrame = nullptr;
-            }
-            // update the frame reference
-            mpGraphics->setGraphicsFrame( pSalFrame );
+            pSalFrame = static_cast<AquaSalFrame*>( 
GetSalData()->mpFirstInstance->anyFrame() );
+            if ( pSalFrame )
+                // update the frame reference
+                mpGraphics->setGraphicsFrame( pSalFrame );
         }
         if( pSalFrame )
         {
diff --git a/vcl/source/app/salusereventlist.cxx 
b/vcl/source/app/salusereventlist.cxx
new file mode 100644
index 000000000000..af588e4bb151
--- /dev/null
+++ b/vcl/source/app/salusereventlist.cxx
@@ -0,0 +1,119 @@
+/* -*- 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 <salusereventlist.hxx>
+#include <salwtype.hxx>
+
+#include <algorithm>
+
+SalUserEventList::SalUserEventList()
+{
+}
+
+SalUserEventList::~SalUserEventList()
+{
+}
+
+void SalUserEventList::insertFrame( SalFrame* pFrame )
+{
+    auto aPair = m_aFrames.insert( pFrame );
+    assert( aPair.second ); (void) aPair;
+}
+
+void SalUserEventList::eraseFrame( SalFrame* pFrame )
+{
+    auto it = m_aFrames.find( pFrame );
+    assert( it != m_aFrames.end() );
+    if ( it != m_aFrames.end() )
+        m_aFrames.erase( it );
+}
+
+bool SalUserEventList::DispatchUserEvents( bool bHandleAllCurrentEvents )
+{
+    bool bWasEvent = false;
+
+    {
+        osl::MutexGuard aGuard( m_aUserEventsMutex );
+        if( ! m_aUserEvents.empty() )
+        {
+            if( bHandleAllCurrentEvents )
+                m_aProcessingUserEvents.swap( m_aUserEvents );
+            else
+            {
+                m_aProcessingUserEvents.push_back( m_aUserEvents.front() );
+                m_aUserEvents.pop_front();
+            }
+            bWasEvent = true;
+        }
+    }
+
+    if( bWasEvent )
+    {
+        SalUserEvent aEvent( nullptr, nullptr, SalEvent::NONE );
+        do {
+            {
+                osl::MutexGuard aGuard( m_aUserEventsMutex );
+                if ( m_aProcessingUserEvents.empty() )
+                    break;
+                aEvent = m_aProcessingUserEvents.front();
+                m_aProcessingUserEvents.pop_front();
+            }
+
+            if ( isFrameAlive( aEvent.m_pFrame ) )
+                ProcessEvent( aEvent );
+        }
+        while( true );
+    }
+
+    osl::MutexGuard aGuard( m_aUserEventsMutex );
+    if ( !HasUserEvents() )
+        TriggerAllUserEventsProcessed();
+
+    return bWasEvent;
+}
+
+bool SalUserEventList::RemoveEvent( SalFrame* pFrame, void* pData, SalEvent 
nEvent )
+{
+    SalUserEvent aEvent( pFrame, pData, nEvent );
+    bool bResult = false;
+
+    osl::MutexGuard aGuard( m_aUserEventsMutex );
+    auto it = std::find( m_aUserEvents.begin(), m_aUserEvents.end(), aEvent );
+    if ( it != m_aUserEvents.end() )
+    {
+        m_aUserEvents.erase( it );
+        bResult = true;
+    }
+    else
+    {
+        it = std::find( m_aProcessingUserEvents.begin(), 
m_aProcessingUserEvents.end(), aEvent );
+        if ( it != m_aProcessingUserEvents.end() )
+        {
+            m_aProcessingUserEvents.erase( it );
+            bResult = true;
+        }
+    }
+
+    if ( bResult && !HasUserEvents() )
+        TriggerAllUserEventsProcessed();
+
+    return bResult;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/app/gendisp.cxx b/vcl/unx/generic/app/gendisp.cxx
index edaf0e6ffb95..1be8606602e0 100644
--- a/vcl/unx/generic/app/gendisp.cxx
+++ b/vcl/unx/generic/app/gendisp.cxx
@@ -22,7 +22,6 @@
 #include <unx/geninst.h>
 
 SalGenericDisplay::SalGenericDisplay()
- : m_aEventGuard()
 {
     m_pCapture = nullptr;
 }
@@ -33,94 +32,39 @@ SalGenericDisplay::~SalGenericDisplay()
 
 void SalGenericDisplay::registerFrame( SalFrame* pFrame )
 {
-    m_aFrames.push_front( pFrame );
+    insertFrame( pFrame );
 }
 
 void SalGenericDisplay::deregisterFrame( SalFrame* pFrame )
 {
-    {
-        osl::MutexGuard g( m_aEventGuard );
-        std::list< SalUserEvent >::iterator it = m_aUserEvents.begin();
-        while ( it != m_aUserEvents.end() )
-        {
-            if( it->m_pFrame == pFrame )
-            {
-                if (it->m_nEvent == SalEvent::UserEvent) {
-                    delete static_cast<ImplSVEvent *>(it->m_pData);
-                }
-                it = m_aUserEvents.erase( it );
-            }
-            else
-                ++it;
-        }
-    }
-
-    m_aFrames.remove( pFrame );
+    eraseFrame( pFrame );
 }
 
 void SalGenericDisplay::emitDisplayChanged()
 {
-    if( !m_aFrames.empty() )
-        m_aFrames.front()->CallCallback( SalEvent::DisplayChanged, nullptr );
+    SalFrame *pAnyFrame = anyFrame();
+    if( pAnyFrame )
+        pAnyFrame->CallCallback( SalEvent::DisplayChanged, nullptr );
 }
 
 bool SalGenericDisplay::DispatchInternalEvent()
 {
-    void* pData = nullptr;
-    SalFrame* pFrame = nullptr;
-    SalEvent nEvent = SalEvent::NONE;
-
-    {
-        osl::MutexGuard g( m_aEventGuard );
-        if( !m_aUserEvents.empty() )
-        {
-            pFrame  = m_aUserEvents.front().m_pFrame;
-            pData   = m_aUserEvents.front().m_pData;
-            nEvent  = m_aUserEvents.front().m_nEvent;
-
-            m_aUserEvents.pop_front();
-        }
-    }
-
-    if( pFrame )
-        pFrame->CallCallback( nEvent, pData );
-
-    return pFrame != nullptr;
+    return DispatchUserEvents( false );
 }
 
 void SalGenericDisplay::SendInternalEvent( SalFrame* pFrame, void* pData, 
SalEvent nEvent )
 {
-    osl::MutexGuard g( m_aEventGuard );
-
-    m_aUserEvents.emplace_back( pFrame, pData, nEvent );
-
-    PostUserEvent(); // wakeup the concrete mainloop
+    PostEvent( pFrame, pData, nEvent );
 }
 
-void SalGenericDisplay::CancelInternalEvent( SalFrame const * pFrame, void 
const * pData, SalEvent nEvent )
+void SalGenericDisplay::CancelInternalEvent( SalFrame* pFrame, void* pData, 
SalEvent nEvent )
 {
-    osl::MutexGuard g( m_aEventGuard );
-    if( ! m_aUserEvents.empty() )
-    {
-        std::list< SalUserEvent >::iterator it = m_aUserEvents.begin();
-        while (it != m_aUserEvents.end())
-        {
-            if( it->m_pFrame    == pFrame   &&
-                it->m_pData     == pData    &&
-                it->m_nEvent    == nEvent )
-            {
-                it = m_aUserEvents.erase( it );
-            }
-            else
-                ++it;
-        }
-    }
+    RemoveEvent( pFrame, pData, nEvent );
 }
 
-bool SalGenericDisplay::HasUserEvents() const
+void SalGenericDisplay::ProcessEvent( SalUserEvent aEvent )
 {
-    osl::MutexGuard g( m_aEventGuard );
-    return !m_aUserEvents.empty();
+    aEvent.m_pFrame->CallCallback( aEvent.m_nEvent, aEvent.m_pData );
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/app/i18n_status.cxx 
b/vcl/unx/generic/app/i18n_status.cxx
index f2be4d7b47a2..81ce3a5450b2 100644
--- a/vcl/unx/generic/app/i18n_status.cxx
+++ b/vcl/unx/generic/app/i18n_status.cxx
@@ -170,12 +170,9 @@ bool XIMStatusWindow::checkLastParent() const
 {
     if( m_pLastParent )
     {
-        const std::list< SalFrame* >& rFrames = 
vcl_sal::getSalDisplay(GetGenericUnixSalData())->getFrames();
-        for( std::list< SalFrame* >::const_iterator it = rFrames.begin(); it 
!= rFrames.end(); ++it )
-        {
-            if( *it == m_pLastParent )
-                return true;
-        }
+        auto rFrameList = 
vcl_sal::getSalDisplay(GetGenericUnixSalData())->getFrames();
+        auto it = rFrameList.find( m_pLastParent );
+        return it != rFrameList.end();
     }
     return false;
 }
diff --git a/vcl/unx/generic/app/saldata.cxx b/vcl/unx/generic/app/saldata.cxx
index 930356b76992..4ad2c02db54f 100644
--- a/vcl/unx/generic/app/saldata.cxx
+++ b/vcl/unx/generic/app/saldata.cxx
@@ -786,7 +786,7 @@ void SalXLib::Wakeup()
     OSL_VERIFY(write (m_pTimeoutFDS[1], "", 1) == 1);
 }
 
-void SalXLib::PostUserEvent()
+void SalXLib::TriggerUserEventProcessing()
 {
     Wakeup();
 }
diff --git a/vcl/unx/generic/app/saldisp.cxx b/vcl/unx/generic/app/saldisp.cxx
index cd96818420ad..6afeeb81739a 100644
--- a/vcl/unx/generic/app/saldisp.cxx
+++ b/vcl/unx/generic/app/saldisp.cxx
@@ -431,10 +431,10 @@ SalX11Display::~SalX11Display()
     }
 }
 
-void SalX11Display::PostUserEvent()
+void SalX11Display::TriggerUserEventProcessing()
 {
     if( pXLib_ )
-        pXLib_->PostUserEvent();
+        pXLib_->TriggerUserEventProcessing();
 }
 
 SalDisplay::ScreenData *
@@ -1935,17 +1935,16 @@ bool SalX11Display::Dispatch( XEvent *pEvent )
     {
         ::Window aWindow = pEvent->xkey.window;
 
-        std::list< SalFrame* >::const_iterator it;
-        for( it = m_aFrames.begin(); it != m_aFrames.end(); ++it )
+        for (auto pSalFrame : m_aFrames )
         {
-            const X11SalFrame* pFrame = static_cast< const X11SalFrame* >(*it);
+            const X11SalFrame* pFrame = static_cast< const X11SalFrame* >( 
pSalFrame );
             if( pFrame->GetWindow() == aWindow || pFrame->GetShellWindow() == 
aWindow )
             {
                 aWindow = pFrame->GetWindow();
                 break;
             }
         }
-        if( it != m_aFrames.end() )
+        if( aWindow != pEvent->xkey.window )
         {
             if ( pInputMethod && pInputMethod->FilterEvent( pEvent , aWindow ) 
)
                 return false;
@@ -1975,9 +1974,8 @@ bool SalX11Display::Dispatch( XEvent *pEvent )
                 {
                     if( pEvent->xproperty.window == rScreen.m_aRefWindow )
                     {
-                        std::list< SalFrame* >::const_iterator it;
-                        for( it = m_aFrames.begin(); it != m_aFrames.end(); 
++it )
-                            (*it)->CallCallback( SalEvent::SettingsChanged, 
nullptr );
+                        for (auto pSalFrame : m_aFrames )
+                             pSalFrame->CallCallback( 
SalEvent::SettingsChanged, nullptr );
                         return false;
                     }
                 }
@@ -2009,10 +2007,10 @@ bool SalX11Display::Dispatch( XEvent *pEvent )
             break;
     }
 
-    std::list< SalFrame* >::iterator it;
-    for( it = m_aFrames.begin(); it != m_aFrames.end(); ++it )
+    for (auto pSalFrame : m_aFrames )
     {
-        X11SalFrame* pFrame = static_cast< X11SalFrame* >(*it);
+        X11SalFrame* pFrame = static_cast<X11SalFrame*>( pSalFrame );
+
         ::Window aDispatchWindow = pEvent->xany.window;
         if( pFrame->GetWindow() == aDispatchWindow
             || pFrame->GetShellWindow() == aDispatchWindow
diff --git a/vcl/unx/generic/app/salinst.cxx b/vcl/unx/generic/app/salinst.cxx
index e38164ee247b..abd29a78c077 100644
--- a/vcl/unx/generic/app/salinst.cxx
+++ b/vcl/unx/generic/app/salinst.cxx
@@ -225,10 +225,8 @@ void X11SalInstance::AddToRecentDocumentList(const 
OUString& rFileUrl, const OUS
 void X11SalInstance::PostPrintersChanged()
 {
     SalDisplay* pDisp = vcl_sal::getSalDisplay(GetGenericUnixSalData());
-    const std::list< SalFrame* >& rList = pDisp->getFrames();
-    for( std::list< SalFrame* >::const_iterator it = rList.begin();
-         it != rList.end(); ++it )
-        pDisp->SendInternalEvent( *it, nullptr, SalEvent::PrinterChanged );
+    for (auto pSalFrame : pDisp->getFrames() )
+        pDisp->PostEvent( pSalFrame, nullptr, SalEvent::PrinterChanged );
 }
 
 GenPspGraphics *X11SalInstance::CreatePrintGraphics()
diff --git a/vcl/unx/generic/app/sm.cxx b/vcl/unx/generic/app/sm.cxx
index e6da11244074..4beb1d58b2c3 100644
--- a/vcl/unx/generic/app/sm.cxx
+++ b/vcl/unx/generic/app/sm.cxx
@@ -293,10 +293,9 @@ IMPL_STATIC_LINK( SessionManagerClient, SaveYourselfHdl, 
void*, pStateVal, void
           task of the quick-starter)
         */
         *pSmRestartHint = SmRestartNever;
-        const std::list< SalFrame* >& rFrames = 
vcl_sal::getSalDisplay(GetGenericUnixSalData())->getFrames();
-        for( std::list< SalFrame* >::const_iterator it = rFrames.begin(); it 
!= rFrames.end(); ++it )
+        for (auto pSalFrame : 
vcl_sal::getSalDisplay(GetGenericUnixSalData())->getFrames() )
         {
-            vcl::Window *pWindow = (*it)->GetWindow();
+            vcl::Window *pWindow = pSalFrame->GetWindow();
             if (pWindow && pWindow->IsVisible())
             {
                 *pSmRestartHint = SmRestartIfRunning;
@@ -394,11 +393,10 @@ IMPL_STATIC_LINK_NOARG( SessionManagerClient, 
ShutDownHdl, void*, void )
         m_pSession->CallCallback( &aEvent );
     }
 
-    const std::list< SalFrame* >& rFrames = 
vcl_sal::getSalDisplay(GetGenericUnixSalData())->getFrames();
-
-    SAL_INFO("vcl.sm.debug", "  rFrames.empty() = " << (rFrames.empty() ? 
"true" : "false"));
-    if( !rFrames.empty() )
-        rFrames.front()->CallCallback( SalEvent::Shutdown, nullptr );
+    SalFrame *pAnyFrame = 
vcl_sal::getSalDisplay(GetGenericUnixSalData())->anyFrame();
+    SAL_INFO("vcl.sm.debug", "  rFrames.empty() = " << (pAnyFrame ? "true" : 
"false"));
+    if( pAnyFrame )
+        pAnyFrame->CallCallback( SalEvent::Shutdown, nullptr );
 }
 
 void SessionManagerClient::DieProc(
diff --git a/vcl/unx/generic/gdi/salgdi2.cxx b/vcl/unx/generic/gdi/salgdi2.cxx
index 6c4aba94f9d4..76fe85451f86 100644
--- a/vcl/unx/generic/gdi/salgdi2.cxx
+++ b/vcl/unx/generic/gdi/salgdi2.cxx
@@ -127,12 +127,11 @@ void X11SalGraphics::YieldGraphicsExpose()
     ::Window aWindow = GetDrawable();
     if( ! pFrame )
     {
-        const std::list< SalFrame* >& rFrames = 
vcl_sal::getSalDisplay(GetGenericUnixSalData())->getFrames();
-        for( std::list< SalFrame* >::const_iterator it = rFrames.begin(); it 
!= rFrames.end() && ! pFrame; ++it )
+        for (auto pSalFrame : 
vcl_sal::getSalDisplay(GetGenericUnixSalData())->getFrames() )
         {
-            const SystemEnvData* pEnvData = (*it)->GetSystemData();
+            const SystemEnvData* pEnvData = pSalFrame->GetSystemData();
             if( Drawable(pEnvData->aWindow) == aWindow )
-                pFrame = *it;
+                pFrame = pSalFrame;
         }
         if( ! pFrame )
             return;
diff --git a/vcl/unx/generic/window/salframe.cxx 
b/vcl/unx/generic/window/salframe.cxx
index b89a736581d2..e2eb2ee2d237 100644
--- a/vcl/unx/generic/window/salframe.cxx
+++ b/vcl/unx/generic/window/salframe.cxx
@@ -492,15 +492,14 @@ void X11SalFrame::Init( SalFrameStyleFlags 
nSalFrameStyle, SalX11Screen nXScreen
 
         // check if this is really one of our own frames
         // do not change the input mask in that case
-        const std::list< SalFrame* >& rFrames = GetDisplay()->getFrames();
-        std::list< SalFrame* >::const_iterator it = rFrames.begin();
-        while( it != rFrames.end() && mhForeignParent != static_cast<const 
X11SalFrame*>(*it)->GetWindow() )
-            ++it;
-
-        if( it == rFrames.end() )
+        for (auto pSalFrame : GetDisplay()->getFrames() )
         {
-            XSelectInput( GetDisplay()->GetDisplay(), mhForeignParent, 
StructureNotifyMask | FocusChangeMask );
-            XSelectInput( GetDisplay()->GetDisplay(), mhShellWindow, 
StructureNotifyMask | FocusChangeMask );
+            if ( static_cast<const X11SalFrame*>( pSalFrame )->GetWindow() == 
mhForeignParent )
+            {
+                XSelectInput( GetDisplay()->GetDisplay(), mhForeignParent, 
StructureNotifyMask | FocusChangeMask );
+                XSelectInput( GetDisplay()->GetDisplay(), mhShellWindow, 
StructureNotifyMask | FocusChangeMask );
+                break;
+            }
         }
     }
     else
@@ -521,11 +520,9 @@ void X11SalFrame::Init( SalFrameStyleFlags nSalFrameStyle, 
SalX11Screen nXScreen
             {
                 // find the last document window (if any)
                 const X11SalFrame* pFrame = nullptr;
-                const std::list< SalFrame* >& rFrames = 
GetDisplay()->getFrames();
-                std::list< SalFrame* >::const_iterator it = rFrames.begin();
-                while( it != rFrames.end() )
+                for (auto pSalFrame : GetDisplay()->getFrames() )
                 {
-                    pFrame = static_cast< const X11SalFrame* >(*it);
+                    pFrame = static_cast< const X11SalFrame* >( pSalFrame );
                     if( ! ( pFrame->mpParent
                             || pFrame->mbFullScreen
                             || ! ( pFrame->nStyle_ & 
SalFrameStyleFlags::SIZEABLE )
@@ -534,10 +531,9 @@ void X11SalFrame::Init( SalFrameStyleFlags nSalFrameStyle, 
SalX11Screen nXScreen
                             )
                         )
                         break;
-                    ++it;
                 }
 
-                if( it != rFrames.end() )
+                if( pFrame )
                 {
                     // set a document position and size
                     // the first frame gets positioned by the window manager
@@ -954,13 +950,12 @@ X11SalFrame::~X11SalFrame()
      *  check if there is only the status frame left
      *  if so, free it
      */
-    if( ! GetDisplay()->getFrames().empty() && vcl::I18NStatus::exists() )
+    auto &rFrames = GetDisplay()->getFrames();
+    if( ! rFrames.empty() && vcl::I18NStatus::exists() )
     {
         SalFrame* pStatusFrame = vcl::I18NStatus::get().getStatusFrame();
-        std::list< SalFrame* >::const_iterator sit = 
GetDisplay()->getFrames().begin();
-        if( pStatusFrame
-            && *sit == pStatusFrame
-            && ++sit == GetDisplay()->getFrames().end() )
+        auto sit = rFrames.begin();
+        if( pStatusFrame && *sit == pStatusFrame && ++sit == rFrames.end() )
             vcl::I18NStatus::free();
     }
 }
@@ -1204,10 +1199,9 @@ void X11SalFrame::Show( bool bVisible, bool bNoActivate )
         if( ! (nStyle_ & SalFrameStyleFlags::INTRO) )
         {
             // hide all INTRO frames
-            const std::list< SalFrame* >& rFrames = GetDisplay()->getFrames();
-            for( std::list< SalFrame* >::const_iterator it = rFrames.begin(); 
it != rFrames.end(); ++it )
+            for (auto pSalFrame : GetDisplay()->getFrames() )
             {
-                const X11SalFrame* pFrame = static_cast< const X11SalFrame* 
>(*it);
+                const X11SalFrame* pFrame = static_cast< const X11SalFrame* >( 
pSalFrame );
                 // look for intro bit map; if present, hide it
                 if( pFrame->nStyle_ & SalFrameStyleFlags::INTRO )
                 {
@@ -2698,10 +2692,9 @@ bool X11SalFrame::HandleMouseEvent( XEvent *pEvent )
             // see if the user clicks outside all of the floats
             // if yes release the grab
             bool bInside = false;
-            const std::list< SalFrame* >& rFrames = GetDisplay()->getFrames();
-            for( std::list< SalFrame* >::const_iterator it = rFrames.begin(); 
it != rFrames.end(); ++it )
+            for (auto pSalFrame : GetDisplay()->getFrames() )
             {
-                const X11SalFrame* pFrame = static_cast< const X11SalFrame* 
>(*it);
+                const X11SalFrame* pFrame = static_cast< const X11SalFrame* >( 
pSalFrame );
                 if( pFrame->IsFloatGrabWindow()                                
     &&
                     pFrame->bMapped_                                           
     &&
                     pEvent->xbutton.x_root >= pFrame->maGeometry.nX            
                 &&
@@ -2738,9 +2731,9 @@ bool X11SalFrame::HandleMouseEvent( XEvent *pEvent )
                     && aChild // pointer may not be in any child
                     )
                 {
-                    for( std::list< SalFrame* >::const_iterator it = 
rFrames.begin(); it != rFrames.end(); ++it )
+                    for (auto pSalFrame : GetDisplay()->getFrames() )
                     {
-                        const X11SalFrame* pFrame = static_cast< const 
X11SalFrame* >(*it);
+                        const X11SalFrame* pFrame = static_cast< const 
X11SalFrame* >( pSalFrame );
                         if( ! pFrame->IsFloatGrabWindow()
                             && ( pFrame->GetWindow() == aChild ||
                                  pFrame->GetShellWindow() == aChild ||
diff --git a/vcl/unx/gtk/gtkdata.cxx b/vcl/unx/gtk/gtkdata.cxx
index eaa34d9461e5..da70c0fbd62c 100644
--- a/vcl/unx/gtk/gtkdata.cxx
+++ b/vcl/unx/gtk/gtkdata.cxx
@@ -133,19 +133,17 @@ GdkFilterReturn GtkSalDisplay::filterGdkEvent( GdkXEvent* 
sys_event )
         // so we need to listen for corresponding property notifications here
         // these should be rare enough so that we can assume that the settings
         // actually change when a corresponding PropertyNotify occurs
-        if( pEvent->type == PropertyNotify &&
-            pEvent->xproperty.atom == getWMAdaptor()->getAtom( 
WMAdaptor::XSETTINGS ) &&
-            ! m_aFrames.empty()
-           )
+        SalFrame *pAnyFrame = anyFrame();
+        if( pAnyFrame && pEvent->type == PropertyNotify &&
+            pEvent->xproperty.atom == getWMAdaptor()->getAtom( 
WMAdaptor::XSETTINGS ) )
         {
-            SendInternalEvent( m_aFrames.front(), nullptr, 
SalEvent::SettingsChanged );
+            PostEvent( pAnyFrame, nullptr, SalEvent::SettingsChanged );
         }
         // let's see if one of our frames wants to swallow these events
         // get the frame
-        for( std::list< SalFrame* >::const_iterator it = m_aFrames.begin();
-                 it != m_aFrames.end(); ++it )
+        for (auto pSalFrame : m_aFrames )
         {
-            GtkSalFrame* pFrame = static_cast<GtkSalFrame*>(*it);
+            GtkSalFrame* pFrame = static_cast<GtkSalFrame*>( pSalFrame );
             if( pFrame->GetSystemData()->aWindow == pEvent->xany.window ||
                 ( pFrame->getForeignParent() && 
pFrame->getForeignParentWindow() == pEvent->xany.window ) ||
                 ( pFrame->getForeignTopLevel() && 
pFrame->getForeignTopLevelWindow() == pEvent->xany.window )
@@ -213,11 +211,10 @@ bool GtkSalDisplay::Dispatch( XEvent* pEvent )
     {
         // let's see if one of our frames wants to swallow these events
         // get the child frame
-        for( std::list< SalFrame* >::const_iterator it = m_aFrames.begin();
-             it != m_aFrames.end(); ++it )
+        for (auto pSalFrame : m_aFrames )
         {
-            if ((*it)->GetSystemData()->aWindow == pEvent->xany.window)
-                return static_cast<GtkSalFrame*>(*it)->Dispatch( pEvent );
+            if (pSalFrame->GetSystemData()->aWindow == pEvent->xany.window)
+                return static_cast<GtkSalFrame*>( pSalFrame )->Dispatch( 
pEvent );
         }
     }
 
@@ -816,47 +813,23 @@ void GtkSalTimer::Stop()
     }
 }
 
-gboolean GtkSalData::userEventFn( gpointer data )
-{
-    gboolean bContinue = FALSE;
-    GtkSalData *pThis = static_cast<GtkSalData *>(data);
-    GenericUnixSalData *pData = GetGenericUnixSalData();
-    SolarMutexGuard aGuard;
-    const SalGenericDisplay *pDisplay = pData->GetDisplay();
-    if (pDisplay)
-    {
-        OSL_ASSERT(static_cast<const SalGenericDisplay 
*>(pThis->GetGtkDisplay()) == pDisplay);
-        {
-            osl::MutexGuard g (pThis->GetGtkDisplay()->getEventGuardMutex());
-
-            if( !pThis->GetGtkDisplay()->HasUserEvents() )
-            {
-                if( pThis->m_pUserEvent )
-                {
-                    g_source_unref (pThis->m_pUserEvent);
-                    pThis->m_pUserEvent = nullptr;
-                }
-                bContinue = FALSE;
-            }
-            else
-                bContinue = TRUE;
-        }
-        pThis->GetGtkDisplay()->DispatchInternalEvent();
-    }
-
-    return bContinue;
-}
-
 extern "C" {
     static gboolean call_userEventFn( void *data )
     {
+        GtkSalData *pThis = static_cast<GtkSalData *>(data);
         SolarMutexGuard aGuard;
-        return GtkSalData::userEventFn( data );
+        const SalGenericDisplay *pDisplay = 
GetGenericUnixSalData()->GetDisplay();
+        if ( pDisplay )
+        {
+            GtkSalDisplay *pThisDisplay = pThis->GetGtkDisplay();
+            assert(static_cast<const SalGenericDisplay *>(pThisDisplay) == 
pDisplay);
+            pThisDisplay->DispatchInternalEvent();
+        }
+        return TRUE;
     }
 }
 
-// hEventGuard_ held during this invocation
-void GtkSalData::PostUserEvent()
+void GtkSalData::TriggerUserEventProcessing()
 {
     if (m_pUserEvent)
         g_main_context_wakeup (nullptr); // really needed ?
@@ -871,16 +844,28 @@ void GtkSalData::PostUserEvent()
     }
 }
 
-void GtkSalDisplay::PostUserEvent()
+void GtkSalData::TriggerAllUserEventsProcessed()
+{
+    assert( m_pUserEvent );
+    g_source_destroy( m_pUserEvent );
+    g_source_unref( m_pUserEvent );
+    m_pUserEvent = nullptr;
+}
+
+void GtkSalDisplay::TriggerUserEventProcessing()
+{
+    GetGtkSalData()->TriggerUserEventProcessing();
+}
+
+void GtkSalDisplay::TriggerAllUserEventsProcessed()
 {
-    GetGtkSalData()->PostUserEvent();
+    GetGtkSalData()->TriggerAllUserEventsProcessed();
 }
 
 GtkWidget* GtkSalDisplay::findGtkWidgetForNativeHandle(sal_uIntPtr hWindow) 
const
 {
-    for (auto it = m_aFrames.begin(); it != m_aFrames.end(); ++it)
+    for (auto pFrame : m_aFrames)
     {
-        SalFrame* pFrame = *it;
         const SystemEnvData* pEnvData = pFrame->GetSystemData();
         if (pEnvData->aWindow == hWindow)
             return GTK_WIDGET(pEnvData->pWidget);
diff --git a/vcl/unx/gtk/gtksalframe.cxx b/vcl/unx/gtk/gtksalframe.cxx
index 3ca2b4816ad8..0077a056bb53 100644
--- a/vcl/unx/gtk/gtksalframe.cxx
+++ b/vcl/unx/gtk/gtksalframe.cxx
@@ -2180,10 +2180,9 @@ void GtkSalFrame::grabPointer( bool bGrab, bool 
bOwnerEvents )
     if( bGrab )
     {
         bool bUseGdkGrab = true;
-        const std::list< SalFrame* >& rFrames = getDisplay()->getFrames();
-        for( std::list< SalFrame* >::const_iterator it = rFrames.begin(); it 
!= rFrames.end(); ++it )
+        for (auto pSalFrame : getDisplay()->getFrames() )
         {
-            const GtkSalFrame* pFrame = static_cast< const GtkSalFrame* >(*it);
+            const GtkSalFrame* pFrame = static_cast< const GtkSalFrame* >( 
pSalFrame );
             if( pFrame->m_bWindowIsGtkPlug )
             {
                 bUseGdkGrab = false;
diff --git a/vcl/unx/gtk3/gtk3gtkdata.cxx b/vcl/unx/gtk3/gtk3gtkdata.cxx
index 844dc77f20c1..fbd449ef4ec6 100644
--- a/vcl/unx/gtk3/gtk3gtkdata.cxx
+++ b/vcl/unx/gtk3/gtk3gtkdata.cxx
@@ -778,47 +778,23 @@ void GtkSalTimer::Stop()
     }
 }
 
-gboolean GtkSalData::userEventFn( gpointer data )
-{
-    gboolean bContinue = FALSE;
-    GtkSalData *pThis = static_cast<GtkSalData *>(data);
-    GenericUnixSalData *pData = GetGenericUnixSalData();
-    SolarMutexGuard aGuard;
-    const SalGenericDisplay *pDisplay = pData->GetDisplay();
-    if (pDisplay)
-    {
-        OSL_ASSERT(static_cast<const SalGenericDisplay 
*>(pThis->GetGtkDisplay()) == pDisplay);
-        {
-            osl::MutexGuard g (pThis->GetGtkDisplay()->getEventGuardMutex());
-
-            if( !pThis->GetGtkDisplay()->HasUserEvents() )
-            {
-                if( pThis->m_pUserEvent )
-                {
-                    g_source_unref (pThis->m_pUserEvent);
-                    pThis->m_pUserEvent = nullptr;
-                }
-                bContinue = FALSE;
-            }
-            else
-                bContinue = TRUE;
-        }
-        pThis->GetGtkDisplay()->DispatchInternalEvent();
-    }
-
-    return bContinue;
-}
-
 extern "C" {
     static gboolean call_userEventFn( void *data )
     {
+        GtkSalData *pThis = static_cast<GtkSalData *>(data);
         SolarMutexGuard aGuard;
-        return GtkSalData::userEventFn( data );
+        const SalGenericDisplay *pDisplay = 
GetGenericUnixSalData()->GetDisplay();
+        if ( pDisplay )
+        {
+            GtkSalDisplay *pThisDisplay = pThis->GetGtkDisplay();
+            assert(static_cast<const SalGenericDisplay *>(pThisDisplay) == 
pDisplay);
+            pThisDisplay->DispatchInternalEvent();
+        }
+        return TRUE;
     }
 }
 
-// hEventGuard_ held during this invocation
-void GtkSalData::PostUserEvent()
+void GtkSalData::TriggerUserEventProcessing()
 {
     if (m_pUserEvent)
         g_main_context_wakeup (nullptr); // really needed ?
@@ -836,17 +812,29 @@ void GtkSalData::PostUserEvent()
     }
 }
 
-void GtkSalDisplay::PostUserEvent()
+void GtkSalData::TriggerAllUserEventsProcessed()
+{
+    assert( m_pUserEvent );
+    g_source_destroy( m_pUserEvent );
+    g_source_unref( m_pUserEvent );
+    m_pUserEvent = nullptr;
+}
+
+void GtkSalDisplay::TriggerUserEventProcessing()
+{
+    GetGtkSalData()->TriggerUserEventProcessing();
+}
+
+void GtkSalDisplay::TriggerAllUserEventsProcessed()
 {
-    GetGtkSalData()->PostUserEvent();
+    GetGtkSalData()->TriggerAllUserEventsProcessed();
 }
 
 GtkWidget* GtkSalDisplay::findGtkWidgetForNativeHandle(sal_uIntPtr hWindow) 
const
 {
-    for (auto it = m_aFrames.begin(); it != m_aFrames.end(); ++it)
+    for (auto pSalFrame : m_aFrames )
     {
-        SalFrame* pFrame = *it;
-        const SystemEnvData* pEnvData = pFrame->GetSystemData();
+        const SystemEnvData* pEnvData = pSalFrame->GetSystemData();
         if (pEnvData->aWindow == hWindow)
             return GTK_WIDGET(pEnvData->pWidget);
     }
diff --git a/vcl/unx/kde4/KDESalDisplay.cxx b/vcl/unx/kde4/KDESalDisplay.cxx
index 4647b3d111c8..8a2422a3918d 100644
--- a/vcl/unx/kde4/KDESalDisplay.cxx
+++ b/vcl/unx/kde4/KDESalDisplay.cxx
@@ -86,4 +86,9 @@ bool SalKDEDisplay::checkDirectInputEvent( XEvent* ev )
     return false;
 }
 
+void SalKDEDisplay::TriggerUserEventProcessing()
+{
+    static_cast<KDEXLib*>(GetXLib())->TriggerUserEventProcessing();
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/kde4/KDESalDisplay.hxx b/vcl/unx/kde4/KDESalDisplay.hxx
index 4a0458dcc5c2..07b5ca3dadf5 100644
--- a/vcl/unx/kde4/KDESalDisplay.hxx
+++ b/vcl/unx/kde4/KDESalDisplay.hxx
@@ -23,15 +23,18 @@
 
 class SalKDEDisplay : public SalX11Display
 {
-    public:
-        explicit SalKDEDisplay( Display* pDisp );
-        virtual ~SalKDEDisplay() override;
-        static SalKDEDisplay* self();
-        virtual void Yield() override;
-        bool checkDirectInputEvent( XEvent* ev );
-    private:
-        Atom xim_protocol;
-        static SalKDEDisplay* selfptr;
+    Atom xim_protocol;
+    static SalKDEDisplay* selfptr;
+
+protected:
+    virtual void TriggerUserEventProcessing() override;
+
+public:
+    explicit SalKDEDisplay( Display* pDisp );
+    virtual ~SalKDEDisplay() override;
+    static SalKDEDisplay* self();
+    virtual void Yield() override;
+    bool checkDirectInputEvent( XEvent* ev );
 };
 
 inline SalKDEDisplay* SalKDEDisplay::self()
diff --git a/vcl/unx/kde4/KDEXLib.cxx b/vcl/unx/kde4/KDEXLib.cxx
index 402461e45bc6..f047ed9fce65 100644
--- a/vcl/unx/kde4/KDEXLib.cxx
+++ b/vcl/unx/kde4/KDEXLib.cxx
@@ -357,10 +357,10 @@ void KDEXLib::Wakeup()
     QAbstractEventDispatcher::instance( qApp->thread())->wakeUp(); // main 
thread event loop
 }
 
-void KDEXLib::PostUserEvent()
+void KDEXLib::TriggerUserEventProcessing()
 {
     if( !m_isGlibEventLoopType )
-        return SalXLib::PostUserEvent();
+        return SalXLib::TriggerUserEventProcessing();
     QApplication::postEvent(this, new QEvent(QEvent::Type( m_postUserEventId 
)));
 }
 
diff --git a/vcl/unx/kde4/KDEXLib.hxx b/vcl/unx/kde4/KDEXLib.hxx
index 2fe497d019fa..4c06104b4c59 100644
--- a/vcl/unx/kde4/KDEXLib.hxx
+++ b/vcl/unx/kde4/KDEXLib.hxx
@@ -83,7 +83,7 @@ class KDEXLib : public QObject, public SalXLib
         virtual void StartTimer( sal_uLong nMS ) override;
         virtual void StopTimer() override;
         virtual void Wakeup() override;
-        virtual void PostUserEvent() override;
+        void TriggerUserEventProcessing();
 
         void doStartup();
         bool allowKdeDialogs() { return m_allowKdeDialogs; }
commit 517964a8210c36e39b4a2051ac9aa99b447a4210
Author: Jan-Marek Glogowski <glo...@fbihome.de>
Date:   Fri Aug 25 14:52:38 2017 +0200

    Disable ScHeaderFooterTextCursor scenario test
    
    Just like the ScHeaderFooterTextObj, it depends on weak referenced
    objects, which might be gone / cleaned up at test time.
    
    Change-Id: I52503646c51b0915df11f5c7f90c16208e45879a

diff --git a/sc/qa/unoapi/sc_4.sce b/sc/qa/unoapi/sc_4.sce
index d631ac99878b..ce879cc83272 100644
--- a/sc/qa/unoapi/sc_4.sce
+++ b/sc/qa/unoapi/sc_4.sce
@@ -36,6 +36,8 @@
 # The css::text::XTextRange test fails often when the weak SHF_ContentObj is
 # already gone. If just this test is disabled, later tests of this object fail
 # too, so this disables the whole interface.
+# Same for ScHeaderFooterTextCursor.
+# -o sc.ScHeaderFooterTextCursor
 # -o sc.ScHeaderFooterTextObj
 -o sc.ScIndexEnumeration_CellAnnotationsEnumeration
 -o sc.ScIndexEnumeration_CellAreaLinksEnumeration
commit 0b20137badc4b359a338f2ef235f17d2ccbcbf11
Author: Gabor Kelemen <kelem...@ubuntu.com>
Date:   Fri Sep 22 17:36:38 2017 +0200

    tdf#112555 Mark default area pattern names for translation
    
    These need to be kept in sync with the contents of
    extras/source/palettes/standard.sop:Contents.xml
    
    Change-Id: I424919cacafd19dc456b4975b13f1c7333d14fa4
    Reviewed-on: https://gerrit.libreoffice.org/42671
    Tested-by: Jenkins <c...@libreoffice.org>
    Reviewed-by: Katarina Behrens <katarina.behr...@cib.de>

diff --git a/include/svx/strings.hrc b/include/svx/strings.hrc
index feb1cca33ccd..9a06e3f01c64 100644
--- a/include/svx/strings.hrc
+++ b/include/svx/strings.hrc
@@ -737,6 +737,60 @@
 #define RID_SVXSTR_BMP19                                    
NC_("RID_SVXSTR_BMP19", "Fiery")
 #define RID_SVXSTR_BMP20                                    
NC_("RID_SVXSTR_BMP20", "Roses")
 #define RID_SVXSTR_BMP21                                    
NC_("RID_SVXSTR_BMP21", "Bitmap")
+#define RID_SVXSTR_BMP22                                    
NC_("RID_SVXSTR_BMP22", "5 Percent")
+#define RID_SVXSTR_BMP23                                    
NC_("RID_SVXSTR_BMP23", "10 Percent")
+#define RID_SVXSTR_BMP24                                    
NC_("RID_SVXSTR_BMP24", "20 Percent")
+#define RID_SVXSTR_BMP25                                    
NC_("RID_SVXSTR_BMP25", "25 Percent")
+#define RID_SVXSTR_BMP26                                    
NC_("RID_SVXSTR_BMP26", "30 Percent")
+#define RID_SVXSTR_BMP27                                    
NC_("RID_SVXSTR_BMP27", "40 Percent")
+#define RID_SVXSTR_BMP28                                    
NC_("RID_SVXSTR_BMP28", "50 Percent")
+#define RID_SVXSTR_BMP29                                    
NC_("RID_SVXSTR_BMP29", "60 Percent")
+#define RID_SVXSTR_BMP30                                    
NC_("RID_SVXSTR_BMP30", "70 Percent")
+#define RID_SVXSTR_BMP31                                    
NC_("RID_SVXSTR_BMP31", "75 Percent")
+#define RID_SVXSTR_BMP32                                    
NC_("RID_SVXSTR_BMP32", "80 Percent")
+#define RID_SVXSTR_BMP33                                    
NC_("RID_SVXSTR_BMP33", "90 Percent")
+#define RID_SVXSTR_BMP34                                    
NC_("RID_SVXSTR_BMP34", "Light Downward Diagonal")
+#define RID_SVXSTR_BMP35                                    
NC_("RID_SVXSTR_BMP35", "Light Upward Diagonal")
+#define RID_SVXSTR_BMP36                                    
NC_("RID_SVXSTR_BMP36", "Dark Downward Diagonal")
+#define RID_SVXSTR_BMP37                                    
NC_("RID_SVXSTR_BMP37", "Dark Upward Diagonal")
+#define RID_SVXSTR_BMP38                                    
NC_("RID_SVXSTR_BMP38", "Wide Downward Diagonal")
+#define RID_SVXSTR_BMP39                                    
NC_("RID_SVXSTR_BMP39", "Wide Upward Diagonal")
+#define RID_SVXSTR_BMP40                                    
NC_("RID_SVXSTR_BMP40", "Light Vertical")
+#define RID_SVXSTR_BMP41                                    
NC_("RID_SVXSTR_BMP41", "Light Horizontal")
+#define RID_SVXSTR_BMP42                                    
NC_("RID_SVXSTR_BMP42", "Narrow Vertical")
+#define RID_SVXSTR_BMP43                                    
NC_("RID_SVXSTR_BMP43", "Narrow Horizontal")
+#define RID_SVXSTR_BMP44                                    
NC_("RID_SVXSTR_BMP44", "Dark Vertical")
+#define RID_SVXSTR_BMP45                                    
NC_("RID_SVXSTR_BMP45", "Dark Horizontal")
+#define RID_SVXSTR_BMP46                                    
NC_("RID_SVXSTR_BMP46", "Dashed Downward Diagonal")
+#define RID_SVXSTR_BMP47                                    
NC_("RID_SVXSTR_BMP47", "Dashed Upward Diagonal")
+#define RID_SVXSTR_BMP48                                    
NC_("RID_SVXSTR_BMP48", "Dashed Horizontal")
+#define RID_SVXSTR_BMP49                                    
NC_("RID_SVXSTR_BMP49", "Dashed Vertical")
+#define RID_SVXSTR_BMP50                                    
NC_("RID_SVXSTR_BMP50", "Small Confetti")
+#define RID_SVXSTR_BMP51                                    
NC_("RID_SVXSTR_BMP51", "Large Confetti")
+#define RID_SVXSTR_BMP52                                    
NC_("RID_SVXSTR_BMP52", "Zig Zag")
+#define RID_SVXSTR_BMP53                                    
NC_("RID_SVXSTR_BMP53", "Wave")
+#define RID_SVXSTR_BMP54                                    
NC_("RID_SVXSTR_BMP54", "Diagonal Brick")
+#define RID_SVXSTR_BMP55                                    
NC_("RID_SVXSTR_BMP55", "Horizontal Brick")
+#define RID_SVXSTR_BMP56                                    
NC_("RID_SVXSTR_BMP56", "Weave")
+#define RID_SVXSTR_BMP57                                    
NC_("RID_SVXSTR_BMP57", "Plaid")
+#define RID_SVXSTR_BMP58                                    
NC_("RID_SVXSTR_BMP58", "Divot")
+#define RID_SVXSTR_BMP59                                    
NC_("RID_SVXSTR_BMP59", "Dotted Grid")
+#define RID_SVXSTR_BMP60                                    
NC_("RID_SVXSTR_BMP60", "Dotted Diamond")
+#define RID_SVXSTR_BMP61                                    
NC_("RID_SVXSTR_BMP61", "Shingle")
+#define RID_SVXSTR_BMP62                                    
NC_("RID_SVXSTR_BMP62", "Trellis")
+#define RID_SVXSTR_BMP63                                    
NC_("RID_SVXSTR_BMP63", "Sphere")
+#define RID_SVXSTR_BMP64                                    
NC_("RID_SVXSTR_BMP64", "Small Grid")
+#define RID_SVXSTR_BMP65                                    
NC_("RID_SVXSTR_BMP65", "Large Grid")
+#define RID_SVXSTR_BMP66                                    
NC_("RID_SVXSTR_BMP66", "Small Checker Board")
+#define RID_SVXSTR_BMP67                                    
NC_("RID_SVXSTR_BMP67", "Large Checker Board")
+#define RID_SVXSTR_BMP68                                    
NC_("RID_SVXSTR_BMP68", "Outlined Diamond")
+#define RID_SVXSTR_BMP69                                    
NC_("RID_SVXSTR_BMP69", "Solid Diamond")
+#define RID_SVXSTR_BMP70                                    
NC_("RID_SVXSTR_BMP70", "Vertical")
+#define RID_SVXSTR_BMP71                                    
NC_("RID_SVXSTR_BMP71", "Horizontal")
+#define RID_SVXSTR_BMP72                                    
NC_("RID_SVXSTR_BMP72", "Downward Diagonal")
+#define RID_SVXSTR_BMP73                                    
NC_("RID_SVXSTR_BMP72", "Upward Diagonal")
+#define RID_SVXSTR_BMP74                                    
NC_("RID_SVXSTR_BMP74", "Cross")
+#define RID_SVXSTR_BMP75                                    
NC_("RID_SVXSTR_BMP75", "Diagonal Cross")
 #define RID_SVXSTR_DASH0                                    
NC_("RID_SVXSTR_DASH0", "Ultrafine Dashed")
 #define RID_SVXSTR_DASH1                                    
NC_("RID_SVXSTR_DASH1", "Fine Dashed")
 #define RID_SVXSTR_DASH2                                    
NC_("RID_SVXSTR_DASH2", "2 Dots 3 Dashes")
diff --git a/svx/inc/strings.hxx b/svx/inc/strings.hxx
index cb726c172189..0ca35e05a736 100644
--- a/svx/inc/strings.hxx
+++ b/svx/inc/strings.hxx
@@ -168,6 +168,61 @@
 #define RID_SVXSTR_BMP19_DEF                        "Fiery"
 #define RID_SVXSTR_BMP20_DEF                        "Roses"
 #define RID_SVXSTR_BMP21_DEF                        "Bitmap"
+// Reference strings for patterns - they are a variation of bitmaps
+#define RID_SVXSTR_BMP22_DEF                        "5 Percent"
+#define RID_SVXSTR_BMP23_DEF                        "10 Percent"
+#define RID_SVXSTR_BMP24_DEF                        "20 Percent"
+#define RID_SVXSTR_BMP25_DEF                        "25 Percent"
+#define RID_SVXSTR_BMP26_DEF                        "30 Percent"
+#define RID_SVXSTR_BMP27_DEF                        "40 Percent"
+#define RID_SVXSTR_BMP28_DEF                        "50 Percent"
+#define RID_SVXSTR_BMP29_DEF                        "60 Percent"
+#define RID_SVXSTR_BMP30_DEF                        "70 Percent"
+#define RID_SVXSTR_BMP31_DEF                        "75 Percent"
+#define RID_SVXSTR_BMP32_DEF                        "80 Percent"
+#define RID_SVXSTR_BMP33_DEF                        "90 Percent"
+#define RID_SVXSTR_BMP34_DEF                        "Light Downward Diagonal"
+#define RID_SVXSTR_BMP35_DEF                        "Light Upward Diagonal"
+#define RID_SVXSTR_BMP36_DEF                        "Dark Downward Diagonal"
+#define RID_SVXSTR_BMP37_DEF                        "Dark Upward Diagonal"
+#define RID_SVXSTR_BMP38_DEF                        "Wide Downward Diagonal"
+#define RID_SVXSTR_BMP39_DEF                        "Wide Upward Diagonal"
+#define RID_SVXSTR_BMP40_DEF                        "Light Vertical"
+#define RID_SVXSTR_BMP41_DEF                        "Light Horizontal"
+#define RID_SVXSTR_BMP42_DEF                        "Narrow Vertical"
+#define RID_SVXSTR_BMP43_DEF                        "Narrow Horizontal"
+#define RID_SVXSTR_BMP44_DEF                        "Dark Vertical"
+#define RID_SVXSTR_BMP45_DEF                        "Dark Horizontal"
+#define RID_SVXSTR_BMP46_DEF                        "Dashed Downward Diagonal"
+#define RID_SVXSTR_BMP47_DEF                        "Dashed Upward Diagonal"
+#define RID_SVXSTR_BMP48_DEF                        "Dashed Horizontal"
+#define RID_SVXSTR_BMP49_DEF                        "Dashed Vertical"
+#define RID_SVXSTR_BMP50_DEF                        "Small Confetti"
+#define RID_SVXSTR_BMP51_DEF                        "Large Confetti"
+#define RID_SVXSTR_BMP52_DEF                        "Zig Zag"
+#define RID_SVXSTR_BMP53_DEF                        "Wave"
+#define RID_SVXSTR_BMP54_DEF                        "Diagonal Brick"
+#define RID_SVXSTR_BMP55_DEF                        "Horizontal Brick"
+#define RID_SVXSTR_BMP56_DEF                        "Weave"
+#define RID_SVXSTR_BMP57_DEF                        "Plaid"
+#define RID_SVXSTR_BMP58_DEF                        "Divot"
+#define RID_SVXSTR_BMP59_DEF                        "Dotted Grid"
+#define RID_SVXSTR_BMP60_DEF                        "Dotted Diamond"
+#define RID_SVXSTR_BMP61_DEF                        "Shingle"
+#define RID_SVXSTR_BMP62_DEF                        "Trellis"
+#define RID_SVXSTR_BMP63_DEF                        "Sphere"
+#define RID_SVXSTR_BMP64_DEF                        "Small Grid"
+#define RID_SVXSTR_BMP65_DEF                        "Large Grid"
+#define RID_SVXSTR_BMP66_DEF                        "Small Checker Board"
+#define RID_SVXSTR_BMP67_DEF                        "Large Checker Board"
+#define RID_SVXSTR_BMP68_DEF                        "Outlined Diamond"
+#define RID_SVXSTR_BMP69_DEF                        "Solid Diamond"
+#define RID_SVXSTR_BMP70_DEF                        "Vertical"
+#define RID_SVXSTR_BMP71_DEF                        "Horizontal"
+#define RID_SVXSTR_BMP72_DEF                        "Downward Diagonal"
+#define RID_SVXSTR_BMP73_DEF                        "Upward Diagonal"
+#define RID_SVXSTR_BMP74_DEF                        "Cross"
+#define RID_SVXSTR_BMP75_DEF                        "Diagonal Cross"
 // Reference-strings for standard-dash-table
 #define RID_SVXSTR_DASH0_DEF                        "Ultrafine Dashed"
 #define RID_SVXSTR_DASH1_DEF                        "Fine Dashed"
diff --git a/svx/source/unodraw/unoprov.cxx b/svx/source/unodraw/unoprov.cxx
index c03ede3c1ad3..abe266261ec6 100644
--- a/svx/source/unodraw/unoprov.cxx
+++ b/svx/source/unodraw/unoprov.cxx
@@ -1054,7 +1054,61 @@ static const char* RID_SVXSTR_BMP_DEF[] =
     RID_SVXSTR_BMP18_DEF,
     RID_SVXSTR_BMP19_DEF,
     RID_SVXSTR_BMP20_DEF,
-    RID_SVXSTR_BMP21_DEF
+    RID_SVXSTR_BMP21_DEF,
+    RID_SVXSTR_BMP22_DEF,
+    RID_SVXSTR_BMP23_DEF,
+    RID_SVXSTR_BMP24_DEF,
+    RID_SVXSTR_BMP25_DEF,
+    RID_SVXSTR_BMP26_DEF,
+    RID_SVXSTR_BMP27_DEF,
+    RID_SVXSTR_BMP28_DEF,
+    RID_SVXSTR_BMP29_DEF,
+    RID_SVXSTR_BMP30_DEF,
+    RID_SVXSTR_BMP31_DEF,
+    RID_SVXSTR_BMP32_DEF,
+    RID_SVXSTR_BMP33_DEF,
+    RID_SVXSTR_BMP34_DEF,
+    RID_SVXSTR_BMP35_DEF,
+    RID_SVXSTR_BMP36_DEF,
+    RID_SVXSTR_BMP37_DEF,
+    RID_SVXSTR_BMP38_DEF,
+    RID_SVXSTR_BMP39_DEF,
+    RID_SVXSTR_BMP40_DEF,
+    RID_SVXSTR_BMP41_DEF,
+    RID_SVXSTR_BMP42_DEF,
+    RID_SVXSTR_BMP43_DEF,
+    RID_SVXSTR_BMP44_DEF,
+    RID_SVXSTR_BMP45_DEF,
+    RID_SVXSTR_BMP46_DEF,
+    RID_SVXSTR_BMP47_DEF,
+    RID_SVXSTR_BMP48_DEF,
+    RID_SVXSTR_BMP49_DEF,
+    RID_SVXSTR_BMP50_DEF,
+    RID_SVXSTR_BMP51_DEF,
+    RID_SVXSTR_BMP52_DEF,
+    RID_SVXSTR_BMP53_DEF,
+    RID_SVXSTR_BMP54_DEF,
+    RID_SVXSTR_BMP55_DEF,
+    RID_SVXSTR_BMP56_DEF,
+    RID_SVXSTR_BMP57_DEF,
+    RID_SVXSTR_BMP58_DEF,
+    RID_SVXSTR_BMP59_DEF,
+    RID_SVXSTR_BMP60_DEF,
+    RID_SVXSTR_BMP61_DEF,
+    RID_SVXSTR_BMP62_DEF,
+    RID_SVXSTR_BMP63_DEF,
+    RID_SVXSTR_BMP64_DEF,
+    RID_SVXSTR_BMP65_DEF,
+    RID_SVXSTR_BMP66_DEF,
+    RID_SVXSTR_BMP67_DEF,
+    RID_SVXSTR_BMP68_DEF,
+    RID_SVXSTR_BMP69_DEF,
+    RID_SVXSTR_BMP70_DEF,
+    RID_SVXSTR_BMP71_DEF,
+    RID_SVXSTR_BMP72_DEF,
+    RID_SVXSTR_BMP73_DEF,
+    RID_SVXSTR_BMP74_DEF,
+    RID_SVXSTR_BMP75_DEF
 };
 
 static const char* RID_SVXSTR_BMP[] =
@@ -1080,7 +1134,61 @@ static const char* RID_SVXSTR_BMP[] =
     RID_SVXSTR_BMP18,
     RID_SVXSTR_BMP19,
     RID_SVXSTR_BMP20,
-    RID_SVXSTR_BMP21
+    RID_SVXSTR_BMP21,
+    RID_SVXSTR_BMP22,
+    RID_SVXSTR_BMP23,
+    RID_SVXSTR_BMP24,
+    RID_SVXSTR_BMP25,
+    RID_SVXSTR_BMP26,
+    RID_SVXSTR_BMP27,
+    RID_SVXSTR_BMP28,
+    RID_SVXSTR_BMP29,
+    RID_SVXSTR_BMP30,
+    RID_SVXSTR_BMP31,
+    RID_SVXSTR_BMP32,
+    RID_SVXSTR_BMP33,
+    RID_SVXSTR_BMP34,
+    RID_SVXSTR_BMP35,
+    RID_SVXSTR_BMP36,
+    RID_SVXSTR_BMP37,
+    RID_SVXSTR_BMP38,
+    RID_SVXSTR_BMP39,
+    RID_SVXSTR_BMP40,
+    RID_SVXSTR_BMP41,
+    RID_SVXSTR_BMP42,
+    RID_SVXSTR_BMP43,
+    RID_SVXSTR_BMP44,
+    RID_SVXSTR_BMP45,
+    RID_SVXSTR_BMP46,
+    RID_SVXSTR_BMP47,
+    RID_SVXSTR_BMP48,
+    RID_SVXSTR_BMP49,
+    RID_SVXSTR_BMP50,
+    RID_SVXSTR_BMP51,
+    RID_SVXSTR_BMP52,
+    RID_SVXSTR_BMP53,
+    RID_SVXSTR_BMP54,
+    RID_SVXSTR_BMP55,
+    RID_SVXSTR_BMP56,
+    RID_SVXSTR_BMP57,
+    RID_SVXSTR_BMP58,
+    RID_SVXSTR_BMP59,
+    RID_SVXSTR_BMP60,
+    RID_SVXSTR_BMP61,
+    RID_SVXSTR_BMP62,
+    RID_SVXSTR_BMP63,
+    RID_SVXSTR_BMP64,
+    RID_SVXSTR_BMP65,
+    RID_SVXSTR_BMP66,
+    RID_SVXSTR_BMP67,
+    RID_SVXSTR_BMP68,
+    RID_SVXSTR_BMP69,
+    RID_SVXSTR_BMP70,
+    RID_SVXSTR_BMP71,
+    RID_SVXSTR_BMP72,
+    RID_SVXSTR_BMP73,
+    RID_SVXSTR_BMP74,
+    RID_SVXSTR_BMP75
 };
 
 static const char* RID_SVXSTR_DASH_DEF[] =
commit 6a313ab973378e82715cfda7431a8abbe474fd06
Author: Jens Carl <j.car...@gmx.de>
Date:   Tue Aug 29 04:48:13 2017 +0000

    tdf#106894: Rewrite packimages.pl in Python (pack_images.py)
    
    Change-Id: I2e9054775941b38392ba3ee38575891b5339249e
    Reviewed-on: https://gerrit.libreoffice.org/42790
    Reviewed-by: Samuel Mehrbrodt <samuel.mehrbr...@cib.de>
    Tested-by: Samuel Mehrbrodt <samuel.mehrbr...@cib.de>

diff --git a/postprocess/CustomTarget_images.mk 
b/postprocess/CustomTarget_images.mk
index 44899e6105a5..603c73d522d4 100644
--- a/postprocess/CustomTarget_images.mk
+++ b/postprocess/CustomTarget_images.mk
@@ -33,7 +33,7 @@ $(packimages_DIR)/%.zip : \
        $(call gb_Output_announce,$(subst $(WORKDIR)/,,$@),$(true),PRL,2)
        $(call gb_Helper_abbreviate_dirs, \
                ILSTFILE=$(call var2file,$(shell $(gb_MKTEMP)),100,$(filter 
%.ilst,$^)) && \
-               $(PERL) $(SRCDIR)/solenv/bin/packimages.pl \
+               $(PYTHON) $(SRCDIR)/solenv/bin/pack_images.py \
                        $(if $(DEFAULT_THEME),\
                                -g $(packimages_DIR) -m $(packimages_DIR) -c 
$(packimages_DIR),\
                                -g $(SRCDIR)/icon-themes/$(subst images_,,$*) 
-m $(SRCDIR)/icon-themes/$(subst images_,,$*) -c $(SRCDIR)/icon-themes/$(subst 
images_,,$*) \
diff --git a/solenv/bin/pack_images.py b/solenv/bin/pack_images.py
new file mode 100755
index 000000000000..0e1a5fe329f0
--- /dev/null
+++ b/solenv/bin/pack_images.py
@@ -0,0 +1,590 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-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/.
+#
+""" Pack images into archives. """
+
+from __future__ import with_statement
+
+import argparse
+from collections import OrderedDict
+import logging
+import os
+import shutil
+import sys

... etc. - the rest is truncated
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to