diff options
author | Patrick Luby <guibmacdev@gmail.com> | 2024-10-14 18:26:27 -0400 |
---|---|---|
committer | Christian Lohmaier <lohmaier+LibreOffice@googlemail.com> | 2024-10-25 18:44:59 +0200 |
commit | d218e9e497dcf442f0b5141a8ee6656b8ae3967f (patch) | |
tree | 7c857b11347905fc42057e33bf4497c30a2fcbb1 | |
parent | 1650365a1b6f33ab0f2edd5832d4c402dd6ed7f8 (diff) |
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 <guibomacdev@gmail.com>
Tested-by: Jenkins
(cherry picked from commit 633fad32611e39620218319327428050405a6b1a)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/174943
Reviewed-by: Christian Lohmaier <lohmaier+LibreOffice@googlemail.com>
-rw-r--r-- | vcl/inc/osx/salframeview.h | 4 | ||||
-rw-r--r-- | vcl/osx/salframeview.mm | 53 |
2 files changed, 57 insertions, 0 deletions
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 a8432aba31b9..fa59f1018a39 100644 --- a/vcl/osx/salframeview.mm +++ b/vcl/osx/salframeview.mm @@ -222,6 +222,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()) } }; @@ -272,9 +273,20 @@ static void updateWinDataInLiveResize(bool bInLiveResize) } } +-(void)clearResetParentWindowTimer +{ + if ( mpResetParentWindowTimer ) + { + [mpResetParentWindowTimer invalidate]; + [mpResetParentWindowTimer release]; + mpResetParentWindowTimer = nil; + } +} + -(void)dealloc { [self clearLiveResizeTimer]; + [self clearResetParentWindowTimer]; [super dealloc]; } @@ -373,6 +385,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 @@ -692,6 +716,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 |