[Libreoffice-commits] core.git: Branch 'private/jmux/scheduler-fixes' - 2 commits - vcl/headless vcl/inc vcl/Library_vcl.mk vcl/osx vcl/quartz vcl/source vcl/unx

Jan-Marek Glogowski glogow at fbihome.de
Tue Sep 5 17:13:26 UTC 2017


Rebased ref, commits from common ancestor:
commit 3c6ed5446121f74b9a8ff763f347c5d5dea41a3b
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Tue Sep 5 18:54:49 2017 +0200

    OSX revert fix for i#90083
    
    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.
    
    With the replacement of the list with a set, the result is probably
    also a bit unexpected.
    
    Change-Id: I456503a74d8cddbd1e81b4a826b94381b424c78c

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/osx/vclnsapp.mm b/vcl/osx/vclnsapp.mm
index 535286e698a6..337e92d4f0fe 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,77 +227,6 @@ SAL_WNODEPRECATED_DECLARATIONS_POP
     [super sendEvent: pEvent];
 }
 
--(void)cycleFrameForward: (AquaSalFrame*)pCurFrame
-{
-    // find current frame in list
-    auto &rFrames( GetSalData()->mpFirstInstance->getFrames() );
-    auto it = rFrames.find( pCurFrame );
-    if( it != rFrames.end() )
-    {
-        ++it;
-        // now find the next frame (or end)
-        for( ; it != rFrames.end(); ++it )
-        {
-            auto pFrame = static_cast<const AquaSalFrame*>( *it );
-            if( pFrame->mpDockMenuEntry != nullptr && pFrame->mbShown )
-            {
-                [pFrame->getNSWindow() makeKeyAndOrderFront: NSApp];
-                return;
-            }
-        }
-        // cycle around, find the next up to pCurFrame
-        for( it = rFrames.begin(); *it != pCurFrame; ++it )
-        {
-            auto pFrame = static_cast<const AquaSalFrame*>( *it );
-            if( pFrame->mpDockMenuEntry != nullptr && pFrame->mbShown )
-            {
-                [pFrame->getNSWindow() makeKeyAndOrderFront: NSApp];
-                return;
-            }
-        }
-    }
-}
-
-template< class Iterator >
-std::reverse_iterator<Iterator> make_reverse_iterator( Iterator i )
-{
-    return std::reverse_iterator<Iterator>(i);
-}
-
--(void)cycleFrameBackward: (AquaSalFrame*)pCurFrame
-{
-    // do the same as cycleFrameForward only with a reverse iterator
-
-    // find current frame in list
-    auto &rFrames( GetSalData()->mpFirstInstance->getFrames() );
-    auto search_it = rFrames.find( pCurFrame );
-    if( search_it != rFrames.end() )
-    {
-        auto it = ::make_reverse_iterator( search_it );
-        ++it;
-        // now find the next frame (or end)
-        for( ; it != rFrames.rend(); ++it )
-        {
-            auto pFrame = static_cast<const AquaSalFrame*>( *it );
-            if( pFrame->mpDockMenuEntry != nullptr && pFrame->mbShown )
-            {
-                [pFrame->getNSWindow() makeKeyAndOrderFront: NSApp];
-                return;
-            }
-        }
-        // cycle around, find the next up to pCurFrame
-        for( it = rFrames.rbegin(); *it != pCurFrame; ++it )
-        {
-            auto pFrame = static_cast<const AquaSalFrame*>( *it );
-            if( pFrame->mpDockMenuEntry != nullptr && pFrame->mbShown )
-            {
-                [pFrame->getNSWindow() makeKeyAndOrderFront: NSApp];
-                return;
-            }
-        }
-    }
-}
-
 -(NSMenu*)applicationDockMenu:(NSApplication *)sender
 {
     (void)sender;
commit c43044ea27150dcec5b0242b1905c864695a839d
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Tue Sep 5 13:50:23 2017 +0200

    Unify SalUserEvent handling
    
    Change-Id: I188b567e44fd79c162b2d9cabbd771d1f66c7dc4

diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 1a2105877de5..d76567776b42 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..08c6a09ef834 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*>( const_cast<SalFrame*>( 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 5fcb7c57d602..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.push_back( SalUserEvent( 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,45 +262,24 @@ SalBitmap* SvpSalInstance::CreateSalBitmap()
 #endif
 }
 
-bool SvpSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents)
+void SvpSalInstance::ProcessEvent( SalUserEvent aEvent )
 {
-    bool bEvent = false;
-
-    // first, process current user events
-    std::list< SalUserEvent > aCurrentEvents;
+    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 )
-                aCurrentEvents.swap( m_aUserEvents );
-            else
-            {
-                aCurrentEvents.push_back( m_aUserEvents.front() );
-                m_aUserEvents.pop_front();
-            }
-            bEvent = true;
-        }
+        // this would be a good time to post a paint
+        const SvpSalFrame* pSvpFrame = static_cast<const SvpSalFrame*>( aEvent.m_pFrame);
+        pSvpFrame->PostPaint();
     }
-    if( bEvent )
-    {
-        for( auto it = aCurrentEvents.begin(); it != aCurrentEvents.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();
-                }
-            }
+}
 
-            if ( !bHandleAllCurrentEvents )
-                return true;
-        }
-    }
+
+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 92a11e99d03a..eb9b322a9de5 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( const_cast<SalFrame*>( pSalFrame ), nullptr, SalEvent::PrinterChanged );
 }
 
 GenPspGraphics *SvpSalInstance::CreatePrintGraphics()
diff --git a/vcl/inc/headless/svpinst.hxx b/vcl/inc/headless/svpinst.hxx
index 0883981c4406..a411315c761d 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( const SalFrame* pFrame );
+    inline void             deregisterFrame( const SalFrame* pFrame );
 
     bool                    CheckTimeout( bool bExecuteTimers = true );
 
@@ -171,6 +150,16 @@ public:
     virtual GenPspGraphics *CreatePrintGraphics() override;
 };
 
+inline void SvpSalInstance::registerFrame( const SalFrame* pFrame )
+{
+    insertFrame( pFrame );
+}
+
+inline void SvpSalInstance::deregisterFrame( const 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 1cbdabb88563..6ca1adb235c5 100644
--- a/vcl/inc/osx/saldata.hxx
+++ b/vcl/inc/osx/saldata.hxx
@@ -47,6 +47,7 @@
 
 #include "osx/runinmain.hxx"
 
+class AquaSalFrame;
 class AquaSalInstance;
 class SalObject;
 class SalFrame;
@@ -56,7 +57,6 @@ class SystemFontList;
 
 #define SAL_CLIPRECT_COUNT 16
 
-class AquaSalFrame;
 struct FrameHash : public std::hash<sal_IntPtr>
 {
     size_t operator()(const AquaSalFrame* frame) const
@@ -73,8 +73,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 307356c76caa..5d46c136bcfe 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"
@@ -164,8 +165,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; }
 
@@ -205,6 +205,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 028b02afe630..4109526e02fa 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,28 +61,19 @@ 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;
     bool                                    mbWaitingYield;
     int                                     mnActivePrintJobs;
-    std::list< SalUserEvent >               maUserEvents;
     osl::Mutex                              maUserEventListMutex;
     osl::Condition                          maWaitingYieldCond;
     bool                                    mbIsLiveResize;
@@ -146,7 +139,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/salusereventlist.hxx b/vcl/inc/salusereventlist.hxx
new file mode 100644
index 000000000000..5165294fa387
--- /dev/null
+++ b/vcl/inc/salusereventlist.hxx
@@ -0,0 +1,118 @@
+/* -*- 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 <set>
+
+class SalFrame;
+enum class SalEvent;
+
+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;
+    std::set< const SalFrame* >   m_aFrames;
+    const SalFrame *              m_pFirstFrame;
+
+    virtual void ProcessEvent( SalUserEvent aEvent ) = 0;
+    virtual void TriggerUserEventProcessing() = 0;
+
+public:
+    SalUserEventList();
+    virtual ~SalUserEventList();
+
+    inline const std::set< const SalFrame* >& getFrames() const;
+    inline SalFrame* firstFrame() const;
+    void insertFrame( const SalFrame* pFrame );
+    void eraseFrame( const 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::firstFrame() const
+{
+    return const_cast<SalFrame*>( m_pFirstFrame );
+}
+
+inline bool SalUserEventList::isFrameAlive( const SalFrame* pFrame ) const
+{
+    auto it = m_aFrames.find( 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 std::set< const SalFrame* >& 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..13f1247e20d3 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();
+    virtual      ~SalGenericDisplay() override;
 
-    osl::Mutex& getEventGuardMutex() { return m_aEventGuard; }
-
-    void registerFrame( SalFrame* pFrame );
-    virtual void deregisterFrame( SalFrame* pFrame );
+    void registerFrame( const SalFrame* pFrame );
+    virtual void deregisterFrame( const 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 60a0940d9439..45d1564043da 100644
--- a/vcl/inc/unx/gtk/gtkdata.hxx
+++ b/vcl/inc/unx/gtk/gtkdata.hxx
@@ -111,7 +111,7 @@ public:
 
     static gboolean userEventFn( gpointer data );
 
-    void PostUserEvent();
+    void TriggerUserEventProcessing();
     bool Yield( bool bWait, bool bHandleAllCurrentEvents );
     inline GdkDisplay *GetGdkDisplay();
 
@@ -138,6 +138,9 @@ class GtkSalDisplay : public SalDisplay
 
     GdkCursor* getFromXBM( const unsigned char *pBitmap, const unsigned char *pMask,
                            int nWidth, int nHeight, int nXHot, int nYHot );
+
+    void WakeupMainLoop();
+
 public:
              GtkSalDisplay( GdkDisplay* pDisplay );
     virtual ~GtkSalDisplay() override;
@@ -149,7 +152,7 @@ public:
 
     GtkWidget* findGtkWidgetForNativeHandle(sal_uIntPtr hWindow) const;
 
-    virtual void deregisterFrame( SalFrame* pFrame ) override;
+    virtual void deregisterFrame( const SalFrame* pFrame ) override;
     GdkCursor *getCursor( PointerStyle ePointerStyle );
 #if GTK_CHECK_VERSION(3,0,0)
     virtual int CaptureMouse( SalFrame* pFrame );
@@ -172,7 +175,7 @@ public:
     void screenSizeChanged( GdkScreen const * );
     void monitorsChanged( GdkScreen const * );
 
-    virtual void PostUserEvent() override;
+    virtual void TriggerUserEventProcessing() 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 2c23d6010c35..72f3a43df371 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 std::set< const SalFrame* >& 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 c037c9cf5ddf..32132bde2940 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,19 @@ 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;
+        if( pInst->firstFrame() )
+            pInst->firstFrame()->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;
     }
 };
@@ -392,18 +392,20 @@ 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 ) );
-    }
     if( mbWaitingYield )
         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;
@@ -456,15 +458,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])
@@ -500,9 +504,8 @@ void AquaSalInstance::handleAppDefinedEvent( NSEvent* pEvent )
             default:
                 break;
         }
-        AquaSalFrame* pFrame = pSalData->maFrames.front();
+        AquaSalFrame* pFrame = static_cast<AquaSalFrame*>( pInst->firstFrame() );
         vcl::Window* pWindow = pFrame ? pFrame->GetWindow() : nullptr;
-
         if( pWindow )
         {
             const Point aPoint;
@@ -545,40 +548,10 @@ bool AquaSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents)
     // an own pool for each yield level
     ReleasePoolHolder aReleasePool;
 
-    bool bHadEvent = false;
-
     // first, process current user events
-    std::list< SalUserEvent > aCurrentEvents;
-    {
-        osl::MutexGuard g(m_aEventGuard);
-        if( ! m_aUserEvents.empty() )
-        {
-            if( bHandleAllCurrentEvents )
-                aCurrentEvents.swap( m_aUserEvents );
-            else
-            {
-                aCurrentEvents.push_back( m_aUserEvents.front() );
-                m_aUserEvents.pop_front();
-            }
-            bHadEvent = true;
-        }
-    }
-    if ( bHadEvent )
-    {
-        for( auto it = aCurrentEvents.begin(); it != aCurrentEvents.end(); ++it )
-        {
-            // dispatch it
-            if( it->mpFrame && AquaSalFrame::isAlive( it->mpFrame ) )
-            {
-                aEvent.mpFrame->CallCallback( it->mnType, it->mpData );
-                maWaitingYieldCond.set();
-            }
-
-            // return if only one event is asked for
-            if( !bHandleAllCurrentEvents )
-                return true;
-        }
-    }
+    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
@@ -637,13 +610,13 @@ SAL_WNODEPRECATED_DECLARATIONS_POP
         mbWaitingYield = bOldWaitingYield;
 
         // 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();
             }
         }
         maWaitingYieldCond.set();
diff --git a/vcl/osx/vclnsapp.mm b/vcl/osx/vclnsapp.mm
index 651fa2a014cc..535286e698a6 100644
--- a/vcl/osx/vclnsapp.mm
+++ b/vcl/osx/vclnsapp.mm
@@ -248,77 +248,70 @@ SAL_WNODEPRECATED_DECLARATIONS_POP
 -(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 )
-        ;
+    auto &rFrames( GetSalData()->mpFirstInstance->getFrames() );
+    auto it = rFrames.find( pCurFrame );
     if( it != rFrames.end() )
     {
+        ++it;
         // now find the next frame (or end)
-        do
+        for( ; it != rFrames.end(); ++it )
         {
-            ++it;
-            if( it != rFrames.end() )
+            auto pFrame = static_cast<const AquaSalFrame*>( *it );
+            if( pFrame->mpDockMenuEntry != nullptr && pFrame->mbShown )
             {
-                if( (*it)->mpDockMenuEntry != nullptr &&
-                    (*it)->mbShown )
-                {
-                    [(*it)->getNSWindow() makeKeyAndOrderFront: NSApp];
-                    return;
-                }
+                [pFrame->getNSWindow() makeKeyAndOrderFront: NSApp];
+                return;
             }
-        } while( it != rFrames.end() );
+        }
         // cycle around, find the next up to pCurFrame
-        it = rFrames.begin();
-        while( *it != pCurFrame )
+        for( it = rFrames.begin(); *it != pCurFrame; ++it )
         {
-            if( (*it)->mpDockMenuEntry != nullptr &&
-                (*it)->mbShown )
+            auto pFrame = static_cast<const AquaSalFrame*>( *it );
+            if( pFrame->mpDockMenuEntry != nullptr && pFrame->mbShown )
             {
-                [(*it)->getNSWindow() makeKeyAndOrderFront: NSApp];
+                [pFrame->getNSWindow() makeKeyAndOrderFront: NSApp];
                 return;
             }
-            ++it;
         }
     }
 }
 
+template< class Iterator >
+std::reverse_iterator<Iterator> make_reverse_iterator( Iterator i )
+{
+    return std::reverse_iterator<Iterator>(i);
+}
+
 -(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() )
+    auto &rFrames( GetSalData()->mpFirstInstance->getFrames() );
+    auto search_it = rFrames.find( pCurFrame );
+    if( search_it != rFrames.end() )
     {
+        auto it = ::make_reverse_iterator( search_it );
+        ++it;
         // now find the next frame (or end)
-        do
+        for( ; it != rFrames.rend(); ++it )
         {
-            ++it;
-            if( it != rFrames.rend() )
+            auto pFrame = static_cast<const AquaSalFrame*>( *it );
+            if( pFrame->mpDockMenuEntry != nullptr && pFrame->mbShown )
             {
-                if( (*it)->mpDockMenuEntry != nullptr &&
-                    (*it)->mbShown )
-                {
-                    [(*it)->getNSWindow() makeKeyAndOrderFront: NSApp];
-                    return;
-                }
+                [pFrame->getNSWindow() makeKeyAndOrderFront: NSApp];
+                return;
             }
-        } while( it != rFrames.rend() );
+        }
         // cycle around, find the next up to pCurFrame
-        it = rFrames.rbegin();
-        while( *it != pCurFrame )
+        for( it = rFrames.rbegin(); *it != pCurFrame; ++it )
         {
-            if( (*it)->mpDockMenuEntry != nullptr &&
-                (*it)->mbShown )
+            auto pFrame = static_cast<const AquaSalFrame*>( *it );
+            if( pFrame->mpDockMenuEntry != nullptr && pFrame->mbShown )
             {
-                [(*it)->getNSWindow() makeKeyAndOrderFront: NSApp];
+                [pFrame->getNSWindow() makeKeyAndOrderFront: NSApp];
                 return;
             }
-            ++it;
         }
     }
 }
@@ -413,12 +406,12 @@ SAL_WNODEPRECATED_DECLARATIONS_POP
     {
         SolarMutexGuard aGuard;
 
-        SalData* pSalData = GetSalData();
-        if( ! pSalData->maFrames.empty() )
+        AquaSalInstance *pInst = GetSalData()->mpFirstInstance;
+        if( pInst->firstFrame() )
         {
             // 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 = pInst->firstFrame()->CallCallback( SalEvent::Shutdown, nullptr ) ? NSTerminateCancel : NSTerminateNow;
         }
 
         if( aReply == NSTerminateNow )
@@ -439,9 +432,9 @@ 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;
+    if(  pInst->firstFrame() )
+        pInst->firstFrame()->CallCallback( SalEvent::SettingsChanged, nullptr );
 }
 
 -(void)screenParametersChanged: (NSNotification*) pNotification
@@ -449,11 +442,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..68d18870a44e 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->firstFrame() );
+            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..1630b1e4d014
--- /dev/null
+++ b/vcl/source/app/salusereventlist.cxx
@@ -0,0 +1,121 @@
+/* -*- 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()
+    : m_pFirstFrame( nullptr )
+{
+}
+
+SalUserEventList::~SalUserEventList()
+{
+}
+
+void SalUserEventList::insertFrame( const SalFrame* pFrame )
+{
+    auto aPair = m_aFrames.insert( pFrame );
+    assert( aPair.second ); (void) aPair;
+    if ( nullptr == m_pFirstFrame )
+        m_pFirstFrame = pFrame;
+}
+
+void SalUserEventList::eraseFrame( const SalFrame* pFrame )
+{
+    auto it = m_aFrames.find( pFrame );
+    assert( it != m_aFrames.end() );
+    if ( it != m_aFrames.end() )
+    {
+        if ( it == m_aFrames.begin() )
+            m_pFirstFrame = nullptr;
+        m_aFrames.erase( it );
+        if ( !m_aFrames.empty() )
+            m_pFirstFrame = *m_aFrames.begin();
+    }
+}
+
+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 );
+    }
+
+    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;
+        }
+    }
+
+    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 c1cd5a23112e..87b9c14585b5 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;
 }
@@ -31,96 +30,40 @@ SalGenericDisplay::~SalGenericDisplay()
 {
 }
 
-void SalGenericDisplay::registerFrame( SalFrame* pFrame )
+void SalGenericDisplay::registerFrame( const SalFrame* pFrame )
 {
-    m_aFrames.push_front( pFrame );
+    insertFrame( pFrame );
 }
 
-void SalGenericDisplay::deregisterFrame( SalFrame* pFrame )
+void SalGenericDisplay::deregisterFrame( const 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 );
+    if( m_pFirstFrame )
+        m_pFirstFrame->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.push_back( SalUserEvent( 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 cca11999e6b6..f6ea79399c9e 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(GetGenericData())->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(GetGenericData())->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 fb5131473e5a..007162a17b36 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 73d63086bec6..326d68f5adde 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*>( const_cast<SalFrame*>( 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 897d955ddccb..c306f6a78f70 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(GetGenericData());
-    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( const_cast<SalFrame*>( pSalFrame ), nullptr, SalEvent::PrinterChanged );
 }
 
 GenPspGraphics *X11SalInstance::CreatePrintGraphics()
diff --git a/vcl/unx/generic/app/sm.cxx b/vcl/unx/generic/app/sm.cxx
index b86435fbaf73..5d6bf68edd7f 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(GetGenericData())->getFrames();
-        for( std::list< SalFrame* >::const_iterator it = rFrames.begin(); it != rFrames.end(); ++it )
+        for (auto pSalFrame : vcl_sal::getSalDisplay(GetGenericData())->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(GetGenericData())->getFrames();
-
-    SAL_INFO("vcl.sm.debug", "  rFrames.empty() = " << (rFrames.empty() ? "true" : "false"));
-    if( !rFrames.empty() )
-        rFrames.front()->CallCallback( SalEvent::Shutdown, nullptr );
+    auto pFirstFrame = vcl_sal::getSalDisplay(GetGenericData())->firstFrame();
+    SAL_INFO("vcl.sm.debug", "  rFrames.empty() = " << (pFirstFrame ? "true" : "false"));
+    if( pFirstFrame )
+        pFirstFrame->CallCallback( SalEvent::Shutdown, nullptr );
 }
 
 void SessionManagerClient::DieProc(
diff --git a/vcl/unx/generic/gdi/salgdi2.cxx b/vcl/unx/generic/gdi/salgdi2.cxx
index 4e9219505069..0d726f59466a 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(GetGenericData())->getFrames();
-        for( std::list< SalFrame* >::const_iterator it = rFrames.begin(); it != rFrames.end() && ! pFrame; ++it )
+        for (auto pSalFrame : vcl_sal::getSalDisplay(GetGenericData())->getFrames() )
         {
-            const SystemEnvData* pEnvData = (*it)->GetSystemData();
+            const SystemEnvData* pEnvData = pSalFrame->GetSystemData();
             if( Drawable(pEnvData->aWindow) == aWindow )
-                pFrame = *it;
+                pFrame = const_cast<SalFrame*>( pSalFrame );
         }
         if( ! pFrame )
             return;
diff --git a/vcl/unx/generic/window/salframe.cxx b/vcl/unx/generic/window/salframe.cxx
index f8baf9b0742e..2bc836d6afe5 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 bcbce082ef29..5f6a30f35479 100644
--- a/vcl/unx/gtk/gtkdata.cxx
+++ b/vcl/unx/gtk/gtkdata.cxx
@@ -135,17 +135,16 @@ GdkFilterReturn GtkSalDisplay::filterGdkEvent( GdkXEvent* sys_event )
         // actually change when a corresponding PropertyNotify occurs
         if( pEvent->type == PropertyNotify &&
             pEvent->xproperty.atom == getWMAdaptor()->getAtom( WMAdaptor::XSETTINGS ) &&
-            ! m_aFrames.empty()
+            m_pFirstFrame
            )
         {
-            SendInternalEvent( m_aFrames.front(), nullptr, SalEvent::SettingsChanged );
+            PostEvent( firstFrame(), 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*>( const_cast<SalFrame*>( pSalFrame ) );
             if( pFrame->GetSystemData()->aWindow == pEvent->xany.window ||
                 ( pFrame->getForeignParent() && pFrame->getForeignParentWindow() == pEvent->xany.window ) ||
                 ( pFrame->getForeignTopLevel() && pFrame->getForeignTopLevelWindow() == pEvent->xany.window )
@@ -213,11 +212,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*>( const_cast<SalFrame*>( pSalFrame ) )->Dispatch( pEvent );
         }
     }
 
@@ -826,8 +824,7 @@ gboolean GtkData::userEventFn( gpointer data )
     {
         OSL_ASSERT(static_cast<const SalGenericDisplay *>(pThis->GetGtkDisplay()) == pDisplay);
         {
-            osl::MutexGuard g (pThis->GetGtkDisplay()->getEventGuardMutex());
-
+            osl::MutexGuard g( pThis->m_aDispatchMutex );
             if( !pThis->GetGtkDisplay()->HasUserEvents() )
             {
                 if( pThis->m_pUserEvent )
@@ -855,8 +852,9 @@ extern "C" {
 }
 
 // hEventGuard_ held during this invocation
-void GtkData::PostUserEvent()
+void GtkData::TriggerUserEventProcessing()
 {
+    osl::MutexGuard g( m_aDispatchMutex );
     if (m_pUserEvent)
         g_main_context_wakeup (nullptr); // really needed ?
     else // nothing pending anyway
@@ -870,16 +868,15 @@ void GtkData::PostUserEvent()
     }
 }
 
-void GtkSalDisplay::PostUserEvent()
+void GtkSalDisplay::TriggerUserEventProcessing()
 {
-    GetGtkSalData()->PostUserEvent();
+    GetGtkSalData()->TriggerUserEventProcessing();
 }
 
 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);
@@ -887,7 +884,7 @@ GtkWidget* GtkSalDisplay::findGtkWidgetForNativeHandle(sal_uIntPtr hWindow) cons
     return nullptr;
 }
 
-void GtkSalDisplay::deregisterFrame( SalFrame* pFrame )
+void GtkSalDisplay::deregisterFrame( const SalFrame* pFrame )
 {
     if( m_pCapture == pFrame )
     {
diff --git a/vcl/unx/gtk/gtksalframe.cxx b/vcl/unx/gtk/gtksalframe.cxx
index 8bd532eea78c..ab011854fdb9 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 77048114c2d0..2a6440b8ce61 100644
--- a/vcl/unx/gtk3/gtk3gtkdata.cxx
+++ b/vcl/unx/gtk3/gtk3gtkdata.cxx
@@ -788,8 +788,7 @@ gboolean GtkData::userEventFn( gpointer data )
     {
         OSL_ASSERT(static_cast<const SalGenericDisplay *>(pThis->GetGtkDisplay()) == pDisplay);
         {
-            osl::MutexGuard g (pThis->GetGtkDisplay()->getEventGuardMutex());
-
+            osl::MutexGuard g( pThis->m_aDispatchMutex );
             if( !pThis->GetGtkDisplay()->HasUserEvents() )
             {
                 if( pThis->m_pUserEvent )
@@ -817,8 +816,9 @@ extern "C" {
 }
 
 // hEventGuard_ held during this invocation
-void GtkData::PostUserEvent()
+void GtkData::TriggerUserEventProcessing()
 {
+    osl::MutexGuard g( m_aDispatchMutex );
     if (m_pUserEvent)
         g_main_context_wakeup (nullptr); // really needed ?
     else // nothing pending anyway
@@ -832,24 +832,23 @@ void GtkData::PostUserEvent()
     }
 }
 
-void GtkSalDisplay::PostUserEvent()
+void GtkSalDisplay::TriggerUserEventProcessing()
 {
-    GetGtkSalData()->PostUserEvent();
+    GetGtkSalData()->TriggerUserEventProcessing();
 }
 
 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);
     }
     return nullptr;
 }
 
-void GtkSalDisplay::deregisterFrame( SalFrame* pFrame )
+void GtkSalDisplay::deregisterFrame( const SalFrame* pFrame )
 {
     if( m_pCapture == pFrame )
     {
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 d56c67e008cb..17920e276869 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; }


More information about the Libreoffice-commits mailing list