vcl/inc/osx/salframeview.h |    4 +++
 vcl/osx/salframeview.mm    |   53 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 57 insertions(+)

New commits:
commit 0e74b05b607d931d63762b7d8f69f59b457c1e17
Author:     Patrick Luby <guibmac...@gmail.com>
AuthorDate: Mon Oct 14 18:26:27 2024 -0400
Commit:     Adolfo Jayme Barrientos <fit...@ubuntu.com>
CommitDate: Sat Oct 26 10:49:35 2024 +0200

    Stop hiding of child windows when dragged to a different screen
    
    LibreOffice sets all dialog windows as a native child window of
    its related document window in order to force the dialog windows
    to always remain in front of their releated document window.
    
    However, for some unknown reason, if a native child window is
    dragged to a different screen than its native parent window,
    macOS will hide the native child window when the drag has ended.
    
    So, once the current drag has finished, unattach and reattach
    the native child window to its native parent window. This should
    cause macOS to force the native child window to jump back to the
    same screen as its native parent window.
    
    Change-Id: Ic859a44f4a0e113146f06cc5d311faf15b9c38dc
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/174914
    Reviewed-by: Patrick Luby <guibomac...@gmail.com>
    Tested-by: Jenkins
    (cherry picked from commit 633fad32611e39620218319327428050405a6b1a)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/174944
    Reviewed-by: Adolfo Jayme Barrientos <fit...@ubuntu.com>

diff --git a/vcl/inc/osx/salframeview.h b/vcl/inc/osx/salframeview.h
index 2b1a3f9baaed..dec2f03a42f3 100644
--- a/vcl/inc/osx/salframeview.h
+++ b/vcl/inc/osx/salframeview.h
@@ -30,9 +30,11 @@ enum class SalEvent;
     id mDraggingDestinationHandler;
     BOOL                mbInWindowDidResize;
     NSTimer*            mpLiveResizeTimer;
+    NSTimer*            mpResetParentWindowTimer;
 }
 -(id)initWithSalFrame: (AquaSalFrame*)pFrame;
 -(void)clearLiveResizeTimer;
+-(void)clearResetParentWindowTimer;
 -(void)dealloc;
 -(BOOL)canBecomeKeyWindow;
 -(void)displayIfNeeded;
@@ -80,6 +82,8 @@ enum class SalEvent;
 -(BOOL)accessibilityIsIgnored;
 -(BOOL)isAccessibilityElement;
 
+-(void)resetParentWindow;
+
 @end
 
 @interface SalFrameView : NSView <NSTextInputClient>
diff --git a/vcl/osx/salframeview.mm b/vcl/osx/salframeview.mm
index dba377899838..e43f0d14df3e 100644
--- a/vcl/osx/salframeview.mm
+++ b/vcl/osx/salframeview.mm
@@ -221,6 +221,7 @@ static void updateWinDataInLiveResize(bool bInLiveResize)
     mDraggingDestinationHandler = nil;
     mbInWindowDidResize = NO;
     mpLiveResizeTimer = nil;
+    mpResetParentWindowTimer = nil;
     mpFrame = pFrame;
     NSRect aRect = { { static_cast<CGFloat>(pFrame->maGeometry.x()), 
static_cast<CGFloat>(pFrame->maGeometry.y()) },
                      { static_cast<CGFloat>(pFrame->maGeometry.width()), 
static_cast<CGFloat>(pFrame->maGeometry.height()) } };
@@ -271,9 +272,20 @@ static void updateWinDataInLiveResize(bool bInLiveResize)
     }
 }
 
+-(void)clearResetParentWindowTimer
+{
+    if ( mpResetParentWindowTimer )
+    {
+        [mpResetParentWindowTimer invalidate];
+        [mpResetParentWindowTimer release];
+        mpResetParentWindowTimer = nil;
+    }
+}
+
 -(void)dealloc
 {
     [self clearLiveResizeTimer];
+    [self clearResetParentWindowTimer];
     [super dealloc];
 }
 
@@ -372,6 +384,18 @@ static void updateWinDataInLiveResize(bool bInLiveResize)
 
     if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
         mpFrame->screenParametersChanged();
+
+    // Start timer to handle hiding of native child windows that have been
+    // dragged to a different screen.
+    if( !mpResetParentWindowTimer )
+    {
+        mpResetParentWindowTimer = [NSTimer scheduledTimerWithTimeInterval: 
0.1f target: self selector: @selector(resetParentWindow) userInfo: nil repeats: 
YES];
+        if( mpResetParentWindowTimer )
+        {
+            [mpResetParentWindowTimer retain];
+            [[NSRunLoop currentRunLoop] addTimer: mpResetParentWindowTimer 
forMode: NSEventTrackingRunLoopMode];
+        }
+    }
 }
 
 -(void)windowDidMove: (NSNotification*)pNotification
@@ -691,6 +715,35 @@ static void updateWinDataInLiveResize(bool bInLiveResize)
         [self windowDidResize:[pTimer userInfo]];
 }
 
+-(void)resetParentWindow
+{
+    // Wait until the left mouse button has been released. Otherwise
+    // the code below will cause native child windows to flicker while
+    // dragging the window in a different screen than its parent window.
+    if( [NSEvent pressedMouseButtons] & 0x1 )
+        return;
+
+    // Stop hiding of child windows when dragged to a different screen
+    // LibreOffice sets all dialog windows as a native child window of
+    // its related document window in order to force the dialog windows
+    // to always remain in front of their releated document window.
+    // However, for some unknown reason, if a native child window is
+    // dragged to a different screen than its native parent window,
+    // macOS will hide the native child window when the drag has ended.
+    // So, once the current drag has finished, unattach and reattach
+    // the native child window to its native parent window. This should
+    // cause macOS to force the native child window to jump back to the
+    // same screen as its native parent window.
+    NSWindow *pParentWindow = [self parentWindow];
+    if( pParentWindow && [pParentWindow screen] != [self screen] )
+    {
+        [pParentWindow removeChildWindow: self];
+        [pParentWindow addChildWindow: self ordered: NSWindowAbove];
+    }
+
+    [self clearResetParentWindowTimer];
+}
+
 @end
 
 @implementation SalFrameView

Reply via email to