[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-5.3-desktop' - vcl/inc vcl/osx

Tor Lillqvist tml at collabora.com
Wed Feb 28 10:10:20 UTC 2018


 vcl/inc/osx/salframe.h |    6 ++++
 vcl/osx/salframe.cxx   |   66 +++++++++++++++++++++++++++++++++++++------------
 2 files changed, 56 insertions(+), 16 deletions(-)

New commits:
commit 2b309a8e027173285274c68f8d2a0219fea5f3fd
Author: Tor Lillqvist <tml at collabora.com>
Date:   Fri Feb 23 15:27:51 2018 +0200

    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 at libreoffice.org>
    Reviewed-by: Tor Lillqvist <tml at collabora.com>
    (cherry picked from commit 715b7b6f346fdd9c856db268dcd66334b58c273c)
    Reviewed-on: https://gerrit.libreoffice.org/50498
    Reviewed-by: Andras Timar <andras.timar at collabora.com>
    Tested-by: Andras Timar <andras.timar at collabora.com>

diff --git a/vcl/inc/osx/salframe.h b/vcl/inc/osx/salframe.h
index 94afaf3e9f0e..849ea2132559 100644
--- a/vcl/inc/osx/salframe.h
+++ b/vcl/inc/osx/salframe.h
@@ -81,6 +81,7 @@ public:
     PointerStyle                    mePointerStyle;         // currently active pointer style
 
     NSTrackingRectTag               mnTrackingRectTag;      // used to get enter/leave messages
+    NSRect                          maTrackingRect;
 
     CGMutablePathRef                mrClippingPath;         // used for "shaping"
     std::vector< CGRect >           maClippingRects;
@@ -94,6 +95,11 @@ public:
     // To prevent display sleep during presentation
     IOPMAssertionID                 mnAssertionID;
 
+    NSRect                          maFrameRect;
+    NSRect                          maContentRect;
+
+    bool                            mbGeometryDidChange;
+
 public:
     /** Constructor
 
diff --git a/vcl/osx/salframe.cxx b/vcl/osx/salframe.cxx
index ca4a5d9928d7..53f5cc3a0da2 100644
--- a/vcl/osx/salframe.cxx
+++ b/vcl/osx/salframe.cxx
@@ -263,6 +263,10 @@ void AquaSalFrame::screenParametersChanged()
 
     if( mpGraphics )
         mpGraphics->updateResolution();
+
+    if (!mbGeometryDidChange)
+        return;
+
     CallCallback( SalEvent::DisplayChanged, nullptr );
 }
 
@@ -1534,6 +1538,9 @@ void AquaSalFrame::SetParent( SalFrame* pNewParent )
 
 void AquaSalFrame::UpdateFrameGeometry()
 {
+    bool bFirstTime = (mnTrackingRectTag == 0);
+    mbGeometryDidChange = false;
+
     if ( !mpNSWindow )
     {
         return;
@@ -1546,38 +1553,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 )


More information about the Libreoffice-commits mailing list