Kaydet (Commit) 715b7b6f authored tarafından Tor Lillqvist's avatar Tor Lillqvist

tdf#103571: Avoid spurious heavy SalEvent::DisplayChanged callbacks

It seems that on some Macs that the
NSApplicationDidChangeScreenParametersNotification is sent for unknown
reasons quite often. I can reproduce the problem by changing the Dock
size in System Preferences while LibreOffice is running, but others
seem to get it without resorting to such trickery.

The code used to invoke the SalEvent::DisplayChanged callback in all
cases, which can be extremely heavy, as it involves re-measuring text
layouts all over the place in all open document windows.

Avoid that if the geometry in fact has not changed.

Sure, there still is the problem that LibreOffice can become
unresponsive for several seconds when the display geometry *does*
change, like when you attach or detach a display.

Change-Id: I659881e5e392bd599f6be190835e32a77d9f4725
Reviewed-on: https://gerrit.libreoffice.org/50249Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarTor Lillqvist <tml@collabora.com>
üst 6d673473
...@@ -82,6 +82,7 @@ public: ...@@ -82,6 +82,7 @@ public:
PointerStyle mePointerStyle; // currently active pointer style PointerStyle mePointerStyle; // currently active pointer style
NSTrackingRectTag mnTrackingRectTag; // used to get enter/leave messages NSTrackingRectTag mnTrackingRectTag; // used to get enter/leave messages
NSRect maTrackingRect;
CGMutablePathRef mrClippingPath; // used for "shaping" CGMutablePathRef mrClippingPath; // used for "shaping"
std::vector< CGRect > maClippingRects; std::vector< CGRect > maClippingRects;
...@@ -95,6 +96,11 @@ public: ...@@ -95,6 +96,11 @@ public:
// To prevent display sleep during presentation // To prevent display sleep during presentation
IOPMAssertionID mnAssertionID; IOPMAssertionID mnAssertionID;
NSRect maFrameRect;
NSRect maContentRect;
bool mbGeometryDidChange;
public: public:
/** Constructor /** Constructor
......
...@@ -268,6 +268,10 @@ void AquaSalFrame::screenParametersChanged() ...@@ -268,6 +268,10 @@ void AquaSalFrame::screenParametersChanged()
if( mpGraphics ) if( mpGraphics )
mpGraphics->updateResolution(); mpGraphics->updateResolution();
if (!mbGeometryDidChange)
return;
CallCallback( SalEvent::DisplayChanged, nullptr ); CallCallback( SalEvent::DisplayChanged, nullptr );
} }
...@@ -1522,6 +1526,9 @@ void AquaSalFrame::SetParent( SalFrame* pNewParent ) ...@@ -1522,6 +1526,9 @@ void AquaSalFrame::SetParent( SalFrame* pNewParent )
void AquaSalFrame::UpdateFrameGeometry() void AquaSalFrame::UpdateFrameGeometry()
{ {
bool bFirstTime = (mnTrackingRectTag == 0);
mbGeometryDidChange = false;
if ( !mpNSWindow ) if ( !mpNSWindow )
return; return;
...@@ -1534,38 +1541,65 @@ void AquaSalFrame::UpdateFrameGeometry() ...@@ -1534,38 +1541,65 @@ void AquaSalFrame::UpdateFrameGeometry()
NSScreen * pScreen = [mpNSWindow screen]; NSScreen * pScreen = [mpNSWindow screen];
if( pScreen ) if( pScreen )
{ {
maScreenRect = [pScreen frame]; NSRect aNewScreenRect = [pScreen frame];
if (bFirstTime || !NSEqualRects(maScreenRect, aNewScreenRect))
{
mbGeometryDidChange = true;
maScreenRect = aNewScreenRect;
}
NSArray* pScreens = [NSScreen screens]; NSArray* pScreens = [NSScreen screens];
if( pScreens ) if( pScreens )
maGeometry.nDisplayScreenNumber = [pScreens indexOfObject: pScreen]; {
unsigned int nNewDisplayScreenNumber = [pScreens indexOfObject: pScreen];
if (bFirstTime || maGeometry.nDisplayScreenNumber != nNewDisplayScreenNumber)
{
mbGeometryDidChange = true;
maGeometry.nDisplayScreenNumber = nNewDisplayScreenNumber;
}
}
} }
NSRect aFrameRect = [mpNSWindow frame]; NSRect aFrameRect = [mpNSWindow frame];
NSRect aContentRect = [NSWindow contentRectForFrameRect: aFrameRect styleMask: mnStyleMask]; NSRect aContentRect = [NSWindow contentRectForFrameRect: aFrameRect styleMask: mnStyleMask];
// release old track rect
[mpNSView removeTrackingRect: mnTrackingRectTag];
// install the new track rect
NSRect aTrackRect = { NSZeroPoint, aContentRect.size }; NSRect aTrackRect = { NSZeroPoint, aContentRect.size };
mnTrackingRectTag = [mpNSView addTrackingRect: aTrackRect owner: mpNSView userData: nil assumeInside: NO];
if (bFirstTime || !NSEqualRects(maTrackingRect, aTrackRect))
{
mbGeometryDidChange = true;
maTrackingRect = aTrackRect;
// release old track rect
[mpNSView removeTrackingRect: mnTrackingRectTag];
// install the new track rect
mnTrackingRectTag = [mpNSView addTrackingRect: aTrackRect owner: mpNSView userData: nil assumeInside: NO];
}
// convert to vcl convention // convert to vcl convention
CocoaToVCL( aFrameRect ); CocoaToVCL( aFrameRect );
CocoaToVCL( aContentRect ); CocoaToVCL( aContentRect );
maGeometry.nX = static_cast<int>(aContentRect.origin.x); if (bFirstTime || !NSEqualRects(maContentRect, aContentRect) || !NSEqualRects(maFrameRect, aFrameRect))
maGeometry.nY = static_cast<int>(aContentRect.origin.y); {
mbGeometryDidChange = true;
maContentRect = aContentRect;
maFrameRect = aFrameRect;
maGeometry.nLeftDecoration = static_cast<unsigned int>(aContentRect.origin.x - aFrameRect.origin.x); maGeometry.nX = static_cast<int>(aContentRect.origin.x);
maGeometry.nRightDecoration = static_cast<unsigned int>((aFrameRect.origin.x + aFrameRect.size.width) - maGeometry.nY = static_cast<int>(aContentRect.origin.y);
(aContentRect.origin.x + aContentRect.size.width));
maGeometry.nTopDecoration = static_cast<unsigned int>(aContentRect.origin.y - aFrameRect.origin.y); maGeometry.nLeftDecoration = static_cast<unsigned int>(aContentRect.origin.x - aFrameRect.origin.x);
maGeometry.nBottomDecoration = static_cast<unsigned int>((aFrameRect.origin.y + aFrameRect.size.height) - maGeometry.nRightDecoration = static_cast<unsigned int>((aFrameRect.origin.x + aFrameRect.size.width) -
(aContentRect.origin.y + aContentRect.size.height)); (aContentRect.origin.x + aContentRect.size.width));
maGeometry.nWidth = static_cast<unsigned int>(aContentRect.size.width); maGeometry.nTopDecoration = static_cast<unsigned int>(aContentRect.origin.y - aFrameRect.origin.y);
maGeometry.nHeight = static_cast<unsigned int>(aContentRect.size.height); maGeometry.nBottomDecoration = static_cast<unsigned int>((aFrameRect.origin.y + aFrameRect.size.height) -
(aContentRect.origin.y + aContentRect.size.height));
maGeometry.nWidth = static_cast<unsigned int>(aContentRect.size.width);
maGeometry.nHeight = static_cast<unsigned int>(aContentRect.size.height);
}
} }
void AquaSalFrame::CaptureMouse( bool bCapture ) void AquaSalFrame::CaptureMouse( bool bCapture )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment