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(); }