Files
libreoffice/vcl/qt5/QtFrame.cxx

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

1535 lines
50 KiB
C++
Raw Normal View History

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <QtFrame.hxx>
#include <QtFrame.moc>
#include <QtData.hxx>
#include <QtDragAndDrop.hxx>
#include <QtFontFace.hxx>
#include <QtGraphics.hxx>
#include <QtInstance.hxx>
#include <QtMainWindow.hxx>
#include <QtMenu.hxx>
#include <QtSvpGraphics.hxx>
#include <QtSystem.hxx>
#include <QtTools.hxx>
#include <QtTransferable.hxx>
#if CHECK_ANY_QT_USING_X11
#include <QtX11Support.hxx>
#endif
#include <QtCore/QMimeData>
#include <QtCore/QPoint>
#include <QtCore/QSize>
2019-06-02 21:01:33 +00:00
#include <QtCore/QThread>
#include <QtGui/QDragMoveEvent>
#include <QtGui/QDropEvent>
#include <QtGui/QIcon>
#include <QtGui/QWindow>
#include <QtGui/QScreen>
tdf#156894 qt: Prefer dark icon theme in dark mode When in dark mode, pass the param to prefer a dark icon theme to `StyleSettings::SetPreferredIconTheme`. For Qt >= 6.5 use `QStyleHints::colorScheme` introduced in Qt 6.5 to get the color scheme. For older Qt versions, use the same algorithm based on the gray value of the window background as xdg-desktop-portal-kde does for evaluating whether a light or dark color scheme is preferred [1]. On my Debian testing, the Breeze dark icon theme is now used as expected with kf5 or qt6 when setting the Global KDE Plasma theme to "Breeze Dark" and manually setting the Icon theme to "GNOME" afterwards. Previously, this would not use a dark icon theme and icons would be hard to see. Without manually setting the icon theme to "GNOME", the Breeze Dark icon theme would already be used before, because selecting "Breeze Dark" as the global KDE Plasma theme also selects the "Breeze Dark" icon theme by default, and therefore "breeze-dark" was already passed as the first param to `StyleSettings::SetPreferredIconTheme` and since that icon theme is present, the `bPreferDarkTheme` wouldn't be evaluated at all; it's only used when determining the fallback icon theme when the specified icon theme is not present. (Likewise, by enabling the "Breeze Dark" global theme and then manually setting the icon theme to "Breeze" in Plasma System settings, the Breeze light icon theme will be used in LibreOffice as well, resulting in hard to see icons, but I tend to think that that behavior is correct and works as designed - it's a misconfiguration.) The color scheme is also specified in xdg-desktop-portal (s. commit [2]) and can be retrived via dbus. Example with "Breeze Light" active: $ dbus-send --session --print-reply=literal --reply-timeout=1000 --dest=org.freedesktop.portal.Desktop /org/freedesktop/portal/desktop org.freedesktop.portal.Settings.Read string:'org.freedesktop.appearance' string:'color-scheme' variant variant uint32 2 With "Breeze Dark": $ dbus-send --session --print-reply=literal --reply-timeout=1000 --dest=org.freedesktop.portal.Desktop /org/freedesktop/portal/desktop org.freedesktop.portal.Settings.Read string:'org.freedesktop.appearance' string:'color-scheme' variant variant uint32 1 [1] https://invent.kde.org/plasma/xdg-desktop-portal-kde/-/blob/0a4237549debf9518f8cfbaf531456850c0729bd/src/settings.cpp#L213-227 [2] https://github.com/flatpak/xdg-desktop-portal/commit/d7a304a00697d7d608821253cd013f3b97ac0fb6 Change-Id: I8f347c6e7f775cc55377c5c84481de3051c3cf24 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156465 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2023-09-02 10:12:54 +02:00
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
#include <QtGui/QStyleHints>
#endif
#include <QtWidgets/QStyle>
#include <QtWidgets/QToolTip>
#include <QtWidgets/QApplication>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QMainWindow>
#if CHECK_QT5_USING_X11
#include <QtX11Extras/QX11Info>
#endif
#include <window.h>
#include <vcl/syswin.hxx>
#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
#include <cairo.h>
#include <headless/svpgdi.hxx>
#include <unx/fontmanager.hxx>
static void SvpDamageHandler(void* handle, sal_Int32 nExtentsX, sal_Int32 nExtentsY,
sal_Int32 nExtentsWidth, sal_Int32 nExtentsHeight)
{
QtFrame* pThis = static_cast<QtFrame*>(handle);
pThis->Damage(nExtentsX, nExtentsY, nExtentsWidth, nExtentsHeight);
}
namespace
{
sal_Int32 screenNumber(const QScreen* pScreen)
{
const QList<QScreen*> screens = QApplication::screens();
sal_Int32 nScreen = 0;
bool bFound = false;
for (const QScreen* pCurScreen : screens)
{
if (pScreen == pCurScreen)
{
bFound = true;
break;
}
nScreen++;
}
return bFound ? nScreen : -1;
}
}
QtFrame::QtFrame(QtFrame* pParent, SalFrameStyleFlags nStyle, bool bUseCairo)
: m_pTopLevel(nullptr)
, m_bUseCairo(bUseCairo)
, m_bNullRegion(true)
, m_bGraphicsInUse(false)
, m_ePointerStyle(PointerStyle::Arrow)
, m_pDragSource(nullptr)
, m_pDropTarget(nullptr)
, m_bInDrag(false)
, m_bDefaultSize(true)
, m_bDefaultPos(true)
, m_bFullScreen(false)
, m_bFullScreenSpanAll(false)
#if CHECK_ANY_QT_USING_X11
, m_nKeyModifiers(ModKeyFlags::NONE)
#endif
, m_nInputLanguage(LANGUAGE_DONTKNOW)
{
QtInstance* pInst = GetQtInstance();
pInst->insertFrame(this);
m_aDamageHandler.handle = this;
m_aDamageHandler.damaged = ::SvpDamageHandler;
if (nStyle & SalFrameStyleFlags::DEFAULT) // ensure default style
{
nStyle |= SalFrameStyleFlags::MOVEABLE | SalFrameStyleFlags::SIZEABLE
| SalFrameStyleFlags::CLOSEABLE;
nStyle &= ~SalFrameStyleFlags::FLOAT;
}
m_nStyle = nStyle;
m_pParent = pParent;
Qt::WindowFlags aWinFlags(Qt::Widget);
if (!(nStyle & SalFrameStyleFlags::SYSTEMCHILD))
{
if (nStyle & SalFrameStyleFlags::INTRO)
aWinFlags = Qt::SplashScreen;
// floating toolbars are frameless tool windows
// + they must be able to receive keyboard focus
else if ((nStyle & SalFrameStyleFlags::FLOAT)
&& (nStyle & SalFrameStyleFlags::OWNERDRAWDECORATION))
aWinFlags = Qt::Tool | Qt::FramelessWindowHint;
else if (nStyle & SalFrameStyleFlags::TOOLTIP)
aWinFlags = Qt::ToolTip;
// Can't use Qt::Popup, because it grabs the input focus and generates a focus-out event,
// instantly auto-closing the LO's editable ComboBox popup.
// On X11, the alternative Qt::Window | Qt::FramelessWindowHint | Qt::BypassWindowManagerHint
// seems to work well enough, but at least on Wayland and WASM, this results in problems.
// So while using Qt::ToolTip, the popups are wrongly advertised via accessibility, at least
// the GUI seems to work on all platforms... what a mess.
else if (isPopup())
aWinFlags = Qt::ToolTip | Qt::FramelessWindowHint;
else if (nStyle & SalFrameStyleFlags::TOOLWINDOW)
aWinFlags = Qt::Tool;
// top level windows can't be transient in Qt, so make them dialogs, if they have a parent. At least
// the plasma shell relies on this setting to skip dialogs in the window list. And Qt Xcb will just
// set transient for the types Dialog, Sheet, Tool, SplashScreen, ToolTip, Drawer and Popup.
else if (nStyle & SalFrameStyleFlags::DIALOG || m_pParent)
aWinFlags = Qt::Dialog;
else
aWinFlags = Qt::Window;
}
if (aWinFlags == Qt::Window)
{
m_pTopLevel = new QtMainWindow(*this, aWinFlags);
m_pQWidget = new QtWidget(*this);
m_pTopLevel->setCentralWidget(m_pQWidget);
m_pTopLevel->setFocusProxy(m_pQWidget);
}
else
{
m_pQWidget = new QtWidget(*this, aWinFlags);
// from Qt's POV the popup window doesn't have the input focus, so we must force tooltips...
if (isPopup())
m_pQWidget->setAttribute(Qt::WA_AlwaysShowToolTips);
}
FillSystemEnvData(m_aSystemData, reinterpret_cast<sal_IntPtr>(this), m_pQWidget);
QWindow* pChildWindow = windowHandle();
connect(pChildWindow, &QWindow::screenChanged, this, &QtFrame::screenChanged);
if (pParent && !(pParent->m_nStyle & SalFrameStyleFlags::PLUG))
{
QWindow* pParentWindow = pParent->windowHandle();
if (pParentWindow && pChildWindow && (pParentWindow != pChildWindow))
pChildWindow->setTransientParent(pParentWindow);
}
SetIcon(SV_ICON_ID_OFFICE);
}
void QtFrame::screenChanged(QScreen*) { m_pQWidget->fakeResize(); }
void QtFrame::FillSystemEnvData(SystemEnvData& rData, sal_IntPtr pWindow, QWidget* pWidget)
{
assert(rData.platform == SystemEnvData::Platform::Invalid);
assert(rData.toolkit == SystemEnvData::Toolkit::Invalid);
if (QGuiApplication::platformName() == "wayland")
rData.platform = SystemEnvData::Platform::Wayland;
else if (QGuiApplication::platformName() == "xcb")
rData.platform = SystemEnvData::Platform::Xcb;
else if (QGuiApplication::platformName() == "wasm")
rData.platform = SystemEnvData::Platform::WASM;
else
{
// maybe add a SystemEnvData::Platform::Unsupported to avoid special cases and not abort?
SAL_WARN("vcl.qt",
"Unsupported qt VCL platform: " << toOUString(QGuiApplication::platformName()));
std::abort();
}
rData.toolkit = SystemEnvData::Toolkit::Qt;
rData.aShellWindow = pWindow;
rData.pWidget = pWidget;
}
QtFrame::~QtFrame()
{
QtInstance* pInst = GetQtInstance();
pInst->eraseFrame(this);
delete asChild();
m_aSystemData.aShellWindow = 0;
}
void QtFrame::Damage(sal_Int32 nExtentsX, sal_Int32 nExtentsY, sal_Int32 nExtentsWidth,
sal_Int32 nExtentsHeight) const
{
tdf#149805 tdf#151677 tdf#152217 tdf#154043 tdf#153458 tdf#153800 Revert "VCL expect ... correct frame size for native menubars" This reverts commit afc828b9833b7a612369e95606ba56d41ef2c369 Date: Sat May 28 23:47:21 2022 +0200 VCL expect correct frame size for native menubars ... and renove the wrong framesize hack in the Qt backend because it caused several regressions and unfortunately the commit also doesn't fix all of the bugs mentioned in its commit message (while some previous patch sets of the change did address more, yet had other issues, s.a. the discussion in the commit's Gerrit change [1]). While e.g. the drag and drop issues reported in tdf#153458 and tdf#153800 could be fixed by translating the event position using `mapToParent()` (as is done in `QtWidget::fillSalAbstractMouseEvent` with the above commit in place), I currently don't see how to address the other issues and the overall direction of the change is not fully clear to me at this point. (There are also other pending changes in the relation change still pending in Gerrit that would presumably need more work/analysis.) After all, it seems the best way forward to revert the commit for now. This also reverts the follow-up commit commit 25da92004038c03c0feedf373e8038e7ee3e0c37 Date: Thu Jul 21 11:33:02 2022 +0200 Make JunitTest_toolkit_unoapi_1 succeed again on macOS that fixed a test failure introduced by the above commit. Luckily, there seem to be no follow-up commits that depend on this and the commits can be reverted cleanly without the need to resolve any conflicts manually. This reverts commit 25da92004038c03c0feedf373e8038e7ee3e0c37. This reverts commit afc828b9833b7a612369e95606ba56d41ef2c369. [1] https://gerrit.libreoffice.org/c/core/+/135082 Change-Id: I4c099ad7de8cbbad10da391ede4770d8c748fbde Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149495 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org> Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2023-03-24 08:06:56 +01:00
m_pQWidget->update(scaledQRect(QRect(nExtentsX, nExtentsY, nExtentsWidth, nExtentsHeight),
1 / devicePixelRatioF()));
}
SalGraphics* QtFrame::AcquireGraphics()
{
if (m_bGraphicsInUse)
return nullptr;
m_bGraphicsInUse = true;
if (m_bUseCairo)
{
if (!m_pSvpGraphics)
{
tdf#149805 tdf#151677 tdf#152217 tdf#154043 tdf#153458 tdf#153800 Revert "VCL expect ... correct frame size for native menubars" This reverts commit afc828b9833b7a612369e95606ba56d41ef2c369 Date: Sat May 28 23:47:21 2022 +0200 VCL expect correct frame size for native menubars ... and renove the wrong framesize hack in the Qt backend because it caused several regressions and unfortunately the commit also doesn't fix all of the bugs mentioned in its commit message (while some previous patch sets of the change did address more, yet had other issues, s.a. the discussion in the commit's Gerrit change [1]). While e.g. the drag and drop issues reported in tdf#153458 and tdf#153800 could be fixed by translating the event position using `mapToParent()` (as is done in `QtWidget::fillSalAbstractMouseEvent` with the above commit in place), I currently don't see how to address the other issues and the overall direction of the change is not fully clear to me at this point. (There are also other pending changes in the relation change still pending in Gerrit that would presumably need more work/analysis.) After all, it seems the best way forward to revert the commit for now. This also reverts the follow-up commit commit 25da92004038c03c0feedf373e8038e7ee3e0c37 Date: Thu Jul 21 11:33:02 2022 +0200 Make JunitTest_toolkit_unoapi_1 succeed again on macOS that fixed a test failure introduced by the above commit. Luckily, there seem to be no follow-up commits that depend on this and the commits can be reverted cleanly without the need to resolve any conflicts manually. This reverts commit 25da92004038c03c0feedf373e8038e7ee3e0c37. This reverts commit afc828b9833b7a612369e95606ba56d41ef2c369. [1] https://gerrit.libreoffice.org/c/core/+/135082 Change-Id: I4c099ad7de8cbbad10da391ede4770d8c748fbde Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149495 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org> Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2023-03-24 08:06:56 +01:00
QSize aSize = m_pQWidget->size() * devicePixelRatioF();
m_pSvpGraphics.reset(new QtSvpGraphics(this));
m_pSurface.reset(
cairo_image_surface_create(CAIRO_FORMAT_ARGB32, aSize.width(), aSize.height()));
m_pSvpGraphics->setSurface(m_pSurface.get(),
basegfx::B2IVector(aSize.width(), aSize.height()));
cairo_surface_set_user_data(m_pSurface.get(), QtSvpGraphics::getDamageKey(),
&m_aDamageHandler, nullptr);
}
return m_pSvpGraphics.get();
}
else
{
if (!m_pQtGraphics)
{
m_pQtGraphics.reset(new QtGraphics(this));
m_pQImage.reset(
tdf#149805 tdf#151677 tdf#152217 tdf#154043 tdf#153458 tdf#153800 Revert "VCL expect ... correct frame size for native menubars" This reverts commit afc828b9833b7a612369e95606ba56d41ef2c369 Date: Sat May 28 23:47:21 2022 +0200 VCL expect correct frame size for native menubars ... and renove the wrong framesize hack in the Qt backend because it caused several regressions and unfortunately the commit also doesn't fix all of the bugs mentioned in its commit message (while some previous patch sets of the change did address more, yet had other issues, s.a. the discussion in the commit's Gerrit change [1]). While e.g. the drag and drop issues reported in tdf#153458 and tdf#153800 could be fixed by translating the event position using `mapToParent()` (as is done in `QtWidget::fillSalAbstractMouseEvent` with the above commit in place), I currently don't see how to address the other issues and the overall direction of the change is not fully clear to me at this point. (There are also other pending changes in the relation change still pending in Gerrit that would presumably need more work/analysis.) After all, it seems the best way forward to revert the commit for now. This also reverts the follow-up commit commit 25da92004038c03c0feedf373e8038e7ee3e0c37 Date: Thu Jul 21 11:33:02 2022 +0200 Make JunitTest_toolkit_unoapi_1 succeed again on macOS that fixed a test failure introduced by the above commit. Luckily, there seem to be no follow-up commits that depend on this and the commits can be reverted cleanly without the need to resolve any conflicts manually. This reverts commit 25da92004038c03c0feedf373e8038e7ee3e0c37. This reverts commit afc828b9833b7a612369e95606ba56d41ef2c369. [1] https://gerrit.libreoffice.org/c/core/+/135082 Change-Id: I4c099ad7de8cbbad10da391ede4770d8c748fbde Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149495 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org> Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2023-03-24 08:06:56 +01:00
new QImage(m_pQWidget->size() * devicePixelRatioF(), Qt_DefaultFormat32));
m_pQImage->fill(Qt::transparent);
m_pQtGraphics->ChangeQImage(m_pQImage.get());
}
return m_pQtGraphics.get();
}
}
void QtFrame::ReleaseGraphics(SalGraphics* pSalGraph)
{
(void)pSalGraph;
if (m_bUseCairo)
assert(pSalGraph == m_pSvpGraphics.get());
else
assert(pSalGraph == m_pQtGraphics.get());
m_bGraphicsInUse = false;
}
bool QtFrame::PostEvent(std::unique_ptr<ImplSVEvent> pData)
{
QtInstance* pInst = GetQtInstance();
pInst->PostEvent(this, pData.release(), SalEvent::UserEvent);
return true;
}
QWidget* QtFrame::asChild() const
{
if (m_pTopLevel)
return m_pTopLevel;
return m_pQWidget;
}
qreal QtFrame::devicePixelRatioF() const { return asChild()->devicePixelRatioF(); }
bool QtFrame::isWindow() const { return asChild()->isWindow(); }
QWindow* QtFrame::windowHandle() const
{
tdf#122293 qt5: Use "alien widgets" by default on Wayland As described in QWidget doc [1], calling 'QWidget::winId()', implicitly enforces a native window, i.e. one that has a native window associated with it. For this reason, avoid calling 'QWidget::winId()' for the Wayland case. Quoting QWidget doc: > Introduced in Qt 4.4, alien widgets are widgets unknown to the windowing > system. They do not have a native window handle associated with them. > This feature significantly speeds up widget painting, resizing, and > removes flicker. This in particular avoids tdf#122293/QTBUG-75766, which led to 'mousePressEvent's not being emitted unless a mouse button was pressed, causing non-existent reaction to hovering over objects. As a consequence to widgets being non-native by default on Wayland, 'Qt5Frame::windowHandle' needs to be adapted to make sure that the widgets handled in there are native ones, otherwise no window handle is associated with them. Probably more needs to be done here to make video playback via GStreamer work under Wayland, s.a. commit c0d4f3ad3307c ("implement wayland handle passing for gstreamer") for how it was done for gtk3. With and without this change, slideshows with videos are currently not handled properly with kde5 on Wayland (s. tdf#125219). [1] https://doc.qt.io/qt-5/qwidget.html#native-widgets-vs-alien-widgets Change-Id: Id46678e0ea594220a1765c3e59d39c41cb8bfe25 Reviewed-on: https://gerrit.libreoffice.org/72164 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2019-05-11 21:31:33 +02:00
// set attribute 'Qt::WA_NativeWindow' first to make sure a window handle actually exists
QWidget* pChild = asChild();
assert(pChild->window() == pChild);
switch (m_aSystemData.platform)
{
case SystemEnvData::Platform::Wayland:
case SystemEnvData::Platform::Xcb:
pChild->setAttribute(Qt::WA_NativeWindow);
break;
case SystemEnvData::Platform::WASM:
// no idea, why Qt::WA_NativeWindow breaks the menubar for EMSCRIPTEN
break;
case SystemEnvData::Platform::Invalid:
std::abort();
break;
}
return pChild->windowHandle();
}
QScreen* QtFrame::screen() const { return asChild()->screen(); }
bool QtFrame::GetUseDarkMode() const
tdf#156894 qt: Prefer dark icon theme in dark mode When in dark mode, pass the param to prefer a dark icon theme to `StyleSettings::SetPreferredIconTheme`. For Qt >= 6.5 use `QStyleHints::colorScheme` introduced in Qt 6.5 to get the color scheme. For older Qt versions, use the same algorithm based on the gray value of the window background as xdg-desktop-portal-kde does for evaluating whether a light or dark color scheme is preferred [1]. On my Debian testing, the Breeze dark icon theme is now used as expected with kf5 or qt6 when setting the Global KDE Plasma theme to "Breeze Dark" and manually setting the Icon theme to "GNOME" afterwards. Previously, this would not use a dark icon theme and icons would be hard to see. Without manually setting the icon theme to "GNOME", the Breeze Dark icon theme would already be used before, because selecting "Breeze Dark" as the global KDE Plasma theme also selects the "Breeze Dark" icon theme by default, and therefore "breeze-dark" was already passed as the first param to `StyleSettings::SetPreferredIconTheme` and since that icon theme is present, the `bPreferDarkTheme` wouldn't be evaluated at all; it's only used when determining the fallback icon theme when the specified icon theme is not present. (Likewise, by enabling the "Breeze Dark" global theme and then manually setting the icon theme to "Breeze" in Plasma System settings, the Breeze light icon theme will be used in LibreOffice as well, resulting in hard to see icons, but I tend to think that that behavior is correct and works as designed - it's a misconfiguration.) The color scheme is also specified in xdg-desktop-portal (s. commit [2]) and can be retrived via dbus. Example with "Breeze Light" active: $ dbus-send --session --print-reply=literal --reply-timeout=1000 --dest=org.freedesktop.portal.Desktop /org/freedesktop/portal/desktop org.freedesktop.portal.Settings.Read string:'org.freedesktop.appearance' string:'color-scheme' variant variant uint32 2 With "Breeze Dark": $ dbus-send --session --print-reply=literal --reply-timeout=1000 --dest=org.freedesktop.portal.Desktop /org/freedesktop/portal/desktop org.freedesktop.portal.Settings.Read string:'org.freedesktop.appearance' string:'color-scheme' variant variant uint32 1 [1] https://invent.kde.org/plasma/xdg-desktop-portal-kde/-/blob/0a4237549debf9518f8cfbaf531456850c0729bd/src/settings.cpp#L213-227 [2] https://github.com/flatpak/xdg-desktop-portal/commit/d7a304a00697d7d608821253cd013f3b97ac0fb6 Change-Id: I8f347c6e7f775cc55377c5c84481de3051c3cf24 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156465 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2023-09-02 10:12:54 +02:00
{
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
const QStyleHints* pStyleHints = QApplication::styleHints();
return pStyleHints->colorScheme() == Qt::ColorScheme::Dark;
#else
// use same mechanism for determining dark mode preference as xdg-desktop-portal-kde, s.
// https://invent.kde.org/plasma/xdg-desktop-portal-kde/-/blob/0a4237549debf9518f8cfbaf531456850c0729bd/src/settings.cpp#L213-227
const QPalette aPalette = QApplication::palette();
const int nWindowBackGroundGray = qGray(aPalette.window().color().rgb());
return nWindowBackGroundGray < 192;
#endif
}
bool QtFrame::isMinimized() const { return asChild()->isMinimized(); }
bool QtFrame::isMaximized() const { return asChild()->isMaximized(); }
void QtFrame::SetWindowStateImpl(Qt::WindowStates eState)
{
return asChild()->setWindowState(eState);
}
void QtFrame::SetTitle(const OUString& rTitle)
{
qt: Set window title etc. in main thread These QWidget methods need to be called in the main thread. Otherwise, opening the Update dialog ("Help" -> "Check for Updates", enabled by `--enable-online-update` autogen switch) triggers asserts like the one below with a self-compiled Qt 6 development build (qtbase dev branch as of c802a9e987c9e38c01580f467eab92a651b3e033). ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 0x0x7fff780160e0. Receiver '' (of type 'QtWidget') was created in thread 0x0x5555555fcd30", file /home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp, line 537 Thread 40 "InitUpdateCheck" received signal SIGABRT, Aborted. [Switching to Thread 0x7fff7ffff6c0 (LWP 1516868)] __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44 44 ./nptl/pthread_kill.c: No such file or directory. (gdb) bt #0 __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44 #1 0x00007ffff78a815f in __pthread_kill_internal (signo=6, threadid=<optimized out>) at ./nptl/pthread_kill.c:78 #2 0x00007ffff785a472 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26 #3 0x00007ffff78444b2 in __GI_abort () at ./stdlib/abort.c:79 #4 0x00007fffe32eb45a in qAbort() () at /home/michi/development/git/qt5/qtbase/src/corelib/global/qglobal.cpp:161 #5 0x00007fffe32f9ee5 in qt_message_fatal(QtMsgType, QMessageLogContext const&, QString const&) (context=..., message=...) at /home/michi/development/git/qt5/qtbase/src/corelib/global/qlogging.cpp:2057 #6 0x00007fffe32f620c in QMessageLogger::fatal(char const*, ...) const (this=0x7fff7fffb980, msg=0x7fffe37fd9a0 "ASSERT failure in %s: \"%s\", file %s, line %d") at /home/michi/development/git/qt5/qtbase/src/corelib/global/qlogging.cpp:938 #7 0x00007fffe32e9d54 in qt_assert_x(char const*, char const*, char const*, int) (where=0x7fffe38131e9 "QCoreApplication::sendEvent", what=0x7fff78180110 "Cannot send events to objects owned by a different thread. Current thread 0x0x7fff780160e0. Receiver '' (of type 'QtWidget') was created in thread 0x0x5555555fcd30", file=0x7fffe3812e18 "/home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp", line=537) at /home/michi/development/git/qt5/qtbase/src/corelib/global/qassert.cpp:77 #8 0x00007fffe33a4d74 in QCoreApplicationPrivate::checkReceiverThread(QObject*) (receiver=0x55555d27d5d0) at /home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:537 #9 0x00007fffe19a3a81 in QApplication::notify(QObject*, QEvent*) (this=0x5555555fcb80, receiver=0x55555d27d5d0, e=0x7fff7fffc0b0) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qapplication.cpp:2584 #10 0x00007fffe33a5ed0 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x55555d27d5d0, event=0x7fff7fffc0b0) at /home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1125 #11 0x00007fffe33a6991 in QCoreApplication::sendEvent(QObject*, QEvent*) (receiver=0x55555d27d5d0, event=0x7fff7fffc0b0) at /home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1559 #12 0x00007fffe1a279b4 in QWidget::setWindowTitle(QString const&) (this=0x55555d27d5d0, title=...) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qwidget.cpp:6119 #13 0x00007fffe3c9d4c4 in QtFrame::SetTitle(rtl::OUString const&) (this=0x555555619d20, rTitle="Check for Updates") at /home/michi/development/git/libreoffice/vcl/qt6/../qt5/QtFrame.cxx:365 #14 0x00007fffedd98d44 in vcl::Window::SetText(rtl::OUString const&) (this=0x7fff7803cd90, rStr="Check for Updates") at /home/michi/development/git/libreoffice/vcl/source/window/window.cxx:3042 #15 0x00007fffedd311c9 in SystemWindow::SetText(rtl::OUString const&) (this=0x7fff7803cd90, rStr="Check for Updates") at /home/michi/development/git/libreoffice/vcl/source/window/syswin.cxx:1048 #16 0x00007ffff048bd6b in VCLXWindow::setProperty(rtl::OUString const&, com::sun::star::uno::Any const&) (this=0x7fff7804ac00, PropertyName="Title", Value=uno::Any("string": "Check for Updates")) at /home/michi/development/git/libreoffice/toolkit/source/awt/vclxwindow.cxx:1515 #17 0x00007ffff03e486d in VCLXContainer::setProperty(rtl::OUString const&, com::sun::star::uno::Any const&) (this=0x7fff7804ac00, PropertyName="Title", Value=uno::Any("string": "Check for Updates")) at /home/michi/development/git/libreoffice/toolkit/source/awt/vclxcontainer.cxx:260 #18 0x00007ffff04dfa2c in VCLXDialog::setProperty(rtl::OUString const&, com::sun::star::uno::Any const&) (this=0x7fff7804ac00, PropertyName="Title", Value=uno::Any("string": "Check for Updates")) at /home/michi/development/git/libreoffice/toolkit/source/awt/vclxwindows.cxx:2364 #19 0x00007ffff06a89b7 in UnoControl::ImplSetPeerProperty(rtl::OUString const&, com::sun::star::uno::Any const&) (this=0x7fff7803b4f0, rPropName="Title", rVal=uno::Any("string": "Check for Updates")) at /home/michi/development/git/libreoffice/toolkit/source/controls/unocontrol.cxx:288 #20 0x00007ffff06aa701 in UnoControl::ImplModelPropertiesChanged(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyChangeEvent> const&) (this=0x7fff7803b4f0, rEvents=uno::Sequence of length 51 = {...}) at /home/michi/development/git/libreoffice/toolkit/source/controls/unocontrol.cxx:649 #21 0x00007ffff0531ae9 in ControlContainerBase::ImplModelPropertiesChanged(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyChangeEvent> const&) (this=0x7fff7803b4f0, rEvents=uno::Sequence of length 51 = {...}) at /home/michi/development/git/libreoffice/toolkit/source/controls/controlmodelcontainerbase.cxx:1600 #22 0x00007ffff0575a25 in UnoDialogControl::ImplModelPropertiesChanged(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyChangeEvent> const&) (this=0x7fff7803b4f0, rEvents=uno::Sequence of length 51 = {...}) at /home/michi/development/git/libreoffice/toolkit/source/controls/dialogcontrol.cxx:651 #23 0x00007ffff06a95f3 in UnoControl::propertiesChange(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyChangeEvent> const&) (this=0x7fff7803b4f0, rEvents=uno::Sequence of length 51 = {...}) at /home/michi/development/git/libreoffice/toolkit/source/controls/unocontrol.cxx:431 #24 0x00007ffff66bc4ee in cppu::OPropertySetHelper::firePropertiesChangeEvent(com::sun::star::uno::Sequence<rtl::OUString> const&, com::sun::star::uno::Reference<com::sun::star::beans::XPropertiesChangeListener> const&) (this=0x7fff78006170, rPropertyNames=uno::Sequence of length 51 = {...}, rListener=uno::Reference to (UnoDialogControl *) 0x7fff7803b540) at /home/michi/development/git/libreoffice/cppuhelper/source/propshlp.cxx:961 #25 0x00007ffff06a8c6b in UnoControl::updateFromModel() (this=0x7fff7803b4f0) at /home/michi/development/git/libreoffice/toolkit/source/controls/unocontrol.cxx:320 #26 0x00007ffff06aefc9 in UnoControl::createPeer(com::sun::star::uno::Reference<com::sun::star::awt::XToolkit> const&, com::sun::star::uno::Reference<com::sun::star::awt::XWindowPeer> const&) (this=0x7fff7803b4f0, rxToolkit=empty uno::Reference, rParentPeer=empty uno::Reference) at /home/michi/development/git/libreoffice/toolkit/source/controls/unocontrol.cxx:1325 #27 0x00007ffff06c9905 in UnoControlContainer::createPeer(com::sun::star::uno::Reference<com::sun::star::awt::XToolkit> const&, com::sun::star::uno::Reference<com::sun::star::awt::XWindowPeer> const&) (this=0x7fff7803b4f0, rxToolkit=empty uno::Reference, rParent=empty uno::Reference) at /home/michi/development/git/libreoffice/toolkit/source/controls/unocontrolcontainer.cxx:727 #28 0x00007ffff057336d in UnoDialogControl::createPeer(com::sun::star::uno::Reference<com::sun::star::awt::XToolkit> const&, com::sun::star::uno::Reference<com::sun::star::awt::XWindowPeer> const&) (this=0x7fff7803b4f0, rxToolkit=empty uno::Reference, rParentPeer=empty uno::Reference) at /home/michi/development/git/libreoffice/toolkit/source/controls/dialogcontrol.cxx:358 #29 0x00007fffb7264e62 in UpdateHandler::createDialog() (this=0x7fff78003aa0) at /home/michi/development/git/libreoffice/extensions/source/update/check/updatehdl.cxx:1232 #30 0x00007fffb725b0e1 in UpdateHandler::setVisible(bool) (this=0x7fff78003aa0, bVisible=true) at /home/michi/development/git/libreoffice/extensions/source/update/check/updatehdl.cxx:188 #31 0x00007fffb7235887 in UpdateCheck::showDialog(bool) (this=0x7fff78000b90, forceCheck=true) at /home/michi/development/git/libreoffice/extensions/source/update/check/updatecheck.cxx:1171 #32 0x00007fffb7255c5e in (anonymous namespace)::InitUpdateCheckJobThread::run() (this=0x55555d192690) at /home/michi/development/git/libreoffice/extensions/source/update/check/updatecheckjob.cxx:148 #33 0x00007fffb723a74a in osl::threadFunc(void*) (param=0x55555d192690) at /home/michi/development/git/libreoffice/include/osl/thread.hxx:189 #34 0x00007ffff7f3f693 in osl_thread_start_Impl(void*) (pData=0x55555d1a68b0) at /home/michi/development/git/libreoffice/sal/osl/unx/thread.cxx:237 #35 0x00007ffff78a63ec in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:444 #36 0x00007ffff7926a1c in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81 Change-Id: I6ccdee00fe26619f201459ebbe6c4d8cf8b57b45 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156426 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2023-09-01 17:50:19 +02:00
QtInstance* pSalInst(GetQtInstance());
assert(pSalInst);
pSalInst->RunInMainThread(
[this, rTitle]() { m_pQWidget->window()->setWindowTitle(toQString(rTitle)); });
}
void QtFrame::SetIcon(sal_uInt16 nIcon)
{
if (m_nStyle
& (SalFrameStyleFlags::PLUG | SalFrameStyleFlags::SYSTEMCHILD
| SalFrameStyleFlags::FLOAT | SalFrameStyleFlags::INTRO
| SalFrameStyleFlags::OWNERDRAWDECORATION)
|| !isWindow())
return;
QString appicon;
if (nIcon == SV_ICON_ID_TEXT)
appicon = "libreoffice-writer";
else if (nIcon == SV_ICON_ID_SPREADSHEET)
appicon = "libreoffice-calc";
else if (nIcon == SV_ICON_ID_DRAWING)
appicon = "libreoffice-draw";
else if (nIcon == SV_ICON_ID_PRESENTATION)
appicon = "libreoffice-impress";
else if (nIcon == SV_ICON_ID_DATABASE)
appicon = "libreoffice-base";
else if (nIcon == SV_ICON_ID_FORMULA)
appicon = "libreoffice-math";
else
appicon = "libreoffice-startcenter";
QIcon aIcon = QIcon::fromTheme(appicon);
m_pQWidget->window()->setWindowIcon(aIcon);
if (QGuiApplication::platformName() == "wayland" && m_pQWidget->window()->isVisible())
{
// Qt currently doesn't provide API to directly set the app_id for a single
// window/toplevel on Wayland, but the one set for the application is picked up
// on hide/show, so do that.
// An alternative would be to use private Qt API and low-level wayland API to set the
// app_id directly, s. discussion in QTBUG-77182.
const QString sOrigDesktopFileName = QGuiApplication::desktopFileName();
QGuiApplication::setDesktopFileName(appicon);
m_pQWidget->window()->hide();
m_pQWidget->window()->show();
QGuiApplication::setDesktopFileName(sOrigDesktopFileName);
}
}
void QtFrame::SetMenu(SalMenu*) {}
void QtFrame::SetExtendedFrameStyle(SalExtStyle /*nExtStyle*/) { /* not needed */}
void QtFrame::Show(bool bVisible, bool bNoActivate)
{
assert(m_pQWidget);
if (bVisible == asChild()->isVisible())
return;
auto* pSalInst(GetQtInstance());
assert(pSalInst);
if (!bVisible) // hide
{
pSalInst->RunInMainThread([this]() { asChild()->setVisible(false); });
return;
}
// show
SetDefaultSize();
pSalInst->RunInMainThread([this, bNoActivate]() {
QWidget* const pChild = asChild();
pChild->setVisible(true);
pChild->raise();
if (!bNoActivate)
{
pChild->activateWindow();
pChild->setFocus();
}
});
}
void QtFrame::SetMinClientSize(tools::Long nWidth, tools::Long nHeight)
{
if (!isChild())
{
const qreal fRatio = devicePixelRatioF();
asChild()->setMinimumSize(round(nWidth / fRatio), round(nHeight / fRatio));
}
}
void QtFrame::SetMaxClientSize(tools::Long nWidth, tools::Long nHeight)
{
if (!isChild())
{
const qreal fRatio = devicePixelRatioF();
asChild()->setMaximumSize(round(nWidth / fRatio), round(nHeight / fRatio));
}
}
tdf#149805 tdf#151677 tdf#152217 tdf#154043 tdf#153458 tdf#153800 Revert "VCL expect ... correct frame size for native menubars" This reverts commit afc828b9833b7a612369e95606ba56d41ef2c369 Date: Sat May 28 23:47:21 2022 +0200 VCL expect correct frame size for native menubars ... and renove the wrong framesize hack in the Qt backend because it caused several regressions and unfortunately the commit also doesn't fix all of the bugs mentioned in its commit message (while some previous patch sets of the change did address more, yet had other issues, s.a. the discussion in the commit's Gerrit change [1]). While e.g. the drag and drop issues reported in tdf#153458 and tdf#153800 could be fixed by translating the event position using `mapToParent()` (as is done in `QtWidget::fillSalAbstractMouseEvent` with the above commit in place), I currently don't see how to address the other issues and the overall direction of the change is not fully clear to me at this point. (There are also other pending changes in the relation change still pending in Gerrit that would presumably need more work/analysis.) After all, it seems the best way forward to revert the commit for now. This also reverts the follow-up commit commit 25da92004038c03c0feedf373e8038e7ee3e0c37 Date: Thu Jul 21 11:33:02 2022 +0200 Make JunitTest_toolkit_unoapi_1 succeed again on macOS that fixed a test failure introduced by the above commit. Luckily, there seem to be no follow-up commits that depend on this and the commits can be reverted cleanly without the need to resolve any conflicts manually. This reverts commit 25da92004038c03c0feedf373e8038e7ee3e0c37. This reverts commit afc828b9833b7a612369e95606ba56d41ef2c369. [1] https://gerrit.libreoffice.org/c/core/+/135082 Change-Id: I4c099ad7de8cbbad10da391ede4770d8c748fbde Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149495 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org> Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2023-03-24 08:06:56 +01:00
int QtFrame::menuBarOffset() const
{
QtMainWindow* pTopLevel = m_pParent->GetTopLevelWindow();
if (pTopLevel && pTopLevel->menuBar() && pTopLevel->menuBar()->isVisible())
return round(pTopLevel->menuBar()->geometry().height() * devicePixelRatioF());
return 0;
}
void QtFrame::SetDefaultPos()
{
if (!m_bDefaultPos)
return;
tdf#149805 tdf#151677 tdf#152217 tdf#154043 tdf#153458 tdf#153800 Revert "VCL expect ... correct frame size for native menubars" This reverts commit afc828b9833b7a612369e95606ba56d41ef2c369 Date: Sat May 28 23:47:21 2022 +0200 VCL expect correct frame size for native menubars ... and renove the wrong framesize hack in the Qt backend because it caused several regressions and unfortunately the commit also doesn't fix all of the bugs mentioned in its commit message (while some previous patch sets of the change did address more, yet had other issues, s.a. the discussion in the commit's Gerrit change [1]). While e.g. the drag and drop issues reported in tdf#153458 and tdf#153800 could be fixed by translating the event position using `mapToParent()` (as is done in `QtWidget::fillSalAbstractMouseEvent` with the above commit in place), I currently don't see how to address the other issues and the overall direction of the change is not fully clear to me at this point. (There are also other pending changes in the relation change still pending in Gerrit that would presumably need more work/analysis.) After all, it seems the best way forward to revert the commit for now. This also reverts the follow-up commit commit 25da92004038c03c0feedf373e8038e7ee3e0c37 Date: Thu Jul 21 11:33:02 2022 +0200 Make JunitTest_toolkit_unoapi_1 succeed again on macOS that fixed a test failure introduced by the above commit. Luckily, there seem to be no follow-up commits that depend on this and the commits can be reverted cleanly without the need to resolve any conflicts manually. This reverts commit 25da92004038c03c0feedf373e8038e7ee3e0c37. This reverts commit afc828b9833b7a612369e95606ba56d41ef2c369. [1] https://gerrit.libreoffice.org/c/core/+/135082 Change-Id: I4c099ad7de8cbbad10da391ede4770d8c748fbde Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149495 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org> Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2023-03-24 08:06:56 +01:00
// center on parent
if (m_pParent)
{
tdf#149805 tdf#151677 tdf#152217 tdf#154043 tdf#153458 tdf#153800 Revert "VCL expect ... correct frame size for native menubars" This reverts commit afc828b9833b7a612369e95606ba56d41ef2c369 Date: Sat May 28 23:47:21 2022 +0200 VCL expect correct frame size for native menubars ... and renove the wrong framesize hack in the Qt backend because it caused several regressions and unfortunately the commit also doesn't fix all of the bugs mentioned in its commit message (while some previous patch sets of the change did address more, yet had other issues, s.a. the discussion in the commit's Gerrit change [1]). While e.g. the drag and drop issues reported in tdf#153458 and tdf#153800 could be fixed by translating the event position using `mapToParent()` (as is done in `QtWidget::fillSalAbstractMouseEvent` with the above commit in place), I currently don't see how to address the other issues and the overall direction of the change is not fully clear to me at this point. (There are also other pending changes in the relation change still pending in Gerrit that would presumably need more work/analysis.) After all, it seems the best way forward to revert the commit for now. This also reverts the follow-up commit commit 25da92004038c03c0feedf373e8038e7ee3e0c37 Date: Thu Jul 21 11:33:02 2022 +0200 Make JunitTest_toolkit_unoapi_1 succeed again on macOS that fixed a test failure introduced by the above commit. Luckily, there seem to be no follow-up commits that depend on this and the commits can be reverted cleanly without the need to resolve any conflicts manually. This reverts commit 25da92004038c03c0feedf373e8038e7ee3e0c37. This reverts commit afc828b9833b7a612369e95606ba56d41ef2c369. [1] https://gerrit.libreoffice.org/c/core/+/135082 Change-Id: I4c099ad7de8cbbad10da391ede4770d8c748fbde Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149495 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org> Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2023-03-24 08:06:56 +01:00
const qreal fRatio = devicePixelRatioF();
QWidget* const pParentWin = m_pParent->asChild()->window();
tdf#149805 tdf#151677 tdf#152217 tdf#154043 tdf#153458 tdf#153800 Revert "VCL expect ... correct frame size for native menubars" This reverts commit afc828b9833b7a612369e95606ba56d41ef2c369 Date: Sat May 28 23:47:21 2022 +0200 VCL expect correct frame size for native menubars ... and renove the wrong framesize hack in the Qt backend because it caused several regressions and unfortunately the commit also doesn't fix all of the bugs mentioned in its commit message (while some previous patch sets of the change did address more, yet had other issues, s.a. the discussion in the commit's Gerrit change [1]). While e.g. the drag and drop issues reported in tdf#153458 and tdf#153800 could be fixed by translating the event position using `mapToParent()` (as is done in `QtWidget::fillSalAbstractMouseEvent` with the above commit in place), I currently don't see how to address the other issues and the overall direction of the change is not fully clear to me at this point. (There are also other pending changes in the relation change still pending in Gerrit that would presumably need more work/analysis.) After all, it seems the best way forward to revert the commit for now. This also reverts the follow-up commit commit 25da92004038c03c0feedf373e8038e7ee3e0c37 Date: Thu Jul 21 11:33:02 2022 +0200 Make JunitTest_toolkit_unoapi_1 succeed again on macOS that fixed a test failure introduced by the above commit. Luckily, there seem to be no follow-up commits that depend on this and the commits can be reverted cleanly without the need to resolve any conflicts manually. This reverts commit 25da92004038c03c0feedf373e8038e7ee3e0c37. This reverts commit afc828b9833b7a612369e95606ba56d41ef2c369. [1] https://gerrit.libreoffice.org/c/core/+/135082 Change-Id: I4c099ad7de8cbbad10da391ede4770d8c748fbde Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149495 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org> Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2023-03-24 08:06:56 +01:00
QWidget* const pChildWin = asChild()->window();
QPoint aPos = (pParentWin->rect().center() - pChildWin->rect().center()) * fRatio;
aPos.ry() -= menuBarOffset();
SetPosSize(aPos.x(), aPos.y(), 0, 0, SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y);
assert(!m_bDefaultPos);
}
else
tdf#149805 tdf#151677 tdf#152217 tdf#154043 tdf#153458 tdf#153800 Revert "VCL expect ... correct frame size for native menubars" This reverts commit afc828b9833b7a612369e95606ba56d41ef2c369 Date: Sat May 28 23:47:21 2022 +0200 VCL expect correct frame size for native menubars ... and renove the wrong framesize hack in the Qt backend because it caused several regressions and unfortunately the commit also doesn't fix all of the bugs mentioned in its commit message (while some previous patch sets of the change did address more, yet had other issues, s.a. the discussion in the commit's Gerrit change [1]). While e.g. the drag and drop issues reported in tdf#153458 and tdf#153800 could be fixed by translating the event position using `mapToParent()` (as is done in `QtWidget::fillSalAbstractMouseEvent` with the above commit in place), I currently don't see how to address the other issues and the overall direction of the change is not fully clear to me at this point. (There are also other pending changes in the relation change still pending in Gerrit that would presumably need more work/analysis.) After all, it seems the best way forward to revert the commit for now. This also reverts the follow-up commit commit 25da92004038c03c0feedf373e8038e7ee3e0c37 Date: Thu Jul 21 11:33:02 2022 +0200 Make JunitTest_toolkit_unoapi_1 succeed again on macOS that fixed a test failure introduced by the above commit. Luckily, there seem to be no follow-up commits that depend on this and the commits can be reverted cleanly without the need to resolve any conflicts manually. This reverts commit 25da92004038c03c0feedf373e8038e7ee3e0c37. This reverts commit afc828b9833b7a612369e95606ba56d41ef2c369. [1] https://gerrit.libreoffice.org/c/core/+/135082 Change-Id: I4c099ad7de8cbbad10da391ede4770d8c748fbde Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149495 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org> Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2023-03-24 08:06:56 +01:00
m_bDefaultPos = false;
}
Size QtFrame::CalcDefaultSize()
{
assert(isWindow());
Size aSize;
if (!m_bFullScreen)
{
const QScreen* pScreen = screen();
if (!pScreen)
pScreen = QGuiApplication::screens().at(0);
aSize = bestmaxFrameSizeForScreenSize(toSize(pScreen->size()));
}
else
{
if (!m_bFullScreenSpanAll)
{
aSize = toSize(QGuiApplication::screens().at(maGeometry.screen())->size());
}
else
{
QScreen* pScreen = QGuiApplication::screenAt(QPoint(0, 0));
aSize = toSize(pScreen->availableVirtualGeometry().size());
}
}
return aSize;
}
void QtFrame::SetDefaultSize()
{
if (!m_bDefaultSize)
return;
Size aDefSize = CalcDefaultSize();
SetPosSize(0, 0, aDefSize.Width(), aDefSize.Height(),
SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT);
assert(!m_bDefaultSize);
}
void QtFrame::SetPosSize(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight,
sal_uInt16 nFlags)
{
if (!isWindow() || isChild(true, false))
return;
if (nFlags & (SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT))
{
if (isChild(false) || !m_pQWidget->isMaximized())
{
if (!(nFlags & SAL_FRAME_POSSIZE_WIDTH))
nWidth = maGeometry.width();
else if (!(nFlags & SAL_FRAME_POSSIZE_HEIGHT))
nHeight = maGeometry.height();
if (nWidth > 0 && nHeight > 0)
{
m_bDefaultSize = false;
const int nNewWidth = round(nWidth / devicePixelRatioF());
const int nNewHeight = round(nHeight / devicePixelRatioF());
if (m_nStyle & SalFrameStyleFlags::SIZEABLE)
asChild()->resize(nNewWidth, nNewHeight);
else
asChild()->setFixedSize(nNewWidth, nNewHeight);
}
// assume the resize happened
// needed for calculations and will eventually be corrected by events
if (nWidth > 0)
maGeometry.setWidth(nWidth);
if (nHeight > 0)
maGeometry.setHeight(nHeight);
}
}
if (!(nFlags & (SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y)))
{
if (nFlags & (SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT))
SetDefaultPos();
return;
}
if (m_pParent)
{
const SalFrameGeometry& aParentGeometry = m_pParent->maGeometry;
if (QGuiApplication::isRightToLeft())
tdf#149805 tdf#151677 tdf#152217 tdf#154043 tdf#153458 tdf#153800 Revert "VCL expect ... correct frame size for native menubars" This reverts commit afc828b9833b7a612369e95606ba56d41ef2c369 Date: Sat May 28 23:47:21 2022 +0200 VCL expect correct frame size for native menubars ... and renove the wrong framesize hack in the Qt backend because it caused several regressions and unfortunately the commit also doesn't fix all of the bugs mentioned in its commit message (while some previous patch sets of the change did address more, yet had other issues, s.a. the discussion in the commit's Gerrit change [1]). While e.g. the drag and drop issues reported in tdf#153458 and tdf#153800 could be fixed by translating the event position using `mapToParent()` (as is done in `QtWidget::fillSalAbstractMouseEvent` with the above commit in place), I currently don't see how to address the other issues and the overall direction of the change is not fully clear to me at this point. (There are also other pending changes in the relation change still pending in Gerrit that would presumably need more work/analysis.) After all, it seems the best way forward to revert the commit for now. This also reverts the follow-up commit commit 25da92004038c03c0feedf373e8038e7ee3e0c37 Date: Thu Jul 21 11:33:02 2022 +0200 Make JunitTest_toolkit_unoapi_1 succeed again on macOS that fixed a test failure introduced by the above commit. Luckily, there seem to be no follow-up commits that depend on this and the commits can be reverted cleanly without the need to resolve any conflicts manually. This reverts commit 25da92004038c03c0feedf373e8038e7ee3e0c37. This reverts commit afc828b9833b7a612369e95606ba56d41ef2c369. [1] https://gerrit.libreoffice.org/c/core/+/135082 Change-Id: I4c099ad7de8cbbad10da391ede4770d8c748fbde Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149495 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org> Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2023-03-24 08:06:56 +01:00
nX = aParentGeometry.x() + aParentGeometry.width() - nX - maGeometry.width() - 1;
else
tdf#149805 tdf#151677 tdf#152217 tdf#154043 tdf#153458 tdf#153800 Revert "VCL expect ... correct frame size for native menubars" This reverts commit afc828b9833b7a612369e95606ba56d41ef2c369 Date: Sat May 28 23:47:21 2022 +0200 VCL expect correct frame size for native menubars ... and renove the wrong framesize hack in the Qt backend because it caused several regressions and unfortunately the commit also doesn't fix all of the bugs mentioned in its commit message (while some previous patch sets of the change did address more, yet had other issues, s.a. the discussion in the commit's Gerrit change [1]). While e.g. the drag and drop issues reported in tdf#153458 and tdf#153800 could be fixed by translating the event position using `mapToParent()` (as is done in `QtWidget::fillSalAbstractMouseEvent` with the above commit in place), I currently don't see how to address the other issues and the overall direction of the change is not fully clear to me at this point. (There are also other pending changes in the relation change still pending in Gerrit that would presumably need more work/analysis.) After all, it seems the best way forward to revert the commit for now. This also reverts the follow-up commit commit 25da92004038c03c0feedf373e8038e7ee3e0c37 Date: Thu Jul 21 11:33:02 2022 +0200 Make JunitTest_toolkit_unoapi_1 succeed again on macOS that fixed a test failure introduced by the above commit. Luckily, there seem to be no follow-up commits that depend on this and the commits can be reverted cleanly without the need to resolve any conflicts manually. This reverts commit 25da92004038c03c0feedf373e8038e7ee3e0c37. This reverts commit afc828b9833b7a612369e95606ba56d41ef2c369. [1] https://gerrit.libreoffice.org/c/core/+/135082 Change-Id: I4c099ad7de8cbbad10da391ede4770d8c748fbde Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149495 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org> Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2023-03-24 08:06:56 +01:00
nX += aParentGeometry.x();
nY += aParentGeometry.y() + menuBarOffset();
}
if (!(nFlags & SAL_FRAME_POSSIZE_X))
nX = maGeometry.x();
else if (!(nFlags & SAL_FRAME_POSSIZE_Y))
nY = maGeometry.y();
// assume the reposition happened
// needed for calculations and will eventually be corrected by events later
maGeometry.setPos({ nX, nY });
m_bDefaultPos = false;
asChild()->move(round(nX / devicePixelRatioF()), round(nY / devicePixelRatioF()));
}
void QtFrame::GetClientSize(tools::Long& rWidth, tools::Long& rHeight)
{
tdf#149805 tdf#151677 tdf#152217 tdf#154043 tdf#153458 tdf#153800 Revert "VCL expect ... correct frame size for native menubars" This reverts commit afc828b9833b7a612369e95606ba56d41ef2c369 Date: Sat May 28 23:47:21 2022 +0200 VCL expect correct frame size for native menubars ... and renove the wrong framesize hack in the Qt backend because it caused several regressions and unfortunately the commit also doesn't fix all of the bugs mentioned in its commit message (while some previous patch sets of the change did address more, yet had other issues, s.a. the discussion in the commit's Gerrit change [1]). While e.g. the drag and drop issues reported in tdf#153458 and tdf#153800 could be fixed by translating the event position using `mapToParent()` (as is done in `QtWidget::fillSalAbstractMouseEvent` with the above commit in place), I currently don't see how to address the other issues and the overall direction of the change is not fully clear to me at this point. (There are also other pending changes in the relation change still pending in Gerrit that would presumably need more work/analysis.) After all, it seems the best way forward to revert the commit for now. This also reverts the follow-up commit commit 25da92004038c03c0feedf373e8038e7ee3e0c37 Date: Thu Jul 21 11:33:02 2022 +0200 Make JunitTest_toolkit_unoapi_1 succeed again on macOS that fixed a test failure introduced by the above commit. Luckily, there seem to be no follow-up commits that depend on this and the commits can be reverted cleanly without the need to resolve any conflicts manually. This reverts commit 25da92004038c03c0feedf373e8038e7ee3e0c37. This reverts commit afc828b9833b7a612369e95606ba56d41ef2c369. [1] https://gerrit.libreoffice.org/c/core/+/135082 Change-Id: I4c099ad7de8cbbad10da391ede4770d8c748fbde Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149495 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org> Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2023-03-24 08:06:56 +01:00
rWidth = round(m_pQWidget->width() * devicePixelRatioF());
rHeight = round(m_pQWidget->height() * devicePixelRatioF());
}
void QtFrame::GetWorkArea(AbsoluteScreenPixelRectangle& rRect)
{
if (!isWindow())
return;
QScreen* pScreen = screen();
if (!pScreen)
return;
QSize aSize = pScreen->availableVirtualSize() * devicePixelRatioF();
rRect = AbsoluteScreenPixelRectangle(0, 0, aSize.width(), aSize.height());
}
SalFrame* QtFrame::GetParent() const { return m_pParent; }
void QtFrame::SetModal(bool bModal)
{
if (!isWindow() || asChild()->isModal() == bModal)
return;
2019-06-02 21:01:33 +00:00
auto* pSalInst(GetQtInstance());
assert(pSalInst);
pSalInst->RunInMainThread([this, bModal]() {
tdf#119856 vcl: fix Qt warning Qt5Frame::SetModal() This prints a warning "Cannot create children for a parent that is in a different thread"; let's fix it before it causes another hard to debug crash. 0 check_parent_thread(QObject*, QThreadData*, QThreadData*) (parent=parent@entry=0xe88ca0, parentThreadData=<optimized out>, currentThreadData=<optimized out>) at kernel/qobject.cpp:781 1 check_parent_thread (currentThreadData=<optimized out>, parentThreadData=<optimized out>, parent=0xe88ca0) at kernel/qobject.cpp:822 2 QObject::QObject(QObject*) (this=0x9ed2e80, parent=0xe88ca0) at kernel/qobject.cpp:810 3 Adwaita::GenericData::GenericData(QObject*, QWidget*, int) () at /usr/lib64/qt5/plugins/styles/adwaita.so 4 Adwaita::WidgetStateEngine::registerWidget(QWidget*, QFlags<Adwaita::AnimationMode>) () at /usr/lib64/qt5/plugins/styles/adwaita.so 5 Adwaita::Animations::registerWidget(QWidget*) const () at /usr/lib64/qt5/plugins/styles/adwaita.so 6 Adwaita::Style::polish(QWidget*) () at /usr/lib64/qt5/plugins/styles/adwaita.so 7 QWidget::event(QEvent*) () at /lib64/libQt5Widgets.so.5 8 Qt5Widget::event(QEvent*) (this=0x7321790, pEvent=0x7f90c27d3750) at vcl/qt5/Qt5Widget.cxx:416 9 QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /lib64/libQt5Widgets.so.5 10 QApplication::notify(QObject*, QEvent*) () at /lib64/libQt5Widgets.so.5 11 QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x7321790, event=0x7f90c27d3750) at kernel/qcoreapplication.cpp:1047 12 QWidget::ensurePolished() const () at /lib64/libQt5Widgets.so.5 13 QWidget::setVisible(bool) () at /lib64/libQt5Widgets.so.5 14 Qt5Frame::SetModal(bool) (this=0x9f411b0, bModal=true) at vcl/qt5/Qt5Frame.cxx:482 Change-Id: Ib6b4d1ee859dfce650422a6c7860abf2eb2686f1 Reviewed-on: https://gerrit.libreoffice.org/68356 Tested-by: Jenkins Reviewed-by: Katarina Behrens <Katarina.Behrens@cib.de>
2019-02-25 16:56:59 +01:00
QWidget* const pChild = asChild();
const bool bWasVisible = pChild->isVisible();
tdf#119856 vcl: fix Qt warning Qt5Frame::SetModal() This prints a warning "Cannot create children for a parent that is in a different thread"; let's fix it before it causes another hard to debug crash. 0 check_parent_thread(QObject*, QThreadData*, QThreadData*) (parent=parent@entry=0xe88ca0, parentThreadData=<optimized out>, currentThreadData=<optimized out>) at kernel/qobject.cpp:781 1 check_parent_thread (currentThreadData=<optimized out>, parentThreadData=<optimized out>, parent=0xe88ca0) at kernel/qobject.cpp:822 2 QObject::QObject(QObject*) (this=0x9ed2e80, parent=0xe88ca0) at kernel/qobject.cpp:810 3 Adwaita::GenericData::GenericData(QObject*, QWidget*, int) () at /usr/lib64/qt5/plugins/styles/adwaita.so 4 Adwaita::WidgetStateEngine::registerWidget(QWidget*, QFlags<Adwaita::AnimationMode>) () at /usr/lib64/qt5/plugins/styles/adwaita.so 5 Adwaita::Animations::registerWidget(QWidget*) const () at /usr/lib64/qt5/plugins/styles/adwaita.so 6 Adwaita::Style::polish(QWidget*) () at /usr/lib64/qt5/plugins/styles/adwaita.so 7 QWidget::event(QEvent*) () at /lib64/libQt5Widgets.so.5 8 Qt5Widget::event(QEvent*) (this=0x7321790, pEvent=0x7f90c27d3750) at vcl/qt5/Qt5Widget.cxx:416 9 QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /lib64/libQt5Widgets.so.5 10 QApplication::notify(QObject*, QEvent*) () at /lib64/libQt5Widgets.so.5 11 QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x7321790, event=0x7f90c27d3750) at kernel/qcoreapplication.cpp:1047 12 QWidget::ensurePolished() const () at /lib64/libQt5Widgets.so.5 13 QWidget::setVisible(bool) () at /lib64/libQt5Widgets.so.5 14 Qt5Frame::SetModal(bool) (this=0x9f411b0, bModal=true) at vcl/qt5/Qt5Frame.cxx:482 Change-Id: Ib6b4d1ee859dfce650422a6c7860abf2eb2686f1 Reviewed-on: https://gerrit.libreoffice.org/68356 Tested-by: Jenkins Reviewed-by: Katarina Behrens <Katarina.Behrens@cib.de>
2019-02-25 16:56:59 +01:00
// modality change is only effective if the window is hidden
if (bWasVisible)
tdf#152979 qt: Re-add workaround for X11 modality change w/ hide/show Essentially add back the workaround originally added in commit e770bacc85a0eec96de77068d61b03f374b3cdec Date: Sun Jun 2 21:01:33 2019 +0000 Qt5 workaround modal change after show bug but then dropped again in commit 2dc6bdd1d5789ace0500cad90f5d2eb930888bb9 Date: Wed Jun 5 17:39:45 2019 +0000 tdf#125692 SalObject always holds a SystemChildWindow , since it turns out that it is still needed for other use cases than the original one from tdf#125692, as the freeze of the basic IDE dialog dialog preview described in tdf#152979. The qt.qpa.xcb: internal error: void QXcbWindow::setNetWmStateOnUnmappedWindow() called on mapped window issue mentioned there is apparently also worked around in upstream Qt tests, s. this qtbase commit [1]: commit 3714e51436eebb64873c58dc36cf89ef8f139f09 Author: Volker Hilsheimer <volker.hilsheimer@qt.io> Date: Mon Sep 20 13:44:26 2021 +0200 QWidgetWindow: Stabilize test on Xcb Showing, hiding, and showing a window can result in the Xcb QPA plugin warning about qt.qpa.xcb: internal error: void QXcbWindow::setNetWmStateOnUnmappedWindow() called on mapped window The point of the test is to verify that we get a paint event on a window that is shown again after having been hidden, not to verify that async windowing systems can handle a show/hide/show sequence. So wait for the window being exposed before we hide it. Pick-to: 6.2 5.15 Change-Id: If91a9926613645e78e332dacff34bd57e4034b6f Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> Decrease the sleep from the original 250 ms to 100 ms, since tdf#152979 comment 14 mentions that this is enough. [1] https://code.qt.io/cgit/qt/qtbase.git/commit/?id=3714e51436eebb64873c58dc36cf89ef8f139f09 Change-Id: I57ed520d0df85b7a3bcf47c2f9314754649482ee Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149912 Tested-by: Jenkins Reviewed-by: Rafael Lima <rafael.palma.lima@gmail.com>
2023-04-01 20:08:13 +03:00
{
pChild->hide();
tdf#152979 qt: Re-add workaround for X11 modality change w/ hide/show Essentially add back the workaround originally added in commit e770bacc85a0eec96de77068d61b03f374b3cdec Date: Sun Jun 2 21:01:33 2019 +0000 Qt5 workaround modal change after show bug but then dropped again in commit 2dc6bdd1d5789ace0500cad90f5d2eb930888bb9 Date: Wed Jun 5 17:39:45 2019 +0000 tdf#125692 SalObject always holds a SystemChildWindow , since it turns out that it is still needed for other use cases than the original one from tdf#125692, as the freeze of the basic IDE dialog dialog preview described in tdf#152979. The qt.qpa.xcb: internal error: void QXcbWindow::setNetWmStateOnUnmappedWindow() called on mapped window issue mentioned there is apparently also worked around in upstream Qt tests, s. this qtbase commit [1]: commit 3714e51436eebb64873c58dc36cf89ef8f139f09 Author: Volker Hilsheimer <volker.hilsheimer@qt.io> Date: Mon Sep 20 13:44:26 2021 +0200 QWidgetWindow: Stabilize test on Xcb Showing, hiding, and showing a window can result in the Xcb QPA plugin warning about qt.qpa.xcb: internal error: void QXcbWindow::setNetWmStateOnUnmappedWindow() called on mapped window The point of the test is to verify that we get a paint event on a window that is shown again after having been hidden, not to verify that async windowing systems can handle a show/hide/show sequence. So wait for the window being exposed before we hide it. Pick-to: 6.2 5.15 Change-Id: If91a9926613645e78e332dacff34bd57e4034b6f Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> Decrease the sleep from the original 250 ms to 100 ms, since tdf#152979 comment 14 mentions that this is enough. [1] https://code.qt.io/cgit/qt/qtbase.git/commit/?id=3714e51436eebb64873c58dc36cf89ef8f139f09 Change-Id: I57ed520d0df85b7a3bcf47c2f9314754649482ee Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149912 Tested-by: Jenkins Reviewed-by: Rafael Lima <rafael.palma.lima@gmail.com>
2023-04-01 20:08:13 +03:00
if (QGuiApplication::platformName() == "xcb")
{
SAL_WARN("vcl.qt", "SetModal called after Show - apply delay");
// tdf#152979 give QXcbConnection some time to avoid
// "qt.qpa.xcb: internal error: void QXcbWindow::setNetWmStateOnUnmappedWindow() called on mapped window"
QThread::msleep(100);
}
}
tdf#119856 vcl: fix Qt warning Qt5Frame::SetModal() This prints a warning "Cannot create children for a parent that is in a different thread"; let's fix it before it causes another hard to debug crash. 0 check_parent_thread(QObject*, QThreadData*, QThreadData*) (parent=parent@entry=0xe88ca0, parentThreadData=<optimized out>, currentThreadData=<optimized out>) at kernel/qobject.cpp:781 1 check_parent_thread (currentThreadData=<optimized out>, parentThreadData=<optimized out>, parent=0xe88ca0) at kernel/qobject.cpp:822 2 QObject::QObject(QObject*) (this=0x9ed2e80, parent=0xe88ca0) at kernel/qobject.cpp:810 3 Adwaita::GenericData::GenericData(QObject*, QWidget*, int) () at /usr/lib64/qt5/plugins/styles/adwaita.so 4 Adwaita::WidgetStateEngine::registerWidget(QWidget*, QFlags<Adwaita::AnimationMode>) () at /usr/lib64/qt5/plugins/styles/adwaita.so 5 Adwaita::Animations::registerWidget(QWidget*) const () at /usr/lib64/qt5/plugins/styles/adwaita.so 6 Adwaita::Style::polish(QWidget*) () at /usr/lib64/qt5/plugins/styles/adwaita.so 7 QWidget::event(QEvent*) () at /lib64/libQt5Widgets.so.5 8 Qt5Widget::event(QEvent*) (this=0x7321790, pEvent=0x7f90c27d3750) at vcl/qt5/Qt5Widget.cxx:416 9 QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /lib64/libQt5Widgets.so.5 10 QApplication::notify(QObject*, QEvent*) () at /lib64/libQt5Widgets.so.5 11 QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x7321790, event=0x7f90c27d3750) at kernel/qcoreapplication.cpp:1047 12 QWidget::ensurePolished() const () at /lib64/libQt5Widgets.so.5 13 QWidget::setVisible(bool) () at /lib64/libQt5Widgets.so.5 14 Qt5Frame::SetModal(bool) (this=0x9f411b0, bModal=true) at vcl/qt5/Qt5Frame.cxx:482 Change-Id: Ib6b4d1ee859dfce650422a6c7860abf2eb2686f1 Reviewed-on: https://gerrit.libreoffice.org/68356 Tested-by: Jenkins Reviewed-by: Katarina Behrens <Katarina.Behrens@cib.de>
2019-02-25 16:56:59 +01:00
pChild->setWindowModality(bModal ? Qt::WindowModal : Qt::NonModal);
if (bWasVisible)
pChild->show();
});
}
bool QtFrame::GetModal() const { return isWindow() && windowHandle()->isModal(); }
void QtFrame::SetWindowState(const vcl::WindowData* pState)
{
if (!isWindow() || !pState || isChild(true, false))
return;
const vcl::WindowDataMask nMaxGeometryMask
= vcl::WindowDataMask::PosSize | vcl::WindowDataMask::MaximizedX
| vcl::WindowDataMask::MaximizedY | vcl::WindowDataMask::MaximizedWidth
| vcl::WindowDataMask::MaximizedHeight;
if ((pState->mask() & vcl::WindowDataMask::State)
&& (pState->state() & vcl::WindowState::Maximized) && !isMaximized()
&& (pState->mask() & nMaxGeometryMask) == nMaxGeometryMask)
{
const qreal fRatio = devicePixelRatioF();
QWidget* const pChild = asChild();
pChild->resize(ceil(pState->width() / fRatio), ceil(pState->height() / fRatio));
pChild->move(ceil(pState->x() / fRatio), ceil(pState->y() / fRatio));
SetWindowStateImpl(Qt::WindowMaximized);
}
else if (pState->mask() & vcl::WindowDataMask::PosSize)
{
sal_uInt16 nPosSizeFlags = 0;
if (pState->mask() & vcl::WindowDataMask::X)
nPosSizeFlags |= SAL_FRAME_POSSIZE_X;
if (pState->mask() & vcl::WindowDataMask::Y)
nPosSizeFlags |= SAL_FRAME_POSSIZE_Y;
if (pState->mask() & vcl::WindowDataMask::Width)
nPosSizeFlags |= SAL_FRAME_POSSIZE_WIDTH;
if (pState->mask() & vcl::WindowDataMask::Height)
nPosSizeFlags |= SAL_FRAME_POSSIZE_HEIGHT;
SetPosSize(pState->x(), pState->y(), pState->width(), pState->height(), nPosSizeFlags);
}
else if (pState->mask() & vcl::WindowDataMask::State && !isChild())
{
if (pState->state() & vcl::WindowState::Maximized)
SetWindowStateImpl(Qt::WindowMaximized);
else if (pState->state() & vcl::WindowState::Minimized)
SetWindowStateImpl(Qt::WindowMinimized);
else
SetWindowStateImpl(Qt::WindowNoState);
}
}
bool QtFrame::GetWindowState(vcl::WindowData* pState)
{
pState->setState(vcl::WindowState::Normal);
pState->setMask(vcl::WindowDataMask::State);
if (isMinimized())
pState->rState() |= vcl::WindowState::Minimized;
else if (isMaximized())
pState->rState() |= vcl::WindowState::Maximized;
else
{
// we want the frame position and the client area size
QRect rect = scaledQRect({ asChild()->pos(), asChild()->size() }, devicePixelRatioF());
pState->setPosSize(toRectangle(rect));
pState->rMask() |= vcl::WindowDataMask::PosSize;
}
return true;
}
void QtFrame::ShowFullScreen(bool bFullScreen, sal_Int32 nScreen)
{
// only top-level windows can go fullscreen
assert(m_pTopLevel);
if (m_bFullScreen == bFullScreen)
return;
m_bFullScreen = bFullScreen;
m_bFullScreenSpanAll = m_bFullScreen && (nScreen < 0);
// show it if it isn't shown yet
if (!isWindow())
m_pTopLevel->show();
if (m_bFullScreen)
{
m_aRestoreGeometry = m_pTopLevel->geometry();
m_nRestoreScreen = maGeometry.screen();
SetScreenNumber(m_bFullScreenSpanAll ? m_nRestoreScreen : nScreen);
if (!m_bFullScreenSpanAll)
windowHandle()->showFullScreen();
else
windowHandle()->showNormal();
}
else
{
SetScreenNumber(m_nRestoreScreen);
windowHandle()->showNormal();
m_pTopLevel->setGeometry(m_aRestoreGeometry);
}
}
void QtFrame::StartPresentation(bool bStart)
{
qt: Fix qt6 build after fbc61e06584ff8e6d9240f8b67be8dc28ecab5b9 Failed like this: In file included from /home/michi/development/git/libreoffice/vcl/qt6/QtX11Support.cxx:10: /home/michi/development/git/libreoffice/vcl/qt6/../qt5/QtX11Support.cxx:15:10: fatal error: QtX11Extras/QX11Info: No such file or directory 15 | #include <QtX11Extras/QX11Info> | ^~~~~~~~~~~~~~~~~~~~~~ compilation terminated. make[1]: *** [/home/michi/development/git/libreoffice/solenv/gbuild/LinkTarget.mk:334: /home/michi/development/git/libreoffice/workdir/CxxObject/vcl/qt6/QtX11Support.o] Error 1 make[1]: *** Waiting for unfinished jobs.... In file included from /home/michi/development/git/libreoffice/vcl/qt6/QtFrame.cxx:10: /home/michi/development/git/libreoffice/vcl/qt6/../qt5/QtFrame.cxx: In member function ‘virtual void QtFrame::StartPresentation(bool)’: /home/michi/development/git/libreoffice/vcl/qt6/../qt5/QtFrame.cxx:746:5: error: ‘m_ScreenSaverInhibitor’ was not declared in this scope 746 | m_ScreenSaverInhibitor.inhibit(bStart, u"presentation", bIsX11, aRootWindow, aDisplay); | ^~~~~~~~~~~~~~~~~~~~~~ make[1]: *** [/home/michi/development/git/libreoffice/solenv/gbuild/LinkTarget.mk:334: /home/michi/development/git/libreoffice/workdir/CxxObject/vcl/qt6/QtFrame.o] Error 1 make: *** [Makefile:288: build] Error 2 As mentioned in [1], `QX11Info` has been removed in Qt 6. The `ScreenSaverInhibitor` related code (except for the `QX11Info` part) can be used for Qt 6 as well, so adapt the checks in the header accordingly. [1] https://www.qt.io/blog/qt-extras-modules-in-qt-6 Co-authored-by: Jan-Marek Glogowski <glogow@fbihome.de> Change-Id: Ifd546b4f4210aaf7f09ebaa8c36d2a031763d492 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136091 Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de> Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2022-06-18 21:11:28 +02:00
#if CHECK_ANY_QT_USING_X11
// meh - so there's no Qt platform independent solution
// https://forum.qt.io/topic/38504/solved-qdialog-in-fullscreen-disable-os-screensaver
assert(m_aSystemData.platform != SystemEnvData::Platform::Invalid);
unsigned int nRootWindow(0);
std::optional<Display*> aDisplay;
#if CHECK_QT5_USING_X11
if (QX11Info::isPlatformX11())
{
nRootWindow = QX11Info::appRootWindow();
aDisplay = QX11Info::display();
}
#endif
m_SessionManagerInhibitor.inhibit(bStart, u"presentation", APPLICATION_INHIBIT_IDLE,
nRootWindow, aDisplay);
qt: Fix qt6 build after fbc61e06584ff8e6d9240f8b67be8dc28ecab5b9 Failed like this: In file included from /home/michi/development/git/libreoffice/vcl/qt6/QtX11Support.cxx:10: /home/michi/development/git/libreoffice/vcl/qt6/../qt5/QtX11Support.cxx:15:10: fatal error: QtX11Extras/QX11Info: No such file or directory 15 | #include <QtX11Extras/QX11Info> | ^~~~~~~~~~~~~~~~~~~~~~ compilation terminated. make[1]: *** [/home/michi/development/git/libreoffice/solenv/gbuild/LinkTarget.mk:334: /home/michi/development/git/libreoffice/workdir/CxxObject/vcl/qt6/QtX11Support.o] Error 1 make[1]: *** Waiting for unfinished jobs.... In file included from /home/michi/development/git/libreoffice/vcl/qt6/QtFrame.cxx:10: /home/michi/development/git/libreoffice/vcl/qt6/../qt5/QtFrame.cxx: In member function ‘virtual void QtFrame::StartPresentation(bool)’: /home/michi/development/git/libreoffice/vcl/qt6/../qt5/QtFrame.cxx:746:5: error: ‘m_ScreenSaverInhibitor’ was not declared in this scope 746 | m_ScreenSaverInhibitor.inhibit(bStart, u"presentation", bIsX11, aRootWindow, aDisplay); | ^~~~~~~~~~~~~~~~~~~~~~ make[1]: *** [/home/michi/development/git/libreoffice/solenv/gbuild/LinkTarget.mk:334: /home/michi/development/git/libreoffice/workdir/CxxObject/vcl/qt6/QtFrame.o] Error 1 make: *** [Makefile:288: build] Error 2 As mentioned in [1], `QX11Info` has been removed in Qt 6. The `ScreenSaverInhibitor` related code (except for the `QX11Info` part) can be used for Qt 6 as well, so adapt the checks in the header accordingly. [1] https://www.qt.io/blog/qt-extras-modules-in-qt-6 Co-authored-by: Jan-Marek Glogowski <glogow@fbihome.de> Change-Id: Ifd546b4f4210aaf7f09ebaa8c36d2a031763d492 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136091 Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de> Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2022-06-18 21:11:28 +02:00
#else
Q_UNUSED(bStart)
#endif
}
void QtFrame::SetAlwaysOnTop(bool bOnTop)
{
QWidget* const pWidget = asChild();
const Qt::WindowFlags flags = pWidget->windowFlags();
if (bOnTop)
pWidget->setWindowFlags(flags | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint);
else
pWidget->setWindowFlags(flags & ~(Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint));
}
void QtFrame::ToTop(SalFrameToTop nFlags)
{
qt: Set window title etc. in main thread These QWidget methods need to be called in the main thread. Otherwise, opening the Update dialog ("Help" -> "Check for Updates", enabled by `--enable-online-update` autogen switch) triggers asserts like the one below with a self-compiled Qt 6 development build (qtbase dev branch as of c802a9e987c9e38c01580f467eab92a651b3e033). ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 0x0x7fff780160e0. Receiver '' (of type 'QtWidget') was created in thread 0x0x5555555fcd30", file /home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp, line 537 Thread 40 "InitUpdateCheck" received signal SIGABRT, Aborted. [Switching to Thread 0x7fff7ffff6c0 (LWP 1516868)] __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44 44 ./nptl/pthread_kill.c: No such file or directory. (gdb) bt #0 __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44 #1 0x00007ffff78a815f in __pthread_kill_internal (signo=6, threadid=<optimized out>) at ./nptl/pthread_kill.c:78 #2 0x00007ffff785a472 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26 #3 0x00007ffff78444b2 in __GI_abort () at ./stdlib/abort.c:79 #4 0x00007fffe32eb45a in qAbort() () at /home/michi/development/git/qt5/qtbase/src/corelib/global/qglobal.cpp:161 #5 0x00007fffe32f9ee5 in qt_message_fatal(QtMsgType, QMessageLogContext const&, QString const&) (context=..., message=...) at /home/michi/development/git/qt5/qtbase/src/corelib/global/qlogging.cpp:2057 #6 0x00007fffe32f620c in QMessageLogger::fatal(char const*, ...) const (this=0x7fff7fffb980, msg=0x7fffe37fd9a0 "ASSERT failure in %s: \"%s\", file %s, line %d") at /home/michi/development/git/qt5/qtbase/src/corelib/global/qlogging.cpp:938 #7 0x00007fffe32e9d54 in qt_assert_x(char const*, char const*, char const*, int) (where=0x7fffe38131e9 "QCoreApplication::sendEvent", what=0x7fff78180110 "Cannot send events to objects owned by a different thread. Current thread 0x0x7fff780160e0. Receiver '' (of type 'QtWidget') was created in thread 0x0x5555555fcd30", file=0x7fffe3812e18 "/home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp", line=537) at /home/michi/development/git/qt5/qtbase/src/corelib/global/qassert.cpp:77 #8 0x00007fffe33a4d74 in QCoreApplicationPrivate::checkReceiverThread(QObject*) (receiver=0x55555d27d5d0) at /home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:537 #9 0x00007fffe19a3a81 in QApplication::notify(QObject*, QEvent*) (this=0x5555555fcb80, receiver=0x55555d27d5d0, e=0x7fff7fffc0b0) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qapplication.cpp:2584 #10 0x00007fffe33a5ed0 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x55555d27d5d0, event=0x7fff7fffc0b0) at /home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1125 #11 0x00007fffe33a6991 in QCoreApplication::sendEvent(QObject*, QEvent*) (receiver=0x55555d27d5d0, event=0x7fff7fffc0b0) at /home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1559 #12 0x00007fffe1a279b4 in QWidget::setWindowTitle(QString const&) (this=0x55555d27d5d0, title=...) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qwidget.cpp:6119 #13 0x00007fffe3c9d4c4 in QtFrame::SetTitle(rtl::OUString const&) (this=0x555555619d20, rTitle="Check for Updates") at /home/michi/development/git/libreoffice/vcl/qt6/../qt5/QtFrame.cxx:365 #14 0x00007fffedd98d44 in vcl::Window::SetText(rtl::OUString const&) (this=0x7fff7803cd90, rStr="Check for Updates") at /home/michi/development/git/libreoffice/vcl/source/window/window.cxx:3042 #15 0x00007fffedd311c9 in SystemWindow::SetText(rtl::OUString const&) (this=0x7fff7803cd90, rStr="Check for Updates") at /home/michi/development/git/libreoffice/vcl/source/window/syswin.cxx:1048 #16 0x00007ffff048bd6b in VCLXWindow::setProperty(rtl::OUString const&, com::sun::star::uno::Any const&) (this=0x7fff7804ac00, PropertyName="Title", Value=uno::Any("string": "Check for Updates")) at /home/michi/development/git/libreoffice/toolkit/source/awt/vclxwindow.cxx:1515 #17 0x00007ffff03e486d in VCLXContainer::setProperty(rtl::OUString const&, com::sun::star::uno::Any const&) (this=0x7fff7804ac00, PropertyName="Title", Value=uno::Any("string": "Check for Updates")) at /home/michi/development/git/libreoffice/toolkit/source/awt/vclxcontainer.cxx:260 #18 0x00007ffff04dfa2c in VCLXDialog::setProperty(rtl::OUString const&, com::sun::star::uno::Any const&) (this=0x7fff7804ac00, PropertyName="Title", Value=uno::Any("string": "Check for Updates")) at /home/michi/development/git/libreoffice/toolkit/source/awt/vclxwindows.cxx:2364 #19 0x00007ffff06a89b7 in UnoControl::ImplSetPeerProperty(rtl::OUString const&, com::sun::star::uno::Any const&) (this=0x7fff7803b4f0, rPropName="Title", rVal=uno::Any("string": "Check for Updates")) at /home/michi/development/git/libreoffice/toolkit/source/controls/unocontrol.cxx:288 #20 0x00007ffff06aa701 in UnoControl::ImplModelPropertiesChanged(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyChangeEvent> const&) (this=0x7fff7803b4f0, rEvents=uno::Sequence of length 51 = {...}) at /home/michi/development/git/libreoffice/toolkit/source/controls/unocontrol.cxx:649 #21 0x00007ffff0531ae9 in ControlContainerBase::ImplModelPropertiesChanged(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyChangeEvent> const&) (this=0x7fff7803b4f0, rEvents=uno::Sequence of length 51 = {...}) at /home/michi/development/git/libreoffice/toolkit/source/controls/controlmodelcontainerbase.cxx:1600 #22 0x00007ffff0575a25 in UnoDialogControl::ImplModelPropertiesChanged(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyChangeEvent> const&) (this=0x7fff7803b4f0, rEvents=uno::Sequence of length 51 = {...}) at /home/michi/development/git/libreoffice/toolkit/source/controls/dialogcontrol.cxx:651 #23 0x00007ffff06a95f3 in UnoControl::propertiesChange(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyChangeEvent> const&) (this=0x7fff7803b4f0, rEvents=uno::Sequence of length 51 = {...}) at /home/michi/development/git/libreoffice/toolkit/source/controls/unocontrol.cxx:431 #24 0x00007ffff66bc4ee in cppu::OPropertySetHelper::firePropertiesChangeEvent(com::sun::star::uno::Sequence<rtl::OUString> const&, com::sun::star::uno::Reference<com::sun::star::beans::XPropertiesChangeListener> const&) (this=0x7fff78006170, rPropertyNames=uno::Sequence of length 51 = {...}, rListener=uno::Reference to (UnoDialogControl *) 0x7fff7803b540) at /home/michi/development/git/libreoffice/cppuhelper/source/propshlp.cxx:961 #25 0x00007ffff06a8c6b in UnoControl::updateFromModel() (this=0x7fff7803b4f0) at /home/michi/development/git/libreoffice/toolkit/source/controls/unocontrol.cxx:320 #26 0x00007ffff06aefc9 in UnoControl::createPeer(com::sun::star::uno::Reference<com::sun::star::awt::XToolkit> const&, com::sun::star::uno::Reference<com::sun::star::awt::XWindowPeer> const&) (this=0x7fff7803b4f0, rxToolkit=empty uno::Reference, rParentPeer=empty uno::Reference) at /home/michi/development/git/libreoffice/toolkit/source/controls/unocontrol.cxx:1325 #27 0x00007ffff06c9905 in UnoControlContainer::createPeer(com::sun::star::uno::Reference<com::sun::star::awt::XToolkit> const&, com::sun::star::uno::Reference<com::sun::star::awt::XWindowPeer> const&) (this=0x7fff7803b4f0, rxToolkit=empty uno::Reference, rParent=empty uno::Reference) at /home/michi/development/git/libreoffice/toolkit/source/controls/unocontrolcontainer.cxx:727 #28 0x00007ffff057336d in UnoDialogControl::createPeer(com::sun::star::uno::Reference<com::sun::star::awt::XToolkit> const&, com::sun::star::uno::Reference<com::sun::star::awt::XWindowPeer> const&) (this=0x7fff7803b4f0, rxToolkit=empty uno::Reference, rParentPeer=empty uno::Reference) at /home/michi/development/git/libreoffice/toolkit/source/controls/dialogcontrol.cxx:358 #29 0x00007fffb7264e62 in UpdateHandler::createDialog() (this=0x7fff78003aa0) at /home/michi/development/git/libreoffice/extensions/source/update/check/updatehdl.cxx:1232 #30 0x00007fffb725b0e1 in UpdateHandler::setVisible(bool) (this=0x7fff78003aa0, bVisible=true) at /home/michi/development/git/libreoffice/extensions/source/update/check/updatehdl.cxx:188 #31 0x00007fffb7235887 in UpdateCheck::showDialog(bool) (this=0x7fff78000b90, forceCheck=true) at /home/michi/development/git/libreoffice/extensions/source/update/check/updatecheck.cxx:1171 #32 0x00007fffb7255c5e in (anonymous namespace)::InitUpdateCheckJobThread::run() (this=0x55555d192690) at /home/michi/development/git/libreoffice/extensions/source/update/check/updatecheckjob.cxx:148 #33 0x00007fffb723a74a in osl::threadFunc(void*) (param=0x55555d192690) at /home/michi/development/git/libreoffice/include/osl/thread.hxx:189 #34 0x00007ffff7f3f693 in osl_thread_start_Impl(void*) (pData=0x55555d1a68b0) at /home/michi/development/git/libreoffice/sal/osl/unx/thread.cxx:237 #35 0x00007ffff78a63ec in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:444 #36 0x00007ffff7926a1c in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81 Change-Id: I6ccdee00fe26619f201459ebbe6c4d8cf8b57b45 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156426 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2023-09-01 17:50:19 +02:00
QtInstance* pSalInst(GetQtInstance());
assert(pSalInst);
pSalInst->RunInMainThread([this, nFlags]() {
QWidget* const pWidget = asChild();
if (isWindow() && !(nFlags & SalFrameToTop::GrabFocusOnly))
pWidget->raise();
if ((nFlags & SalFrameToTop::RestoreWhenMin) || (nFlags & SalFrameToTop::ForegroundTask))
{
if (nFlags & SalFrameToTop::RestoreWhenMin)
pWidget->setWindowState(pWidget->windowState() & ~Qt::WindowMinimized);
pWidget->activateWindow();
qt: Set window title etc. in main thread These QWidget methods need to be called in the main thread. Otherwise, opening the Update dialog ("Help" -> "Check for Updates", enabled by `--enable-online-update` autogen switch) triggers asserts like the one below with a self-compiled Qt 6 development build (qtbase dev branch as of c802a9e987c9e38c01580f467eab92a651b3e033). ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 0x0x7fff780160e0. Receiver '' (of type 'QtWidget') was created in thread 0x0x5555555fcd30", file /home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp, line 537 Thread 40 "InitUpdateCheck" received signal SIGABRT, Aborted. [Switching to Thread 0x7fff7ffff6c0 (LWP 1516868)] __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44 44 ./nptl/pthread_kill.c: No such file or directory. (gdb) bt #0 __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44 #1 0x00007ffff78a815f in __pthread_kill_internal (signo=6, threadid=<optimized out>) at ./nptl/pthread_kill.c:78 #2 0x00007ffff785a472 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26 #3 0x00007ffff78444b2 in __GI_abort () at ./stdlib/abort.c:79 #4 0x00007fffe32eb45a in qAbort() () at /home/michi/development/git/qt5/qtbase/src/corelib/global/qglobal.cpp:161 #5 0x00007fffe32f9ee5 in qt_message_fatal(QtMsgType, QMessageLogContext const&, QString const&) (context=..., message=...) at /home/michi/development/git/qt5/qtbase/src/corelib/global/qlogging.cpp:2057 #6 0x00007fffe32f620c in QMessageLogger::fatal(char const*, ...) const (this=0x7fff7fffb980, msg=0x7fffe37fd9a0 "ASSERT failure in %s: \"%s\", file %s, line %d") at /home/michi/development/git/qt5/qtbase/src/corelib/global/qlogging.cpp:938 #7 0x00007fffe32e9d54 in qt_assert_x(char const*, char const*, char const*, int) (where=0x7fffe38131e9 "QCoreApplication::sendEvent", what=0x7fff78180110 "Cannot send events to objects owned by a different thread. Current thread 0x0x7fff780160e0. Receiver '' (of type 'QtWidget') was created in thread 0x0x5555555fcd30", file=0x7fffe3812e18 "/home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp", line=537) at /home/michi/development/git/qt5/qtbase/src/corelib/global/qassert.cpp:77 #8 0x00007fffe33a4d74 in QCoreApplicationPrivate::checkReceiverThread(QObject*) (receiver=0x55555d27d5d0) at /home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:537 #9 0x00007fffe19a3a81 in QApplication::notify(QObject*, QEvent*) (this=0x5555555fcb80, receiver=0x55555d27d5d0, e=0x7fff7fffc0b0) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qapplication.cpp:2584 #10 0x00007fffe33a5ed0 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x55555d27d5d0, event=0x7fff7fffc0b0) at /home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1125 #11 0x00007fffe33a6991 in QCoreApplication::sendEvent(QObject*, QEvent*) (receiver=0x55555d27d5d0, event=0x7fff7fffc0b0) at /home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1559 #12 0x00007fffe1a279b4 in QWidget::setWindowTitle(QString const&) (this=0x55555d27d5d0, title=...) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qwidget.cpp:6119 #13 0x00007fffe3c9d4c4 in QtFrame::SetTitle(rtl::OUString const&) (this=0x555555619d20, rTitle="Check for Updates") at /home/michi/development/git/libreoffice/vcl/qt6/../qt5/QtFrame.cxx:365 #14 0x00007fffedd98d44 in vcl::Window::SetText(rtl::OUString const&) (this=0x7fff7803cd90, rStr="Check for Updates") at /home/michi/development/git/libreoffice/vcl/source/window/window.cxx:3042 #15 0x00007fffedd311c9 in SystemWindow::SetText(rtl::OUString const&) (this=0x7fff7803cd90, rStr="Check for Updates") at /home/michi/development/git/libreoffice/vcl/source/window/syswin.cxx:1048 #16 0x00007ffff048bd6b in VCLXWindow::setProperty(rtl::OUString const&, com::sun::star::uno::Any const&) (this=0x7fff7804ac00, PropertyName="Title", Value=uno::Any("string": "Check for Updates")) at /home/michi/development/git/libreoffice/toolkit/source/awt/vclxwindow.cxx:1515 #17 0x00007ffff03e486d in VCLXContainer::setProperty(rtl::OUString const&, com::sun::star::uno::Any const&) (this=0x7fff7804ac00, PropertyName="Title", Value=uno::Any("string": "Check for Updates")) at /home/michi/development/git/libreoffice/toolkit/source/awt/vclxcontainer.cxx:260 #18 0x00007ffff04dfa2c in VCLXDialog::setProperty(rtl::OUString const&, com::sun::star::uno::Any const&) (this=0x7fff7804ac00, PropertyName="Title", Value=uno::Any("string": "Check for Updates")) at /home/michi/development/git/libreoffice/toolkit/source/awt/vclxwindows.cxx:2364 #19 0x00007ffff06a89b7 in UnoControl::ImplSetPeerProperty(rtl::OUString const&, com::sun::star::uno::Any const&) (this=0x7fff7803b4f0, rPropName="Title", rVal=uno::Any("string": "Check for Updates")) at /home/michi/development/git/libreoffice/toolkit/source/controls/unocontrol.cxx:288 #20 0x00007ffff06aa701 in UnoControl::ImplModelPropertiesChanged(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyChangeEvent> const&) (this=0x7fff7803b4f0, rEvents=uno::Sequence of length 51 = {...}) at /home/michi/development/git/libreoffice/toolkit/source/controls/unocontrol.cxx:649 #21 0x00007ffff0531ae9 in ControlContainerBase::ImplModelPropertiesChanged(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyChangeEvent> const&) (this=0x7fff7803b4f0, rEvents=uno::Sequence of length 51 = {...}) at /home/michi/development/git/libreoffice/toolkit/source/controls/controlmodelcontainerbase.cxx:1600 #22 0x00007ffff0575a25 in UnoDialogControl::ImplModelPropertiesChanged(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyChangeEvent> const&) (this=0x7fff7803b4f0, rEvents=uno::Sequence of length 51 = {...}) at /home/michi/development/git/libreoffice/toolkit/source/controls/dialogcontrol.cxx:651 #23 0x00007ffff06a95f3 in UnoControl::propertiesChange(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyChangeEvent> const&) (this=0x7fff7803b4f0, rEvents=uno::Sequence of length 51 = {...}) at /home/michi/development/git/libreoffice/toolkit/source/controls/unocontrol.cxx:431 #24 0x00007ffff66bc4ee in cppu::OPropertySetHelper::firePropertiesChangeEvent(com::sun::star::uno::Sequence<rtl::OUString> const&, com::sun::star::uno::Reference<com::sun::star::beans::XPropertiesChangeListener> const&) (this=0x7fff78006170, rPropertyNames=uno::Sequence of length 51 = {...}, rListener=uno::Reference to (UnoDialogControl *) 0x7fff7803b540) at /home/michi/development/git/libreoffice/cppuhelper/source/propshlp.cxx:961 #25 0x00007ffff06a8c6b in UnoControl::updateFromModel() (this=0x7fff7803b4f0) at /home/michi/development/git/libreoffice/toolkit/source/controls/unocontrol.cxx:320 #26 0x00007ffff06aefc9 in UnoControl::createPeer(com::sun::star::uno::Reference<com::sun::star::awt::XToolkit> const&, com::sun::star::uno::Reference<com::sun::star::awt::XWindowPeer> const&) (this=0x7fff7803b4f0, rxToolkit=empty uno::Reference, rParentPeer=empty uno::Reference) at /home/michi/development/git/libreoffice/toolkit/source/controls/unocontrol.cxx:1325 #27 0x00007ffff06c9905 in UnoControlContainer::createPeer(com::sun::star::uno::Reference<com::sun::star::awt::XToolkit> const&, com::sun::star::uno::Reference<com::sun::star::awt::XWindowPeer> const&) (this=0x7fff7803b4f0, rxToolkit=empty uno::Reference, rParent=empty uno::Reference) at /home/michi/development/git/libreoffice/toolkit/source/controls/unocontrolcontainer.cxx:727 #28 0x00007ffff057336d in UnoDialogControl::createPeer(com::sun::star::uno::Reference<com::sun::star::awt::XToolkit> const&, com::sun::star::uno::Reference<com::sun::star::awt::XWindowPeer> const&) (this=0x7fff7803b4f0, rxToolkit=empty uno::Reference, rParentPeer=empty uno::Reference) at /home/michi/development/git/libreoffice/toolkit/source/controls/dialogcontrol.cxx:358 #29 0x00007fffb7264e62 in UpdateHandler::createDialog() (this=0x7fff78003aa0) at /home/michi/development/git/libreoffice/extensions/source/update/check/updatehdl.cxx:1232 #30 0x00007fffb725b0e1 in UpdateHandler::setVisible(bool) (this=0x7fff78003aa0, bVisible=true) at /home/michi/development/git/libreoffice/extensions/source/update/check/updatehdl.cxx:188 #31 0x00007fffb7235887 in UpdateCheck::showDialog(bool) (this=0x7fff78000b90, forceCheck=true) at /home/michi/development/git/libreoffice/extensions/source/update/check/updatecheck.cxx:1171 #32 0x00007fffb7255c5e in (anonymous namespace)::InitUpdateCheckJobThread::run() (this=0x55555d192690) at /home/michi/development/git/libreoffice/extensions/source/update/check/updatecheckjob.cxx:148 #33 0x00007fffb723a74a in osl::threadFunc(void*) (param=0x55555d192690) at /home/michi/development/git/libreoffice/include/osl/thread.hxx:189 #34 0x00007ffff7f3f693 in osl_thread_start_Impl(void*) (pData=0x55555d1a68b0) at /home/michi/development/git/libreoffice/sal/osl/unx/thread.cxx:237 #35 0x00007ffff78a63ec in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:444 #36 0x00007ffff7926a1c in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81 Change-Id: I6ccdee00fe26619f201459ebbe6c4d8cf8b57b45 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156426 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2023-09-01 17:50:19 +02:00
}
else if ((nFlags & SalFrameToTop::GrabFocus) || (nFlags & SalFrameToTop::GrabFocusOnly))
{
if (!(nFlags & SalFrameToTop::GrabFocusOnly))
pWidget->activateWindow();
pWidget->setFocus(Qt::OtherFocusReason);
}
});
}
void QtFrame::SetPointer(PointerStyle ePointerStyle)
{
if (ePointerStyle == m_ePointerStyle)
return;
m_ePointerStyle = ePointerStyle;
m_pQWidget->setCursor(GetQtData()->getCursor(ePointerStyle));
}
void QtFrame::CaptureMouse(bool bMouse)
{
static const char* pEnv = getenv("SAL_NO_MOUSEGRABS");
if (pEnv && *pEnv)
return;
if (bMouse)
m_pQWidget->grabMouse();
else
m_pQWidget->releaseMouse();
}
void QtFrame::SetPointerPos(tools::Long nX, tools::Long nY)
{
// some cursor already exists (and it has m_ePointerStyle shape)
// so here we just reposition it
QCursor::setPos(m_pQWidget->mapToGlobal(QPoint(nX, nY) / devicePixelRatioF()));
}
void QtFrame::Flush()
{
// was: QGuiApplication::sync();
// but FIXME it causes too many issues, figure out sth better
// unclear if we need to also flush cairo surface - gtk3 backend
// does not do it. QPainter in QtWidget::paintEvent() is
// destroyed, so that state should be safely flushed.
}
bool QtFrame::ShowTooltip(const OUString& rText, const tools::Rectangle& rHelpArea)
{
QRect aHelpArea(toQRect(rHelpArea));
if (QGuiApplication::isRightToLeft())
aHelpArea.moveLeft(maGeometry.width() - aHelpArea.width() - aHelpArea.left() - 1);
m_aTooltipText = rText;
m_aTooltipArea = aHelpArea;
return true;
}
void QtFrame::SetInputContext(SalInputContext* pContext)
{
if (!pContext)
return;
if (!(pContext->mnOptions & InputContextFlags::Text))
return;
m_pQWidget->setAttribute(Qt::WA_InputMethodEnabled);
}
void QtFrame::EndExtTextInput(EndExtTextInputFlags /*nFlags*/)
{
if (m_pQWidget)
m_pQWidget->endExtTextInput();
}
OUString QtFrame::GetKeyName(sal_uInt16 nKeyCode)
{
vcl::KeyCode vclKeyCode(nKeyCode);
int nCode = vclKeyCode.GetCode();
int nRetCode = 0;
if (nCode >= KEY_0 && nCode <= KEY_9)
nRetCode = (nCode - KEY_0) + Qt::Key_0;
else if (nCode >= KEY_A && nCode <= KEY_Z)
nRetCode = (nCode - KEY_A) + Qt::Key_A;
else if (nCode >= KEY_F1 && nCode <= KEY_F26)
nRetCode = (nCode - KEY_F1) + Qt::Key_F1;
else
{
switch (nCode)
{
case KEY_DOWN:
nRetCode = Qt::Key_Down;
break;
case KEY_UP:
nRetCode = Qt::Key_Up;
break;
case KEY_LEFT:
nRetCode = Qt::Key_Left;
break;
case KEY_RIGHT:
nRetCode = Qt::Key_Right;
break;
case KEY_HOME:
nRetCode = Qt::Key_Home;
break;
case KEY_END:
nRetCode = Qt::Key_End;
break;
case KEY_PAGEUP:
nRetCode = Qt::Key_PageUp;
break;
case KEY_PAGEDOWN:
nRetCode = Qt::Key_PageDown;
break;
case KEY_RETURN:
nRetCode = Qt::Key_Return;
break;
case KEY_ESCAPE:
nRetCode = Qt::Key_Escape;
break;
case KEY_TAB:
nRetCode = Qt::Key_Tab;
break;
case KEY_BACKSPACE:
nRetCode = Qt::Key_Backspace;
break;
case KEY_SPACE:
nRetCode = Qt::Key_Space;
break;
case KEY_INSERT:
nRetCode = Qt::Key_Insert;
break;
case KEY_DELETE:
nRetCode = Qt::Key_Delete;
break;
case KEY_ADD:
nRetCode = Qt::Key_Plus;
break;
case KEY_SUBTRACT:
nRetCode = Qt::Key_Minus;
break;
case KEY_MULTIPLY:
nRetCode = Qt::Key_Asterisk;
break;
case KEY_DIVIDE:
nRetCode = Qt::Key_Slash;
break;
case KEY_POINT:
nRetCode = Qt::Key_Period;
break;
case KEY_COMMA:
nRetCode = Qt::Key_Comma;
break;
case KEY_LESS:
nRetCode = Qt::Key_Less;
break;
case KEY_GREATER:
nRetCode = Qt::Key_Greater;
break;
case KEY_EQUAL:
nRetCode = Qt::Key_Equal;
break;
case KEY_FIND:
nRetCode = Qt::Key_Find;
break;
case KEY_CONTEXTMENU:
nRetCode = Qt::Key_Menu;
break;
case KEY_HELP:
nRetCode = Qt::Key_Help;
break;
case KEY_UNDO:
nRetCode = Qt::Key_Undo;
break;
case KEY_REPEAT:
nRetCode = Qt::Key_Redo;
break;
case KEY_TILDE:
nRetCode = Qt::Key_AsciiTilde;
break;
case KEY_QUOTELEFT:
nRetCode = Qt::Key_QuoteLeft;
break;
case KEY_BRACKETLEFT:
nRetCode = Qt::Key_BracketLeft;
break;
case KEY_BRACKETRIGHT:
nRetCode = Qt::Key_BracketRight;
break;
case KEY_NUMBERSIGN:
nRetCode = Qt::Key_NumberSign;
break;
case KEY_XF86FORWARD:
nRetCode = Qt::Key_Forward;
break;
case KEY_XF86BACK:
nRetCode = Qt::Key_Back;
break;
case KEY_COLON:
nRetCode = Qt::Key_Colon;
break;
case KEY_SEMICOLON:
nRetCode = Qt::Key_Semicolon;
break;
// Special cases
case KEY_COPY:
nRetCode = Qt::Key_Copy;
break;
case KEY_CUT:
nRetCode = Qt::Key_Cut;
break;
case KEY_PASTE:
nRetCode = Qt::Key_Paste;
break;
case KEY_OPEN:
nRetCode = Qt::Key_Open;
break;
}
}
if (vclKeyCode.IsShift())
nRetCode += Qt::SHIFT;
if (vclKeyCode.IsMod1())
nRetCode += Qt::CTRL;
if (vclKeyCode.IsMod2())
nRetCode += Qt::ALT;
QKeySequence keySeq(nRetCode);
OUString sKeyName = toOUString(keySeq.toString());
return sKeyName;
}
bool QtFrame::MapUnicodeToKeyCode(sal_Unicode /*aUnicode*/, LanguageType /*aLangType*/,
vcl::KeyCode& /*rKeyCode*/)
{
// not supported yet
return false;
}
LanguageType QtFrame::GetInputLanguage() { return m_nInputLanguage; }
void QtFrame::setInputLanguage(LanguageType nInputLanguage)
{
if (nInputLanguage == m_nInputLanguage)
return;
m_nInputLanguage = nInputLanguage;
CallCallback(SalEvent::InputLanguageChange, nullptr);
}
static Color toColor(const QColor& rColor)
{
return Color(rColor.red(), rColor.green(), rColor.blue());
}
static bool toVclFont(const QFont& rQFont, const css::lang::Locale& rLocale, vcl::Font& rVclFont)
{
FontAttributes aFA;
QtFontFace::fillAttributesFromQFont(rQFont, aFA);
bool bFound = psp::PrintFontManager::get().matchFont(aFA, rLocale);
SAL_INFO("vcl.qt", "font match result for '"
<< rQFont.family() << "': "
<< (bFound ? OUString::Concat("'") + aFA.GetFamilyName() + "'"
: OUString("failed")));
if (!bFound)
return false;
QFontInfo qFontInfo(rQFont);
int nPointHeight = qFontInfo.pointSize();
if (nPointHeight <= 0)
nPointHeight = rQFont.pointSize();
vcl::Font aFont(aFA.GetFamilyName(), Size(0, nPointHeight));
if (aFA.GetWeight() != WEIGHT_DONTKNOW)
aFont.SetWeight(aFA.GetWeight());
if (aFA.GetWidthType() != WIDTH_DONTKNOW)
aFont.SetWidthType(aFA.GetWidthType());
if (aFA.GetItalic() != ITALIC_DONTKNOW)
aFont.SetItalic(aFA.GetItalic());
if (aFA.GetPitch() != PITCH_DONTKNOW)
aFont.SetPitch(aFA.GetPitch());
rVclFont = aFont;
return true;
}
void QtFrame::UpdateSettings(AllSettings& rSettings)
{
if (QtData::noNativeControls())
return;
StyleSettings style(rSettings.GetStyleSettings());
const css::lang::Locale aLocale = rSettings.GetUILanguageTag().getLocale();
// General settings
QPalette pal = QApplication::palette();
style.SetToolbarIconSize(ToolbarIconSize::Large);
Color aFore = toColor(pal.color(QPalette::Active, QPalette::WindowText));
Color aBack = toColor(pal.color(QPalette::Active, QPalette::Window));
Color aText = toColor(pal.color(QPalette::Active, QPalette::Text));
Color aBase = toColor(pal.color(QPalette::Active, QPalette::Base));
Color aButn = toColor(pal.color(QPalette::Active, QPalette::ButtonText));
Color aMid = toColor(pal.color(QPalette::Active, QPalette::Mid));
Color aHigh = toColor(pal.color(QPalette::Active, QPalette::Highlight));
Color aHighText = toColor(pal.color(QPalette::Active, QPalette::HighlightedText));
Color aLink = toColor(pal.color(QPalette::Active, QPalette::Link));
Color aVisitedLink = toColor(pal.color(QPalette::Active, QPalette::LinkVisited));
style.SetSkipDisabledInMenus(true);
// Foreground
style.SetRadioCheckTextColor(aFore);
style.SetLabelTextColor(aFore);
style.SetDialogTextColor(aFore);
style.SetGroupTextColor(aFore);
// Text
style.SetFieldTextColor(aText);
style.SetFieldRolloverTextColor(aText);
style.SetListBoxWindowTextColor(aText);
style.SetWindowTextColor(aText);
style.SetToolTextColor(aText);
// Base
style.SetFieldColor(aBase);
style.SetWindowColor(aBase);
style.SetActiveTabColor(aBase);
style.SetListBoxWindowBackgroundColor(aBase);
style.SetAlternatingRowColor(toColor(pal.color(QPalette::Active, QPalette::AlternateBase)));
// Buttons
style.SetDefaultButtonTextColor(aButn);
style.SetButtonTextColor(aButn);
style.SetDefaultActionButtonTextColor(aButn);
style.SetActionButtonTextColor(aButn);
style.SetFlatButtonTextColor(aButn);
style.SetDefaultButtonRolloverTextColor(aButn);
style.SetButtonRolloverTextColor(aButn);
style.SetDefaultActionButtonRolloverTextColor(aButn);
style.SetActionButtonRolloverTextColor(aButn);
style.SetFlatButtonRolloverTextColor(aButn);
style.SetDefaultButtonPressedRolloverTextColor(aButn);
style.SetButtonPressedRolloverTextColor(aButn);
style.SetDefaultActionButtonPressedRolloverTextColor(aButn);
style.SetActionButtonPressedRolloverTextColor(aButn);
style.SetFlatButtonPressedRolloverTextColor(aButn);
// Tabs
style.SetTabTextColor(aButn);
style.SetTabRolloverTextColor(aButn);
style.SetTabHighlightTextColor(aButn);
// Disable color
style.SetDisableColor(toColor(pal.color(QPalette::Disabled, QPalette::WindowText)));
// Background
style.BatchSetBackgrounds(aBack);
style.SetInactiveTabColor(aBack);
// Workspace
style.SetWorkspaceColor(aMid);
// Selection
// https://invent.kde.org/plasma/plasma-workspace/-/merge_requests/305
style.SetAccentColor(aHigh);
style.SetHighlightColor(aHigh);
style.SetHighlightTextColor(aHighText);
style.SetListBoxWindowHighlightColor(aHigh);
style.SetListBoxWindowHighlightTextColor(aHighText);
style.SetActiveColor(aHigh);
style.SetActiveTextColor(aHighText);
// Links
style.SetLinkColor(aLink);
style.SetVisitedLinkColor(aVisitedLink);
// Tooltip
style.SetHelpColor(toColor(QToolTip::palette().color(QPalette::Active, QPalette::ToolTipBase)));
style.SetHelpTextColor(
toColor(QToolTip::palette().color(QPalette::Active, QPalette::ToolTipText)));
// Menu
std::unique_ptr<QMenuBar> pMenuBar = std::make_unique<QMenuBar>();
QPalette qMenuCG = pMenuBar->palette();
// Menu text and background color, theme specific
Color aMenuFore = toColor(qMenuCG.color(QPalette::WindowText));
Color aMenuBack = toColor(qMenuCG.color(QPalette::Window));
style.SetMenuTextColor(aMenuFore);
style.SetMenuBarTextColor(style.GetPersonaMenuBarTextColor().value_or(aMenuFore));
style.SetMenuColor(aMenuBack);
style.SetMenuBarColor(aMenuBack);
style.SetMenuHighlightColor(toColor(qMenuCG.color(QPalette::Highlight)));
style.SetMenuHighlightTextColor(toColor(qMenuCG.color(QPalette::HighlightedText)));
// set special menubar highlight text color
if (QApplication::style()->inherits("HighContrastStyle"))
ImplGetSVData()->maNWFData.maMenuBarHighlightTextColor
= toColor(qMenuCG.color(QPalette::HighlightedText));
else
ImplGetSVData()->maNWFData.maMenuBarHighlightTextColor = aMenuFore;
// set menubar rollover color
if (pMenuBar->style()->styleHint(QStyle::SH_MenuBar_MouseTracking))
{
style.SetMenuBarRolloverColor(toColor(qMenuCG.color(QPalette::Highlight)));
style.SetMenuBarRolloverTextColor(ImplGetSVData()->maNWFData.maMenuBarHighlightTextColor);
}
else
{
style.SetMenuBarRolloverColor(aMenuBack);
style.SetMenuBarRolloverTextColor(aMenuFore);
}
style.SetMenuBarHighlightTextColor(style.GetMenuHighlightTextColor());
// Default fonts
vcl::Font aFont;
if (toVclFont(QApplication::font(), aLocale, aFont))
{
style.BatchSetFonts(aFont, aFont);
aFont.SetWeight(WEIGHT_BOLD);
style.SetTitleFont(aFont);
style.SetFloatTitleFont(aFont);
}
// Tooltip font
if (toVclFont(QToolTip::font(), aLocale, aFont))
style.SetHelpFont(aFont);
// Menu bar font
if (toVclFont(pMenuBar->font(), aLocale, aFont))
style.SetMenuFont(aFont);
// Icon theme
const bool bPreferDarkTheme = GetUseDarkMode();
tdf#156894 qt: Prefer dark icon theme in dark mode When in dark mode, pass the param to prefer a dark icon theme to `StyleSettings::SetPreferredIconTheme`. For Qt >= 6.5 use `QStyleHints::colorScheme` introduced in Qt 6.5 to get the color scheme. For older Qt versions, use the same algorithm based on the gray value of the window background as xdg-desktop-portal-kde does for evaluating whether a light or dark color scheme is preferred [1]. On my Debian testing, the Breeze dark icon theme is now used as expected with kf5 or qt6 when setting the Global KDE Plasma theme to "Breeze Dark" and manually setting the Icon theme to "GNOME" afterwards. Previously, this would not use a dark icon theme and icons would be hard to see. Without manually setting the icon theme to "GNOME", the Breeze Dark icon theme would already be used before, because selecting "Breeze Dark" as the global KDE Plasma theme also selects the "Breeze Dark" icon theme by default, and therefore "breeze-dark" was already passed as the first param to `StyleSettings::SetPreferredIconTheme` and since that icon theme is present, the `bPreferDarkTheme` wouldn't be evaluated at all; it's only used when determining the fallback icon theme when the specified icon theme is not present. (Likewise, by enabling the "Breeze Dark" global theme and then manually setting the icon theme to "Breeze" in Plasma System settings, the Breeze light icon theme will be used in LibreOffice as well, resulting in hard to see icons, but I tend to think that that behavior is correct and works as designed - it's a misconfiguration.) The color scheme is also specified in xdg-desktop-portal (s. commit [2]) and can be retrived via dbus. Example with "Breeze Light" active: $ dbus-send --session --print-reply=literal --reply-timeout=1000 --dest=org.freedesktop.portal.Desktop /org/freedesktop/portal/desktop org.freedesktop.portal.Settings.Read string:'org.freedesktop.appearance' string:'color-scheme' variant variant uint32 2 With "Breeze Dark": $ dbus-send --session --print-reply=literal --reply-timeout=1000 --dest=org.freedesktop.portal.Desktop /org/freedesktop/portal/desktop org.freedesktop.portal.Settings.Read string:'org.freedesktop.appearance' string:'color-scheme' variant variant uint32 1 [1] https://invent.kde.org/plasma/xdg-desktop-portal-kde/-/blob/0a4237549debf9518f8cfbaf531456850c0729bd/src/settings.cpp#L213-227 [2] https://github.com/flatpak/xdg-desktop-portal/commit/d7a304a00697d7d608821253cd013f3b97ac0fb6 Change-Id: I8f347c6e7f775cc55377c5c84481de3051c3cf24 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156465 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2023-09-02 10:12:54 +02:00
style.SetPreferredIconTheme(toOUString(QIcon::themeName()), bPreferDarkTheme);
// Scroll bar size
style.SetScrollBarSize(QApplication::style()->pixelMetric(QStyle::PM_ScrollBarExtent));
style.SetMinThumbSize(QApplication::style()->pixelMetric(QStyle::PM_ScrollBarSliderMin));
// These colors are used for the ruler text and marks
style.SetShadowColor(toColor(pal.color(QPalette::Disabled, QPalette::WindowText)));
style.SetDarkShadowColor(toColor(pal.color(QPalette::Inactive, QPalette::WindowText)));
// Cursor blink interval
int nFlashTime = QApplication::cursorFlashTime();
style.SetCursorBlinkTime(nFlashTime != 0 ? nFlashTime / 2 : STYLE_CURSOR_NOBLINKTIME);
rSettings.SetStyleSettings(style);
}
void QtFrame::Beep() { QApplication::beep(); }
SalFrame::SalPointerState QtFrame::GetPointerState()
{
SalPointerState aState;
aState.maPos = toPoint(QCursor::pos() * devicePixelRatioF());
aState.maPos.Move(-maGeometry.x(), -maGeometry.y());
aState.mnState = GetMouseModCode(QGuiApplication::mouseButtons())
| GetKeyModCode(QGuiApplication::keyboardModifiers());
return aState;
}
KeyIndicatorState QtFrame::GetIndicatorState() { return KeyIndicatorState(); }
void QtFrame::SimulateKeyPress(sal_uInt16 nKeyCode)
{
SAL_WARN("vcl.qt", "missing simulate keypress " << nKeyCode);
}
// don't set QWidget parents; this breaks popups on Wayland, like the LO ComboBox or ColorPicker!
void QtFrame::SetParent(SalFrame* pNewParent) { m_pParent = static_cast<QtFrame*>(pNewParent); }
void QtFrame::SetPluginParent(SystemParentData* /*pNewParent*/)
{
//FIXME: no SetPluginParent impl. for qt5
}
void QtFrame::ResetClipRegion() { m_bNullRegion = true; }
void QtFrame::BeginSetClipRegion(sal_uInt32)
{
m_aRegion = QRegion(QRect(QPoint(0, 0), m_pQWidget->size()));
}
void QtFrame::UnionClipRegion(tools::Long nX, tools::Long nY, tools::Long nWidth,
tools::Long nHeight)
{
m_aRegion
= m_aRegion.united(scaledQRect(QRect(nX, nY, nWidth, nHeight), 1 / devicePixelRatioF()));
}
void QtFrame::EndSetClipRegion() { m_bNullRegion = false; }
void QtFrame::SetScreenNumber(unsigned int nScreen)
{
if (!isWindow())
return;
QWindow* const pWindow = windowHandle();
if (!pWindow)
return;
QList<QScreen*> screens = QApplication::screens();
if (static_cast<int>(nScreen) < screens.size() || m_bFullScreenSpanAll)
{
QRect screenGeo;
if (!m_bFullScreenSpanAll)
{
screenGeo = QGuiApplication::screens().at(nScreen)->geometry();
pWindow->setScreen(QApplication::screens()[nScreen]);
}
else // special case: fullscreen over all available screens
{
assert(m_bFullScreen);
// left-most screen
QScreen* pScreen = QGuiApplication::screenAt(QPoint(0, 0));
// entire virtual desktop
screenGeo = pScreen->availableVirtualGeometry();
pWindow->setScreen(pScreen);
pWindow->setGeometry(screenGeo);
nScreen = screenNumber(pScreen);
}
// setScreen by itself has no effect, explicitly move the widget to
// the new screen
asChild()->move(screenGeo.topLeft());
}
else
{
// index outta bounds, use primary screen
QScreen* primaryScreen = QApplication::primaryScreen();
pWindow->setScreen(primaryScreen);
nScreen = static_cast<sal_uInt32>(screenNumber(primaryScreen));
}
maGeometry.setScreen(nScreen);
}
void QtFrame::SetApplicationID(const OUString& rWMClass)
{
#if CHECK_QT5_USING_X11
assert(m_aSystemData.platform != SystemEnvData::Platform::Invalid);
if (m_aSystemData.platform != SystemEnvData::Platform::Xcb || !m_pTopLevel)
return;
QtX11Support::setApplicationID(m_pTopLevel->winId(), rWMClass);
#else
Q_UNUSED(rWMClass);
#endif
}
void QtFrame::ResolveWindowHandle(SystemEnvData& rData) const
{
if (!rData.pWidget)
return;
assert(rData.platform != SystemEnvData::Platform::Invalid);
if (rData.platform != SystemEnvData::Platform::Wayland)
rData.SetWindowHandle(static_cast<QWidget*>(rData.pWidget)->winId());
}
tdf#155414 kf a11y: Honor KDE Plasma setting to reduce animation When using the kf5/kf6 VCL plugin on KDE Plasma, use the animation speed setting to determine whether animations should be disabled, in line with what is documented in MDN docs for Firefox using for the "prefers-reduced-motion" CSS media feature [1] and how kde-gtk-config maps that to the "gtk-enable-animations" setting [2]. The setting can be set as described in [2]: > In Plasma/KDE: System Settings > Workspace Behavior -> General Behavior > > "Animation speed" is set all the way to right to "Instant". On top of commit 9d68c794d67259a38de1465090f6f1e7fb588d62 Author: Patrick Luby <plubius@neooffice.org> Date: Fri Jul 21 19:55:02 2023 -0400 tdf#155414 include system "reduce animation" preferences , this basically implements the KF5/KDE Plasma equivalent of what that change does for macOS. Other than Gtk, Qt does not seem to have a general way to specify that animations should be reduced/disabled, so evaluate that based on the desktop environment instead, and implement for KDE Plasma for the kf5/kf6 VCL plugin only for now, which is probably the most common use case. Logically, this would better fit in the qt5/qt6 VCL plugin than the kf5/kf6 one, but do it in the KF-specific code to avoid a dependency on KF5/KF6 libraries in qt5/qt6. (And other than qt5/qt6, kf5/kf6 are auto-selected in Qt-based desktop environments, so it shouldn't make much of a difference in practice.) Another alternative - should the need aries - might be to move this from the VCL plugin to the desktop backend (`shell/source/backends/kf5be/` for the case of KDE Plasma 5.) and introduce a new property for that. [1] https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion [2] https://docs.gtk.org/gtk4/property.Settings.gtk-enable-animations.html [3] https://invent.kde.org/plasma/kde-gtk-config/-/blob/881ae01ad361a03396f7f327365f225ef87688e8/kded/gtkconfig.cpp#L205 Change-Id: I35cd6c2568a3716491581e51dfaeaf32cad454aa Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154888 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2023-07-25 11:52:32 +02:00
bool QtFrame::GetUseReducedAnimation() const { return GetQtInstance()->GetUseReducedAnimation(); }
// Drag'n'drop foo
void QtFrame::registerDragSource(QtDragSource* pDragSource)
{
assert(!m_pDragSource);
m_pDragSource = pDragSource;
}
void QtFrame::deregisterDragSource(QtDragSource const* pDragSource)
{
assert(m_pDragSource == pDragSource);
(void)pDragSource;
m_pDragSource = nullptr;
}
void QtFrame::registerDropTarget(QtDropTarget* pDropTarget)
{
assert(!m_pDropTarget);
m_pDropTarget = pDropTarget;
qt: Set window title etc. in main thread These QWidget methods need to be called in the main thread. Otherwise, opening the Update dialog ("Help" -> "Check for Updates", enabled by `--enable-online-update` autogen switch) triggers asserts like the one below with a self-compiled Qt 6 development build (qtbase dev branch as of c802a9e987c9e38c01580f467eab92a651b3e033). ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 0x0x7fff780160e0. Receiver '' (of type 'QtWidget') was created in thread 0x0x5555555fcd30", file /home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp, line 537 Thread 40 "InitUpdateCheck" received signal SIGABRT, Aborted. [Switching to Thread 0x7fff7ffff6c0 (LWP 1516868)] __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44 44 ./nptl/pthread_kill.c: No such file or directory. (gdb) bt #0 __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44 #1 0x00007ffff78a815f in __pthread_kill_internal (signo=6, threadid=<optimized out>) at ./nptl/pthread_kill.c:78 #2 0x00007ffff785a472 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26 #3 0x00007ffff78444b2 in __GI_abort () at ./stdlib/abort.c:79 #4 0x00007fffe32eb45a in qAbort() () at /home/michi/development/git/qt5/qtbase/src/corelib/global/qglobal.cpp:161 #5 0x00007fffe32f9ee5 in qt_message_fatal(QtMsgType, QMessageLogContext const&, QString const&) (context=..., message=...) at /home/michi/development/git/qt5/qtbase/src/corelib/global/qlogging.cpp:2057 #6 0x00007fffe32f620c in QMessageLogger::fatal(char const*, ...) const (this=0x7fff7fffb980, msg=0x7fffe37fd9a0 "ASSERT failure in %s: \"%s\", file %s, line %d") at /home/michi/development/git/qt5/qtbase/src/corelib/global/qlogging.cpp:938 #7 0x00007fffe32e9d54 in qt_assert_x(char const*, char const*, char const*, int) (where=0x7fffe38131e9 "QCoreApplication::sendEvent", what=0x7fff78180110 "Cannot send events to objects owned by a different thread. Current thread 0x0x7fff780160e0. Receiver '' (of type 'QtWidget') was created in thread 0x0x5555555fcd30", file=0x7fffe3812e18 "/home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp", line=537) at /home/michi/development/git/qt5/qtbase/src/corelib/global/qassert.cpp:77 #8 0x00007fffe33a4d74 in QCoreApplicationPrivate::checkReceiverThread(QObject*) (receiver=0x55555d27d5d0) at /home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:537 #9 0x00007fffe19a3a81 in QApplication::notify(QObject*, QEvent*) (this=0x5555555fcb80, receiver=0x55555d27d5d0, e=0x7fff7fffc0b0) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qapplication.cpp:2584 #10 0x00007fffe33a5ed0 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x55555d27d5d0, event=0x7fff7fffc0b0) at /home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1125 #11 0x00007fffe33a6991 in QCoreApplication::sendEvent(QObject*, QEvent*) (receiver=0x55555d27d5d0, event=0x7fff7fffc0b0) at /home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1559 #12 0x00007fffe1a279b4 in QWidget::setWindowTitle(QString const&) (this=0x55555d27d5d0, title=...) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qwidget.cpp:6119 #13 0x00007fffe3c9d4c4 in QtFrame::SetTitle(rtl::OUString const&) (this=0x555555619d20, rTitle="Check for Updates") at /home/michi/development/git/libreoffice/vcl/qt6/../qt5/QtFrame.cxx:365 #14 0x00007fffedd98d44 in vcl::Window::SetText(rtl::OUString const&) (this=0x7fff7803cd90, rStr="Check for Updates") at /home/michi/development/git/libreoffice/vcl/source/window/window.cxx:3042 #15 0x00007fffedd311c9 in SystemWindow::SetText(rtl::OUString const&) (this=0x7fff7803cd90, rStr="Check for Updates") at /home/michi/development/git/libreoffice/vcl/source/window/syswin.cxx:1048 #16 0x00007ffff048bd6b in VCLXWindow::setProperty(rtl::OUString const&, com::sun::star::uno::Any const&) (this=0x7fff7804ac00, PropertyName="Title", Value=uno::Any("string": "Check for Updates")) at /home/michi/development/git/libreoffice/toolkit/source/awt/vclxwindow.cxx:1515 #17 0x00007ffff03e486d in VCLXContainer::setProperty(rtl::OUString const&, com::sun::star::uno::Any const&) (this=0x7fff7804ac00, PropertyName="Title", Value=uno::Any("string": "Check for Updates")) at /home/michi/development/git/libreoffice/toolkit/source/awt/vclxcontainer.cxx:260 #18 0x00007ffff04dfa2c in VCLXDialog::setProperty(rtl::OUString const&, com::sun::star::uno::Any const&) (this=0x7fff7804ac00, PropertyName="Title", Value=uno::Any("string": "Check for Updates")) at /home/michi/development/git/libreoffice/toolkit/source/awt/vclxwindows.cxx:2364 #19 0x00007ffff06a89b7 in UnoControl::ImplSetPeerProperty(rtl::OUString const&, com::sun::star::uno::Any const&) (this=0x7fff7803b4f0, rPropName="Title", rVal=uno::Any("string": "Check for Updates")) at /home/michi/development/git/libreoffice/toolkit/source/controls/unocontrol.cxx:288 #20 0x00007ffff06aa701 in UnoControl::ImplModelPropertiesChanged(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyChangeEvent> const&) (this=0x7fff7803b4f0, rEvents=uno::Sequence of length 51 = {...}) at /home/michi/development/git/libreoffice/toolkit/source/controls/unocontrol.cxx:649 #21 0x00007ffff0531ae9 in ControlContainerBase::ImplModelPropertiesChanged(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyChangeEvent> const&) (this=0x7fff7803b4f0, rEvents=uno::Sequence of length 51 = {...}) at /home/michi/development/git/libreoffice/toolkit/source/controls/controlmodelcontainerbase.cxx:1600 #22 0x00007ffff0575a25 in UnoDialogControl::ImplModelPropertiesChanged(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyChangeEvent> const&) (this=0x7fff7803b4f0, rEvents=uno::Sequence of length 51 = {...}) at /home/michi/development/git/libreoffice/toolkit/source/controls/dialogcontrol.cxx:651 #23 0x00007ffff06a95f3 in UnoControl::propertiesChange(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyChangeEvent> const&) (this=0x7fff7803b4f0, rEvents=uno::Sequence of length 51 = {...}) at /home/michi/development/git/libreoffice/toolkit/source/controls/unocontrol.cxx:431 #24 0x00007ffff66bc4ee in cppu::OPropertySetHelper::firePropertiesChangeEvent(com::sun::star::uno::Sequence<rtl::OUString> const&, com::sun::star::uno::Reference<com::sun::star::beans::XPropertiesChangeListener> const&) (this=0x7fff78006170, rPropertyNames=uno::Sequence of length 51 = {...}, rListener=uno::Reference to (UnoDialogControl *) 0x7fff7803b540) at /home/michi/development/git/libreoffice/cppuhelper/source/propshlp.cxx:961 #25 0x00007ffff06a8c6b in UnoControl::updateFromModel() (this=0x7fff7803b4f0) at /home/michi/development/git/libreoffice/toolkit/source/controls/unocontrol.cxx:320 #26 0x00007ffff06aefc9 in UnoControl::createPeer(com::sun::star::uno::Reference<com::sun::star::awt::XToolkit> const&, com::sun::star::uno::Reference<com::sun::star::awt::XWindowPeer> const&) (this=0x7fff7803b4f0, rxToolkit=empty uno::Reference, rParentPeer=empty uno::Reference) at /home/michi/development/git/libreoffice/toolkit/source/controls/unocontrol.cxx:1325 #27 0x00007ffff06c9905 in UnoControlContainer::createPeer(com::sun::star::uno::Reference<com::sun::star::awt::XToolkit> const&, com::sun::star::uno::Reference<com::sun::star::awt::XWindowPeer> const&) (this=0x7fff7803b4f0, rxToolkit=empty uno::Reference, rParent=empty uno::Reference) at /home/michi/development/git/libreoffice/toolkit/source/controls/unocontrolcontainer.cxx:727 #28 0x00007ffff057336d in UnoDialogControl::createPeer(com::sun::star::uno::Reference<com::sun::star::awt::XToolkit> const&, com::sun::star::uno::Reference<com::sun::star::awt::XWindowPeer> const&) (this=0x7fff7803b4f0, rxToolkit=empty uno::Reference, rParentPeer=empty uno::Reference) at /home/michi/development/git/libreoffice/toolkit/source/controls/dialogcontrol.cxx:358 #29 0x00007fffb7264e62 in UpdateHandler::createDialog() (this=0x7fff78003aa0) at /home/michi/development/git/libreoffice/extensions/source/update/check/updatehdl.cxx:1232 #30 0x00007fffb725b0e1 in UpdateHandler::setVisible(bool) (this=0x7fff78003aa0, bVisible=true) at /home/michi/development/git/libreoffice/extensions/source/update/check/updatehdl.cxx:188 #31 0x00007fffb7235887 in UpdateCheck::showDialog(bool) (this=0x7fff78000b90, forceCheck=true) at /home/michi/development/git/libreoffice/extensions/source/update/check/updatecheck.cxx:1171 #32 0x00007fffb7255c5e in (anonymous namespace)::InitUpdateCheckJobThread::run() (this=0x55555d192690) at /home/michi/development/git/libreoffice/extensions/source/update/check/updatecheckjob.cxx:148 #33 0x00007fffb723a74a in osl::threadFunc(void*) (param=0x55555d192690) at /home/michi/development/git/libreoffice/include/osl/thread.hxx:189 #34 0x00007ffff7f3f693 in osl_thread_start_Impl(void*) (pData=0x55555d1a68b0) at /home/michi/development/git/libreoffice/sal/osl/unx/thread.cxx:237 #35 0x00007ffff78a63ec in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:444 #36 0x00007ffff7926a1c in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81 Change-Id: I6ccdee00fe26619f201459ebbe6c4d8cf8b57b45 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156426 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2023-09-01 17:50:19 +02:00
QtInstance* pSalInst(GetQtInstance());
assert(pSalInst);
pSalInst->RunInMainThread([this]() { m_pQWidget->setAcceptDrops(true); });
}
void QtFrame::deregisterDropTarget(QtDropTarget const* pDropTarget)
{
assert(m_pDropTarget == pDropTarget);
(void)pDropTarget;
m_pDropTarget = nullptr;
}
static css::uno::Reference<css::datatransfer::XTransferable>
lcl_getXTransferable(const QMimeData* pMimeData)
{
css::uno::Reference<css::datatransfer::XTransferable> xTransferable;
const QtMimeData* pQtMimeData = dynamic_cast<const QtMimeData*>(pMimeData);
if (!pQtMimeData)
xTransferable = new QtDnDTransferable(pMimeData);
else
xTransferable = pQtMimeData->xTransferable();
return xTransferable;
}
static sal_Int8 lcl_getUserDropAction(const QDropEvent* pEvent, const sal_Int8 nSourceActions,
const QMimeData* pMimeData)
{
qt6: Add a qt6 VCL plugin This adds a new "qt6" VCL plugin based on Qt 6. Building the plugin is enabled by autogen option '--enable-qt6' (and optionally setting 'QT6DIR' as needed). Use the 'SAL_USE_VCLPLUGIN=qt6' environment variable before running LO to select this VCL plugin. Taking qt6 into account at all relevant places certainly still requires follow-up changes, but this builds and runs with a self-compiled qtbase from the 'dev' git branch as of commit 3ce0672143d2eb3c3809f82998a4d71c5800d77a. I didn't see anything obviously broken in a quick run, but didn't test much. This reuses and shares the qt5 VCL plugin code; the qt6 headers and sources for now just '#include' the qt5 ones. Version checks are used for the code places that need different handling to be built against Qt 6. The build system parts in this commit were mostly done by copying the qt5 equivalents, then adapting as needed. Some notes on things I came across while porting to qt6: 1) At least in my self-compiled Qt versions, 'moc' (the meta-object compiler) is located in the 'libexec' subdirectory in 'QT6DIR', while the Qt 5 equivalent is located in the "bin" subdirectory of 'QT5DIR', so the configure.ac check uses the former. 2) moc does not process classes from the included headers. Since the headers in 'vcl/inc/qt6' just '#include' the ones from 'vcl/inc/qt5', running moc on the qt6 headers doesn't work, so moc is currently run on the qt5 headers for qt6 as well (s. 'vcl/CustomTarget_qt6_moc.mk'). That will have to be adapted in case the qt6 VCL plugin uses "own" headers instead of just including the qt5 ones at some point. 3) QX11Extras has been removed from Qt 6. [1] says: > Changes to Qt X11 Extras > > The QX11Info class has been removed. > > Clients that still rely on the functionality can include the private > header <QtGui/private/qtx11extras_p.h> as a stopgap solution. To enable > private headers use QT += core-private with qmake, or add a project > dependency to Qt::CorePrivate with CMake. I didn't take any closer look, just dropped the use of QtX11Extras for qt6 for now. 4) XCB_ICCCM is no longer needed. It is only used in qt5 to workaround a Qt bug fixed in Qt 5.12, s. commit fe2baf9e84e0ca9aeaa683e37076f57fa3f38dca Author: Jan-Marek Glogowski <jan-marek.glogowski@extern.cib.de> Date: Tue Dec 3 08:32:58 2019 +0100 Qt5 fix missing XCB_ICCCM_WM_HINT_WINDOW_GROUP 5) X11-specific code is still used for key modifier handling. Therefore, still check for the XCB headers when 'USING_X11' is set in configure.ac, and use a 'QT6_USING_X11' define (as qt5 uses 'QT5_USING_X11'). 6) There's currently no Qt 6 video sink for GStreamer. As of today, qt-gstreamer is unmaintained and there is no Qt 6 version. The project's README [2] says: > 0. Maintenance Notice > --------------------- > > This code is unmaintained. You can use it at your own risk. > > If you want to integrate video display in your QML-based UI, > you should consider using 'qmlglsink', from gst-plugins-good. > This is a well supported video sink that uses the generic > gstreamer-gl stack and is in many ways superior to 'qtquick2videosink' > that is provided by qt-gstreamer. You can use this code as an example: > https://cgit.freedesktop.org/gstreamer/gst-plugins-good/tree/tests/examples/qt/qmlsink > > If you are not interested in using QML in your UI, then you > may use one of the other elements provided by this module > (see below). If you do that, it would be helpful to let us > know that this code is still useful to you. We may consider > adding these elements in one of the core gstreamer modules. > > If you are here for the Qt-style bindings, I'm sorry to disappoint you. > The alternative is to use the C API, or the GStreamermm C++ API. > Qt-style bindings are cool, but unfortunately they are very hard > to maintain because they are written by hand. If you are interested > in continuing this project, you are welcome to implement a > generator for them, probably based on GObject-Introspection. > I am happy to provide directions if you want to pursue such a thing. Therefore, the Qt video sink handling is qt5-only and the corresponding handling for GOBJECT (used for the GStreamer video sink handling) was not taken over for qt6. This presumably means that video playback in Impress presentations does not work when using qt6 with they Qt Wayland plugin, s. tdf#125219 for the corresponding bug for qt5/kf5. (I did not build the qtwayland module to actually test this, though. Video playback with the Qt xcb plugin in a Wayland session works.) [1] https://doc-snapshots.qt.io/qt6-dev/extras-changes-qt6.html [2] https://cgit.freedesktop.org/gstreamer/qt-gstreamer/tree/README Change-Id: Ib105ccfb2c3630ec5d5403793a3cd9ba31d85bdf Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122808 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-09-29 11:09:51 +02:00
// we completely ignore all proposals by the Qt event, as they don't
// match at all with the preferred LO DnD actions.
// check the key modifiers to detect a user-overridden DnD action
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
const Qt::KeyboardModifiers eKeyMod = pEvent->modifiers();
#else
const Qt::KeyboardModifiers eKeyMod = pEvent->keyboardModifiers();
qt6: Add a qt6 VCL plugin This adds a new "qt6" VCL plugin based on Qt 6. Building the plugin is enabled by autogen option '--enable-qt6' (and optionally setting 'QT6DIR' as needed). Use the 'SAL_USE_VCLPLUGIN=qt6' environment variable before running LO to select this VCL plugin. Taking qt6 into account at all relevant places certainly still requires follow-up changes, but this builds and runs with a self-compiled qtbase from the 'dev' git branch as of commit 3ce0672143d2eb3c3809f82998a4d71c5800d77a. I didn't see anything obviously broken in a quick run, but didn't test much. This reuses and shares the qt5 VCL plugin code; the qt6 headers and sources for now just '#include' the qt5 ones. Version checks are used for the code places that need different handling to be built against Qt 6. The build system parts in this commit were mostly done by copying the qt5 equivalents, then adapting as needed. Some notes on things I came across while porting to qt6: 1) At least in my self-compiled Qt versions, 'moc' (the meta-object compiler) is located in the 'libexec' subdirectory in 'QT6DIR', while the Qt 5 equivalent is located in the "bin" subdirectory of 'QT5DIR', so the configure.ac check uses the former. 2) moc does not process classes from the included headers. Since the headers in 'vcl/inc/qt6' just '#include' the ones from 'vcl/inc/qt5', running moc on the qt6 headers doesn't work, so moc is currently run on the qt5 headers for qt6 as well (s. 'vcl/CustomTarget_qt6_moc.mk'). That will have to be adapted in case the qt6 VCL plugin uses "own" headers instead of just including the qt5 ones at some point. 3) QX11Extras has been removed from Qt 6. [1] says: > Changes to Qt X11 Extras > > The QX11Info class has been removed. > > Clients that still rely on the functionality can include the private > header <QtGui/private/qtx11extras_p.h> as a stopgap solution. To enable > private headers use QT += core-private with qmake, or add a project > dependency to Qt::CorePrivate with CMake. I didn't take any closer look, just dropped the use of QtX11Extras for qt6 for now. 4) XCB_ICCCM is no longer needed. It is only used in qt5 to workaround a Qt bug fixed in Qt 5.12, s. commit fe2baf9e84e0ca9aeaa683e37076f57fa3f38dca Author: Jan-Marek Glogowski <jan-marek.glogowski@extern.cib.de> Date: Tue Dec 3 08:32:58 2019 +0100 Qt5 fix missing XCB_ICCCM_WM_HINT_WINDOW_GROUP 5) X11-specific code is still used for key modifier handling. Therefore, still check for the XCB headers when 'USING_X11' is set in configure.ac, and use a 'QT6_USING_X11' define (as qt5 uses 'QT5_USING_X11'). 6) There's currently no Qt 6 video sink for GStreamer. As of today, qt-gstreamer is unmaintained and there is no Qt 6 version. The project's README [2] says: > 0. Maintenance Notice > --------------------- > > This code is unmaintained. You can use it at your own risk. > > If you want to integrate video display in your QML-based UI, > you should consider using 'qmlglsink', from gst-plugins-good. > This is a well supported video sink that uses the generic > gstreamer-gl stack and is in many ways superior to 'qtquick2videosink' > that is provided by qt-gstreamer. You can use this code as an example: > https://cgit.freedesktop.org/gstreamer/gst-plugins-good/tree/tests/examples/qt/qmlsink > > If you are not interested in using QML in your UI, then you > may use one of the other elements provided by this module > (see below). If you do that, it would be helpful to let us > know that this code is still useful to you. We may consider > adding these elements in one of the core gstreamer modules. > > If you are here for the Qt-style bindings, I'm sorry to disappoint you. > The alternative is to use the C API, or the GStreamermm C++ API. > Qt-style bindings are cool, but unfortunately they are very hard > to maintain because they are written by hand. If you are interested > in continuing this project, you are welcome to implement a > generator for them, probably based on GObject-Introspection. > I am happy to provide directions if you want to pursue such a thing. Therefore, the Qt video sink handling is qt5-only and the corresponding handling for GOBJECT (used for the GStreamer video sink handling) was not taken over for qt6. This presumably means that video playback in Impress presentations does not work when using qt6 with they Qt Wayland plugin, s. tdf#125219 for the corresponding bug for qt5/kf5. (I did not build the qtwayland module to actually test this, though. Video playback with the Qt xcb plugin in a Wayland session works.) [1] https://doc-snapshots.qt.io/qt6-dev/extras-changes-qt6.html [2] https://cgit.freedesktop.org/gstreamer/qt-gstreamer/tree/README Change-Id: Ib105ccfb2c3630ec5d5403793a3cd9ba31d85bdf Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122808 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-09-29 11:09:51 +02:00
#endif
sal_Int8 nUserDropAction = 0;
if ((eKeyMod & Qt::ShiftModifier) && !(eKeyMod & Qt::ControlModifier))
nUserDropAction = css::datatransfer::dnd::DNDConstants::ACTION_MOVE;
else if ((eKeyMod & Qt::ControlModifier) && !(eKeyMod & Qt::ShiftModifier))
nUserDropAction = css::datatransfer::dnd::DNDConstants::ACTION_COPY;
else if ((eKeyMod & Qt::ShiftModifier) && (eKeyMod & Qt::ControlModifier))
nUserDropAction = css::datatransfer::dnd::DNDConstants::ACTION_LINK;
nUserDropAction &= nSourceActions;
// select the default DnD action, if there isn't a user preference
if (0 == nUserDropAction)
{
// default LO internal action is move, but default external action is copy
nUserDropAction = dynamic_cast<const QtMimeData*>(pMimeData)
? css::datatransfer::dnd::DNDConstants::ACTION_MOVE
: css::datatransfer::dnd::DNDConstants::ACTION_COPY;
nUserDropAction &= nSourceActions;
// if the default doesn't match any allowed source action, fall back to the
// preferred of all allowed source actions
if (0 == nUserDropAction)
nUserDropAction = toVclDropAction(getPreferredDropAction(nSourceActions));
// this is "our" preference, but actually we would even prefer any default,
// if there is any
nUserDropAction |= css::datatransfer::dnd::DNDConstants::ACTION_DEFAULT;
}
return nUserDropAction;
}
void QtFrame::handleDragMove(QDragMoveEvent* pEvent)
{
assert(m_pDropTarget);
// prepare our suggested drop action for the drop target
const sal_Int8 nSourceActions = toVclDropActions(pEvent->possibleActions());
const QMimeData* pMimeData = pEvent->mimeData();
const sal_Int8 nUserDropAction = lcl_getUserDropAction(pEvent, nSourceActions, pMimeData);
qt6: Add a qt6 VCL plugin This adds a new "qt6" VCL plugin based on Qt 6. Building the plugin is enabled by autogen option '--enable-qt6' (and optionally setting 'QT6DIR' as needed). Use the 'SAL_USE_VCLPLUGIN=qt6' environment variable before running LO to select this VCL plugin. Taking qt6 into account at all relevant places certainly still requires follow-up changes, but this builds and runs with a self-compiled qtbase from the 'dev' git branch as of commit 3ce0672143d2eb3c3809f82998a4d71c5800d77a. I didn't see anything obviously broken in a quick run, but didn't test much. This reuses and shares the qt5 VCL plugin code; the qt6 headers and sources for now just '#include' the qt5 ones. Version checks are used for the code places that need different handling to be built against Qt 6. The build system parts in this commit were mostly done by copying the qt5 equivalents, then adapting as needed. Some notes on things I came across while porting to qt6: 1) At least in my self-compiled Qt versions, 'moc' (the meta-object compiler) is located in the 'libexec' subdirectory in 'QT6DIR', while the Qt 5 equivalent is located in the "bin" subdirectory of 'QT5DIR', so the configure.ac check uses the former. 2) moc does not process classes from the included headers. Since the headers in 'vcl/inc/qt6' just '#include' the ones from 'vcl/inc/qt5', running moc on the qt6 headers doesn't work, so moc is currently run on the qt5 headers for qt6 as well (s. 'vcl/CustomTarget_qt6_moc.mk'). That will have to be adapted in case the qt6 VCL plugin uses "own" headers instead of just including the qt5 ones at some point. 3) QX11Extras has been removed from Qt 6. [1] says: > Changes to Qt X11 Extras > > The QX11Info class has been removed. > > Clients that still rely on the functionality can include the private > header <QtGui/private/qtx11extras_p.h> as a stopgap solution. To enable > private headers use QT += core-private with qmake, or add a project > dependency to Qt::CorePrivate with CMake. I didn't take any closer look, just dropped the use of QtX11Extras for qt6 for now. 4) XCB_ICCCM is no longer needed. It is only used in qt5 to workaround a Qt bug fixed in Qt 5.12, s. commit fe2baf9e84e0ca9aeaa683e37076f57fa3f38dca Author: Jan-Marek Glogowski <jan-marek.glogowski@extern.cib.de> Date: Tue Dec 3 08:32:58 2019 +0100 Qt5 fix missing XCB_ICCCM_WM_HINT_WINDOW_GROUP 5) X11-specific code is still used for key modifier handling. Therefore, still check for the XCB headers when 'USING_X11' is set in configure.ac, and use a 'QT6_USING_X11' define (as qt5 uses 'QT5_USING_X11'). 6) There's currently no Qt 6 video sink for GStreamer. As of today, qt-gstreamer is unmaintained and there is no Qt 6 version. The project's README [2] says: > 0. Maintenance Notice > --------------------- > > This code is unmaintained. You can use it at your own risk. > > If you want to integrate video display in your QML-based UI, > you should consider using 'qmlglsink', from gst-plugins-good. > This is a well supported video sink that uses the generic > gstreamer-gl stack and is in many ways superior to 'qtquick2videosink' > that is provided by qt-gstreamer. You can use this code as an example: > https://cgit.freedesktop.org/gstreamer/gst-plugins-good/tree/tests/examples/qt/qmlsink > > If you are not interested in using QML in your UI, then you > may use one of the other elements provided by this module > (see below). If you do that, it would be helpful to let us > know that this code is still useful to you. We may consider > adding these elements in one of the core gstreamer modules. > > If you are here for the Qt-style bindings, I'm sorry to disappoint you. > The alternative is to use the C API, or the GStreamermm C++ API. > Qt-style bindings are cool, but unfortunately they are very hard > to maintain because they are written by hand. If you are interested > in continuing this project, you are welcome to implement a > generator for them, probably based on GObject-Introspection. > I am happy to provide directions if you want to pursue such a thing. Therefore, the Qt video sink handling is qt5-only and the corresponding handling for GOBJECT (used for the GStreamer video sink handling) was not taken over for qt6. This presumably means that video playback in Impress presentations does not work when using qt6 with they Qt Wayland plugin, s. tdf#125219 for the corresponding bug for qt5/kf5. (I did not build the qtwayland module to actually test this, though. Video playback with the Qt xcb plugin in a Wayland session works.) [1] https://doc-snapshots.qt.io/qt6-dev/extras-changes-qt6.html [2] https://cgit.freedesktop.org/gstreamer/qt-gstreamer/tree/README Change-Id: Ib105ccfb2c3630ec5d5403793a3cd9ba31d85bdf Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122808 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-09-29 11:09:51 +02:00
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
const Point aPos = toPoint(pEvent->position().toPoint() * devicePixelRatioF());
#else
const Point aPos = toPoint(pEvent->pos() * devicePixelRatioF());
qt6: Add a qt6 VCL plugin This adds a new "qt6" VCL plugin based on Qt 6. Building the plugin is enabled by autogen option '--enable-qt6' (and optionally setting 'QT6DIR' as needed). Use the 'SAL_USE_VCLPLUGIN=qt6' environment variable before running LO to select this VCL plugin. Taking qt6 into account at all relevant places certainly still requires follow-up changes, but this builds and runs with a self-compiled qtbase from the 'dev' git branch as of commit 3ce0672143d2eb3c3809f82998a4d71c5800d77a. I didn't see anything obviously broken in a quick run, but didn't test much. This reuses and shares the qt5 VCL plugin code; the qt6 headers and sources for now just '#include' the qt5 ones. Version checks are used for the code places that need different handling to be built against Qt 6. The build system parts in this commit were mostly done by copying the qt5 equivalents, then adapting as needed. Some notes on things I came across while porting to qt6: 1) At least in my self-compiled Qt versions, 'moc' (the meta-object compiler) is located in the 'libexec' subdirectory in 'QT6DIR', while the Qt 5 equivalent is located in the "bin" subdirectory of 'QT5DIR', so the configure.ac check uses the former. 2) moc does not process classes from the included headers. Since the headers in 'vcl/inc/qt6' just '#include' the ones from 'vcl/inc/qt5', running moc on the qt6 headers doesn't work, so moc is currently run on the qt5 headers for qt6 as well (s. 'vcl/CustomTarget_qt6_moc.mk'). That will have to be adapted in case the qt6 VCL plugin uses "own" headers instead of just including the qt5 ones at some point. 3) QX11Extras has been removed from Qt 6. [1] says: > Changes to Qt X11 Extras > > The QX11Info class has been removed. > > Clients that still rely on the functionality can include the private > header <QtGui/private/qtx11extras_p.h> as a stopgap solution. To enable > private headers use QT += core-private with qmake, or add a project > dependency to Qt::CorePrivate with CMake. I didn't take any closer look, just dropped the use of QtX11Extras for qt6 for now. 4) XCB_ICCCM is no longer needed. It is only used in qt5 to workaround a Qt bug fixed in Qt 5.12, s. commit fe2baf9e84e0ca9aeaa683e37076f57fa3f38dca Author: Jan-Marek Glogowski <jan-marek.glogowski@extern.cib.de> Date: Tue Dec 3 08:32:58 2019 +0100 Qt5 fix missing XCB_ICCCM_WM_HINT_WINDOW_GROUP 5) X11-specific code is still used for key modifier handling. Therefore, still check for the XCB headers when 'USING_X11' is set in configure.ac, and use a 'QT6_USING_X11' define (as qt5 uses 'QT5_USING_X11'). 6) There's currently no Qt 6 video sink for GStreamer. As of today, qt-gstreamer is unmaintained and there is no Qt 6 version. The project's README [2] says: > 0. Maintenance Notice > --------------------- > > This code is unmaintained. You can use it at your own risk. > > If you want to integrate video display in your QML-based UI, > you should consider using 'qmlglsink', from gst-plugins-good. > This is a well supported video sink that uses the generic > gstreamer-gl stack and is in many ways superior to 'qtquick2videosink' > that is provided by qt-gstreamer. You can use this code as an example: > https://cgit.freedesktop.org/gstreamer/gst-plugins-good/tree/tests/examples/qt/qmlsink > > If you are not interested in using QML in your UI, then you > may use one of the other elements provided by this module > (see below). If you do that, it would be helpful to let us > know that this code is still useful to you. We may consider > adding these elements in one of the core gstreamer modules. > > If you are here for the Qt-style bindings, I'm sorry to disappoint you. > The alternative is to use the C API, or the GStreamermm C++ API. > Qt-style bindings are cool, but unfortunately they are very hard > to maintain because they are written by hand. If you are interested > in continuing this project, you are welcome to implement a > generator for them, probably based on GObject-Introspection. > I am happy to provide directions if you want to pursue such a thing. Therefore, the Qt video sink handling is qt5-only and the corresponding handling for GOBJECT (used for the GStreamer video sink handling) was not taken over for qt6. This presumably means that video playback in Impress presentations does not work when using qt6 with they Qt Wayland plugin, s. tdf#125219 for the corresponding bug for qt5/kf5. (I did not build the qtwayland module to actually test this, though. Video playback with the Qt xcb plugin in a Wayland session works.) [1] https://doc-snapshots.qt.io/qt6-dev/extras-changes-qt6.html [2] https://cgit.freedesktop.org/gstreamer/qt-gstreamer/tree/README Change-Id: Ib105ccfb2c3630ec5d5403793a3cd9ba31d85bdf Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122808 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-09-29 11:09:51 +02:00
#endif
css::datatransfer::dnd::DropTargetDragEnterEvent aEvent;
aEvent.Source = static_cast<css::datatransfer::dnd::XDropTarget*>(m_pDropTarget);
aEvent.Context = static_cast<css::datatransfer::dnd::XDropTargetDragContext*>(m_pDropTarget);
aEvent.LocationX = aPos.X();
aEvent.LocationY = aPos.Y();
aEvent.DropAction = nUserDropAction;
aEvent.SourceActions = nSourceActions;
// ask the drop target to accept our drop action
if (!m_bInDrag)
{
aEvent.SupportedDataFlavors = lcl_getXTransferable(pMimeData)->getTransferDataFlavors();
m_pDropTarget->fire_dragEnter(aEvent);
m_bInDrag = true;
}
else
m_pDropTarget->fire_dragOver(aEvent);
// the drop target accepted our drop action => inform Qt
if (m_pDropTarget->proposedDropAction() != 0)
{
pEvent->setDropAction(getPreferredDropAction(m_pDropTarget->proposedDropAction()));
pEvent->accept();
}
else // or maybe someone else likes it?
pEvent->ignore();
}
void QtFrame::handleDrop(QDropEvent* pEvent)
{
assert(m_pDropTarget);
// prepare our suggested drop action for the drop target
const sal_Int8 nSourceActions = toVclDropActions(pEvent->possibleActions());
const sal_Int8 nUserDropAction
= lcl_getUserDropAction(pEvent, nSourceActions, pEvent->mimeData());
qt6: Add a qt6 VCL plugin This adds a new "qt6" VCL plugin based on Qt 6. Building the plugin is enabled by autogen option '--enable-qt6' (and optionally setting 'QT6DIR' as needed). Use the 'SAL_USE_VCLPLUGIN=qt6' environment variable before running LO to select this VCL plugin. Taking qt6 into account at all relevant places certainly still requires follow-up changes, but this builds and runs with a self-compiled qtbase from the 'dev' git branch as of commit 3ce0672143d2eb3c3809f82998a4d71c5800d77a. I didn't see anything obviously broken in a quick run, but didn't test much. This reuses and shares the qt5 VCL plugin code; the qt6 headers and sources for now just '#include' the qt5 ones. Version checks are used for the code places that need different handling to be built against Qt 6. The build system parts in this commit were mostly done by copying the qt5 equivalents, then adapting as needed. Some notes on things I came across while porting to qt6: 1) At least in my self-compiled Qt versions, 'moc' (the meta-object compiler) is located in the 'libexec' subdirectory in 'QT6DIR', while the Qt 5 equivalent is located in the "bin" subdirectory of 'QT5DIR', so the configure.ac check uses the former. 2) moc does not process classes from the included headers. Since the headers in 'vcl/inc/qt6' just '#include' the ones from 'vcl/inc/qt5', running moc on the qt6 headers doesn't work, so moc is currently run on the qt5 headers for qt6 as well (s. 'vcl/CustomTarget_qt6_moc.mk'). That will have to be adapted in case the qt6 VCL plugin uses "own" headers instead of just including the qt5 ones at some point. 3) QX11Extras has been removed from Qt 6. [1] says: > Changes to Qt X11 Extras > > The QX11Info class has been removed. > > Clients that still rely on the functionality can include the private > header <QtGui/private/qtx11extras_p.h> as a stopgap solution. To enable > private headers use QT += core-private with qmake, or add a project > dependency to Qt::CorePrivate with CMake. I didn't take any closer look, just dropped the use of QtX11Extras for qt6 for now. 4) XCB_ICCCM is no longer needed. It is only used in qt5 to workaround a Qt bug fixed in Qt 5.12, s. commit fe2baf9e84e0ca9aeaa683e37076f57fa3f38dca Author: Jan-Marek Glogowski <jan-marek.glogowski@extern.cib.de> Date: Tue Dec 3 08:32:58 2019 +0100 Qt5 fix missing XCB_ICCCM_WM_HINT_WINDOW_GROUP 5) X11-specific code is still used for key modifier handling. Therefore, still check for the XCB headers when 'USING_X11' is set in configure.ac, and use a 'QT6_USING_X11' define (as qt5 uses 'QT5_USING_X11'). 6) There's currently no Qt 6 video sink for GStreamer. As of today, qt-gstreamer is unmaintained and there is no Qt 6 version. The project's README [2] says: > 0. Maintenance Notice > --------------------- > > This code is unmaintained. You can use it at your own risk. > > If you want to integrate video display in your QML-based UI, > you should consider using 'qmlglsink', from gst-plugins-good. > This is a well supported video sink that uses the generic > gstreamer-gl stack and is in many ways superior to 'qtquick2videosink' > that is provided by qt-gstreamer. You can use this code as an example: > https://cgit.freedesktop.org/gstreamer/gst-plugins-good/tree/tests/examples/qt/qmlsink > > If you are not interested in using QML in your UI, then you > may use one of the other elements provided by this module > (see below). If you do that, it would be helpful to let us > know that this code is still useful to you. We may consider > adding these elements in one of the core gstreamer modules. > > If you are here for the Qt-style bindings, I'm sorry to disappoint you. > The alternative is to use the C API, or the GStreamermm C++ API. > Qt-style bindings are cool, but unfortunately they are very hard > to maintain because they are written by hand. If you are interested > in continuing this project, you are welcome to implement a > generator for them, probably based on GObject-Introspection. > I am happy to provide directions if you want to pursue such a thing. Therefore, the Qt video sink handling is qt5-only and the corresponding handling for GOBJECT (used for the GStreamer video sink handling) was not taken over for qt6. This presumably means that video playback in Impress presentations does not work when using qt6 with they Qt Wayland plugin, s. tdf#125219 for the corresponding bug for qt5/kf5. (I did not build the qtwayland module to actually test this, though. Video playback with the Qt xcb plugin in a Wayland session works.) [1] https://doc-snapshots.qt.io/qt6-dev/extras-changes-qt6.html [2] https://cgit.freedesktop.org/gstreamer/qt-gstreamer/tree/README Change-Id: Ib105ccfb2c3630ec5d5403793a3cd9ba31d85bdf Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122808 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-09-29 11:09:51 +02:00
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
const Point aPos = toPoint(pEvent->position().toPoint() * devicePixelRatioF());
#else
const Point aPos = toPoint(pEvent->pos() * devicePixelRatioF());
qt6: Add a qt6 VCL plugin This adds a new "qt6" VCL plugin based on Qt 6. Building the plugin is enabled by autogen option '--enable-qt6' (and optionally setting 'QT6DIR' as needed). Use the 'SAL_USE_VCLPLUGIN=qt6' environment variable before running LO to select this VCL plugin. Taking qt6 into account at all relevant places certainly still requires follow-up changes, but this builds and runs with a self-compiled qtbase from the 'dev' git branch as of commit 3ce0672143d2eb3c3809f82998a4d71c5800d77a. I didn't see anything obviously broken in a quick run, but didn't test much. This reuses and shares the qt5 VCL plugin code; the qt6 headers and sources for now just '#include' the qt5 ones. Version checks are used for the code places that need different handling to be built against Qt 6. The build system parts in this commit were mostly done by copying the qt5 equivalents, then adapting as needed. Some notes on things I came across while porting to qt6: 1) At least in my self-compiled Qt versions, 'moc' (the meta-object compiler) is located in the 'libexec' subdirectory in 'QT6DIR', while the Qt 5 equivalent is located in the "bin" subdirectory of 'QT5DIR', so the configure.ac check uses the former. 2) moc does not process classes from the included headers. Since the headers in 'vcl/inc/qt6' just '#include' the ones from 'vcl/inc/qt5', running moc on the qt6 headers doesn't work, so moc is currently run on the qt5 headers for qt6 as well (s. 'vcl/CustomTarget_qt6_moc.mk'). That will have to be adapted in case the qt6 VCL plugin uses "own" headers instead of just including the qt5 ones at some point. 3) QX11Extras has been removed from Qt 6. [1] says: > Changes to Qt X11 Extras > > The QX11Info class has been removed. > > Clients that still rely on the functionality can include the private > header <QtGui/private/qtx11extras_p.h> as a stopgap solution. To enable > private headers use QT += core-private with qmake, or add a project > dependency to Qt::CorePrivate with CMake. I didn't take any closer look, just dropped the use of QtX11Extras for qt6 for now. 4) XCB_ICCCM is no longer needed. It is only used in qt5 to workaround a Qt bug fixed in Qt 5.12, s. commit fe2baf9e84e0ca9aeaa683e37076f57fa3f38dca Author: Jan-Marek Glogowski <jan-marek.glogowski@extern.cib.de> Date: Tue Dec 3 08:32:58 2019 +0100 Qt5 fix missing XCB_ICCCM_WM_HINT_WINDOW_GROUP 5) X11-specific code is still used for key modifier handling. Therefore, still check for the XCB headers when 'USING_X11' is set in configure.ac, and use a 'QT6_USING_X11' define (as qt5 uses 'QT5_USING_X11'). 6) There's currently no Qt 6 video sink for GStreamer. As of today, qt-gstreamer is unmaintained and there is no Qt 6 version. The project's README [2] says: > 0. Maintenance Notice > --------------------- > > This code is unmaintained. You can use it at your own risk. > > If you want to integrate video display in your QML-based UI, > you should consider using 'qmlglsink', from gst-plugins-good. > This is a well supported video sink that uses the generic > gstreamer-gl stack and is in many ways superior to 'qtquick2videosink' > that is provided by qt-gstreamer. You can use this code as an example: > https://cgit.freedesktop.org/gstreamer/gst-plugins-good/tree/tests/examples/qt/qmlsink > > If you are not interested in using QML in your UI, then you > may use one of the other elements provided by this module > (see below). If you do that, it would be helpful to let us > know that this code is still useful to you. We may consider > adding these elements in one of the core gstreamer modules. > > If you are here for the Qt-style bindings, I'm sorry to disappoint you. > The alternative is to use the C API, or the GStreamermm C++ API. > Qt-style bindings are cool, but unfortunately they are very hard > to maintain because they are written by hand. If you are interested > in continuing this project, you are welcome to implement a > generator for them, probably based on GObject-Introspection. > I am happy to provide directions if you want to pursue such a thing. Therefore, the Qt video sink handling is qt5-only and the corresponding handling for GOBJECT (used for the GStreamer video sink handling) was not taken over for qt6. This presumably means that video playback in Impress presentations does not work when using qt6 with they Qt Wayland plugin, s. tdf#125219 for the corresponding bug for qt5/kf5. (I did not build the qtwayland module to actually test this, though. Video playback with the Qt xcb plugin in a Wayland session works.) [1] https://doc-snapshots.qt.io/qt6-dev/extras-changes-qt6.html [2] https://cgit.freedesktop.org/gstreamer/qt-gstreamer/tree/README Change-Id: Ib105ccfb2c3630ec5d5403793a3cd9ba31d85bdf Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122808 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2021-09-29 11:09:51 +02:00
#endif
css::datatransfer::dnd::DropTargetDropEvent aEvent;
aEvent.Source = static_cast<css::datatransfer::dnd::XDropTarget*>(m_pDropTarget);
aEvent.Context = static_cast<css::datatransfer::dnd::XDropTargetDropContext*>(m_pDropTarget);
aEvent.LocationX = aPos.X();
aEvent.LocationY = aPos.Y();
aEvent.SourceActions = nSourceActions;
aEvent.DropAction = nUserDropAction;
aEvent.Transferable = lcl_getXTransferable(pEvent->mimeData());
// ask the drop target to accept our drop action
m_pDropTarget->fire_drop(aEvent);
m_bInDrag = false;
const bool bDropSuccessful = m_pDropTarget->dropSuccessful();
const sal_Int8 nDropAction = m_pDropTarget->proposedDropAction();
// inform the drag source of the drag-origin frame of the drop result
if (pEvent->source())
{
QtWidget* pWidget = dynamic_cast<QtWidget*>(pEvent->source());
assert(pWidget); // AFAIK there shouldn't be any non-Qt5Widget as source in LO itself
if (pWidget)
pWidget->frame().m_pDragSource->fire_dragEnd(nDropAction, bDropSuccessful);
}
// the drop target accepted our drop action => inform Qt
if (bDropSuccessful)
{
pEvent->setDropAction(getPreferredDropAction(nDropAction));
pEvent->accept();
}
else // or maybe someone else likes it?
pEvent->ignore();
}
void QtFrame::handleDragLeave()
{
css::datatransfer::dnd::DropTargetEvent aEvent;
aEvent.Source = static_cast<css::datatransfer::dnd::XDropTarget*>(m_pDropTarget);
m_pDropTarget->fire_dragExit(aEvent);
m_bInDrag = false;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */