tdf#155092 don't dispatch left mouse up events during live resizing
Round 2 of trying to fix macOS live resizing.
If this is a left mouse up event, dispatching this event
will trigger tdf#155092 to occur in the next mouse down
event. So do not dispatch this event and push it back onto
the front of the event queue so no more events will be
dispatched until live resizing ends. Surprisingly, live
resizing appears to end in the next mouse down event.
Also, reverted parts of commit 54da842381ccb554d3cadc876f23cf183d21bf1a
and cleaned up the setting of ImplGetSVData()->mpWinData->mbIsLiveResize.
Change-Id: Ie93ed496e1f0e2a1711284ab205c6b245f71647c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159960
Tested-by: Jenkins
Reviewed-by: Patrick Luby <plubius@libreoffice.org>
diff --git a/vcl/inc/osx/salframeview.h b/vcl/inc/osx/salframeview.h
index 1bc2b27..2b1a3f9 100644
--- a/vcl/inc/osx/salframeview.h
+++ b/vcl/inc/osx/salframeview.h
@@ -45,6 +45,8 @@ enum class SalEvent;
-(void)windowDidDeminiaturize: (NSNotification*)pNotification;
-(BOOL)windowShouldClose: (NSNotification*)pNotification;
-(void)windowDidChangeBackingProperties:(NSNotification *)pNotification;
-(void)windowWillStartLiveResize:(NSNotification *)pNotification;
-(void)windowDidEndLiveResize:(NSNotification *)pNotification;
//-(void)willEncodeRestorableState:(NSCoder*)pCoderState;
//-(void)didDecodeRestorableState:(NSCoder*)pCoderState;
//-(void)windowWillEnterVersionBrowser:(NSNotification*)pNotification;
@@ -261,9 +263,6 @@ enum class SalEvent;
-(NSArray *)accessibilityChildren;
-(NSArray <id<NSAccessibilityElement>> *)accessibilityChildrenInNavigationOrder;
-(void)viewWillStartLiveResize;
-(void)viewDidEndLiveResize;
@end
@interface SalFrameViewA11yWrapper : AquaA11yWrapper
diff --git a/vcl/osx/salframeview.mm b/vcl/osx/salframeview.mm
index c583205..4fd5913 100644
--- a/vcl/osx/salframeview.mm
+++ b/vcl/osx/salframeview.mm
@@ -196,24 +196,19 @@ static NSArray *getMergedAccessibilityChildren(NSArray *pDefaultChildren, NSArra
return pRet;
}
// Update ImplGetSVData()->mpWinData->mbIsLiveResize and return the old value
static bool updateWinDataInLiveResize(bool bInLiveResize)
// Update ImplGetSVData()->mpWinData->mbIsLiveResize
static void updateWinDataInLiveResize(bool bInLiveResize)
{
bool bRet = false;
ImplSVData* pSVData = ImplGetSVData();
assert( pSVData );
if ( pSVData )
{
bRet = pSVData->mpWinData->mbIsLiveResize;
if ( bRet != bInLiveResize )
if ( pSVData->mpWinData->mbIsLiveResize != bInLiveResize )
{
pSVData->mpWinData->mbIsLiveResize = bInLiveResize;
Scheduler::Wakeup();
}
}
return bRet;
}
@interface NSResponder (SalFrameWindow)
@@ -405,9 +400,8 @@ static bool updateWinDataInLiveResize(bool bInLiveResize)
mpFrame->UpdateFrameGeometry();
mpFrame->CallCallback( SalEvent::Resize, nullptr );
bool bInLiveResize = [self inLiveResize];
bool bOldInLiveResize = updateWinDataInLiveResize(bInLiveResize);
if ( bInLiveResize || bOldInLiveResize )
updateWinDataInLiveResize( [self inLiveResize] );
if ( ImplGetSVData()->mpWinData->mbIsLiveResize )
{
#if HAVE_FEATURE_SKIA
// Related: tdf#152703 Eliminate empty window with Skia/Metal while resizing
@@ -447,7 +441,7 @@ static bool updateWinDataInLiveResize(bool bInLiveResize)
[self setMinSize:aMinSize];
[self setMaxSize:aMaxSize];
if ( bInLiveResize )
if ( ImplGetSVData()->mpWinData->mbIsLiveResize )
{
// tdf#152703 Force repaint after live resizing ends
// Repost this notification so that this selector will be called
@@ -568,6 +562,20 @@ static bool updateWinDataInLiveResize(bool bInLiveResize)
#endif
}
-(void)windowWillStartLiveResize:(NSNotification *)pNotification
{
SolarMutexGuard aGuard;
updateWinDataInLiveResize(true);
}
-(void)windowDidEndLiveResize:(NSNotification *)pNotification
{
SolarMutexGuard aGuard;
updateWinDataInLiveResize(false);
}
-(void)dockMenuItemTriggered: (id)sender
{
(void)sender;
@@ -769,13 +777,7 @@ static bool updateWinDataInLiveResize(bool bInLiveResize)
if (!mpFrame || !AquaSalFrame::isAlive(mpFrame))
return;
const bool bIsLiveResize = [self inLiveResize];
const bool bWasLiveResize = pSVData->mpWinData->mbIsLiveResize;
if (bWasLiveResize != bIsLiveResize)
{
pSVData->mpWinData->mbIsLiveResize = bIsLiveResize;
Scheduler::Wakeup();
}
updateWinDataInLiveResize([self inLiveResize]);
AquaSalGraphics* pGraphics = mpFrame->mpGraphics;
if (pGraphics)
@@ -2518,16 +2520,6 @@ static bool updateWinDataInLiveResize(bool bInLiveResize)
return [self accessibilityChildren];
}
-(void)viewWillStartLiveResize
{
updateWinDataInLiveResize(true);
}
-(void)viewDidEndLiveResize
{
updateWinDataInLiveResize(false);
}
@end
@implementation SalFrameViewA11yWrapper
diff --git a/vcl/osx/salinst.cxx b/vcl/osx/salinst.cxx
index 3c98e4f..62ec90d 100644
--- a/vcl/osx/salinst.cxx
+++ b/vcl/osx/salinst.cxx
@@ -555,13 +555,6 @@ static bool isWakeupEvent( NSEvent *pEvent )
bool AquaSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents)
{
// Related: tdf#152703 Eliminate potential blocking during live resize
// Some events and timers call Application::Reschedule() or
// Application::Yield() so don't block and wait for events when a
// window is in live resize
if ( ImplGetSVData()->mpWinData->mbIsLiveResize )
bWait = false;
// ensure that the per thread autorelease pool is top level and
// will therefore not be destroyed by cocoa implicitly
SalData::ensureThreadAutoreleasePool();
@@ -599,6 +592,19 @@ bool AquaSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents)
dequeue: YES];
if( pEvent )
{
// tdf#155092 don't dispatch left mouse up events during live resizing
// If this is a left mouse up event, dispatching this event
// will trigger tdf#155092 to occur in the next mouse down
// event. So do not dispatch this event and push it back onto
// the front of the event queue so no more events will be
// dispatched until live resizing ends. Surprisingly, live
// resizing appears to end in the next mouse down event.
if ( ImplGetSVData()->mpWinData->mbIsLiveResize && [pEvent type] == NSEventTypeLeftMouseUp )
{
[NSApp postEvent: pEvent atStart: YES];
return false;
}
[NSApp sendEvent: pEvent];
if ( isWakeupEvent( pEvent ) )
continue;
@@ -607,9 +613,7 @@ bool AquaSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents)
[NSApp updateWindows];
// Related: tdf#155092 keep LibreOffice state closely synched to
// the dispatched native event state during live resize.
if ( !bHandleAllCurrentEvents || !pEvent || now < [pEvent timestamp] || ImplGetSVData()->mpWinData->mbIsLiveResize )
if ( !bHandleAllCurrentEvents || !pEvent || now < [pEvent timestamp] )
break;
// noelgrandin: I see sporadic hangs on the macos jenkins boxes, and the backtrace
// points to the this loop - let us see if breaking out of here after too many
@@ -628,20 +632,22 @@ bool AquaSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents)
}
// if we had no event yet, wait for one if requested
if( bWait && ! bHadEvent )
// Related: tdf#152703 Eliminate potential blocking during live resize
// Some events and timers call Application::Reschedule() or
// Application::Yield() so don't block and wait for events when a
// window is in live resize
if( bWait && ! bHadEvent && !ImplGetSVData()->mpWinData->mbIsLiveResize )
{
SolarMutexReleaser aReleaser;
// Related: tdf#155092 don't block during a live resize.
// Also, attempt to fix macos jenkins hangs - part 3
// attempt to fix macos jenkins hangs - part 3
// oox::xls::WorkbookFragment::finalizeImport() calls
// AquaSalInstance::DoYield() with bWait set to true. But
// since unit tests generally have no expected user generated
// events, we can end up blocking and waiting forever so
// don't block and wait when running unit tests.
NSDate *pDate = ( ImplGetSVData()->mpWinData->mbIsLiveResize || SalInstance::IsRunningUnitTest() ) ? [NSDate distantPast] : [NSDate distantFuture];
pEvent = [NSApp nextEventMatchingMask: NSEventMaskAny
untilDate: pDate
untilDate: SalInstance::IsRunningUnitTest() ? [NSDate distantPast] : [NSDate distantFuture]
inMode: NSDefaultRunLoopMode
dequeue: YES];
if( pEvent )