summaryrefslogtreecommitdiff
path: root/vcl/osx/salframe.cxx
diff options
context:
space:
mode:
authorTor Lillqvist <tml@collabora.com>2018-02-23 15:27:51 +0200
committerTor Lillqvist <tml@collabora.com>2018-02-23 20:52:04 +0100
commit715b7b6f346fdd9c856db268dcd66334b58c273c (patch)
tree9481339a3db5393cfab94fcd55ea31ea2306ae56 /vcl/osx/salframe.cxx
parent6d67347311923dbe3975cfa197649f5856c00723 (diff)
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/50249 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Tor Lillqvist <tml@collabora.com>
Diffstat (limited to 'vcl/osx/salframe.cxx')
-rw-r--r--vcl/osx/salframe.cxx66
1 files changed, 50 insertions, 16 deletions
diff --git a/vcl/osx/salframe.cxx b/vcl/osx/salframe.cxx
index e8259b5bc223..5b00f7242900 100644
--- a/vcl/osx/salframe.cxx
+++ b/vcl/osx/salframe.cxx
@@ -268,6 +268,10 @@ void AquaSalFrame::screenParametersChanged()
if( mpGraphics )
mpGraphics->updateResolution();
+
+ if (!mbGeometryDidChange)
+ return;
+
CallCallback( SalEvent::DisplayChanged, nullptr );
}
@@ -1522,6 +1526,9 @@ void AquaSalFrame::SetParent( SalFrame* pNewParent )
void AquaSalFrame::UpdateFrameGeometry()
{
+ bool bFirstTime = (mnTrackingRectTag == 0);
+ mbGeometryDidChange = false;
+
if ( !mpNSWindow )
return;
@@ -1534,38 +1541,65 @@ void AquaSalFrame::UpdateFrameGeometry()
NSScreen * pScreen = [mpNSWindow screen];
if( pScreen )
{
- maScreenRect = [pScreen frame];
+ NSRect aNewScreenRect = [pScreen frame];
+ if (bFirstTime || !NSEqualRects(maScreenRect, aNewScreenRect))
+ {
+ mbGeometryDidChange = true;
+ maScreenRect = aNewScreenRect;
+ }
NSArray* pScreens = [NSScreen screens];
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 aContentRect = [NSWindow contentRectForFrameRect: aFrameRect styleMask: mnStyleMask];
- // release old track rect
- [mpNSView removeTrackingRect: mnTrackingRectTag];
- // install the new track rect
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
CocoaToVCL( aFrameRect );
CocoaToVCL( aContentRect );
- maGeometry.nX = static_cast<int>(aContentRect.origin.x);
- maGeometry.nY = static_cast<int>(aContentRect.origin.y);
+ if (bFirstTime || !NSEqualRects(maContentRect, aContentRect) || !NSEqualRects(maFrameRect, aFrameRect))
+ {
+ mbGeometryDidChange = true;
+
+ maContentRect = aContentRect;
+ maFrameRect = aFrameRect;
- maGeometry.nLeftDecoration = static_cast<unsigned int>(aContentRect.origin.x - aFrameRect.origin.x);
- maGeometry.nRightDecoration = static_cast<unsigned int>((aFrameRect.origin.x + aFrameRect.size.width) -
- (aContentRect.origin.x + aContentRect.size.width));
+ maGeometry.nX = static_cast<int>(aContentRect.origin.x);
+ maGeometry.nY = static_cast<int>(aContentRect.origin.y);
- maGeometry.nTopDecoration = static_cast<unsigned int>(aContentRect.origin.y - aFrameRect.origin.y);
- maGeometry.nBottomDecoration = static_cast<unsigned int>((aFrameRect.origin.y + aFrameRect.size.height) -
- (aContentRect.origin.y + aContentRect.size.height));
+ maGeometry.nLeftDecoration = static_cast<unsigned int>(aContentRect.origin.x - aFrameRect.origin.x);
+ maGeometry.nRightDecoration = static_cast<unsigned int>((aFrameRect.origin.x + aFrameRect.size.width) -
+ (aContentRect.origin.x + aContentRect.size.width));
- maGeometry.nWidth = static_cast<unsigned int>(aContentRect.size.width);
- maGeometry.nHeight = static_cast<unsigned int>(aContentRect.size.height);
+ maGeometry.nTopDecoration = static_cast<unsigned int>(aContentRect.origin.y - aFrameRect.origin.y);
+ 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 )