vcl/qt5/QtFilePicker.cxx |   29 +++++++++--------------------
 1 file changed, 9 insertions(+), 20 deletions(-)

New commits:
commit edc9277e0f8de3f32502db41a3167ce03fff2b50
Author:     Michael Weghorn <m.wegh...@posteo.de>
AuthorDate: Fri Apr 25 15:19:57 2025 +0200
Commit:     Michael Weghorn <m.wegh...@posteo.de>
CommitDate: Fri Apr 25 18:34:46 2025 +0200

    tdf#166334 qt: More reliably detect native file dlg parent
    
    QtFilePicker's XWindow parent can be either a QtXWindow
    when native Qt widgets are used, see
    
    commit 429b08357e0c904d8096ff5830d844a199cd59b0
    Author: Michael Weghorn <m.wegh...@posteo.de>
    Date:   Fri Feb 21 23:48:47 2025 +0100
    
        tdf#130857 qt weld: Introduce QtXWindow
    
    , or a VCLXWindow when vcl::Window is used.
    
    Use a different approach for retrieving the native
    QWidget parent for the file dialog for the VCLXWindow
    case:
    The previous low level handling involving
    resolving the window handle can be problematic
    in particular on Wayland and is therefore refused with
    Qt 6, see
    
        commit 2f4103da5625a9b90eb41d5c767a248a8d0b4255
        Author: Michael Weghorn <m.wegh...@posteo.de>
        Date:   Fri May 17 17:02:49 2024 +0200
    
            tdf#160565 tdf#145735 qt: Avoid native window handles for Qt 6
    
    . Instead, use UnoWrapper to get the underlying
    vcl::Window and then logic similar to the one in
    QtInstance::GetNativeParentFromWeldParent to
    get the corresponding top level QWidget/QtMainWindow
    from its QtFrame.
    
    On Debian testing with qt6 on Wayland, this commit causes
    the main LibreOffice window to be properly grayed out and
    the file dialog always staying on top when using "File" -> "Save As",
    while that was previously not the case. (With
    QT_QPA_PLATFORM=xcb, the main window was greyed out,
    but the dialog didn't open centered on top of it.)
    
    An alternative solution to make that scenario work
    as expected would be to ensure that a QtXWindow is used
    instead, by implementing a QtFrame::GetFrameWeld
    override that returns a QtXWindow as follows,
    similar to what the gtk3 VCL plugin does:
    
        weld::Window* QtFrame::GetFrameWeld() const
        {
            if (!m_xFrameWeld)
                m_xFrameWeld.reset(new QtInstanceWindow(asChild()));
            return m_xFrameWeld.get();
        }
    
    While this works just fine for that scenario, the problem
    about this approach is that all dialogs that are not native
    Qt dialogs yet (s. tdf#130857 for Qt welding) cannot handle
    the QtXWindow parent, so they would not have a proper parent
    set and thus dialog modality wouldn't work properly for these
    cases then.
    This would e.g. affect the "Format" -> "Paragraph" dialog
    (and many more) even with SAL_VCL_QT_USE_WELDED_WIDGETS=1
    set.
    
    Therefore, it would be premature to do that - at least unconditionally -
    at this point in time.
    
    Change-Id: If9ee1de461e3a2f0848e349fdddf0c23ee22cbc7
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184625
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>
    Tested-by: Jenkins

diff --git a/vcl/qt5/QtFilePicker.cxx b/vcl/qt5/QtFilePicker.cxx
index e3e79b065695..373c5b51d161 100644
--- a/vcl/qt5/QtFilePicker.cxx
+++ b/vcl/qt5/QtFilePicker.cxx
@@ -50,6 +50,7 @@
 #include <rtl/process.h>
 #include <sal/log.hxx>
 #include <vcl/qt/QtUtils.hxx>
+#include <vcl/toolkit/unowrap.hxx>
 
 #include <QtCore/QDebug>
 #include <QtCore/QRegularExpression>
@@ -871,28 +872,16 @@ void SAL_CALL QtFilePicker::initialize(const 
uno::Sequence<uno::Any>& args)
         return;
     }
 
-    css::uno::Reference<css::awt::XSystemDependentWindowPeer> 
xSysWinPeer(xParentWindow,
-                                                                          
css::uno::UNO_QUERY);
-    if (!xSysWinPeer.is())
+    UnoWrapperBase* pWrapper = UnoWrapperBase::GetUnoWrapper();
+    if (!pWrapper)
         return;
 
-    // the sal_*Int8 handling is strange, but it's public API - no way around
-    css::uno::Sequence<sal_Int8> aProcessIdent(16);
-    
rtl_getGlobalProcessId(reinterpret_cast<sal_uInt8*>(aProcessIdent.getArray()));
-    uno::Any aAny
-        = xSysWinPeer->getWindowHandle(aProcessIdent, 
css::lang::SystemDependent::SYSTEM_XWINDOW);
-    css::awt::SystemDependentXWindow xSysWin;
-    aAny >>= xSysWin;
-
-    const auto& pFrames = rQtInstance.getFrames();
-    const tools::Long aWindowHandle = xSysWin.WindowHandle;
-    const auto it
-        = std::find_if(pFrames.begin(), pFrames.end(), [&aWindowHandle](auto 
pFrame) -> bool {
-              const SystemEnvData& rData = pFrame->GetSystemData();
-              return tools::Long(rData.GetWindowHandle(pFrame)) == 
aWindowHandle;
-          });
-    if (it != pFrames.end())
-        m_pParentWidget = static_cast<QtFrame*>(*it)->asChild();
+    VclPtr<vcl::Window> xWindow = pWrapper->GetWindow(xParentWindow);
+    if (!xWindow)
+        return;
+
+    if (QtFrame* pFrame = static_cast<QtFrame*>(xWindow->ImplGetFrame()))
+        m_pParentWidget = pFrame->asChild();
 }
 
 void SAL_CALL QtFilePicker::cancel() { m_pFileDialog->reject(); }

Reply via email to