Rebased ref, commits from common ancestor: commit e338f3e6abcdc68730a485701e9cdf78f9397aad Author: Jan-Marek Glogowski <glo...@fbihome.de> Date: Tue Sep 26 19:06:51 2017 +0200
tdf#112605 OSX refactor SalAquaTimer Drops all the static calls and variables from SalAquaTimer and moves all timer handling logic inside the class. This also fixes the leak in in timerElapsed. Change-Id: Ie7a1a8fffb70b8579ec6876eed10a275d2f06d27 diff --git a/vcl/inc/osx/saltimer.h b/vcl/inc/osx/saltimer.h index 86964115d648..ad6adf9d00ed 100644 --- a/vcl/inc/osx/saltimer.h +++ b/vcl/inc/osx/saltimer.h @@ -43,6 +43,12 @@ public: class AquaSalTimer : public SalTimer { + NSTimer *m_pRunningTimer; + sal_uInt32 m_nTimerStartTicks; ///< system ticks at timer start % SAL_MAX_UINT32 + + void queueDispatchTimerEvent( bool bAtStart ); + void callTimerCallback(); + public: AquaSalTimer(); virtual ~AquaSalTimer() override; @@ -50,13 +56,18 @@ public: void Start( sal_uLong nMS ) override; void Stop() override; - static void handleStartTimerEvent( NSEvent* pEvent ); - static void handleDispatchTimerEvent(); + void handleStartTimerEvent( NSEvent* pEvent ); + void handleDispatchTimerEvent( NSEvent* pEvent ); + void handleTimerElapsed(); - static NSTimer* pRunningTimer; - static bool bDispatchTimer; + inline bool IsTimerElapsed() const; }; +inline bool AquaSalTimer::IsTimerElapsed() const +{ + return 0 != m_nTimerStartTicks; +} + #endif // INCLUDED_VCL_INC_OSX_SALTIMER_H /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/osx/salinst.cxx b/vcl/osx/salinst.cxx index 89e3ae6d4e82..1b08a29461e6 100644 --- a/vcl/osx/salinst.cxx +++ b/vcl/osx/salinst.cxx @@ -426,11 +426,13 @@ bool AquaSalInstance::IsMainThread() const void AquaSalInstance::handleAppDefinedEvent( NSEvent* pEvent ) { + AquaSalTimer *pTimer = static_cast<AquaSalTimer*>( ImplGetSVData()->maSchedCtx.mpSalTimer ); int nSubtype = [pEvent subtype]; switch( nSubtype ) { case AppStartTimerEvent: - AquaSalTimer::handleStartTimerEvent( pEvent ); + if ( pTimer ) + pTimer->handleStartTimerEvent( pEvent ); break; case AppEndLoopEvent: [NSApp stop: NSApp]; @@ -450,7 +452,8 @@ void AquaSalInstance::handleAppDefinedEvent( NSEvent* pEvent ) break; } case DispatchTimerEvent: - AquaSalTimer::handleDispatchTimerEvent(); + if ( pTimer ) + pTimer->handleDispatchTimerEvent( pEvent ); break; #if !HAVE_FEATURE_MACOSX_SANDBOX case AppleRemoteControlEvent: // Defined in <apple_remote/RemoteMainController.h> @@ -598,12 +601,11 @@ SAL_WNODEPRECATED_DECLARATIONS_POP { SolarMutexReleaser aReleaser; - NSDate* pDt = AquaSalTimer::pRunningTimer ? [AquaSalTimer::pRunningTimer fireDate] : [NSDate distantFuture]; SAL_WNODEPRECATED_DECLARATIONS_PUSH // 'NSAnyEventMask' is deprecated: first deprecated in macOS 10.12 pEvent = [NSApp nextEventMatchingMask: NSAnyEventMask SAL_WNODEPRECATED_DECLARATIONS_POP - untilDate: pDt + untilDate: [NSDate distantFuture] inMode: NSDefaultRunLoopMode dequeue: YES]; if( pEvent ) @@ -682,14 +684,9 @@ bool AquaSalInstance::AnyInput( VclInputFlags nType ) if( nType & VclInputFlags::TIMER ) { - if( AquaSalTimer::pRunningTimer ) - { - NSDate* pDt = [AquaSalTimer::pRunningTimer fireDate]; - if( pDt && [pDt timeIntervalSinceNow] < 0 ) - { - return true; - } - } + AquaSalTimer *pTimer = static_cast<AquaSalTimer*>( ImplGetSVData()->maSchedCtx.mpSalTimer ); + if (pTimer && pTimer->IsTimerElapsed()) + return true; } unsigned/*NSUInteger*/ nEventMask = 0; diff --git a/vcl/osx/salnstimer.mm b/vcl/osx/salnstimer.mm index c9b657dcd776..9647bb6b87c1 100644 --- a/vcl/osx/salnstimer.mm +++ b/vcl/osx/salnstimer.mm @@ -27,16 +27,12 @@ @implementation TimerCallbackCaller --(void)timerElapsed:(NSTimer*)pTimer +-(void)timerElapsed:(NSTimer*)pNSTimer { - (void)pTimer; - // nil the timer, as it is just invalidated after the firing function - AquaSalTimer::pRunningTimer = nil; - const AquaSalInstance *pInst = GetSalData()->mpFirstInstance; - if (pInst->mbIsLiveResize) - AquaSalTimer::handleDispatchTimerEvent(); - else - ImplNSAppPostEvent( AquaSalInstance::DispatchTimerEvent, YES ); + (void) pNSTimer; + AquaSalTimer *pTimer = static_cast<AquaSalTimer*>( ImplGetSVData()->maSchedCtx.mpSalTimer ); + if (pTimer) + pTimer->handleTimerElapsed(); } @end diff --git a/vcl/osx/saltimer.cxx b/vcl/osx/saltimer.cxx index e442fcf05335..9c5bb7a7db9e 100644 --- a/vcl/osx/saltimer.cxx +++ b/vcl/osx/saltimer.cxx @@ -20,6 +20,7 @@ #include <sal/config.h> #include <rtl/math.hxx> +#include <tools/time.hxx> #include "osx/saltimer.h" #include "osx/salnstimer.h" @@ -27,9 +28,6 @@ #include "osx/salframe.h" #include "osx/salinst.h" -NSTimer* AquaSalTimer::pRunningTimer = nil; - -static void ImplSalStopTimer(); void ImplNSAppPostEvent( short nEventId, BOOL bAtStart, int nUserData ) { @@ -73,7 +71,16 @@ SAL_WNODEPRECATED_DECLARATIONS_POP [NSApp postEvent: pEvent atStart: bAtStart]; } -static void ImplSalStartTimer( sal_uLong nMS ) +void AquaSalTimer::queueDispatchTimerEvent( bool bAtStart ) +{ + Stop(); + m_nTimerStartTicks = tools::Time::GetMonotonicTicks() % SAL_MAX_UINT32; + if ( 0 == m_nTimerStartTicks ) + m_nTimerStartTicks++; + ImplNSAppPostEvent( AquaSalInstance::DispatchTimerEvent, bAtStart, m_nTimerStartTicks ); +} + +void AquaSalTimer::Start( sal_uLong nMS ) { SalData* pSalData = GetSalData(); @@ -84,27 +91,24 @@ static void ImplSalStartTimer( sal_uLong nMS ) } if ( 0 == nMS && !pSalData->mpFirstInstance->mbIsLiveResize ) - { - ImplSalStopTimer(); - ImplNSAppPostEvent( AquaSalInstance::DispatchTimerEvent, NO ); - } + queueDispatchTimerEvent( NO ); else { NSTimeInterval aTI = double(nMS) / 1000.0; - if( AquaSalTimer::pRunningTimer != nil ) + if( m_pRunningTimer != nil ) { - if ([AquaSalTimer::pRunningTimer isValid] && rtl::math::approxEqual( - [AquaSalTimer::pRunningTimer timeInterval], aTI)) + if ([m_pRunningTimer isValid] && rtl::math::approxEqual( + [m_pRunningTimer timeInterval], aTI)) { // set new fire date - [AquaSalTimer::pRunningTimer setFireDate: [NSDate dateWithTimeIntervalSinceNow: aTI]]; + [m_pRunningTimer setFireDate: [NSDate dateWithTimeIntervalSinceNow: aTI]]; } else - ImplSalStopTimer(); + Stop(); } - if( AquaSalTimer::pRunningTimer == nil ) + if( m_pRunningTimer == nil ) { - AquaSalTimer::pRunningTimer = [[NSTimer scheduledTimerWithTimeInterval: aTI + m_pRunningTimer = [[NSTimer scheduledTimerWithTimeInterval: aTI target: [[[TimerCallbackCaller alloc] init] autorelease] selector: @selector(timerElapsed:) userInfo: nil @@ -113,22 +117,23 @@ static void ImplSalStartTimer( sal_uLong nMS ) /* #i84055# add timer to tracking run loop mode, so they also elapse while e.g. life resize */ - [[NSRunLoop currentRunLoop] addTimer: AquaSalTimer::pRunningTimer forMode: NSEventTrackingRunLoopMode]; + [[NSRunLoop currentRunLoop] addTimer: m_pRunningTimer forMode: NSEventTrackingRunLoopMode]; } } } -static void ImplSalStopTimer() +void AquaSalTimer::Stop() { - if( AquaSalTimer::pRunningTimer != nil ) + if( m_pRunningTimer != nil ) { - [AquaSalTimer::pRunningTimer invalidate]; - [AquaSalTimer::pRunningTimer release]; - AquaSalTimer::pRunningTimer = nil; + [m_pRunningTimer invalidate]; + [m_pRunningTimer release]; + m_pRunningTimer = nil; } + m_nTimerStartTicks = 0; } -void AquaSalTimer::handleDispatchTimerEvent() +void AquaSalTimer::callTimerCallback() { ImplSVData* pSVData = ImplGetSVData(); SolarMutexGuard aGuard; @@ -136,6 +141,23 @@ void AquaSalTimer::handleDispatchTimerEvent() pSVData->maSchedCtx.mpSalTimer->CallCallback(); } +void AquaSalTimer::handleTimerElapsed() +{ + // Stop the timer, as it is just invalidated after the firing function + Stop(); + + if ( GetSalData()->mpFirstInstance->mbIsLiveResize ) + callTimerCallback(); + else + queueDispatchTimerEvent( YES ); +} + +void AquaSalTimer::handleDispatchTimerEvent( NSEvent *pEvent ) +{ + if (m_nTimerStartTicks == [pEvent data1]) + callTimerCallback(); +} + void AquaSalTimer::handleStartTimerEvent( NSEvent* pEvent ) { ImplSVData* pSVData = ImplGetSVData(); @@ -144,29 +166,21 @@ void AquaSalTimer::handleStartTimerEvent( NSEvent* pEvent ) NSTimeInterval posted = [pEvent timestamp] + NSTimeInterval([pEvent data1])/1000.0; NSTimeInterval current = [NSDate timeIntervalSinceReferenceDate]; if( (posted - current) <= 0.0 ) - handleDispatchTimerEvent(); + queueDispatchTimerEvent( YES ); else - ImplSalStartTimer( sal_uLong( [pEvent data1] ) ); + Start( sal_uLong( [pEvent data1] ) ); } } AquaSalTimer::AquaSalTimer( ) + : m_pRunningTimer( nullptr ) + , m_nTimerStartTicks( 0 ) { } AquaSalTimer::~AquaSalTimer() { - ImplSalStopTimer(); -} - -void AquaSalTimer::Start( sal_uLong nMS ) -{ - ImplSalStartTimer( nMS ); -} - -void AquaSalTimer::Stop() -{ - ImplSalStopTimer(); + Stop(); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 1d52df8cdc5c0303e5ac3c018db3c6fe8b43cc43 Author: Jan-Marek Glogowski <glo...@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 a little bit unexpected and as all the code has a comment "FIXME: lousy workaround", my fix is simply to drop it. 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 f06c9fd0b2ab..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,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 61fb9b9eb02b64531596e5c621b5f6b5a470adb5 Author: Jan-Marek Glogowski <glo...@fbihome.de> Date: Mon Sep 4 17:40:13 2017 +0200 Unify SalUserEvent handling Merges the various SalUserEvent structs and thier handling into a single class. This includes a common SalFrame* hash map, as all backends use such a map to verify alive SalFrames. Change-Id: I188b567e44fd79c162b2d9cabbd771d1f66c7dc4 diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index 1aa3095d0a6c..5d62542e8b13 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -321,6 +321,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/source/app/help \ vcl/source/app/i18nhelp \ vcl/source/app/idle \ + vcl/source/app/salusereventlist \ vcl/source/app/salvtables \ vcl/source/app/scheduler \ vcl/source/app/session \ diff --git a/vcl/headless/svpframe.cxx b/vcl/headless/svpframe.cxx index 9a086c0b3d6a..7fc7c3a88eb0 100644 --- a/vcl/headless/svpframe.cxx +++ b/vcl/headless/svpframe.cxx @@ -94,10 +94,9 @@ SvpSalFrame::~SvpSalFrame() // pass focus to another frame, preferably a document style window if( s_pFocusFrame == nullptr ) { - const std::list< SalFrame* >& rFrames( m_pInstance->getFrames() ); - for( std::list< SalFrame* >::const_iterator it = rFrames.begin(); it != rFrames.end(); ++it ) + for (auto pSalFrame : m_pInstance->getFrames() ) { - SvpSalFrame* pFrame = static_cast<SvpSalFrame*>(*it); + SvpSalFrame* pFrame = static_cast<SvpSalFrame*>( pSalFrame ); if( pFrame->m_bVisible && pFrame->m_pParent == nullptr && (pFrame->m_nStyle & (SalFrameStyleFlags::MOVEABLE | diff --git a/vcl/headless/svpinst.cxx b/vcl/headless/svpinst.cxx index ab8f91eac31f..5153c8952f4a 100644 --- a/vcl/headless/svpinst.cxx +++ b/vcl/headless/svpinst.cxx @@ -47,19 +47,6 @@ // FIXME: remove when we re-work the svp mainloop #include "unx/salunxtime.h" -bool SvpSalInstance::isFrameAlive( const SalFrame* pFrame ) const -{ - for( std::list< SalFrame* >::const_iterator it = m_aFrames.begin(); - it != m_aFrames.end(); ++it ) - { - if( *it == pFrame ) - { - return true; - } - } - return false; -} - SvpSalInstance* SvpSalInstance::s_pDefaultInstance = nullptr; #if !defined(ANDROID) && !defined(IOS) @@ -165,12 +152,8 @@ void SvpSalInstance::CreateWakeupPipe(bool log) #endif -void SvpSalInstance::PostEvent(const SalFrame* pFrame, ImplSVEvent* pData, SalEvent nEvent) +void SvpSalInstance::TriggerUserEventProcessing() { - { - osl::MutexGuard g(m_aEventGuard); - m_aUserEvents.emplace_back( pFrame, pData, nEvent ); - } Wakeup(); } @@ -186,31 +169,6 @@ bool SvpSalInstance::PostedEventsInQueue() } #endif -void SvpSalInstance::deregisterFrame( SalFrame* pFrame ) -{ - m_aFrames.remove( pFrame ); - - osl::MutexGuard g(m_aEventGuard); - // cancel outstanding events for this frame - if( ! m_aUserEvents.empty() ) - { - std::list< SalUserEvent >::iterator it = m_aUserEvents.begin(); - do - { - if( it->m_pFrame == pFrame ) - { - if (it->m_nEvent == SalEvent::UserEvent) - { - delete it->m_pData; - } - it = m_aUserEvents.erase( it ); - } - else - ++it; - } while( it != m_aUserEvents.end() ); - } -} - void SvpSalInstance::Wakeup() { #ifndef IOS @@ -304,44 +262,24 @@ SalBitmap* SvpSalInstance::CreateSalBitmap() #endif } -bool SvpSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents) +void SvpSalInstance::ProcessEvent( SalUserEvent aEvent ) { - // first, check for already queued events. - std::list< SalUserEvent > aEvents; + aEvent.m_pFrame->CallCallback( aEvent.m_nEvent, aEvent.m_pData ); + if( aEvent.m_nEvent == SalEvent::Resize ) { - osl::MutexGuard g(m_aEventGuard); - if( ! m_aUserEvents.empty() ) - { - if( bHandleAllCurrentEvents ) - { - aEvents = m_aUserEvents; - m_aUserEvents.clear(); - } - else - { - aEvents.push_back( m_aUserEvents.front() ); - m_aUserEvents.pop_front(); - } - } + // this would be a good time to post a paint + const SvpSalFrame* pSvpFrame = static_cast<const SvpSalFrame*>( aEvent.m_pFrame); + pSvpFrame->PostPaint(); } +} - bool bEvent = !aEvents.empty(); - if( bEvent ) - { - for( std::list<SalUserEvent>::const_iterator it = aEvents.begin(); it != aEvents.end(); ++it ) - { - if ( isFrameAlive( it->m_pFrame ) ) - { - it->m_pFrame->CallCallback( it->m_nEvent, it->m_pData ); - if( it->m_nEvent == SalEvent::Resize ) - { - // this would be a good time to post a paint - const SvpSalFrame* pSvpFrame = static_cast<const SvpSalFrame*>(it->m_pFrame); - pSvpFrame->PostPaint(); - } - } - } - } + +bool SvpSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents) +{ + // first, process current user events + bool bEvent = DispatchUserEvents( bHandleAllCurrentEvents ); + if ( !bHandleAllCurrentEvents &&bEvent ) + return true; bEvent = CheckTimeout() || bEvent; diff --git a/vcl/headless/svpprn.cxx b/vcl/headless/svpprn.cxx index 488f17bb4084..2afb52502300 100644 --- a/vcl/headless/svpprn.cxx +++ b/vcl/headless/svpprn.cxx @@ -257,10 +257,9 @@ OUString SvpSalInstance::GetDefaultPrinter() void SvpSalInstance::PostPrintersChanged() { - const std::list< SalFrame* >& rList = SvpSalInstance::s_pDefaultInstance->getFrames(); - for( std::list< SalFrame* >::const_iterator it = rList.begin(); - it != rList.end(); ++it ) - SvpSalInstance::s_pDefaultInstance->PostEvent( *it, nullptr, SalEvent::PrinterChanged ); + SvpSalInstance *pInst = SvpSalInstance::s_pDefaultInstance; + for (auto pSalFrame : pInst->getFrames() ) + pInst->PostEvent( pSalFrame, nullptr, SalEvent::PrinterChanged ); } GenPspGraphics *SvpSalInstance::CreatePrintGraphics() diff --git a/vcl/inc/headless/svpinst.hxx b/vcl/inc/headless/svpinst.hxx index 0883981c4406..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 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/salusereventlist.hxx b/vcl/inc/salusereventlist.hxx new file mode 100644 index 000000000000..feaf62c8a273 --- /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 > SalFrameHashMap; + +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; + SalFrameHashMap m_aFrames; + + virtual void ProcessEvent( SalUserEvent aEvent ) = 0; + virtual void TriggerUserEventProcessing() = 0; + virtual void TriggerAllUserEventsProcessed() {}; + +public: + SalUserEventList(); + virtual ~SalUserEventList(); + + inline const SalFrameHashMap& getFrames() const; + inline SalFrame* anyFrame() 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::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 SalFrameHashMap& 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 4f4d520fc141..1a510095f342 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; @@ -157,7 +158,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 ); @@ -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..4041e93dfe59 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 SalFrameHashMap& 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..f06c9fd0b2ab 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,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 +433,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 +444,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..023c5f974ddd --- /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( const SalFrame* pFrame ) +{ + auto aPair = m_aFrames.insert( const_cast<SalFrame*>( pFrame ) ); + assert( aPair.second ); (void) aPair; +} + +void SalUserEventList::eraseFrame( const SalFrame* pFrame ) +{ + auto it = m_aFrames.find( const_cast<SalFrame*>( 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..fbb27657e76d 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,41 @@ 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 ); + 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..3b282ce7f522 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); @@ -888,7 +873,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 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..acb7db876b73 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,24 +812,36 @@ 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); } 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 402461e45bc6..f047ed9fce65 100644 --- a/vcl/unx/kde4/KDEXLib.cxx +++ b/vcl/unx/kde4/KDEXLib.cxx @@ -357,10 +357,10 @@ void KDEXLib::Wakeup() QAbstractEventDispatcher::instance( qApp->thread())->wakeUp(); // main thread event loop } -void KDEXLib::PostUserEvent() +void KDEXLib::TriggerUserEventProcessing() { if( !m_isGlibEventLoopType ) - return SalXLib::PostUserEvent(); + return SalXLib::TriggerUserEventProcessing(); QApplication::postEvent(this, new QEvent(QEvent::Type( m_postUserEventId ))); } diff --git a/vcl/unx/kde4/KDEXLib.hxx b/vcl/unx/kde4/KDEXLib.hxx index 2fe497d019fa..4c06104b4c59 100644 --- a/vcl/unx/kde4/KDEXLib.hxx +++ b/vcl/unx/kde4/KDEXLib.hxx @@ -83,7 +83,7 @@ class KDEXLib : public QObject, public SalXLib virtual void StartTimer( sal_uLong nMS ) override; virtual void StopTimer() override; virtual void Wakeup() override; - virtual void PostUserEvent() override; + void TriggerUserEventProcessing(); void doStartup(); bool allowKdeDialogs() { return m_allowKdeDialogs; } commit 63965fd9c25f178f24986674dede0efd9cbd05a6 Author: Jan-Marek Glogowski <glo...@fbihome.de> Date: Fri Aug 25 14:52:38 2017 +0200 Disable ScHeaderFooterTextCursor scenario test Just like the ScHeaderFooterTextObj, it depends on weak referenced objects, which might be gone / cleaned up at test time. Change-Id: I52503646c51b0915df11f5c7f90c16208e45879a diff --git a/sc/qa/unoapi/sc_4.sce b/sc/qa/unoapi/sc_4.sce index d631ac99878b..ce879cc83272 100644 --- a/sc/qa/unoapi/sc_4.sce +++ b/sc/qa/unoapi/sc_4.sce @@ -36,6 +36,8 @@ # The css::text::XTextRange test fails often when the weak SHF_ContentObj is # already gone. If just this test is disabled, later tests of this object fail # too, so this disables the whole interface. +# Same for ScHeaderFooterTextCursor. +# -o sc.ScHeaderFooterTextCursor # -o sc.ScHeaderFooterTextObj -o sc.ScIndexEnumeration_CellAnnotationsEnumeration -o sc.ScIndexEnumeration_CellAreaLinksEnumeration commit 155795b9c129584febd9771014078adb6fe25932 Author: Jan-Marek Glogowski <glo...@fbihome.de> Date: Wed Sep 27 14:44:56 2017 +0200 tdf#112288 compare event timestamp with sys uptime This is a "brown paperbag" fixup. untilDate is actually used as a timeout for nextEventMatchingMask, not as a maximum event age. So manually compare the event timestamp with the system uptime. Change-Id: I912bedc0cba45c5cc231679c1b6139fa012492ed diff --git a/vcl/osx/salinst.cxx b/vcl/osx/salinst.cxx index f55e9b4aa297..855dac645e41 100644 --- a/vcl/osx/salinst.cxx +++ b/vcl/osx/salinst.cxx @@ -589,7 +589,7 @@ bool AquaSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents) { // handle available events NSEvent* pEvent = nil; - NSDate *now = [[NSDate alloc] init]; + NSTimeInterval now = [[NSProcessInfo processInfo]systemUptime]; do { SolarMutexReleaser aReleaser; @@ -598,7 +598,7 @@ SAL_WNODEPRECATED_DECLARATIONS_PUSH // 'NSAnyEventMask' is deprecated: first deprecated in macOS 10.12 pEvent = [NSApp nextEventMatchingMask: NSAnyEventMask SAL_WNODEPRECATED_DECLARATIONS_POP - untilDate: now + untilDate: nil inMode: NSDefaultRunLoopMode dequeue: YES]; if( pEvent ) @@ -611,7 +611,7 @@ SAL_WNODEPRECATED_DECLARATIONS_POP [NSApp updateWindows]; - if ( !bHandleAllCurrentEvents || !pEvent ) + if ( !bHandleAllCurrentEvents || !pEvent || now < [pEvent timestamp] ) break; } while( true ); @@ -744,7 +744,7 @@ SAL_WNODEPRECATED_DECLARATIONS_PUSH if( nType & VclInputFlags::KEYBOARD) nEventMask |= NSKeyDownMask | NSKeyUpMask | NSFlagsChangedMask; if( nType & VclInputFlags::OTHER) - nEventMask |= NSTabletPoint; + nEventMask |= NSTabletPoint | NSApplicationDefinedMask; SAL_WNODEPRECATED_DECLARATIONS_POP // TODO: VclInputFlags::PAINT / more VclInputFlags::OTHER if( !bool(nType) ) commit 3d3643491c9b3af082103bbd6bd18994d24cc568 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Wed Sep 27 12:07:02 2017 +0200 EPUB export: improve metadata tests This was the last uncovered piece in the ODF -> librevenge converter part. Change-Id: Ie9482f30c873deb3ddd601e1183b66706e913f14 Reviewed-on: https://gerrit.libreoffice.org/42848 Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk> Tested-by: Jenkins <c...@libreoffice.org> diff --git a/writerperfect/qa/unit/EPUBExportTest.cxx b/writerperfect/qa/unit/EPUBExportTest.cxx index d79a196c7863..374d9f730c23 100644 --- a/writerperfect/qa/unit/EPUBExportTest.cxx +++ b/writerperfect/qa/unit/EPUBExportTest.cxx @@ -292,6 +292,8 @@ void EPUBExportTest::testMeta() // This was "Unknown Author", <meta:initial-creator> was not handled. assertXPathContent(mpXmlDoc, "/opf:package/opf:metadata/dc:creator", "A U Thor"); assertXPathContent(mpXmlDoc, "/opf:package/opf:metadata/dc:title", "Title"); + assertXPathContent(mpXmlDoc, "/opf:package/opf:metadata/dc:language", "hu"); + assertXPathContent(mpXmlDoc, "/opf:package/opf:metadata/opf:meta[@property='dcterms:modified']", "2017-09-27T09:51:19Z"); } void EPUBExportTest::testParaNamedstyle() diff --git a/writerperfect/qa/unit/data/writer/epubexport/meta.fodt b/writerperfect/qa/unit/data/writer/epubexport/meta.fodt index 4e46fe79fcda..8b1af3e44f5a 100644 --- a/writerperfect/qa/unit/data/writer/epubexport/meta.fodt +++ b/writerperfect/qa/unit/data/writer/epubexport/meta.fodt @@ -3,6 +3,8 @@ <office:meta> <meta:initial-creator>A U Thor</meta:initial-creator> <dc:title>Title</dc:title> + <dc:language>hu</dc:language> + <dc:date>2017-09-27T09:51:19.243117081</dc:date> </office:meta> <office:body> <office:text> commit c2999602e2463cb11dbce1f71f0bcb304494a2f4 Author: Olivier Hallot <olivier.hal...@libreoffice.org> Date: Mon Sep 25 15:06:50 2017 -0300 Simplify call to external helponline add indentation chnage helponline.l.org -> help.l.org for good. Change-Id: Ie52a0f0a716c56da1a9553a805e25ebcabcb1490 Reviewed-on: https://gerrit.libreoffice.org/42764 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Julien Nabet <serval2...@yahoo.fr> Tested-by: Julien Nabet <serval2...@yahoo.fr> diff --git a/sfx2/source/appl/sfxhelp.cxx b/sfx2/source/appl/sfxhelp.cxx index 7773c29b9a50..cc06ba7550e0 100644 --- a/sfx2/source/appl/sfxhelp.cxx +++ b/sfx2/source/appl/sfxhelp.cxx @@ -54,6 +54,7 @@ #include <vcl/layout.hxx> #include <svtools/ehdl.hxx> #include <svtools/sfxecode.hxx> +#include "openuriexternally.hxx" #include "newhelp.hxx" #include <sfx2/objsh.hxx> @@ -530,16 +531,13 @@ static bool impl_showOnlineHelp( const OUString& rURL ) if ( rURL.getLength() <= aInternal.getLength() || !rURL.startsWith(aInternal) ) return false; - OUString aHelpLink( "http://helponline.libreoffice.org/help.html?" ); + OUString aHelpLink( "https://help.libreoffice.org/help.html?" ); aHelpLink += rURL.copy( aInternal.getLength() ); aHelpLink = aHelpLink.replaceAll("%2F","/"); try { - Reference< XSystemShellExecute > xSystemShell( - SystemShellExecute::create(::comphelper::getProcessComponentContext()) ); - - xSystemShell->execute( aHelpLink, OUString(), SystemShellExecuteFlags::URIS_ONLY ); + sfx2::openUriExternally(aHelpLink, false); return true; } catch (const Exception&) commit 9313fb9b5b872d7c888993ac186effcdcf9f8f57 Author: jan Iversen <j...@libreoffice.org> Date: Wed Sep 27 13:51:39 2017 +0200 iOS, remove xcconfig generation from configure.ac Moved generation of the xcconfig files out of configure.ac and into the regular ios make. Change-Id: If675eac9e86c4c4a0ff98f84815b0a83555d90a8 diff --git a/config_host.mk.in b/config_host.mk.in index d8a7b9c14083..874d68d46431 100644 --- a/config_host.mk.in +++ b/config_host.mk.in @@ -618,6 +618,8 @@ export WPG_CFLAGS=$(gb_SPACE)@WPG_CFLAGS@ export WPG_LIBS=$(gb_SPACE)@WPG_LIBS@ export WPS_CFLAGS=$(gb_SPACE)@WPS_CFLAGS@ export WPS_LIBS=$(gb_SPACE)@WPS_LIBS@ +export XCODE_DEBUG_INFORMATION_FORMAT=@XCODE_DEBUG_INFORMATION_FORMAT@ +export XCODE_CLANG_CXX_LIBRARY=@XCODE_CLANG_CXX_LIBRARY@ export XCODE_ARCHS=@XCODE_ARCHS@ export XCODEBUILD_SDK=@XCODEBUILD_SDK@ export XINERAMA_LINK=@XINERAMA_LINK@ diff --git a/configure.ac b/configure.ac index 4ecca6e36641..08f6863ae5ec 100644 --- a/configure.ac +++ b/configure.ac @@ -2872,21 +2872,13 @@ if test $_os = iOS; then if test "$enable_ios_simulator" = "yes"; then platform=iPhoneSimulator versionmin=-mios-simulator-version-min=9.3 - if test "$host_cpu" = "arm64"; then - XCODE_ARCHS=x86_64 - BITNESS=-fembed-bitcode - else - XCODE_ARCHS=i386 - fi + XCODE_ARCHS=x86_64 + BITNESS=-fembed-bitcode else platform=iPhoneOS versionmin=-miphoneos-version-min=9.3 - if test "$host_cpu" = "arm64"; then - XCODE_ARCHS=arm64 - BITNESS=-fembed-bitcode - else - XCODE_ARCHS=arm - fi + XCODE_ARCHS=arm64 + BITNESS=-fembed-bitcode fi xcode_developer=`xcode-select -print-path` @@ -4412,9 +4404,7 @@ if test "$cross_compiling" = "yes"; then bin/officeotron.sh.in \ instsetoo_native/util/openoffice.lst.in \ config_host/*.in \ - sysui/desktop/macosx/Info.plist.in \ - ios/LibreOfficeKit/lo_kit.xcconfig.in \ - ios/LibreOfficeLight/lo_app.xcconfig.in) \ + sysui/desktop/macosx/Info.plist.in) \ | (cd CONF-FOR-BUILD && tar xf -) cp configure CONF-FOR-BUILD test -d config_build && cp -p config_build/*.h CONF-FOR-BUILD/config_host 2>/dev/null @@ -12377,9 +12367,7 @@ AC_CONFIG_FILES([config_host.mk bin/odfvalidator.sh bin/officeotron.sh instsetoo_native/util/openoffice.lst - sysui/desktop/macosx/Info.plist - ios/LibreOfficeKit/lo_kit.xcconfig - ios/LibreOfficeLight/lo_app.xcconfig]) + sysui/desktop/macosx/Info.plist]) AC_CONFIG_HEADERS([config_host/config_buildid.h]) AC_CONFIG_HEADERS([config_host/config_clang.h]) AC_CONFIG_HEADERS([config_host/config_dconf.h]) diff --git a/ios/CustomTarget_setup.mk b/ios/CustomTarget_setup.mk new file mode 100644 index 000000000000..d0c64d799d32 --- /dev/null +++ b/ios/CustomTarget_setup.mk @@ -0,0 +1,79 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# 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/. +#- Env ------------------------------------------------------------------------ +IOSGEN := $(SRCDIR)/ios/generated +IOSKIT := $(IOSGEN)/loKit.xcconfig +IOSAPP := $(IOSGEN)/loApp.xcconfig + + +#- Top level ----------------------------------------------------------------- +$(eval $(call gb_CustomTarget_CustomTarget,ios/setup)) + +$(call gb_CustomTarget_get_target,ios/setup): $(IOSKIT) $(IOSAPP) + + +#- Generate xcconfig files --------------------------------------------------- +$(IOSKIT) : $(BUILDDIR)/config_host.mk + $(call gb_Output_announce,$(subst $(WORKDIR)/,,$@),$(true),ENV,2) + @mkdir -p $(IOSGEN); + @echo "// Xcode configuration properties" > $(IOSKIT) + @echo "// To avoid confusion, the LO-specific ones that aren't as such used" >> $(IOSKIT) + @echo "// Xcode (but only expanded in option values) are prefixed with" >> $(IOSKIT) + @echo "// LO_.\n" >> $(IOSKIT) + @echo "LO_BUILDDIR = $(BUILDDIR)" >> $(IOSKIT) + @echo "LO_INSTDIR = $(INSTDIR)" >> $(IOSKIT) + @echo "LO_SRCDIR = $(SRC_ROOT)" >> $(IOSKIT) + @echo "LO_WORKDIR = $(WORKDIR)" >> $(IOSKIT) + @echo "\n// These are actual Xcode-known settings. The corresponding autoconf" >> $(IOSKIT) + @echo "// variables are prefixed with XCODE_ to make it clear in configure.ac" >> $(IOSKIT) + @echo "// what they will be used for." >> $(IOSKIT) + @echo "ARCHS = $(XCODE_ARCHS)" >> $(IOSKIT) + @echo "VALID_ARCHS = $(XCODE_ARCHS)" >> $(IOSKIT) + @echo "CLANG_CXX_LIBRARY = $(XCODE_CLANG_CXX_LIBRARY)" >> $(IOSKIT) + @echo "DEBUG_INFORMATION_FORMAT=$(XCODE_DEBUG_INFORMATION_FORMAT)" >> $(IOSKIT) + @echo "\n// These settings are edited in CustomTarget_Lo_Xcconfig.mk." >> $(IOSKIT) + + @echo "OTHER_CFLAGS = $(gb_GLOBALDEFS)" >> $(IOSKIT) + @echo "OTHER_CPLUSPLUSFLAGS = $(gb_GLOBALDEFS)" >> $(IOSKIT) + @echo "LINK_LDFLAGS = -Wl,-lz,-liconv,-map,$(WORKDIR)/iosKit.map " \ + "`$(SRCDIR)/bin/lo-all-static-libs`" >> $(IOSKIT) + @echo "SYMROOT = $(WORKDIR)/ios/build\n" >> $(IOSKIT) + +$(IOSAPP) : $(BUILDDIR)/config_host.mk + $(call gb_Output_announce,$(subst $(WORKDIR)/,,$@),$(true),ENV,2) + @mkdir -p $(IOSGEN); + @echo "// Xcode configuration properties" > $(IOSAPP) + @echo "// To avoid confusion, the LO-specific ones that aren't as such used" >> $(IOSAPP) + @echo "// Xcode (but only expanded in option values) are prefixed with" >> $(IOSAPP) + @echo "// LO_.\n" >> $(IOSAPP) + @echo "LO_BUILDDIR = $(BUILDDIR)" >> $(IOSAPP) + @echo "LO_INSTDIR = $(INSTDIR)" >> $(IOSAPP) + @echo "LO_SRCDIR = $(SRC_ROOT)" >> $(IOSAPP) + @echo "LO_WORKDIR = $(WORKDIR)" >> $(IOSAPP) + @echo "\n// These are actual Xcode-known settings. The corresponding autoconf" >> $(IOSAPP) + @echo "// variables are prefixed with XCODE_ to make it clear in configure.ac" >> $(IOSAPP) + @echo "// what they will be used for." >> $(IOSAPP) + @echo "ARCHS = $(XCODE_ARCHS)" >> $(IOSAPP) + @echo "VALID_ARCHS = $(XCODE_ARCHS)" >> $(IOSAPP) + @echo "CLANG_CXX_LIBRARY = $(XCODE_CLANG_CXX_LIBRARY)" >> $(IOSAPP) + @echo "DEBUG_INFORMATION_FORMAT=$(XCODE_DEBUG_INFORMATION_FORMAT)" >> $(IOSAPP) + @echo "\n// These settings are edited in CustomTarget_Lo_Xcconfig.mk." >> $(IOSAPP) + + @echo "OTHER_CFLAGS = $(gb_GLOBALDEFS)" >> $(IOSAPP) + @echo "OTHER_CPLUSPLUSFLAGS = $(gb_GLOBALDEFS)" >> $(IOSAPP) + @echo "LINK_LDFLAGS = -Wl,-lz,-liconv,-map,$(WORKDIR)/iosApp.map " >> $(IOSAPP) + @echo "SYMROOT = $(WORKDIR)/ios/build\n" >> $(IOSAPP) + + + +$(call gb_CustomTarget_get_clean_target,ios/setup): + $(call gb_Output_announce,$(subst $(WORKDIR)/Clean/,,$@),$(false),ENV,2) + rm -rf $(IOSGEN) + + +# vim: set noet sw=4 ts=4: diff --git a/ios/LibreOfficeKit/lo_kit.xcconfig.in b/ios/LibreOfficeKit/lo_kit.xcconfig.in deleted file mode 100644 index 08623d8a9067..000000000000 --- a/ios/LibreOfficeKit/lo_kit.xcconfig.in +++ /dev/null @@ -1,32 +0,0 @@ -// -*- Mode: text; tab-width: 4; indent-tabs-mode: nil; word-wrap: nil -*- -// -// This file is part of the LibreOffice project. -// ... etc. - the rest is truncated _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits