diff options
33 files changed, 507 insertions, 589 deletions
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; } |