2024-11-18 09:33:05 +01:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
|
2017-10-21 13:50:30 +00:00
|
|
|
/*
|
|
|
|
* 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 .
|
|
|
|
*/
|
|
|
|
|
2024-11-05 15:25:24 +05:30
|
|
|
#include <IconThemeSelector.hxx>
|
|
|
|
#include <QtCustomStyle.hxx>
|
2021-09-28 15:55:43 +02:00
|
|
|
#include <QtFrame.hxx>
|
|
|
|
#include <QtFrame.moc>
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2021-09-28 15:55:43 +02:00
|
|
|
#include <QtData.hxx>
|
|
|
|
#include <QtDragAndDrop.hxx>
|
2022-05-02 08:50:33 +02:00
|
|
|
#include <QtFontFace.hxx>
|
2021-09-28 15:55:43 +02:00
|
|
|
#include <QtGraphics.hxx>
|
|
|
|
#include <QtInstance.hxx>
|
|
|
|
#include <QtMainWindow.hxx>
|
|
|
|
#include <QtMenu.hxx>
|
|
|
|
#include <QtSvpGraphics.hxx>
|
|
|
|
#include <QtSystem.hxx>
|
|
|
|
#include <QtTransferable.hxx>
|
2022-06-15 23:34:01 +02:00
|
|
|
#if CHECK_ANY_QT_USING_X11
|
|
|
|
#include <QtX11Support.hxx>
|
|
|
|
#endif
|
2017-10-27 13:15:37 +02:00
|
|
|
|
tdf#160565 tdf#145735 qt: Avoid native window handles for Qt 6
Similar to the tdf#122293 scenario with Qt 5 on Wayland,
using native windows causes unresponsive UI even with
the xcb Qt QPA plugin when using Qt 6.
Therefore, don't call `QWidget::winId()` at all when
using Qt 6, but just refuse to resolve a native window
handle, the same way that is already done here for the
wayland Qt QPA plugin with qt5.
Add a comment based on the one originally added with
commit 0e3c3b842e14b9646d3697cf1266be21359e0f13
Author: Michael Weghorn <m.weghorn@posteo.de>
Date: Sat May 11 21:31:33 2019 +0200
tdf#122293 qt5: Use "alien widgets" by default on Wayland
that was later dropped during a refactoring.
This code path is triggered when trying to resolve the
parent window for a file picker (s. `QtFilePicker::initialize`).
In a quick test in a KDE Plasma 5 Wayland session on Debian testing,
the modality behavior was unchanged with or without this change in
place:
* With qt6 xcb, the main window nicely gets grayed out and is
unresponsive while the file dialog gets shown when using
e.g. "File" -> "Open" in Writer.
* With qt6 wayland, the main window is not grayed out and looks
more "active" still, but doesn't actually accept keyboard
or mouse input.
This is basically the same in other Qt/KDE applications, e.g.
a self-compiled Kate from git master, so not LO-specific.
If resolving the parent for the file picker turns out to be necessary,
maybe something similar to what commit
commit 3ff4800fe400de916c97f587322104af06cc0879
Author: Caolán McNamara <caolanm@redhat.com>
Date: Wed Apr 4 10:22:34 2018 +0100
weld SvInsertOleDlg
and
weld SfxInsertFloatingFrameDialog
and smuggle in the parent widget for the Gtk File dialog via
an XWindow interface
did for gtk3 might be worth looking into.
However, I can at least not reproduce issues like the one described
for gtk3 in
commit 203d96787969f707c78101be18d51b44ace98f93
Author: Caolán McNamara <caolanm@redhat.com>
Date: Mon Jun 21 13:01:52 2021 +0100
give folderpicker an optional parent
so, like a file picker, it can make its parent modal while its
operating. Otherwise its possible to interact with the parent dialog in
undesirable ways, e.g. file, export as, export as epub, the folder
picker of 'media directory'
with the qt6 VCL plugin even with this commit in place.
Another scenario relying on a native window handle is video
playback with GStreamer's x11 video sink.
That still works for qt5 with the xcb plugin as the handle is
still returned for that one.
For qt6 with the xcb plugin, that didn't work properly
without this commit either (at least not in my tests with
current qtbase dev as of commit
70a2e7f32b9f9ce19d1538f14fbde7b0d1e77ffd), s.
tdf#145735 comment 7.
It's now broken a different way than before
(extra windows show up instead of no video being shown).
This will be further tracked together with a solution for
Wayland in tdf#125219.
As a side note, forcing native windows for everything
using `QT_USE_NATIVE_WINDOWS=1` as described at [1]
causes more sever brokenness with the qt6 xcb plugin
(mostly black window in Writer instead of showing the
actual content).
[1] https://doc.qt.io/qt-6/qwidget.html#native-widgets-vs-alien-widgets
Change-Id: I9718c680bd8bc4ff0574f171403d965c1beac781
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167783
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
2024-05-17 17:02:49 +02:00
|
|
|
#include <QtCore/QLibraryInfo>
|
2019-02-27 09:40:50 +01:00
|
|
|
#include <QtCore/QMimeData>
|
2017-10-30 18:33:06 +01:00
|
|
|
#include <QtCore/QPoint>
|
|
|
|
#include <QtCore/QSize>
|
2019-06-02 21:01:33 +00:00
|
|
|
#include <QtCore/QThread>
|
2019-08-08 17:59:20 +00:00
|
|
|
#include <QtGui/QDragMoveEvent>
|
|
|
|
#include <QtGui/QDropEvent>
|
2017-10-30 18:33:06 +01:00
|
|
|
#include <QtGui/QIcon>
|
2017-10-27 13:15:37 +02:00
|
|
|
#include <QtGui/QWindow>
|
2017-10-30 19:44:40 +01:00
|
|
|
#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
|
2018-08-09 14:51:41 +02:00
|
|
|
#include <QtWidgets/QStyle>
|
|
|
|
#include <QtWidgets/QToolTip>
|
2017-10-30 19:55:18 +01:00
|
|
|
#include <QtWidgets/QApplication>
|
2018-08-09 14:51:41 +02:00
|
|
|
#include <QtWidgets/QMenuBar>
|
2018-08-09 17:14:14 +02:00
|
|
|
#include <QtWidgets/QMainWindow>
|
2021-12-01 08:53:25 +01:00
|
|
|
#if CHECK_QT5_USING_X11
|
2019-06-14 02:08:22 +00:00
|
|
|
#include <QtX11Extras/QX11Info>
|
|
|
|
#endif
|
|
|
|
|
2017-11-14 00:10:58 +02:00
|
|
|
#include <window.h>
|
2024-10-24 00:19:56 +02:00
|
|
|
#include <vcl/qt/QtUtils.hxx>
|
2017-10-30 18:33:06 +01:00
|
|
|
#include <vcl/syswin.hxx>
|
|
|
|
|
2018-10-15 14:44:29 +02:00
|
|
|
#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
|
|
|
|
|
2017-10-24 19:49:45 +02:00
|
|
|
#include <cairo.h>
|
|
|
|
#include <headless/svpgdi.hxx>
|
|
|
|
|
2022-05-02 08:50:33 +02:00
|
|
|
#include <unx/fontmanager.hxx>
|
|
|
|
|
2017-10-24 19:49:45 +02:00
|
|
|
static void SvpDamageHandler(void* handle, sal_Int32 nExtentsX, sal_Int32 nExtentsY,
|
|
|
|
sal_Int32 nExtentsWidth, sal_Int32 nExtentsHeight)
|
|
|
|
{
|
2021-09-28 15:02:47 +02:00
|
|
|
QtFrame* pThis = static_cast<QtFrame*>(handle);
|
2017-10-24 19:49:45 +02:00
|
|
|
pThis->Damage(nExtentsX, nExtentsY, nExtentsWidth, nExtentsHeight);
|
|
|
|
}
|
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
QtFrame::QtFrame(QtFrame* pParent, SalFrameStyleFlags nStyle, bool bUseCairo)
|
2018-08-09 17:14:14 +02:00
|
|
|
: m_pTopLevel(nullptr)
|
|
|
|
, m_bUseCairo(bUseCairo)
|
2018-09-04 09:17:11 +02:00
|
|
|
, m_bNullRegion(true)
|
2017-10-24 19:49:45 +02:00
|
|
|
, m_bGraphicsInUse(false)
|
2017-10-30 19:32:45 +01:00
|
|
|
, m_ePointerStyle(PointerStyle::Arrow)
|
2018-10-15 14:44:29 +02:00
|
|
|
, m_pDragSource(nullptr)
|
|
|
|
, m_pDropTarget(nullptr)
|
|
|
|
, m_bInDrag(false)
|
2017-10-30 19:44:40 +01:00
|
|
|
, m_bDefaultSize(true)
|
|
|
|
, m_bDefaultPos(true)
|
2018-12-14 12:39:44 +03:00
|
|
|
, m_bFullScreen(false)
|
2019-05-29 19:01:28 +02:00
|
|
|
, m_bFullScreenSpanAll(false)
|
2021-12-01 08:53:25 +01:00
|
|
|
#if CHECK_ANY_QT_USING_X11
|
2021-07-19 15:17:53 +02:00
|
|
|
, m_nKeyModifiers(ModKeyFlags::NONE)
|
|
|
|
#endif
|
Qt5 report input method language
This is in the spirit of tdf#108151, based on the information Qt
provides for the IM setting. I don't know how correct it is,
especially looking at Caolans comment 3 in that bug report
regarding the assumed validity of GtkIMContextInfo. OTOH it seems
to work well enough for my simple tests.
Some BG info: while the QInputMethod object is a global one, it's
"bound" to the focused window. So you'll get change events, when
you change the input window, with the correct IM settings for the
new one, be it a real window or just the menu bar.
To prevent unneeded flushes of buffers and language lookup, this
caches the current IM language of a window.
The language is not affected just by changing keyboard mappings,
which the bug reporter requested! It just works with a configured
input method, like fcitx or ibus (which can have keyboard mappings
too, which work correctly).
Change-Id: Ia9133edf4d1ce77d29adbfe57c180db15db0a560
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106354
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
2020-11-22 14:53:14 +01:00
|
|
|
, m_nInputLanguage(LANGUAGE_DONTKNOW)
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2024-09-27 09:08:43 +02:00
|
|
|
GetQtInstance().insertFrame(this);
|
2017-10-27 13:15:37 +02:00
|
|
|
|
2017-10-24 19:49:45 +02:00
|
|
|
m_aDamageHandler.handle = this;
|
|
|
|
m_aDamageHandler.damaged = ::SvpDamageHandler;
|
|
|
|
|
2017-10-27 13:15:37 +02:00
|
|
|
if (nStyle & SalFrameStyleFlags::DEFAULT) // ensure default style
|
|
|
|
{
|
|
|
|
nStyle |= SalFrameStyleFlags::MOVEABLE | SalFrameStyleFlags::SIZEABLE
|
|
|
|
| SalFrameStyleFlags::CLOSEABLE;
|
|
|
|
nStyle &= ~SalFrameStyleFlags::FLOAT;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_nStyle = nStyle;
|
|
|
|
m_pParent = pParent;
|
|
|
|
|
2021-10-31 14:08:57 +01:00
|
|
|
Qt::WindowFlags aWinFlags(Qt::Widget);
|
2021-11-10 12:18:39 +01:00
|
|
|
if (!(nStyle & SalFrameStyleFlags::SYSTEMCHILD))
|
2017-10-27 13:15:37 +02:00
|
|
|
{
|
|
|
|
if (nStyle & SalFrameStyleFlags::INTRO)
|
2021-10-31 14:08:57 +01:00
|
|
|
aWinFlags = Qt::SplashScreen;
|
2019-02-13 12:24:38 +01:00
|
|
|
// floating toolbars are frameless tool windows
|
|
|
|
// + they must be able to receive keyboard focus
|
|
|
|
else if ((nStyle & SalFrameStyleFlags::FLOAT)
|
|
|
|
&& (nStyle & SalFrameStyleFlags::OWNERDRAWDECORATION))
|
2021-10-31 14:08:57 +01:00
|
|
|
aWinFlags = Qt::Tool | Qt::FramelessWindowHint;
|
2021-07-19 22:13:21 +02:00
|
|
|
else if (nStyle & SalFrameStyleFlags::TOOLTIP)
|
2021-10-31 14:08:57 +01:00
|
|
|
aWinFlags = Qt::ToolTip;
|
tdf#144585 Qt fix Wayland LO fake popups
So Michael Weghorn was somehow reminded of an abandoned
commit from me ("Qt5 rework parent handling") archived in
https://gerrit.libreoffice.org/c/core/+/73463.
The bug introducing the new QWidget parenting, tdf#145363, was
resolved in a better way by explicitly setting parents for the
modal dialogs, so LO doesn't break Qt anymore. The actual problem
is, that an additional modal dialog needs to be stacked to the
previous modal dialog; no "parallel" modal dialogs are allowed,
which my original fix tried to enforce by reparenting.
Then there is the problem with Qt::Popup's focus grabbing on show,
which breaks LO's editable ComboBox. So LO's popup / FLOAT windows
are mapped to Qt::ToolTip, which are automatically advertised as
tooltips via accessibility. For X11 / xcb, Qt:Window with the
Qt::BypassWindowManagerHint works well enough as an alternative,
but WASM and Wayland don't seem to implement it correctly, so this
just handles popups as Qt::ToolTip on all platforms.
This reverts commit b00a68a8e19370e106cd76258a3c1825f43613ee
("tdf#145363 Qt reparent modal dialogs on show").
In addition the popup widgets are switched back to Qt::ToolTip.
Change-Id: If726771b4e9cc3f639f21cf502b3ec5985873643
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132526
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
2022-04-04 18:02:28 +02:00
|
|
|
// 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.
|
2021-07-30 05:25:37 +02:00
|
|
|
else if (isPopup())
|
2021-10-29 22:24:12 +02:00
|
|
|
aWinFlags = Qt::ToolTip | Qt::FramelessWindowHint;
|
2017-10-27 13:15:37 +02:00
|
|
|
else if (nStyle & SalFrameStyleFlags::TOOLWINDOW)
|
2021-10-31 14:08:57 +01:00
|
|
|
aWinFlags = Qt::Tool;
|
2019-12-03 08:20:21 +01:00
|
|
|
// 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)
|
2021-10-31 14:08:57 +01:00
|
|
|
aWinFlags = Qt::Dialog;
|
2017-10-27 13:15:37 +02:00
|
|
|
else
|
2021-10-31 14:08:57 +01:00
|
|
|
aWinFlags = Qt::Window;
|
2017-10-27 13:15:37 +02:00
|
|
|
}
|
|
|
|
|
2019-02-21 10:24:39 +03:00
|
|
|
if (aWinFlags == Qt::Window)
|
2018-08-09 17:14:14 +02:00
|
|
|
{
|
2021-09-28 15:02:47 +02:00
|
|
|
m_pTopLevel = new QtMainWindow(*this, aWinFlags);
|
tdf#144585 Qt fix Wayland LO fake popups
So Michael Weghorn was somehow reminded of an abandoned
commit from me ("Qt5 rework parent handling") archived in
https://gerrit.libreoffice.org/c/core/+/73463.
The bug introducing the new QWidget parenting, tdf#145363, was
resolved in a better way by explicitly setting parents for the
modal dialogs, so LO doesn't break Qt anymore. The actual problem
is, that an additional modal dialog needs to be stacked to the
previous modal dialog; no "parallel" modal dialogs are allowed,
which my original fix tried to enforce by reparenting.
Then there is the problem with Qt::Popup's focus grabbing on show,
which breaks LO's editable ComboBox. So LO's popup / FLOAT windows
are mapped to Qt::ToolTip, which are automatically advertised as
tooltips via accessibility. For X11 / xcb, Qt:Window with the
Qt::BypassWindowManagerHint works well enough as an alternative,
but WASM and Wayland don't seem to implement it correctly, so this
just handles popups as Qt::ToolTip on all platforms.
This reverts commit b00a68a8e19370e106cd76258a3c1825f43613ee
("tdf#145363 Qt reparent modal dialogs on show").
In addition the popup widgets are switched back to Qt::ToolTip.
Change-Id: If726771b4e9cc3f639f21cf502b3ec5985873643
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132526
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
2022-04-04 18:02:28 +02:00
|
|
|
m_pQWidget = new QtWidget(*this);
|
2018-08-09 17:14:14 +02:00
|
|
|
m_pTopLevel->setCentralWidget(m_pQWidget);
|
2019-11-25 14:08:44 +00:00
|
|
|
m_pTopLevel->setFocusProxy(m_pQWidget);
|
2018-08-09 17:14:14 +02:00
|
|
|
}
|
2018-07-17 15:57:41 +02:00
|
|
|
else
|
2022-04-12 00:29:56 +02:00
|
|
|
{
|
2021-09-28 15:02:47 +02:00
|
|
|
m_pQWidget = new QtWidget(*this, aWinFlags);
|
2022-04-12 00:29:56 +02:00
|
|
|
// 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);
|
|
|
|
}
|
2018-12-11 12:12:52 +01:00
|
|
|
|
2022-05-24 18:14:16 +02:00
|
|
|
FillSystemEnvData(m_aSystemData, reinterpret_cast<sal_IntPtr>(this), m_pQWidget);
|
|
|
|
|
2019-02-27 16:13:48 +01:00
|
|
|
SetIcon(SV_ICON_ID_OFFICE);
|
Qt5 fix missing XCB_ICCCM_WM_HINT_WINDOW_GROUP
This is the application level equivalent of the Qt5 fix for bug
QTBUG-46626 / commit 0de4b32 ("xcb: fix issue with dialogs hidden
by other windows"), which was broken since Qt 5.4 and is just
fixed since Qt 5.12.
It is needed for some window managers, which don't know about the
WM_CLIENT_LEADER property. Both settings are the same, but just
the latter is set by older Qt5 releases. This probably isn't a
real problem, as GNOME or XFCE would use the gtk VCL plugin, but
since I already wrote the code when debugging tdf#129071, there
is also no reason to drop it (except: more code, more bugs...).
This fix is optional and needs development headers for xcb-icccm,
which can actually be compiled into Qt5. If missing configure will
just print a warning, since it's a runtime requirement and we
explicitly drop the linked Qt version symbol, so the potential
build Qt version won't matter.
Change-Id: Ifc5a8f8a40ee13779a911efb53e8b8b868614d0b
Reviewed-on: https://gerrit.libreoffice.org/84299
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
2019-12-03 08:32:58 +01:00
|
|
|
}
|
|
|
|
|
2022-04-07 01:07:43 +02:00
|
|
|
void QtFrame::screenChanged(QScreen*) { m_pQWidget->fakeResize(); }
|
|
|
|
|
2021-11-17 13:03:23 +01:00
|
|
|
void QtFrame::FillSystemEnvData(SystemEnvData& rData, sal_IntPtr pWindow, QWidget* pWidget)
|
|
|
|
{
|
2022-05-24 18:14:16 +02:00
|
|
|
assert(rData.platform == SystemEnvData::Platform::Invalid);
|
|
|
|
assert(rData.toolkit == SystemEnvData::Toolkit::Invalid);
|
2021-11-17 13:03:23 +01:00
|
|
|
if (QGuiApplication::platformName() == "wayland")
|
|
|
|
rData.platform = SystemEnvData::Platform::Wayland;
|
|
|
|
else if (QGuiApplication::platformName() == "xcb")
|
|
|
|
rData.platform = SystemEnvData::Platform::Xcb;
|
2021-10-29 22:24:12 +02:00
|
|
|
else if (QGuiApplication::platformName() == "wasm")
|
|
|
|
rData.platform = SystemEnvData::Platform::WASM;
|
2021-11-17 13:03:23 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
QtFrame::~QtFrame()
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2024-09-27 09:08:43 +02:00
|
|
|
GetQtInstance().eraseFrame(this);
|
2019-06-02 15:38:25 +00:00
|
|
|
delete asChild();
|
2018-10-05 11:39:49 +02:00
|
|
|
m_aSystemData.aShellWindow = 0;
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::Damage(sal_Int32 nExtentsX, sal_Int32 nExtentsY, sal_Int32 nExtentsWidth,
|
|
|
|
sal_Int32 nExtentsHeight) const
|
2017-10-24 19:49:45 +02:00
|
|
|
{
|
2023-03-24 08:06:56 +01:00
|
|
|
m_pQWidget->update(scaledQRect(QRect(nExtentsX, nExtentsY, nExtentsWidth, nExtentsHeight),
|
|
|
|
1 / devicePixelRatioF()));
|
2017-10-24 19:49:45 +02:00
|
|
|
}
|
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
SalGraphics* QtFrame::AcquireGraphics()
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2017-10-31 01:07:06 +01:00
|
|
|
if (m_bGraphicsInUse)
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
m_bGraphicsInUse = true;
|
|
|
|
|
2017-10-24 19:49:45 +02:00
|
|
|
if (m_bUseCairo)
|
|
|
|
{
|
2021-07-19 23:28:47 +02:00
|
|
|
if (!m_pSvpGraphics)
|
2017-10-24 19:49:45 +02:00
|
|
|
{
|
2023-03-24 08:06:56 +01:00
|
|
|
QSize aSize = m_pQWidget->size() * devicePixelRatioF();
|
2021-09-28 15:02:47 +02:00
|
|
|
m_pSvpGraphics.reset(new QtSvpGraphics(this));
|
2021-04-11 17:40:26 +02:00
|
|
|
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()));
|
2021-09-28 15:02:47 +02:00
|
|
|
cairo_surface_set_user_data(m_pSurface.get(), QtSvpGraphics::getDamageKey(),
|
2021-04-11 17:40:26 +02:00
|
|
|
&m_aDamageHandler, nullptr);
|
2017-10-24 19:49:45 +02:00
|
|
|
}
|
2021-04-11 17:40:26 +02:00
|
|
|
return m_pSvpGraphics.get();
|
2017-10-24 19:49:45 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-09-28 15:02:47 +02:00
|
|
|
if (!m_pQtGraphics)
|
2017-10-24 19:49:45 +02:00
|
|
|
{
|
2021-09-28 15:02:47 +02:00
|
|
|
m_pQtGraphics.reset(new QtGraphics(this));
|
tdf#127687 Qt5 introduce basic HiDPI scaling
For tdf#124292, Qt's own HiDPI scaling was explicitly disabled,
but it turns out, you can't really scale QStyle painting then.
This patch series had a 2nd approach also used by Gtk+ currently,
which relied on the scaling of ths Cairo surface, which works
surprisingly good, but has to lie about the real DPI value, so
nothing is scaled twice. Also all icons are then scaled instead
of rendered with the proper resolution.
When HiDPI support in Qt is enabled, and the application is
started using QT_SCALE_FACTOR=1.25, Qt simply lowers the reported
resolution, keeps the logical DPI value of 96 and changes the
devicePixelRatio to the specified value. But LO still expects
the real DPI values and sizes, so we have to multiply a lot of
rectangles, sizes and positions.
The current result is far from perfect, which you can see with
the various graphics glitches, but it at least doesn't crash
anymore in the ControlType::Editbox sizing code.
The main problem is all the up and downscaling in the
getNativeControlRegion code, so LO knows the size of the widgets
for the correct layouting, since there seem to be no API to
get the scaled values from Qt / QStyle.
Change-Id: I687b1df6ef27724ce68326d256e9addccd72e759
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86239
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
2020-02-29 13:39:29 +01:00
|
|
|
m_pQImage.reset(
|
2023-03-24 08:06:56 +01:00
|
|
|
new QImage(m_pQWidget->size() * devicePixelRatioF(), Qt_DefaultFormat32));
|
2018-11-07 17:48:06 +03:00
|
|
|
m_pQImage->fill(Qt::transparent);
|
2021-09-28 15:02:47 +02:00
|
|
|
m_pQtGraphics->ChangeQImage(m_pQImage.get());
|
2017-10-24 19:49:45 +02:00
|
|
|
}
|
2021-09-28 15:02:47 +02:00
|
|
|
return m_pQtGraphics.get();
|
2017-10-24 19:49:45 +02:00
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::ReleaseGraphics(SalGraphics* pSalGraph)
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2017-10-31 01:07:06 +01:00
|
|
|
(void)pSalGraph;
|
2017-10-24 19:49:45 +02:00
|
|
|
if (m_bUseCairo)
|
2021-04-11 17:40:26 +02:00
|
|
|
assert(pSalGraph == m_pSvpGraphics.get());
|
2017-10-24 19:49:45 +02:00
|
|
|
else
|
2021-09-28 15:02:47 +02:00
|
|
|
assert(pSalGraph == m_pQtGraphics.get());
|
2017-10-31 01:07:06 +01:00
|
|
|
m_bGraphicsInUse = false;
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
bool QtFrame::PostEvent(std::unique_ptr<ImplSVEvent> pData)
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2024-09-27 09:08:43 +02:00
|
|
|
GetQtInstance().PostEvent(this, pData.release(), SalEvent::UserEvent);
|
2017-10-31 01:07:06 +01:00
|
|
|
return true;
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2022-04-07 01:07:43 +02:00
|
|
|
QWidget* QtFrame::asChild() const
|
|
|
|
{
|
|
|
|
if (m_pTopLevel)
|
|
|
|
return m_pTopLevel;
|
|
|
|
return m_pQWidget;
|
|
|
|
}
|
2019-06-02 15:38:25 +00:00
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
qreal QtFrame::devicePixelRatioF() const { return asChild()->devicePixelRatioF(); }
|
tdf#127687 Qt5 introduce basic HiDPI scaling
For tdf#124292, Qt's own HiDPI scaling was explicitly disabled,
but it turns out, you can't really scale QStyle painting then.
This patch series had a 2nd approach also used by Gtk+ currently,
which relied on the scaling of ths Cairo surface, which works
surprisingly good, but has to lie about the real DPI value, so
nothing is scaled twice. Also all icons are then scaled instead
of rendered with the proper resolution.
When HiDPI support in Qt is enabled, and the application is
started using QT_SCALE_FACTOR=1.25, Qt simply lowers the reported
resolution, keeps the logical DPI value of 96 and changes the
devicePixelRatio to the specified value. But LO still expects
the real DPI values and sizes, so we have to multiply a lot of
rectangles, sizes and positions.
The current result is far from perfect, which you can see with
the various graphics glitches, but it at least doesn't crash
anymore in the ControlType::Editbox sizing code.
The main problem is all the up and downscaling in the
getNativeControlRegion code, so LO knows the size of the widgets
for the correct layouting, since there seem to be no API to
get the scaled values from Qt / QStyle.
Change-Id: I687b1df6ef27724ce68326d256e9addccd72e759
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86239
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
2020-02-29 13:39:29 +01:00
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
bool QtFrame::isWindow() const { return asChild()->isWindow(); }
|
2018-08-09 17:14:14 +02:00
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
QWindow* QtFrame::windowHandle() const
|
2018-08-09 17:14:14 +02:00
|
|
|
{
|
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
|
2019-06-02 15:38:25 +00:00
|
|
|
QWidget* pChild = asChild();
|
2022-01-09 00:51:09 +01:00
|
|
|
assert(pChild->window() == pChild);
|
2022-05-24 18:14:16 +02:00
|
|
|
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;
|
|
|
|
}
|
2019-06-02 15:38:25 +00:00
|
|
|
return pChild->windowHandle();
|
2018-08-09 17:14:14 +02:00
|
|
|
}
|
|
|
|
|
2023-08-03 21:30:22 +02:00
|
|
|
QScreen* QtFrame::screen() const { return asChild()->screen(); }
|
2018-08-29 14:04:56 +02:00
|
|
|
|
2024-09-27 09:54:20 +02:00
|
|
|
sal_Int32 QtFrame::screenNumber() const
|
|
|
|
{
|
|
|
|
QScreen* pScreen = screen();
|
|
|
|
const QList<QScreen*> screens = QApplication::screens();
|
|
|
|
return screens.indexOf(pScreen);
|
|
|
|
}
|
|
|
|
|
2023-09-02 10:37:47 +02:00
|
|
|
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)
|
2024-08-27 13:43:24 +02:00
|
|
|
const Qt::ColorScheme eColorScheme = QApplication::styleHints()->colorScheme();
|
|
|
|
if (eColorScheme == Qt::ColorScheme::Dark)
|
|
|
|
return true;
|
|
|
|
if (eColorScheme == Qt::ColorScheme::Light)
|
|
|
|
return false;
|
|
|
|
#endif
|
|
|
|
|
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
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
bool QtFrame::isMinimized() const { return asChild()->isMinimized(); }
|
2018-08-29 14:04:56 +02:00
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
bool QtFrame::isMaximized() const { return asChild()->isMaximized(); }
|
2018-08-09 17:14:14 +02:00
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::SetWindowStateImpl(Qt::WindowStates eState)
|
2019-02-11 11:22:30 +01:00
|
|
|
{
|
2019-06-02 15:38:25 +00:00
|
|
|
return asChild()->setWindowState(eState);
|
2019-02-11 11:22:30 +01:00
|
|
|
}
|
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::SetTitle(const OUString& rTitle)
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2024-09-27 09:08:43 +02:00
|
|
|
GetQtInstance().RunInMainThread(
|
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
|
|
|
[this, rTitle]() { m_pQWidget->window()->setWindowTitle(toQString(rTitle)); });
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::SetIcon(sal_uInt16 nIcon)
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2024-09-27 09:08:43 +02:00
|
|
|
QtInstance& rQtInstance = GetQtInstance();
|
|
|
|
if (!rQtInstance.IsMainThread())
|
qt: Run QtFrame::SetIcon in main thread
Fixes this crash/assertion seen when starting Writer with
the qt6 VCL plugin with a fresh user profile with qtbase debug
build (as of commit 70a2e7f32b9f9ce19d1538f14fbde7b0d1e77ffd):
Thread 19 "soffice.bin" received signal SIGABRT, Aborted.
[Switching to Thread 0x7fffada006c0 (LWP 150142)]
__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 0x00007ffff78a6b7f in __pthread_kill_internal (signo=6, threadid=<optimized out>) at ./nptl/pthread_kill.c:78
#2 0x00007ffff78584e2 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#3 0x00007ffff78414ed in __GI_abort () at ./stdlib/abort.c:79
#4 0x00007fffe34f95c9 in qAbort() () at /home/michi/development/git/qt5/qtbase/src/corelib/global/qassert.cpp:49
#5 0x00007fffe350d459 in qt_message_fatal<QString&>(QtMsgType, QMessageLogContext const&, QString&) (context=..., message=...) at /home/michi/development/git/qt5/qtbase/src/corelib/global/qlogging.cpp:2112
#6 0x00007fffe35063e6 in qt_message(QtMsgType, const QMessageLogContext &, const char *, typedef __va_list_tag __va_list_tag *)
(msgType=QtFatalMsg, context=..., msg=0x7fffe3b8afa8 "ASSERT failure in %s: \"%s\", file %s, line %d", ap=0x7fffad9faab8) at /home/michi/development/git/qt5/qtbase/src/corelib/global/qlogging.cpp:380
#7 0x00007fffe35084b1 in QMessageLogger::fatal(char const*, ...) const (this=0x7fffad9fad00, msg=0x7fffe3b8afa8 "ASSERT failure in %s: \"%s\", file %s, line %d")
at /home/michi/development/git/qt5/qtbase/src/corelib/global/qlogging.cpp:880
#8 0x00007fffe34f969c in qt_assert_x(char const*, char const*, char const*, int)
(where=0x7fffe3bae469 "QCoreApplication::sendEvent", what=0x7fff9d691f60 "Cannot send events to objects owned by a different thread. Current thread 0x0x7fff9c456670. Receiver 'QtMainWindowClassWindow' (of type 'QWidgetWindow') was created in thread 0x0x55555560dc60", file=0x7fffe3bae098 "/home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp", line=547) at /home/michi/development/git/qt5/qtbase/src/corelib/global/qassert.cpp:114
#9 0x00007fffe35f54e6 in QCoreApplicationPrivate::checkReceiverThread(QObject*) (receiver=0x55555bb8a180) at /home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:547
#10 0x00007fffe15a786e in QApplication::notify(QObject*, QEvent*) (this=0x55555560d9e0, receiver=0x55555bb8a180, e=0x7fffad9fb120) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qapplication.cpp:2580
#11 0x00007fffe35f68be in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x55555bb8a180, event=0x7fffad9fb120) at /home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1154
#12 0x00007fffe35f7677 in QCoreApplication::sendEvent(QObject*, QEvent*) (receiver=0x55555bb8a180, event=0x7fffad9fb120) at /home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1598
#13 0x00007fffe24f74d0 in QWindow::setIcon(QIcon const&) (this=0x55555bb8a180, icon=...) at /home/michi/development/git/qt5/qtbase/src/gui/kernel/qwindow.cpp:1094
#14 0x00007fffe165564d in QWidgetPrivate::setWindowIcon_sys() (this=0x55555b24b370) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qwidget.cpp:6208
#15 0x00007fffe1655598 in QWidget::setWindowIcon(QIcon const&) (this=0x55555735d7a0, icon=...) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qwidget.cpp:6198
#16 0x00007fffe42362a9 in QtFrame::SetIcon(unsigned short) (this=0x55555bba7d30, nIcon=4) at vcl/qt6/../qt5/QtFrame.cxx:378
#17 0x00007fffee0a2aa6 in SystemWindow::SetIcon(unsigned short) (this=0x7fff9d68a7c0, nIcon=4) at /home/michi/development/git/libreoffice/vcl/source/window/syswin.cxx:332
#18 0x00007ffff4c843f1 in framework::TitleBarUpdate::impl_updateIcon(com::sun::star::uno::Reference<com::sun::star::frame::XFrame> const&)
(this=0x7fff9c452fe0, xFrame=uno::Reference to ((anonymous namespace)::XFrameImpl *) 0x7fff9d68c690) at /home/michi/development/git/libreoffice/framework/source/helper/titlebarupdate.cxx:278
#19 0x00007ffff4c831c2 in framework::TitleBarUpdate::impl_forceUpdate() (this=0x7fff9c452fe0) at /home/michi/development/git/libreoffice/framework/source/helper/titlebarupdate.cxx:214
#20 0x00007ffff4c8304b in framework::TitleBarUpdate::frameAction(com::sun::star::frame::FrameActionEvent const&) (this=0x7fff9c452fe0, aEvent=...) at /home/michi/development/git/libreoffice/framework/source/helper/titlebarupdate.cxx:95
#21 0x00007ffff4e25397 in (anonymous namespace)::XFrameImpl::implts_sendFrameActionEvent(com::sun::star::frame::FrameAction const&)
(this=0x7fff9d68c620, aAction=@0x7ffff4a01f68: com::sun::star::frame::FrameAction::FrameAction_COMPONENT_ATTACHED) at /home/michi/development/git/libreoffice/framework/source/services/frame.cxx:2960
#22 0x00007ffff4e1df33 in (anonymous namespace)::XFrameImpl::setComponent(com::sun::star::uno::Reference<com::sun::star::awt::XWindow> const&, com::sun::star::uno::Reference<com::sun::star::frame::XController> const&)
(this=0x7fff9d68c620, xComponentWindow=uno::Reference to (VCLXContainer *) 0x7fff9dd02cd0, xController=uno::Reference to (ScTabViewObj *) 0x7fff9d8d82d8)
at /home/michi/development/git/libreoffice/framework/source/services/frame.cxx:1552
#23 0x00007ffff40291b3 in utl::ConnectFrameControllerModel(com::sun::star::uno::Reference<com::sun::star::frame::XFrame> const&, com::sun::star::uno::Reference<com::sun::star::frame::XController2> const&, com::sun::star::uno::Reference<com::sun::star::frame::XModel> const&)
(xFrame=uno::Reference to ((anonymous namespace)::XFrameImpl *) 0x7fff9d68c690, xController=uno::Reference to (ScTabViewObj *) 0x7fff9d8d82d8, xModel=uno::Reference to (ScModelObj *) 0x7fff9c471680) at include/unotools/fcm.hxx:45
#24 0x00007ffff402551a in (anonymous namespace)::SfxFrameLoader_Impl::impl_createDocumentView(com::sun::star::uno::Reference<com::sun::star::frame::XModel2> const&, com::sun::star::uno::Reference<com::sun::star::frame::XFrame> const&, comphelper::NamedValueCollection const&, rtl::OUString const&)
(i_rModel=uno::Reference to (ScModelObj *) 0x7fff9c471680, i_rFrame=uno::Reference to ((anonymous namespace)::XFrameImpl *) 0x7fff9d68c690, i_rViewFactoryArgs=..., i_rViewName="Default")
at /home/michi/development/git/libreoffice/sfx2/source/view/frmload.cxx:584
#25 0x00007ffff402272f in (anonymous namespace)::SfxFrameLoader_Impl::load(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&, com::sun::star::uno::Reference<com::sun::star::frame::XFrame> const&)
(this=0x7fff9c451600, rArgs=uno::Sequence of length 11 = {...}, _rTargetFrame=uno::Reference to ((anonymous namespace)::XFrameImpl *) 0x7fff9d68c690) at /home/michi/development/git/libreoffice/sfx2/source/view/frmload.cxx:759
#26 0x00007ffff4dd7b61 in framework::LoadEnv::impl_loadContent() (this=0x7fffad9fcbb8) at /home/michi/development/git/libreoffice/framework/source/loadenv/loadenv.cxx:1176
#27 0x00007ffff4dd48e4 in framework::LoadEnv::start() (this=0x7fffad9fcbb8) at /home/michi/development/git/libreoffice/framework/source/loadenv/loadenv.cxx:412
#28 0x00007ffff4dd21b2 in framework::LoadEnv::startLoading(rtl::OUString const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&, com::sun::star::uno::Reference<com::sun::star::frame::XFrame> const&, rtl::OUString const&, int, LoadEnvFeatures)
(this=0x7fffad9fcbb8, sURL="file:///home/michi/development/git/libreoffice/instdir/program/../program/opencl/cl-test.ods", lMediaDescriptor=uno::Sequence of length 1 = {...}, xBaseFrame=uno::Reference to (framework::Desktop *) 0x5555569ad308, sTarget="_blank", nSearchFlags=0, eFeature=LoadEnvFeatures::NONE) at /home/michi/development/git/libreoffice/framework/source/loadenv/loadenv.cxx:308
#29 0x00007ffff4dd0998 in framework::LoadEnv::loadComponentFromURL(com::sun::star::uno::Reference<com::sun::star::frame::XComponentLoader> const&, com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> const&, rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)
(xLoader=uno::Reference to (framework::Desktop *) 0x5555569ad318, xContext=uno::Reference to (cppu::(anonymous namespace)::ComponentContext *) 0x555555623d48, sURL="file:///home/michi/development/git/libreoffice/instdir/program/../program/opencl/cl-test.ods", sTarget="_blank", nSearchFlags=0, lArgs=uno::Sequence of length 1 = {...}) at /home/michi/development/git/libreoffice/framework/source/loadenv/loadenv.cxx:168
#30 0x00007ffff4e06a3f in framework::Desktop::loadComponentFromURL(rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)
(this=0x5555569ad2a0, sURL="file:///home/michi/development/git/libreoffice/instdir/program/../program/opencl/cl-test.ods", sTargetFrameName="_blank", nSearchFlags=0, lArguments=uno::Sequence of length 1 = {...})
at /home/michi/development/git/libreoffice/framework/source/services/desktop.cxx:592
#31 0x00007ffff4e06b34 in non-virtual thunk to framework::Desktop::loadComponentFromURL(rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&) ()
at /home/michi/development/git/libreoffice/instdir/program/libfwklo.so
#32 0x00007ffff7ba9147 in desktop::testOpenCLCompute(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&, rtl::OUString const&)
(xDesktop=uno::Reference to (framework::Desktop *) 0x5555569ad2f8, rURL="file:///home/michi/development/git/libreoffice/instdir/program/../program/opencl/cl-test.ods")
at /home/michi/development/git/libreoffice/desktop/source/app/opencl.cxx:132
#33 0x00007ffff7ba7f54 in desktop::Desktop::CheckOpenCLCompute(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&) (xDesktop=uno::Reference to (framework::Desktop *) 0x5555569ad2f8)
--Type <RET> for more, q to quit, c to continue without paging--
at /home/michi/development/git/libreoffice/desktop/source/app/opencl.cxx:241
#34 0x00007ffff7b5719d in std::__invoke_impl<void, void (*)(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&), com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> >(std::__invoke_other, void (*&&)(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&), com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2>&&)
(__f=@0x5555573c20b0: 0x7ffff7ba7760 <desktop::Desktop::CheckOpenCLCompute(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&)>, __args=...)
at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/invoke.h:61
#35 0x00007ffff7b5712d in std::__invoke<void (*)(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&), com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> >(void (*&&)(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&), com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2>&&)
(__fn=@0x5555573c20b0: 0x7ffff7ba7760 <desktop::Desktop::CheckOpenCLCompute(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&)>, __args=...)
at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/invoke.h:96
#36 0x00007ffff7b57102 in std::thread::_Invoker<std::tuple<void (*)(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&), com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> > >::_M_invoke<0ul, 1ul>(std::_Index_tuple<0ul, 1ul>) (this=0x5555573c20a8) at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_thread.h:292
#37 0x00007ffff7b570c5 in std::thread::_Invoker<std::tuple<void (*)(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&), com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> > >::operator()()
(this=0x5555573c20a8) at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_thread.h:299
#38 0x00007ffff7b56e69 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&), com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> > > >::_M_run() (this=0x5555573c20a0) at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_thread.h:244
#39 0x00007ffff74dee24 in () at /lib/x86_64-linux-gnu/libstdc++.so.6
#40 0x00007ffff78a4dbb in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:444
#41 0x00007ffff79269f8 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78
Change-Id: Ic611eb26b140c060cba4d81603e506806cf43bab
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167778
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
2024-05-17 15:04:26 +02:00
|
|
|
{
|
2024-09-27 09:08:43 +02:00
|
|
|
rQtInstance.RunInMainThread([this, nIcon]() { SetIcon(nIcon); });
|
qt: Run QtFrame::SetIcon in main thread
Fixes this crash/assertion seen when starting Writer with
the qt6 VCL plugin with a fresh user profile with qtbase debug
build (as of commit 70a2e7f32b9f9ce19d1538f14fbde7b0d1e77ffd):
Thread 19 "soffice.bin" received signal SIGABRT, Aborted.
[Switching to Thread 0x7fffada006c0 (LWP 150142)]
__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 0x00007ffff78a6b7f in __pthread_kill_internal (signo=6, threadid=<optimized out>) at ./nptl/pthread_kill.c:78
#2 0x00007ffff78584e2 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#3 0x00007ffff78414ed in __GI_abort () at ./stdlib/abort.c:79
#4 0x00007fffe34f95c9 in qAbort() () at /home/michi/development/git/qt5/qtbase/src/corelib/global/qassert.cpp:49
#5 0x00007fffe350d459 in qt_message_fatal<QString&>(QtMsgType, QMessageLogContext const&, QString&) (context=..., message=...) at /home/michi/development/git/qt5/qtbase/src/corelib/global/qlogging.cpp:2112
#6 0x00007fffe35063e6 in qt_message(QtMsgType, const QMessageLogContext &, const char *, typedef __va_list_tag __va_list_tag *)
(msgType=QtFatalMsg, context=..., msg=0x7fffe3b8afa8 "ASSERT failure in %s: \"%s\", file %s, line %d", ap=0x7fffad9faab8) at /home/michi/development/git/qt5/qtbase/src/corelib/global/qlogging.cpp:380
#7 0x00007fffe35084b1 in QMessageLogger::fatal(char const*, ...) const (this=0x7fffad9fad00, msg=0x7fffe3b8afa8 "ASSERT failure in %s: \"%s\", file %s, line %d")
at /home/michi/development/git/qt5/qtbase/src/corelib/global/qlogging.cpp:880
#8 0x00007fffe34f969c in qt_assert_x(char const*, char const*, char const*, int)
(where=0x7fffe3bae469 "QCoreApplication::sendEvent", what=0x7fff9d691f60 "Cannot send events to objects owned by a different thread. Current thread 0x0x7fff9c456670. Receiver 'QtMainWindowClassWindow' (of type 'QWidgetWindow') was created in thread 0x0x55555560dc60", file=0x7fffe3bae098 "/home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp", line=547) at /home/michi/development/git/qt5/qtbase/src/corelib/global/qassert.cpp:114
#9 0x00007fffe35f54e6 in QCoreApplicationPrivate::checkReceiverThread(QObject*) (receiver=0x55555bb8a180) at /home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:547
#10 0x00007fffe15a786e in QApplication::notify(QObject*, QEvent*) (this=0x55555560d9e0, receiver=0x55555bb8a180, e=0x7fffad9fb120) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qapplication.cpp:2580
#11 0x00007fffe35f68be in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x55555bb8a180, event=0x7fffad9fb120) at /home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1154
#12 0x00007fffe35f7677 in QCoreApplication::sendEvent(QObject*, QEvent*) (receiver=0x55555bb8a180, event=0x7fffad9fb120) at /home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1598
#13 0x00007fffe24f74d0 in QWindow::setIcon(QIcon const&) (this=0x55555bb8a180, icon=...) at /home/michi/development/git/qt5/qtbase/src/gui/kernel/qwindow.cpp:1094
#14 0x00007fffe165564d in QWidgetPrivate::setWindowIcon_sys() (this=0x55555b24b370) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qwidget.cpp:6208
#15 0x00007fffe1655598 in QWidget::setWindowIcon(QIcon const&) (this=0x55555735d7a0, icon=...) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qwidget.cpp:6198
#16 0x00007fffe42362a9 in QtFrame::SetIcon(unsigned short) (this=0x55555bba7d30, nIcon=4) at vcl/qt6/../qt5/QtFrame.cxx:378
#17 0x00007fffee0a2aa6 in SystemWindow::SetIcon(unsigned short) (this=0x7fff9d68a7c0, nIcon=4) at /home/michi/development/git/libreoffice/vcl/source/window/syswin.cxx:332
#18 0x00007ffff4c843f1 in framework::TitleBarUpdate::impl_updateIcon(com::sun::star::uno::Reference<com::sun::star::frame::XFrame> const&)
(this=0x7fff9c452fe0, xFrame=uno::Reference to ((anonymous namespace)::XFrameImpl *) 0x7fff9d68c690) at /home/michi/development/git/libreoffice/framework/source/helper/titlebarupdate.cxx:278
#19 0x00007ffff4c831c2 in framework::TitleBarUpdate::impl_forceUpdate() (this=0x7fff9c452fe0) at /home/michi/development/git/libreoffice/framework/source/helper/titlebarupdate.cxx:214
#20 0x00007ffff4c8304b in framework::TitleBarUpdate::frameAction(com::sun::star::frame::FrameActionEvent const&) (this=0x7fff9c452fe0, aEvent=...) at /home/michi/development/git/libreoffice/framework/source/helper/titlebarupdate.cxx:95
#21 0x00007ffff4e25397 in (anonymous namespace)::XFrameImpl::implts_sendFrameActionEvent(com::sun::star::frame::FrameAction const&)
(this=0x7fff9d68c620, aAction=@0x7ffff4a01f68: com::sun::star::frame::FrameAction::FrameAction_COMPONENT_ATTACHED) at /home/michi/development/git/libreoffice/framework/source/services/frame.cxx:2960
#22 0x00007ffff4e1df33 in (anonymous namespace)::XFrameImpl::setComponent(com::sun::star::uno::Reference<com::sun::star::awt::XWindow> const&, com::sun::star::uno::Reference<com::sun::star::frame::XController> const&)
(this=0x7fff9d68c620, xComponentWindow=uno::Reference to (VCLXContainer *) 0x7fff9dd02cd0, xController=uno::Reference to (ScTabViewObj *) 0x7fff9d8d82d8)
at /home/michi/development/git/libreoffice/framework/source/services/frame.cxx:1552
#23 0x00007ffff40291b3 in utl::ConnectFrameControllerModel(com::sun::star::uno::Reference<com::sun::star::frame::XFrame> const&, com::sun::star::uno::Reference<com::sun::star::frame::XController2> const&, com::sun::star::uno::Reference<com::sun::star::frame::XModel> const&)
(xFrame=uno::Reference to ((anonymous namespace)::XFrameImpl *) 0x7fff9d68c690, xController=uno::Reference to (ScTabViewObj *) 0x7fff9d8d82d8, xModel=uno::Reference to (ScModelObj *) 0x7fff9c471680) at include/unotools/fcm.hxx:45
#24 0x00007ffff402551a in (anonymous namespace)::SfxFrameLoader_Impl::impl_createDocumentView(com::sun::star::uno::Reference<com::sun::star::frame::XModel2> const&, com::sun::star::uno::Reference<com::sun::star::frame::XFrame> const&, comphelper::NamedValueCollection const&, rtl::OUString const&)
(i_rModel=uno::Reference to (ScModelObj *) 0x7fff9c471680, i_rFrame=uno::Reference to ((anonymous namespace)::XFrameImpl *) 0x7fff9d68c690, i_rViewFactoryArgs=..., i_rViewName="Default")
at /home/michi/development/git/libreoffice/sfx2/source/view/frmload.cxx:584
#25 0x00007ffff402272f in (anonymous namespace)::SfxFrameLoader_Impl::load(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&, com::sun::star::uno::Reference<com::sun::star::frame::XFrame> const&)
(this=0x7fff9c451600, rArgs=uno::Sequence of length 11 = {...}, _rTargetFrame=uno::Reference to ((anonymous namespace)::XFrameImpl *) 0x7fff9d68c690) at /home/michi/development/git/libreoffice/sfx2/source/view/frmload.cxx:759
#26 0x00007ffff4dd7b61 in framework::LoadEnv::impl_loadContent() (this=0x7fffad9fcbb8) at /home/michi/development/git/libreoffice/framework/source/loadenv/loadenv.cxx:1176
#27 0x00007ffff4dd48e4 in framework::LoadEnv::start() (this=0x7fffad9fcbb8) at /home/michi/development/git/libreoffice/framework/source/loadenv/loadenv.cxx:412
#28 0x00007ffff4dd21b2 in framework::LoadEnv::startLoading(rtl::OUString const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&, com::sun::star::uno::Reference<com::sun::star::frame::XFrame> const&, rtl::OUString const&, int, LoadEnvFeatures)
(this=0x7fffad9fcbb8, sURL="file:///home/michi/development/git/libreoffice/instdir/program/../program/opencl/cl-test.ods", lMediaDescriptor=uno::Sequence of length 1 = {...}, xBaseFrame=uno::Reference to (framework::Desktop *) 0x5555569ad308, sTarget="_blank", nSearchFlags=0, eFeature=LoadEnvFeatures::NONE) at /home/michi/development/git/libreoffice/framework/source/loadenv/loadenv.cxx:308
#29 0x00007ffff4dd0998 in framework::LoadEnv::loadComponentFromURL(com::sun::star::uno::Reference<com::sun::star::frame::XComponentLoader> const&, com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> const&, rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)
(xLoader=uno::Reference to (framework::Desktop *) 0x5555569ad318, xContext=uno::Reference to (cppu::(anonymous namespace)::ComponentContext *) 0x555555623d48, sURL="file:///home/michi/development/git/libreoffice/instdir/program/../program/opencl/cl-test.ods", sTarget="_blank", nSearchFlags=0, lArgs=uno::Sequence of length 1 = {...}) at /home/michi/development/git/libreoffice/framework/source/loadenv/loadenv.cxx:168
#30 0x00007ffff4e06a3f in framework::Desktop::loadComponentFromURL(rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)
(this=0x5555569ad2a0, sURL="file:///home/michi/development/git/libreoffice/instdir/program/../program/opencl/cl-test.ods", sTargetFrameName="_blank", nSearchFlags=0, lArguments=uno::Sequence of length 1 = {...})
at /home/michi/development/git/libreoffice/framework/source/services/desktop.cxx:592
#31 0x00007ffff4e06b34 in non-virtual thunk to framework::Desktop::loadComponentFromURL(rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&) ()
at /home/michi/development/git/libreoffice/instdir/program/libfwklo.so
#32 0x00007ffff7ba9147 in desktop::testOpenCLCompute(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&, rtl::OUString const&)
(xDesktop=uno::Reference to (framework::Desktop *) 0x5555569ad2f8, rURL="file:///home/michi/development/git/libreoffice/instdir/program/../program/opencl/cl-test.ods")
at /home/michi/development/git/libreoffice/desktop/source/app/opencl.cxx:132
#33 0x00007ffff7ba7f54 in desktop::Desktop::CheckOpenCLCompute(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&) (xDesktop=uno::Reference to (framework::Desktop *) 0x5555569ad2f8)
--Type <RET> for more, q to quit, c to continue without paging--
at /home/michi/development/git/libreoffice/desktop/source/app/opencl.cxx:241
#34 0x00007ffff7b5719d in std::__invoke_impl<void, void (*)(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&), com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> >(std::__invoke_other, void (*&&)(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&), com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2>&&)
(__f=@0x5555573c20b0: 0x7ffff7ba7760 <desktop::Desktop::CheckOpenCLCompute(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&)>, __args=...)
at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/invoke.h:61
#35 0x00007ffff7b5712d in std::__invoke<void (*)(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&), com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> >(void (*&&)(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&), com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2>&&)
(__fn=@0x5555573c20b0: 0x7ffff7ba7760 <desktop::Desktop::CheckOpenCLCompute(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&)>, __args=...)
at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/invoke.h:96
#36 0x00007ffff7b57102 in std::thread::_Invoker<std::tuple<void (*)(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&), com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> > >::_M_invoke<0ul, 1ul>(std::_Index_tuple<0ul, 1ul>) (this=0x5555573c20a8) at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_thread.h:292
#37 0x00007ffff7b570c5 in std::thread::_Invoker<std::tuple<void (*)(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&), com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> > >::operator()()
(this=0x5555573c20a8) at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_thread.h:299
#38 0x00007ffff7b56e69 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&), com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> > > >::_M_run() (this=0x5555573c20a0) at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_thread.h:244
#39 0x00007ffff74dee24 in () at /lib/x86_64-linux-gnu/libstdc++.so.6
#40 0x00007ffff78a4dbb in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:444
#41 0x00007ffff79269f8 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78
Change-Id: Ic611eb26b140c060cba4d81603e506806cf43bab
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167778
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
2024-05-17 15:04:26 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-11-13 09:08:30 +01:00
|
|
|
if (m_nStyle
|
|
|
|
& (SalFrameStyleFlags::PLUG | SalFrameStyleFlags::SYSTEMCHILD
|
|
|
|
| SalFrameStyleFlags::FLOAT | SalFrameStyleFlags::INTRO
|
|
|
|
| SalFrameStyleFlags::OWNERDRAWDECORATION)
|
2018-08-09 17:14:14 +02:00
|
|
|
|| !isWindow())
|
2017-10-30 18:33:06 +01:00
|
|
|
return;
|
|
|
|
|
2019-05-10 10:09:21 +02:00
|
|
|
QString appicon;
|
2017-10-30 18:33:06 +01:00
|
|
|
|
|
|
|
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);
|
2024-02-12 14:09:45 +01:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::SetMenu(SalMenu*) {}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::SetExtendedFrameStyle(SalExtStyle /*nExtStyle*/) { /* not needed */}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::Show(bool bVisible, bool bNoActivate)
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2024-09-19 08:57:41 +02:00
|
|
|
SolarMutexGuard g;
|
2024-09-27 09:08:43 +02:00
|
|
|
QtInstance& rQtInstance = GetQtInstance();
|
|
|
|
if (!rQtInstance.IsMainThread())
|
2024-09-19 08:57:41 +02:00
|
|
|
{
|
2024-09-27 09:08:43 +02:00
|
|
|
rQtInstance.RunInMainThread([&] { Show(bVisible, bNoActivate); });
|
2024-09-19 08:57:41 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-08-09 17:14:14 +02:00
|
|
|
assert(m_pQWidget);
|
2021-04-15 00:37:55 +02:00
|
|
|
if (bVisible == asChild()->isVisible())
|
|
|
|
return;
|
2018-08-29 14:04:56 +02:00
|
|
|
|
2021-10-31 02:33:46 +02:00
|
|
|
if (!bVisible) // hide
|
|
|
|
{
|
2024-09-19 08:57:41 +02:00
|
|
|
asChild()->setVisible(false);
|
2021-10-31 02:33:46 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
qt a11y: Defer QWindow creation until frame gets shown
Calling QtFrame::windowHandle makes sure that the
QWindow exists, by calling
QWidget::setAttribute(Qt::WA_NativeWindow).
QWindows that don't have the Qt::Popup or Qt::Desktop
type, are listed as accessible children of the application,
see QAccessibleApplication::child [1] in qtbase and the
`topLevelObjects()` [2] helper method it uses.
This resulted in various dummy "top-level" objects being
reported as children of the LibreOffice a11y app object,
and therefore shown in Accerciser.
For Writer, there are 2 instances for each of the popups for
the comboboxes in the formatting toolbar that get reported
as toplevels, as can seen by printing the accessible ID of
their parent objects in Accerciser (they have a parent different
from the app, since they're not actually top-levels):
Paragraph style combobox:
In [4]: acc.parent.accessibleId
Out[4]: 'applystyle'
Font name combobox:
In [5]: acc.parent.accessibleId
Out[5]: 'fontnamecombobox'
Font size comobobox:
In [6]: acc.parent.accessibleId
Out[6]: 'fontsizecombobox'
While these *are* popups, the Qt::Popup type is currently
not used for them in LO to work around another issue
with these popus on Wayland, but the Qt::Tooltip type
is used, see the QtFrame ctor and comments there.
To prevent these wrong "top-levels" from always being
part of the a11y tree due to that, defer creating the QWindow
by calling QtFrame::windowHandle to when the window
is actually needed, in QtFrame::Show.
Pass the Qt::UniqueConnection connection type param
in the call to QObject::connect [3], to avoid
duplicate connections if the frame gets hidden/shown
multiple times. (Other than the ctor, QtFrame::Show
could potentially get called multiple times.)
With this in place, Accerciser now only shows a single
top-level frame after starting LO Writer with the qt6
VCL plugin, which is the actual Writer window.
[1] https://code.qt.io/cgit/qt/qtbase.git/tree/src/gui/accessible/qaccessibleobject.cpp?id=0681e720a9851f1873ce5a5f99b5567d2b418261#n160]
[2] https://code.qt.io/cgit/qt/qtbase.git/tree/src/gui/accessible/qaccessibleobject.cpp?id=0681e720a9851f1873ce5a5f99b5567d2b418261#n122
[3] https://doc.qt.io/qt-6/qobject.html#connect
Change-Id: I7aff5c435dfa8b6aadcbbedb0d84db19bb86c8ab
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173656
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-09-19 09:15:37 +02:00
|
|
|
QWindow* pChildWindow = windowHandle();
|
|
|
|
connect(pChildWindow, &QWindow::screenChanged, this, &QtFrame::screenChanged,
|
|
|
|
Qt::UniqueConnection);
|
|
|
|
|
|
|
|
if (m_pParent && !(m_pParent->m_nStyle & SalFrameStyleFlags::PLUG))
|
|
|
|
{
|
|
|
|
QWindow* pParentWindow = m_pParent->windowHandle();
|
|
|
|
if (pParentWindow && pChildWindow && (pParentWindow != pChildWindow))
|
|
|
|
pChildWindow->setTransientParent(pParentWindow);
|
|
|
|
}
|
|
|
|
|
2021-10-31 02:33:46 +02:00
|
|
|
// show
|
2019-06-21 04:09:02 +00:00
|
|
|
SetDefaultSize();
|
2018-08-29 14:04:56 +02:00
|
|
|
|
2024-09-19 08:57:41 +02:00
|
|
|
QWidget* const pChild = asChild();
|
|
|
|
pChild->setVisible(true);
|
|
|
|
pChild->raise();
|
|
|
|
if (!bNoActivate)
|
|
|
|
{
|
|
|
|
pChild->activateWindow();
|
|
|
|
pChild->setFocus();
|
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::SetMinClientSize(tools::Long nWidth, tools::Long nHeight)
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2017-10-31 01:07:06 +01:00
|
|
|
if (!isChild())
|
tdf#127687 Qt5 introduce basic HiDPI scaling
For tdf#124292, Qt's own HiDPI scaling was explicitly disabled,
but it turns out, you can't really scale QStyle painting then.
This patch series had a 2nd approach also used by Gtk+ currently,
which relied on the scaling of ths Cairo surface, which works
surprisingly good, but has to lie about the real DPI value, so
nothing is scaled twice. Also all icons are then scaled instead
of rendered with the proper resolution.
When HiDPI support in Qt is enabled, and the application is
started using QT_SCALE_FACTOR=1.25, Qt simply lowers the reported
resolution, keeps the logical DPI value of 96 and changes the
devicePixelRatio to the specified value. But LO still expects
the real DPI values and sizes, so we have to multiply a lot of
rectangles, sizes and positions.
The current result is far from perfect, which you can see with
the various graphics glitches, but it at least doesn't crash
anymore in the ControlType::Editbox sizing code.
The main problem is all the up and downscaling in the
getNativeControlRegion code, so LO knows the size of the widgets
for the correct layouting, since there seem to be no API to
get the scaled values from Qt / QStyle.
Change-Id: I687b1df6ef27724ce68326d256e9addccd72e759
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86239
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
2020-02-29 13:39:29 +01:00
|
|
|
{
|
|
|
|
const qreal fRatio = devicePixelRatioF();
|
|
|
|
asChild()->setMinimumSize(round(nWidth / fRatio), round(nHeight / fRatio));
|
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::SetMaxClientSize(tools::Long nWidth, tools::Long nHeight)
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2017-10-31 01:07:06 +01:00
|
|
|
if (!isChild())
|
tdf#127687 Qt5 introduce basic HiDPI scaling
For tdf#124292, Qt's own HiDPI scaling was explicitly disabled,
but it turns out, you can't really scale QStyle painting then.
This patch series had a 2nd approach also used by Gtk+ currently,
which relied on the scaling of ths Cairo surface, which works
surprisingly good, but has to lie about the real DPI value, so
nothing is scaled twice. Also all icons are then scaled instead
of rendered with the proper resolution.
When HiDPI support in Qt is enabled, and the application is
started using QT_SCALE_FACTOR=1.25, Qt simply lowers the reported
resolution, keeps the logical DPI value of 96 and changes the
devicePixelRatio to the specified value. But LO still expects
the real DPI values and sizes, so we have to multiply a lot of
rectangles, sizes and positions.
The current result is far from perfect, which you can see with
the various graphics glitches, but it at least doesn't crash
anymore in the ControlType::Editbox sizing code.
The main problem is all the up and downscaling in the
getNativeControlRegion code, so LO knows the size of the widgets
for the correct layouting, since there seem to be no API to
get the scaled values from Qt / QStyle.
Change-Id: I687b1df6ef27724ce68326d256e9addccd72e759
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86239
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
2020-02-29 13:39:29 +01:00
|
|
|
{
|
|
|
|
const qreal fRatio = devicePixelRatioF();
|
|
|
|
asChild()->setMaximumSize(round(nWidth / fRatio), round(nHeight / fRatio));
|
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::SetDefaultPos()
|
2017-10-30 19:44:40 +01:00
|
|
|
{
|
2019-06-24 06:37:45 +02:00
|
|
|
if (!m_bDefaultPos)
|
|
|
|
return;
|
|
|
|
|
2023-03-24 08:06:56 +01:00
|
|
|
// center on parent
|
2017-10-30 19:44:40 +01:00
|
|
|
if (m_pParent)
|
|
|
|
{
|
2023-03-24 08:06:56 +01:00
|
|
|
const qreal fRatio = devicePixelRatioF();
|
2021-12-20 13:02:33 +01:00
|
|
|
QWidget* const pParentWin = m_pParent->asChild()->window();
|
2023-03-24 08:06:56 +01:00
|
|
|
QWidget* const pChildWin = asChild()->window();
|
|
|
|
QPoint aPos = (pParentWin->rect().center() - pChildWin->rect().center()) * fRatio;
|
|
|
|
SetPosSize(aPos.x(), aPos.y(), 0, 0, SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y);
|
|
|
|
assert(!m_bDefaultPos);
|
2017-10-30 19:44:40 +01:00
|
|
|
}
|
2019-06-24 06:37:45 +02:00
|
|
|
else
|
2023-03-24 08:06:56 +01:00
|
|
|
m_bDefaultPos = false;
|
2017-10-30 19:44:40 +01:00
|
|
|
}
|
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
Size QtFrame::CalcDefaultSize()
|
2017-10-30 19:44:40 +01:00
|
|
|
{
|
2018-08-09 17:14:14 +02:00
|
|
|
assert(isWindow());
|
2018-08-29 14:04:56 +02:00
|
|
|
|
2019-05-29 19:01:28 +02:00
|
|
|
Size aSize;
|
2018-12-14 12:39:44 +03:00
|
|
|
if (!m_bFullScreen)
|
2019-05-29 19:01:28 +02:00
|
|
|
{
|
|
|
|
const QScreen* pScreen = screen();
|
2021-09-24 06:39:09 +02:00
|
|
|
if (!pScreen)
|
|
|
|
pScreen = QGuiApplication::screens().at(0);
|
|
|
|
aSize = bestmaxFrameSizeForScreenSize(toSize(pScreen->size()));
|
2019-05-29 19:01:28 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!m_bFullScreenSpanAll)
|
2020-01-13 09:55:12 +01:00
|
|
|
{
|
2024-09-27 11:06:55 +02:00
|
|
|
aSize = toSize(screen()->size());
|
2020-01-13 09:55:12 +01:00
|
|
|
}
|
2019-05-29 19:01:28 +02:00
|
|
|
else
|
|
|
|
{
|
2021-09-24 06:39:09 +02:00
|
|
|
QScreen* pScreen = QGuiApplication::screenAt(QPoint(0, 0));
|
|
|
|
aSize = toSize(pScreen->availableVirtualGeometry().size());
|
2019-05-29 19:01:28 +02:00
|
|
|
}
|
|
|
|
}
|
2018-12-14 12:39:44 +03:00
|
|
|
|
|
|
|
return aSize;
|
2017-10-30 19:44:40 +01:00
|
|
|
}
|
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::SetDefaultSize()
|
2017-10-30 19:44:40 +01:00
|
|
|
{
|
2019-06-21 04:09:02 +00:00
|
|
|
if (!m_bDefaultSize)
|
|
|
|
return;
|
|
|
|
|
2017-10-30 19:44:40 +01:00
|
|
|
Size aDefSize = CalcDefaultSize();
|
|
|
|
SetPosSize(0, 0, aDefSize.Width(), aDefSize.Height(),
|
|
|
|
SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT);
|
2019-06-21 04:09:02 +00:00
|
|
|
assert(!m_bDefaultSize);
|
2017-10-30 19:44:40 +01:00
|
|
|
}
|
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::SetPosSize(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight,
|
|
|
|
sal_uInt16 nFlags)
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
tdf#162696 qt: Always run QtFrame::SetPosSize in main thread
This fixes the following assert seen with the qt6 VCL plugin
when run with a current Qt 6 dev debug build for the tdf#162696
scenario when when native Qt widgets (currently only message dialogs
are implmeneted) are explicitly disabled using
`SAL_VCL_QT_NO_WELDED_WIDGETS=1`.
ASSERT failure in QWidget: "Widgets must be created in the GUI thread.", file /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qwidget.cpp, line 958
terminate called after throwing an instance of 'com::sun::star::uno::RuntimeException'
Fatal exception: Signal 6
Stack:
#0 sal::backtrace_get(unsigned int) at /home/michi/development/git/libreoffice/sal/osl/unx/backtraceapi.cxx:42
#1 (anonymous namespace)::printStack(int) at /home/michi/development/git/libreoffice/sal/osl/unx/signal.cxx:289
#2 (anonymous namespace)::callSystemHandler(int, siginfo_t*, void*) at /home/michi/development/git/libreoffice/sal/osl/unx/signal.cxx:330
#3 (anonymous namespace)::signalHandlerFunction(int, siginfo_t*, void*) at /home/michi/development/git/libreoffice/sal/osl/unx/signal.cxx:427
#4 /lib/x86_64-linux-gnu/libc.so.6(+0x3f590) [0x7f73cbe55590]
#5 __pthread_kill_implementation at ./nptl/pthread_kill.c:44 (discriminator 1)
#6 raise at ./signal/../sysdeps/posix/raise.c:27
#7 abort at ./stdlib/abort.c:81
#8 /lib/x86_64-linux-gnu/libstdc++.so.6(+0xa1a3d) [0x7f73cbaa1a3d]
#9 /lib/x86_64-linux-gnu/libstdc++.so.6(+0xb306a) [0x7f73cbab306a]
#10 std::unexpected() in /lib/x86_64-linux-gnu/libstdc++.so.6
#11 /home/michi/development/git/qt5/qtbase/lib/libQt6Core.so.6(+0xed562) [0x7f73b78ed562]
#12 QMessageLogger::fatal() const at /home/michi/development/git/qt5/qtbase/src/corelib/global/qlogging.cpp:901
#13 qt_assert_x(char const*, char const*, char const*, int) at /home/michi/development/git/qt5/qtbase/src/corelib/global/qassert.cpp:0
#14 QWidgetPrivate::init(QWidget*, QFlags<Qt::WindowType>) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qwidget.cpp:959
#15 QWidget::QWidget(QWidgetPrivate&, QWidget*, QFlags<Qt::WindowType>) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qwidget.cpp:878
#16 QMenuBar::QMenuBar(QWidget*) at /home/michi/development/git/qt5/qtbase/src/widgets/widgets/qmenubar.cpp:715
#17 QMainWindow::menuBar() const at /home/michi/development/git/qt5/qtbase/src/widgets/widgets/qmainwindow.cpp:468
#18 QtFrame::menuBarOffset() const at /home/michi/development/git/libreoffice/vcl/qt6/../qt5/QtFrame.cxx:462
#19 QtFrame::SetDefaultPos() at /home/michi/development/git/libreoffice/vcl/qt6/../qt5/QtFrame.cxx:479
#20 QtFrame::SetPosSize(long, long, long, long, unsigned short) at /home/michi/development/git/libreoffice/vcl/qt6/../qt5/QtFrame.cxx:565
#21 vcl::Window::setPosSizePixel(long, long, long, long, PosSizeFlags) at /home/michi/development/git/libreoffice/vcl/source/window/window.cxx:2786
#22 vcl::Window::SetSizePixel(Size const&) at /home/michi/development/git/libreoffice/vcl/source/window/window2.cxx:1344
#23 SystemWindow::setOptimalLayoutSize(bool) at /home/michi/development/git/libreoffice/vcl/source/window/syswin.cxx:1085
#24 SystemWindow::DoInitialLayout() at /home/michi/development/git/libreoffice/vcl/source/window/syswin.cxx:1098
#25 Dialog::StateChanged(StateChangedType) at /home/michi/development/git/libreoffice/vcl/source/window/dialog.cxx:761
#26 MessageDialog::StateChanged(StateChangedType) at /home/michi/development/git/libreoffice/vcl/source/window/layout.cxx:2706
#27 vcl::Window::CompatStateChanged(StateChangedType) at /home/michi/development/git/libreoffice/vcl/source/window/window.cxx:3921
#28 vcl::Window::ImplCallInitShow() at /home/michi/development/git/libreoffice/vcl/source/window/event.cxx:496
#29 vcl::Window::Show(bool, ShowFlags) at /home/michi/development/git/libreoffice/vcl/source/window/window.cxx:2312
#30 Dialog::ImplStartExecute() at /home/michi/development/git/libreoffice/vcl/source/window/dialog.cxx:1021
#31 Dialog::Execute() at /home/michi/development/git/libreoffice/vcl/source/window/dialog.cxx:1071
#32 SalInstanceDialog::run() at /home/michi/development/git/libreoffice/vcl/source/app/salvtables.cxx:1898
#33 dp_gui::(anonymous namespace)::ProgressCmdEnv::handle(com::sun::star::uno::Reference<com::sun::star::task::XInteractionRequest> const&) at /home/michi/development/git/libreoffice/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx:459
#34 dp_misc::interactContinuation(com::sun::star::uno::Any const&, com::sun::star::uno::Type const&, com::sun::star::uno::Reference<com::sun::star::ucb::XCommandEnvironment> const&, bool*, bool*) at /home/michi/development/git/libreoffice/desktop/source/deployment/misc/dp_interact.cxx:114
#35 dp_manager::ExtensionManager::checkUpdate(rtl::OUString const&, rtl::OUString const&, com::sun::star::uno::Reference<com::sun::star::deployment::XPackage> const&, com::sun::star::uno::Reference<com::sun::star::ucb::XCommandEnvironment> const&) at /home/michi/development/git/libreoffice/desktop/source/deployment/manager/dp_extensionmanager.cxx:1348
[...]
Change-Id: I9eb0ac63c50de3c713328d0466cb01ea90251741
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172685
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-08-30 17:20:41 +02:00
|
|
|
SolarMutexGuard g;
|
2024-09-27 09:08:43 +02:00
|
|
|
QtInstance& rQtInstance = GetQtInstance();
|
|
|
|
if (!rQtInstance.IsMainThread())
|
tdf#162696 qt: Always run QtFrame::SetPosSize in main thread
This fixes the following assert seen with the qt6 VCL plugin
when run with a current Qt 6 dev debug build for the tdf#162696
scenario when when native Qt widgets (currently only message dialogs
are implmeneted) are explicitly disabled using
`SAL_VCL_QT_NO_WELDED_WIDGETS=1`.
ASSERT failure in QWidget: "Widgets must be created in the GUI thread.", file /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qwidget.cpp, line 958
terminate called after throwing an instance of 'com::sun::star::uno::RuntimeException'
Fatal exception: Signal 6
Stack:
#0 sal::backtrace_get(unsigned int) at /home/michi/development/git/libreoffice/sal/osl/unx/backtraceapi.cxx:42
#1 (anonymous namespace)::printStack(int) at /home/michi/development/git/libreoffice/sal/osl/unx/signal.cxx:289
#2 (anonymous namespace)::callSystemHandler(int, siginfo_t*, void*) at /home/michi/development/git/libreoffice/sal/osl/unx/signal.cxx:330
#3 (anonymous namespace)::signalHandlerFunction(int, siginfo_t*, void*) at /home/michi/development/git/libreoffice/sal/osl/unx/signal.cxx:427
#4 /lib/x86_64-linux-gnu/libc.so.6(+0x3f590) [0x7f73cbe55590]
#5 __pthread_kill_implementation at ./nptl/pthread_kill.c:44 (discriminator 1)
#6 raise at ./signal/../sysdeps/posix/raise.c:27
#7 abort at ./stdlib/abort.c:81
#8 /lib/x86_64-linux-gnu/libstdc++.so.6(+0xa1a3d) [0x7f73cbaa1a3d]
#9 /lib/x86_64-linux-gnu/libstdc++.so.6(+0xb306a) [0x7f73cbab306a]
#10 std::unexpected() in /lib/x86_64-linux-gnu/libstdc++.so.6
#11 /home/michi/development/git/qt5/qtbase/lib/libQt6Core.so.6(+0xed562) [0x7f73b78ed562]
#12 QMessageLogger::fatal() const at /home/michi/development/git/qt5/qtbase/src/corelib/global/qlogging.cpp:901
#13 qt_assert_x(char const*, char const*, char const*, int) at /home/michi/development/git/qt5/qtbase/src/corelib/global/qassert.cpp:0
#14 QWidgetPrivate::init(QWidget*, QFlags<Qt::WindowType>) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qwidget.cpp:959
#15 QWidget::QWidget(QWidgetPrivate&, QWidget*, QFlags<Qt::WindowType>) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qwidget.cpp:878
#16 QMenuBar::QMenuBar(QWidget*) at /home/michi/development/git/qt5/qtbase/src/widgets/widgets/qmenubar.cpp:715
#17 QMainWindow::menuBar() const at /home/michi/development/git/qt5/qtbase/src/widgets/widgets/qmainwindow.cpp:468
#18 QtFrame::menuBarOffset() const at /home/michi/development/git/libreoffice/vcl/qt6/../qt5/QtFrame.cxx:462
#19 QtFrame::SetDefaultPos() at /home/michi/development/git/libreoffice/vcl/qt6/../qt5/QtFrame.cxx:479
#20 QtFrame::SetPosSize(long, long, long, long, unsigned short) at /home/michi/development/git/libreoffice/vcl/qt6/../qt5/QtFrame.cxx:565
#21 vcl::Window::setPosSizePixel(long, long, long, long, PosSizeFlags) at /home/michi/development/git/libreoffice/vcl/source/window/window.cxx:2786
#22 vcl::Window::SetSizePixel(Size const&) at /home/michi/development/git/libreoffice/vcl/source/window/window2.cxx:1344
#23 SystemWindow::setOptimalLayoutSize(bool) at /home/michi/development/git/libreoffice/vcl/source/window/syswin.cxx:1085
#24 SystemWindow::DoInitialLayout() at /home/michi/development/git/libreoffice/vcl/source/window/syswin.cxx:1098
#25 Dialog::StateChanged(StateChangedType) at /home/michi/development/git/libreoffice/vcl/source/window/dialog.cxx:761
#26 MessageDialog::StateChanged(StateChangedType) at /home/michi/development/git/libreoffice/vcl/source/window/layout.cxx:2706
#27 vcl::Window::CompatStateChanged(StateChangedType) at /home/michi/development/git/libreoffice/vcl/source/window/window.cxx:3921
#28 vcl::Window::ImplCallInitShow() at /home/michi/development/git/libreoffice/vcl/source/window/event.cxx:496
#29 vcl::Window::Show(bool, ShowFlags) at /home/michi/development/git/libreoffice/vcl/source/window/window.cxx:2312
#30 Dialog::ImplStartExecute() at /home/michi/development/git/libreoffice/vcl/source/window/dialog.cxx:1021
#31 Dialog::Execute() at /home/michi/development/git/libreoffice/vcl/source/window/dialog.cxx:1071
#32 SalInstanceDialog::run() at /home/michi/development/git/libreoffice/vcl/source/app/salvtables.cxx:1898
#33 dp_gui::(anonymous namespace)::ProgressCmdEnv::handle(com::sun::star::uno::Reference<com::sun::star::task::XInteractionRequest> const&) at /home/michi/development/git/libreoffice/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx:459
#34 dp_misc::interactContinuation(com::sun::star::uno::Any const&, com::sun::star::uno::Type const&, com::sun::star::uno::Reference<com::sun::star::ucb::XCommandEnvironment> const&, bool*, bool*) at /home/michi/development/git/libreoffice/desktop/source/deployment/misc/dp_interact.cxx:114
#35 dp_manager::ExtensionManager::checkUpdate(rtl::OUString const&, rtl::OUString const&, com::sun::star::uno::Reference<com::sun::star::deployment::XPackage> const&, com::sun::star::uno::Reference<com::sun::star::ucb::XCommandEnvironment> const&) at /home/michi/development/git/libreoffice/desktop/source/deployment/manager/dp_extensionmanager.cxx:1348
[...]
Change-Id: I9eb0ac63c50de3c713328d0466cb01ea90251741
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172685
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-08-30 17:20:41 +02:00
|
|
|
{
|
2024-09-27 09:08:43 +02:00
|
|
|
rQtInstance.RunInMainThread([&] { SetPosSize(nX, nY, nWidth, nHeight, nFlags); });
|
tdf#162696 qt: Always run QtFrame::SetPosSize in main thread
This fixes the following assert seen with the qt6 VCL plugin
when run with a current Qt 6 dev debug build for the tdf#162696
scenario when when native Qt widgets (currently only message dialogs
are implmeneted) are explicitly disabled using
`SAL_VCL_QT_NO_WELDED_WIDGETS=1`.
ASSERT failure in QWidget: "Widgets must be created in the GUI thread.", file /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qwidget.cpp, line 958
terminate called after throwing an instance of 'com::sun::star::uno::RuntimeException'
Fatal exception: Signal 6
Stack:
#0 sal::backtrace_get(unsigned int) at /home/michi/development/git/libreoffice/sal/osl/unx/backtraceapi.cxx:42
#1 (anonymous namespace)::printStack(int) at /home/michi/development/git/libreoffice/sal/osl/unx/signal.cxx:289
#2 (anonymous namespace)::callSystemHandler(int, siginfo_t*, void*) at /home/michi/development/git/libreoffice/sal/osl/unx/signal.cxx:330
#3 (anonymous namespace)::signalHandlerFunction(int, siginfo_t*, void*) at /home/michi/development/git/libreoffice/sal/osl/unx/signal.cxx:427
#4 /lib/x86_64-linux-gnu/libc.so.6(+0x3f590) [0x7f73cbe55590]
#5 __pthread_kill_implementation at ./nptl/pthread_kill.c:44 (discriminator 1)
#6 raise at ./signal/../sysdeps/posix/raise.c:27
#7 abort at ./stdlib/abort.c:81
#8 /lib/x86_64-linux-gnu/libstdc++.so.6(+0xa1a3d) [0x7f73cbaa1a3d]
#9 /lib/x86_64-linux-gnu/libstdc++.so.6(+0xb306a) [0x7f73cbab306a]
#10 std::unexpected() in /lib/x86_64-linux-gnu/libstdc++.so.6
#11 /home/michi/development/git/qt5/qtbase/lib/libQt6Core.so.6(+0xed562) [0x7f73b78ed562]
#12 QMessageLogger::fatal() const at /home/michi/development/git/qt5/qtbase/src/corelib/global/qlogging.cpp:901
#13 qt_assert_x(char const*, char const*, char const*, int) at /home/michi/development/git/qt5/qtbase/src/corelib/global/qassert.cpp:0
#14 QWidgetPrivate::init(QWidget*, QFlags<Qt::WindowType>) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qwidget.cpp:959
#15 QWidget::QWidget(QWidgetPrivate&, QWidget*, QFlags<Qt::WindowType>) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qwidget.cpp:878
#16 QMenuBar::QMenuBar(QWidget*) at /home/michi/development/git/qt5/qtbase/src/widgets/widgets/qmenubar.cpp:715
#17 QMainWindow::menuBar() const at /home/michi/development/git/qt5/qtbase/src/widgets/widgets/qmainwindow.cpp:468
#18 QtFrame::menuBarOffset() const at /home/michi/development/git/libreoffice/vcl/qt6/../qt5/QtFrame.cxx:462
#19 QtFrame::SetDefaultPos() at /home/michi/development/git/libreoffice/vcl/qt6/../qt5/QtFrame.cxx:479
#20 QtFrame::SetPosSize(long, long, long, long, unsigned short) at /home/michi/development/git/libreoffice/vcl/qt6/../qt5/QtFrame.cxx:565
#21 vcl::Window::setPosSizePixel(long, long, long, long, PosSizeFlags) at /home/michi/development/git/libreoffice/vcl/source/window/window.cxx:2786
#22 vcl::Window::SetSizePixel(Size const&) at /home/michi/development/git/libreoffice/vcl/source/window/window2.cxx:1344
#23 SystemWindow::setOptimalLayoutSize(bool) at /home/michi/development/git/libreoffice/vcl/source/window/syswin.cxx:1085
#24 SystemWindow::DoInitialLayout() at /home/michi/development/git/libreoffice/vcl/source/window/syswin.cxx:1098
#25 Dialog::StateChanged(StateChangedType) at /home/michi/development/git/libreoffice/vcl/source/window/dialog.cxx:761
#26 MessageDialog::StateChanged(StateChangedType) at /home/michi/development/git/libreoffice/vcl/source/window/layout.cxx:2706
#27 vcl::Window::CompatStateChanged(StateChangedType) at /home/michi/development/git/libreoffice/vcl/source/window/window.cxx:3921
#28 vcl::Window::ImplCallInitShow() at /home/michi/development/git/libreoffice/vcl/source/window/event.cxx:496
#29 vcl::Window::Show(bool, ShowFlags) at /home/michi/development/git/libreoffice/vcl/source/window/window.cxx:2312
#30 Dialog::ImplStartExecute() at /home/michi/development/git/libreoffice/vcl/source/window/dialog.cxx:1021
#31 Dialog::Execute() at /home/michi/development/git/libreoffice/vcl/source/window/dialog.cxx:1071
#32 SalInstanceDialog::run() at /home/michi/development/git/libreoffice/vcl/source/app/salvtables.cxx:1898
#33 dp_gui::(anonymous namespace)::ProgressCmdEnv::handle(com::sun::star::uno::Reference<com::sun::star::task::XInteractionRequest> const&) at /home/michi/development/git/libreoffice/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx:459
#34 dp_misc::interactContinuation(com::sun::star::uno::Any const&, com::sun::star::uno::Type const&, com::sun::star::uno::Reference<com::sun::star::ucb::XCommandEnvironment> const&, bool*, bool*) at /home/michi/development/git/libreoffice/desktop/source/deployment/misc/dp_interact.cxx:114
#35 dp_manager::ExtensionManager::checkUpdate(rtl::OUString const&, rtl::OUString const&, com::sun::star::uno::Reference<com::sun::star::deployment::XPackage> const&, com::sun::star::uno::Reference<com::sun::star::ucb::XCommandEnvironment> const&) at /home/michi/development/git/libreoffice/desktop/source/deployment/manager/dp_extensionmanager.cxx:1348
[...]
Change-Id: I9eb0ac63c50de3c713328d0466cb01ea90251741
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172685
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-08-30 17:20:41 +02:00
|
|
|
}
|
|
|
|
|
2018-08-09 17:14:14 +02:00
|
|
|
if (!isWindow() || isChild(true, false))
|
2017-10-30 19:44:40 +01:00
|
|
|
return;
|
|
|
|
|
2019-06-21 04:09:02 +00:00
|
|
|
if (nFlags & (SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT))
|
2017-10-30 19:44:40 +01:00
|
|
|
{
|
|
|
|
if (isChild(false) || !m_pQWidget->isMaximized())
|
|
|
|
{
|
2019-06-21 04:09:02 +00:00
|
|
|
if (!(nFlags & SAL_FRAME_POSSIZE_WIDTH))
|
2024-09-26 15:20:57 +02:00
|
|
|
nWidth = GetWidth();
|
2019-06-21 04:09:02 +00:00
|
|
|
else if (!(nFlags & SAL_FRAME_POSSIZE_HEIGHT))
|
2024-09-26 15:20:57 +02:00
|
|
|
nHeight = GetHeight();
|
2019-06-21 04:09:02 +00:00
|
|
|
|
|
|
|
if (nWidth > 0 && nHeight > 0)
|
|
|
|
{
|
2019-06-24 06:37:45 +02:00
|
|
|
m_bDefaultSize = false;
|
tdf#127687 Qt5 introduce basic HiDPI scaling
For tdf#124292, Qt's own HiDPI scaling was explicitly disabled,
but it turns out, you can't really scale QStyle painting then.
This patch series had a 2nd approach also used by Gtk+ currently,
which relied on the scaling of ths Cairo surface, which works
surprisingly good, but has to lie about the real DPI value, so
nothing is scaled twice. Also all icons are then scaled instead
of rendered with the proper resolution.
When HiDPI support in Qt is enabled, and the application is
started using QT_SCALE_FACTOR=1.25, Qt simply lowers the reported
resolution, keeps the logical DPI value of 96 and changes the
devicePixelRatio to the specified value. But LO still expects
the real DPI values and sizes, so we have to multiply a lot of
rectangles, sizes and positions.
The current result is far from perfect, which you can see with
the various graphics glitches, but it at least doesn't crash
anymore in the ControlType::Editbox sizing code.
The main problem is all the up and downscaling in the
getNativeControlRegion code, so LO knows the size of the widgets
for the correct layouting, since there seem to be no API to
get the scaled values from Qt / QStyle.
Change-Id: I687b1df6ef27724ce68326d256e9addccd72e759
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86239
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
2020-02-29 13:39:29 +01:00
|
|
|
const int nNewWidth = round(nWidth / devicePixelRatioF());
|
|
|
|
const int nNewHeight = round(nHeight / devicePixelRatioF());
|
2019-06-21 04:09:02 +00:00
|
|
|
if (m_nStyle & SalFrameStyleFlags::SIZEABLE)
|
tdf#127687 Qt5 introduce basic HiDPI scaling
For tdf#124292, Qt's own HiDPI scaling was explicitly disabled,
but it turns out, you can't really scale QStyle painting then.
This patch series had a 2nd approach also used by Gtk+ currently,
which relied on the scaling of ths Cairo surface, which works
surprisingly good, but has to lie about the real DPI value, so
nothing is scaled twice. Also all icons are then scaled instead
of rendered with the proper resolution.
When HiDPI support in Qt is enabled, and the application is
started using QT_SCALE_FACTOR=1.25, Qt simply lowers the reported
resolution, keeps the logical DPI value of 96 and changes the
devicePixelRatio to the specified value. But LO still expects
the real DPI values and sizes, so we have to multiply a lot of
rectangles, sizes and positions.
The current result is far from perfect, which you can see with
the various graphics glitches, but it at least doesn't crash
anymore in the ControlType::Editbox sizing code.
The main problem is all the up and downscaling in the
getNativeControlRegion code, so LO knows the size of the widgets
for the correct layouting, since there seem to be no API to
get the scaled values from Qt / QStyle.
Change-Id: I687b1df6ef27724ce68326d256e9addccd72e759
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86239
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
2020-02-29 13:39:29 +01:00
|
|
|
asChild()->resize(nNewWidth, nNewHeight);
|
2019-06-21 04:09:02 +00:00
|
|
|
else
|
tdf#127687 Qt5 introduce basic HiDPI scaling
For tdf#124292, Qt's own HiDPI scaling was explicitly disabled,
but it turns out, you can't really scale QStyle painting then.
This patch series had a 2nd approach also used by Gtk+ currently,
which relied on the scaling of ths Cairo surface, which works
surprisingly good, but has to lie about the real DPI value, so
nothing is scaled twice. Also all icons are then scaled instead
of rendered with the proper resolution.
When HiDPI support in Qt is enabled, and the application is
started using QT_SCALE_FACTOR=1.25, Qt simply lowers the reported
resolution, keeps the logical DPI value of 96 and changes the
devicePixelRatio to the specified value. But LO still expects
the real DPI values and sizes, so we have to multiply a lot of
rectangles, sizes and positions.
The current result is far from perfect, which you can see with
the various graphics glitches, but it at least doesn't crash
anymore in the ControlType::Editbox sizing code.
The main problem is all the up and downscaling in the
getNativeControlRegion code, so LO knows the size of the widgets
for the correct layouting, since there seem to be no API to
get the scaled values from Qt / QStyle.
Change-Id: I687b1df6ef27724ce68326d256e9addccd72e759
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86239
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
2020-02-29 13:39:29 +01:00
|
|
|
asChild()->setFixedSize(nNewWidth, nNewHeight);
|
2019-06-24 06:37:45 +02:00
|
|
|
}
|
2017-10-30 19:44:40 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-04 09:22:10 +02:00
|
|
|
if (!(nFlags & (SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y)))
|
2021-12-20 13:32:52 +01:00
|
|
|
{
|
|
|
|
if (nFlags & (SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT))
|
|
|
|
SetDefaultPos();
|
2020-08-04 09:22:10 +02:00
|
|
|
return;
|
2021-12-20 13:32:52 +01:00
|
|
|
}
|
2020-08-04 09:22:10 +02:00
|
|
|
|
|
|
|
if (m_pParent)
|
2017-10-30 19:44:40 +01:00
|
|
|
{
|
2024-09-26 15:20:57 +02:00
|
|
|
const SalFrameGeometry aParentGeometry = m_pParent->GetUnmirroredGeometry();
|
2020-08-04 09:22:10 +02:00
|
|
|
if (QGuiApplication::isRightToLeft())
|
2024-09-26 15:20:57 +02:00
|
|
|
nX = aParentGeometry.x() + aParentGeometry.width() - nX - GetWidth() - 1;
|
2020-08-04 09:22:10 +02:00
|
|
|
else
|
2023-03-24 08:06:56 +01:00
|
|
|
nX += aParentGeometry.x();
|
tdf#160837 qt: Rely on toolkit for frame positions, drop menubar hack
Make `SalFrame::GetUnmirroredGeometry` overridable
(and let it return a copy of the SalFrameGeometry
instead of a const reference) and document that
subclasses can either make sure to keep the
`SalFrame::maGeometry` member (which is returned by
the default implementation of
`SalFrame::GetUnmirroredGeometry`) up to date or override
the latter in order to always return the current
geometry.
Override the method in `QtFrame` and fully rely on Qt
to report and set the position of the frame, via
the corresponding QWidget: Set the position, width
and height in the returned `SalFrameGeometry`
to the ones of the widget (factoring in the
scale factor).
Stop updating `maGeometry` size/position whenever
the widget position or size changes, as that is no
longer used anymore now that `GetUnmirroredGeometry`
is overriden.
This also allows to drop earlier hacks where
position calculation in some places had to be adjusted
by the height of the native menu bar, as that one
doesn't have a corresponding vcl::Window, but results
in everything else being shifted down a bit.
Using Qt directly to set other members of the
returned `SalFrameGeometry` (like the screen number)
would probably be possible, but is not included
in this change. (It can still be done separately
later.)
This makes Accerciser highlight the correct area
when using the qt6 VCL plugin and using Writer
with the standard interface (where the y position
reported via AT-SPI2 would previously always be
too small, missing the menu bar height) and thus
e.g. also allows to make use of it's "select object
under mouse" feature (s. tdf#160837).
The position via AT-SPI is however currently only
correct on X11/XWayland where global/screen coordinates
are reported via AT-SPI2.
Wayland, where window-relative coordinates are used,
still suffers from another issue that will be addressed
in a separate commit.
The highlighting in Accerciser is also still wrong
when a screen scaling factor other than 100% is set,
but that's broken for other applications (e.g. gtk3-demo)
just the same, so might be an issue in Accerciser instead.
I successfully tested that these behave as expected
when using the qt6 VCL plugin with this change in place:
* Combobox popup positions, with either 100% screen scaling
or a scaling factor of 150% or 200% on both, X11 and
Wayland.
* When enabling RTL mode via env var `SAL_RTL_ENABLED=1`,
RTL layout is used and things look OK at a quick glance.
* The following bugs (somewhat related to positioning and/or
the now dropped menu bar hacks) are still fixed, i.e. don't
reappear:
* tdf#149805 "kf5: Gap when expanding comboboxes in toolbar"
* tdf#151677 "tip on "formula bar" for "formula making" is
displaying over the formula itself."
* tdf#152217 "Black box in Basic IDE where the status bar
should be (kf5 only)"
* tdf#153458 "Connecting to database: wrong cursor position
for dropping data to Calc sheet"
* tdf#153800 "Calc sheet tab drag-and-drop target area has
shifted vertically (kf5-only)"
* tdf#154043 "Change object layer via drag and drop has target
shifted down (KF5-only)"
* tdf#154447 "Clicking a dropdown tool button shouldn't
place the context menu on top of the button (kf5)"
Unrelated to this commit, popup positioning and rendering in
in a multi-screen setup on Wayland with different scaling
factors set for the single screens is still broken (see
tdf#141578).
Change-Id: Ifa0eff271c7d3fa2b6db9bdc1669e62333bd3094
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173996
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
2024-09-26 18:22:12 +02:00
|
|
|
nY += aParentGeometry.y();
|
2020-08-04 09:22:10 +02:00
|
|
|
}
|
2019-06-21 04:09:02 +00:00
|
|
|
|
2020-08-04 09:22:10 +02:00
|
|
|
if (!(nFlags & SAL_FRAME_POSSIZE_X))
|
2024-09-26 15:20:57 +02:00
|
|
|
nX = GetUnmirroredGeometry().x();
|
2020-08-04 09:22:10 +02:00
|
|
|
else if (!(nFlags & SAL_FRAME_POSSIZE_Y))
|
2024-09-26 15:20:57 +02:00
|
|
|
nY = GetUnmirroredGeometry().y();
|
2017-12-08 11:37:18 +00:00
|
|
|
|
2020-08-04 09:22:10 +02:00
|
|
|
m_bDefaultPos = false;
|
|
|
|
asChild()->move(round(nX / devicePixelRatioF()), round(nY / devicePixelRatioF()));
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::GetClientSize(tools::Long& rWidth, tools::Long& rHeight)
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2023-03-24 08:06:56 +01:00
|
|
|
rWidth = round(m_pQWidget->width() * devicePixelRatioF());
|
|
|
|
rHeight = round(m_pQWidget->height() * devicePixelRatioF());
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
tdf#160837 qt: Rely on toolkit for frame positions, drop menubar hack
Make `SalFrame::GetUnmirroredGeometry` overridable
(and let it return a copy of the SalFrameGeometry
instead of a const reference) and document that
subclasses can either make sure to keep the
`SalFrame::maGeometry` member (which is returned by
the default implementation of
`SalFrame::GetUnmirroredGeometry`) up to date or override
the latter in order to always return the current
geometry.
Override the method in `QtFrame` and fully rely on Qt
to report and set the position of the frame, via
the corresponding QWidget: Set the position, width
and height in the returned `SalFrameGeometry`
to the ones of the widget (factoring in the
scale factor).
Stop updating `maGeometry` size/position whenever
the widget position or size changes, as that is no
longer used anymore now that `GetUnmirroredGeometry`
is overriden.
This also allows to drop earlier hacks where
position calculation in some places had to be adjusted
by the height of the native menu bar, as that one
doesn't have a corresponding vcl::Window, but results
in everything else being shifted down a bit.
Using Qt directly to set other members of the
returned `SalFrameGeometry` (like the screen number)
would probably be possible, but is not included
in this change. (It can still be done separately
later.)
This makes Accerciser highlight the correct area
when using the qt6 VCL plugin and using Writer
with the standard interface (where the y position
reported via AT-SPI2 would previously always be
too small, missing the menu bar height) and thus
e.g. also allows to make use of it's "select object
under mouse" feature (s. tdf#160837).
The position via AT-SPI is however currently only
correct on X11/XWayland where global/screen coordinates
are reported via AT-SPI2.
Wayland, where window-relative coordinates are used,
still suffers from another issue that will be addressed
in a separate commit.
The highlighting in Accerciser is also still wrong
when a screen scaling factor other than 100% is set,
but that's broken for other applications (e.g. gtk3-demo)
just the same, so might be an issue in Accerciser instead.
I successfully tested that these behave as expected
when using the qt6 VCL plugin with this change in place:
* Combobox popup positions, with either 100% screen scaling
or a scaling factor of 150% or 200% on both, X11 and
Wayland.
* When enabling RTL mode via env var `SAL_RTL_ENABLED=1`,
RTL layout is used and things look OK at a quick glance.
* The following bugs (somewhat related to positioning and/or
the now dropped menu bar hacks) are still fixed, i.e. don't
reappear:
* tdf#149805 "kf5: Gap when expanding comboboxes in toolbar"
* tdf#151677 "tip on "formula bar" for "formula making" is
displaying over the formula itself."
* tdf#152217 "Black box in Basic IDE where the status bar
should be (kf5 only)"
* tdf#153458 "Connecting to database: wrong cursor position
for dropping data to Calc sheet"
* tdf#153800 "Calc sheet tab drag-and-drop target area has
shifted vertically (kf5-only)"
* tdf#154043 "Change object layer via drag and drop has target
shifted down (KF5-only)"
* tdf#154447 "Clicking a dropdown tool button shouldn't
place the context menu on top of the button (kf5)"
Unrelated to this commit, popup positioning and rendering in
in a multi-screen setup on Wayland with different scaling
factors set for the single screens is still broken (see
tdf#141578).
Change-Id: Ifa0eff271c7d3fa2b6db9bdc1669e62333bd3094
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173996
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
2024-09-26 18:22:12 +02:00
|
|
|
SalFrameGeometry QtFrame::GetUnmirroredGeometry() const
|
|
|
|
{
|
2024-09-27 11:17:05 +02:00
|
|
|
SalFrameGeometry aGeometry;
|
tdf#160837 qt: Rely on toolkit for frame positions, drop menubar hack
Make `SalFrame::GetUnmirroredGeometry` overridable
(and let it return a copy of the SalFrameGeometry
instead of a const reference) and document that
subclasses can either make sure to keep the
`SalFrame::maGeometry` member (which is returned by
the default implementation of
`SalFrame::GetUnmirroredGeometry`) up to date or override
the latter in order to always return the current
geometry.
Override the method in `QtFrame` and fully rely on Qt
to report and set the position of the frame, via
the corresponding QWidget: Set the position, width
and height in the returned `SalFrameGeometry`
to the ones of the widget (factoring in the
scale factor).
Stop updating `maGeometry` size/position whenever
the widget position or size changes, as that is no
longer used anymore now that `GetUnmirroredGeometry`
is overriden.
This also allows to drop earlier hacks where
position calculation in some places had to be adjusted
by the height of the native menu bar, as that one
doesn't have a corresponding vcl::Window, but results
in everything else being shifted down a bit.
Using Qt directly to set other members of the
returned `SalFrameGeometry` (like the screen number)
would probably be possible, but is not included
in this change. (It can still be done separately
later.)
This makes Accerciser highlight the correct area
when using the qt6 VCL plugin and using Writer
with the standard interface (where the y position
reported via AT-SPI2 would previously always be
too small, missing the menu bar height) and thus
e.g. also allows to make use of it's "select object
under mouse" feature (s. tdf#160837).
The position via AT-SPI is however currently only
correct on X11/XWayland where global/screen coordinates
are reported via AT-SPI2.
Wayland, where window-relative coordinates are used,
still suffers from another issue that will be addressed
in a separate commit.
The highlighting in Accerciser is also still wrong
when a screen scaling factor other than 100% is set,
but that's broken for other applications (e.g. gtk3-demo)
just the same, so might be an issue in Accerciser instead.
I successfully tested that these behave as expected
when using the qt6 VCL plugin with this change in place:
* Combobox popup positions, with either 100% screen scaling
or a scaling factor of 150% or 200% on both, X11 and
Wayland.
* When enabling RTL mode via env var `SAL_RTL_ENABLED=1`,
RTL layout is used and things look OK at a quick glance.
* The following bugs (somewhat related to positioning and/or
the now dropped menu bar hacks) are still fixed, i.e. don't
reappear:
* tdf#149805 "kf5: Gap when expanding comboboxes in toolbar"
* tdf#151677 "tip on "formula bar" for "formula making" is
displaying over the formula itself."
* tdf#152217 "Black box in Basic IDE where the status bar
should be (kf5 only)"
* tdf#153458 "Connecting to database: wrong cursor position
for dropping data to Calc sheet"
* tdf#153800 "Calc sheet tab drag-and-drop target area has
shifted vertically (kf5-only)"
* tdf#154043 "Change object layer via drag and drop has target
shifted down (KF5-only)"
* tdf#154447 "Clicking a dropdown tool button shouldn't
place the context menu on top of the button (kf5)"
Unrelated to this commit, popup positioning and rendering in
in a multi-screen setup on Wayland with different scaling
factors set for the single screens is still broken (see
tdf#141578).
Change-Id: Ifa0eff271c7d3fa2b6db9bdc1669e62333bd3094
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173996
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
2024-09-26 18:22:12 +02:00
|
|
|
|
|
|
|
const qreal fRatio = devicePixelRatioF();
|
|
|
|
const QPoint aScreenPos = m_pQWidget->mapToGlobal(QPoint(0, 0));
|
|
|
|
aGeometry.setX(aScreenPos.x() * fRatio);
|
|
|
|
aGeometry.setY(aScreenPos.y() * fRatio);
|
|
|
|
aGeometry.setWidth(m_pQWidget->width() * fRatio);
|
|
|
|
aGeometry.setHeight(m_pQWidget->height() * fRatio);
|
|
|
|
|
2024-09-27 11:06:55 +02:00
|
|
|
aGeometry.setScreen(std::max(sal_Int32(0), screenNumber()));
|
|
|
|
|
tdf#160837 qt: Rely on toolkit for frame positions, drop menubar hack
Make `SalFrame::GetUnmirroredGeometry` overridable
(and let it return a copy of the SalFrameGeometry
instead of a const reference) and document that
subclasses can either make sure to keep the
`SalFrame::maGeometry` member (which is returned by
the default implementation of
`SalFrame::GetUnmirroredGeometry`) up to date or override
the latter in order to always return the current
geometry.
Override the method in `QtFrame` and fully rely on Qt
to report and set the position of the frame, via
the corresponding QWidget: Set the position, width
and height in the returned `SalFrameGeometry`
to the ones of the widget (factoring in the
scale factor).
Stop updating `maGeometry` size/position whenever
the widget position or size changes, as that is no
longer used anymore now that `GetUnmirroredGeometry`
is overriden.
This also allows to drop earlier hacks where
position calculation in some places had to be adjusted
by the height of the native menu bar, as that one
doesn't have a corresponding vcl::Window, but results
in everything else being shifted down a bit.
Using Qt directly to set other members of the
returned `SalFrameGeometry` (like the screen number)
would probably be possible, but is not included
in this change. (It can still be done separately
later.)
This makes Accerciser highlight the correct area
when using the qt6 VCL plugin and using Writer
with the standard interface (where the y position
reported via AT-SPI2 would previously always be
too small, missing the menu bar height) and thus
e.g. also allows to make use of it's "select object
under mouse" feature (s. tdf#160837).
The position via AT-SPI is however currently only
correct on X11/XWayland where global/screen coordinates
are reported via AT-SPI2.
Wayland, where window-relative coordinates are used,
still suffers from another issue that will be addressed
in a separate commit.
The highlighting in Accerciser is also still wrong
when a screen scaling factor other than 100% is set,
but that's broken for other applications (e.g. gtk3-demo)
just the same, so might be an issue in Accerciser instead.
I successfully tested that these behave as expected
when using the qt6 VCL plugin with this change in place:
* Combobox popup positions, with either 100% screen scaling
or a scaling factor of 150% or 200% on both, X11 and
Wayland.
* When enabling RTL mode via env var `SAL_RTL_ENABLED=1`,
RTL layout is used and things look OK at a quick glance.
* The following bugs (somewhat related to positioning and/or
the now dropped menu bar hacks) are still fixed, i.e. don't
reappear:
* tdf#149805 "kf5: Gap when expanding comboboxes in toolbar"
* tdf#151677 "tip on "formula bar" for "formula making" is
displaying over the formula itself."
* tdf#152217 "Black box in Basic IDE where the status bar
should be (kf5 only)"
* tdf#153458 "Connecting to database: wrong cursor position
for dropping data to Calc sheet"
* tdf#153800 "Calc sheet tab drag-and-drop target area has
shifted vertically (kf5-only)"
* tdf#154043 "Change object layer via drag and drop has target
shifted down (KF5-only)"
* tdf#154447 "Clicking a dropdown tool button shouldn't
place the context menu on top of the button (kf5)"
Unrelated to this commit, popup positioning and rendering in
in a multi-screen setup on Wayland with different scaling
factors set for the single screens is still broken (see
tdf#141578).
Change-Id: Ifa0eff271c7d3fa2b6db9bdc1669e62333bd3094
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173996
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
2024-09-26 18:22:12 +02:00
|
|
|
return aGeometry;
|
|
|
|
}
|
|
|
|
|
2023-07-20 08:19:52 +02:00
|
|
|
void QtFrame::GetWorkArea(AbsoluteScreenPixelRectangle& rRect)
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2018-08-09 17:14:14 +02:00
|
|
|
if (!isWindow())
|
2017-10-30 19:44:40 +01:00
|
|
|
return;
|
2018-08-09 17:14:14 +02:00
|
|
|
QScreen* pScreen = screen();
|
2017-10-30 19:44:40 +01:00
|
|
|
if (!pScreen)
|
|
|
|
return;
|
|
|
|
|
tdf#127687 Qt5 introduce basic HiDPI scaling
For tdf#124292, Qt's own HiDPI scaling was explicitly disabled,
but it turns out, you can't really scale QStyle painting then.
This patch series had a 2nd approach also used by Gtk+ currently,
which relied on the scaling of ths Cairo surface, which works
surprisingly good, but has to lie about the real DPI value, so
nothing is scaled twice. Also all icons are then scaled instead
of rendered with the proper resolution.
When HiDPI support in Qt is enabled, and the application is
started using QT_SCALE_FACTOR=1.25, Qt simply lowers the reported
resolution, keeps the logical DPI value of 96 and changes the
devicePixelRatio to the specified value. But LO still expects
the real DPI values and sizes, so we have to multiply a lot of
rectangles, sizes and positions.
The current result is far from perfect, which you can see with
the various graphics glitches, but it at least doesn't crash
anymore in the ControlType::Editbox sizing code.
The main problem is all the up and downscaling in the
getNativeControlRegion code, so LO knows the size of the widgets
for the correct layouting, since there seem to be no API to
get the scaled values from Qt / QStyle.
Change-Id: I687b1df6ef27724ce68326d256e9addccd72e759
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86239
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
2020-02-29 13:39:29 +01:00
|
|
|
QSize aSize = pScreen->availableVirtualSize() * devicePixelRatioF();
|
2023-07-20 08:19:52 +02:00
|
|
|
rRect = AbsoluteScreenPixelRectangle(0, 0, aSize.width(), aSize.height());
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
SalFrame* QtFrame::GetParent() const { return m_pParent; }
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::SetModal(bool bModal)
|
2018-06-27 10:41:03 +02:00
|
|
|
{
|
2021-10-31 02:33:46 +02:00
|
|
|
if (!isWindow() || asChild()->isModal() == bModal)
|
2020-08-04 09:22:10 +02:00
|
|
|
return;
|
2019-06-02 21:01:33 +00:00
|
|
|
|
2024-09-27 09:08:43 +02:00
|
|
|
GetQtInstance().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
|
|
|
|
2020-08-04 09:22:10 +02: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
|
|
|
|
2020-08-04 09:22:10 +02:00
|
|
|
// modality change is only effective if the window is hidden
|
|
|
|
if (bWasVisible)
|
2023-04-01 20:08:13 +03:00
|
|
|
{
|
2020-08-04 09:22:10 +02:00
|
|
|
pChild->hide();
|
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
|
|
|
|
2020-08-04 09:22:10 +02:00
|
|
|
pChild->setWindowModality(bModal ? Qt::WindowModal : Qt::NonModal);
|
|
|
|
|
|
|
|
if (bWasVisible)
|
|
|
|
pChild->show();
|
|
|
|
});
|
2018-06-27 10:41:03 +02:00
|
|
|
}
|
|
|
|
|
2022-06-02 22:42:20 +02:00
|
|
|
void QtFrame::SetWindowState(const vcl::WindowData* pState)
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2024-09-27 09:08:43 +02:00
|
|
|
QtInstance& rQtInstance = GetQtInstance();
|
|
|
|
if (!rQtInstance.IsMainThread())
|
qt: Run QtFrame::SetWindowState in main thread
Fixes this crash/assertion seen when starting Writer with
the qt6 VCL plugin with a fresh user profile with qtbase debug
build (as of commit 70a2e7f32b9f9ce19d1538f14fbde7b0d1e77ffd):
ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 0x0x7fff9c454020. Receiver 'QtMainWindowClassWindow' (of type 'QWidgetWindow') was created in thread 0x0x55555560dc50", file /home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp, line 547
Thread 19 "soffice.bin" received signal SIGABRT, Aborted.
[Switching to Thread 0x7fffada006c0 (LWP 10947)]
__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 0x00007ffff78a6b7f in __pthread_kill_internal (signo=6, threadid=<optimized out>) at ./nptl/pthread_kill.c:78
#2 0x00007ffff78584e2 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#3 0x00007ffff78414ed in __GI_abort () at ./stdlib/abort.c:79
#4 0x00007fffe34f95c9 in qAbort() () at /home/michi/development/git/qt5/qtbase/src/corelib/global/qassert.cpp:49
#5 0x00007fffe350d459 in qt_message_fatal<QString&>(QtMsgType, QMessageLogContext const&, QString&) (context=..., message=...) at /home/michi/development/git/qt5/qtbase/src/corelib/global/qlogging.cpp:2112
#6 0x00007fffe35063e6 in qt_message(QtMsgType, const QMessageLogContext &, const char *, typedef __va_list_tag __va_list_tag *)
(msgType=QtFatalMsg, context=..., msg=0x7fffe3b8afa8 "ASSERT failure in %s: \"%s\", file %s, line %d", ap=0x7fffad9fb108) at /home/michi/development/git/qt5/qtbase/src/corelib/global/qlogging.cpp:380
#7 0x00007fffe35084b1 in QMessageLogger::fatal(char const*, ...) const (this=0x7fffad9fb350, msg=0x7fffe3b8afa8 "ASSERT failure in %s: \"%s\", file %s, line %d")
at /home/michi/development/git/qt5/qtbase/src/corelib/global/qlogging.cpp:880
#8 0x00007fffe34f969c in qt_assert_x(char const*, char const*, char const*, int)
(where=0x7fffe3bae469 "QCoreApplication::sendEvent", what=0x7fff9cd289a0 "Cannot send events to objects owned by a different thread. Current thread 0x0x7fff9c454020. Receiver 'QtMainWindowClassWindow' (of type 'QWidgetWindow') was created in thread 0x0x55555560dc50", file=0x7fffe3bae098 "/home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp", line=547) at /home/michi/development/git/qt5/qtbase/src/corelib/global/qassert.cpp:114
#9 0x00007fffe35f54e6 in QCoreApplicationPrivate::checkReceiverThread(QObject*) (receiver=0x55555bb8b4a0) at /home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:547
#10 0x00007fffe15a786e in QApplication::notify(QObject*, QEvent*) (this=0x55555560d9d0, receiver=0x55555bb8b4a0, e=0x7fffad9fb7f0) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qapplication.cpp:2580
#11 0x00007fffe35f68be in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x55555bb8b4a0, event=0x7fffad9fb7f0) at /home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1154
#12 0x00007fffe35f7677 in QCoreApplication::sendEvent(QObject*, QEvent*) (receiver=0x55555bb8b4a0, event=0x7fffad9fb7f0) at /home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1598
#13 0x00007fffe24f6299 in QWindowPrivate::create(bool) (this=0x5555569bd9a0, recursive=false) at /home/michi/development/git/qt5/qtbase/src/gui/kernel/qwindow.cpp:589
#14 0x00007fffe24f6759 in QWindow::create() (this=0x55555bb8b4a0) at /home/michi/development/git/qt5/qtbase/src/gui/kernel/qwindow.cpp:720
#15 0x00007fffe1643f45 in QWidgetPrivate::create() (this=0x55555b24c140) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qwidget.cpp:1341
#16 0x00007fffe16433c3 in QWidget::create(unsigned long long, bool, bool) (this=0x5555572554a0, window=0, initializeWindow=true, destroyOldWindow=true) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qwidget.cpp:1206
#17 0x00007fffe1649dd5 in QWidget::setWindowState(QFlags<Qt::WindowState>) (this=0x5555572554a0, newstate=...) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qwidget.cpp:2946
#18 0x00007fffe4235db6 in QtFrame::SetWindowStateImpl(QFlags<Qt::WindowState>) (this=0x55555bba8cf0, eState=...) at vcl/qt6/../qt5/QtFrame.cxx:340
#19 0x00007fffe4237fc0 in QtFrame::SetWindowState(vcl::WindowData const*) (this=0x55555bba8cf0, pState=0x7fffad9fbdc0) at vcl/qt6/../qt5/QtFrame.cxx:677
#20 0x00007fffee0a4c63 in SystemWindow::SetWindowState(vcl::WindowData const&) (this=0x7fff9d689d50, rData=...) at /home/michi/development/git/libreoffice/vcl/source/window/syswin.cxx:708
#21 0x00007fffee0a5802 in SystemWindow::SetWindowState(std::basic_string_view<char16_t, std::char_traits<char16_t> >) (this=0x7fff9d689d50, rStr=u",,,;4;") at /home/michi/development/git/libreoffice/vcl/source/window/syswin.cxx:840
#22 0x00007ffff4ddc4c4 in framework::LoadEnv::impl_applyPersistentWindowState(com::sun::star::uno::Reference<com::sun::star::awt::XWindow> const&) (this=0x7fffad9fcbb8, xWindow=uno::Reference to (VCLXTopWindow *) 0x7fff9c003810)
at /home/michi/development/git/libreoffice/framework/source/loadenv/loadenv.cxx:1809
#23 0x00007ffff4dd6f5b in framework::LoadEnv::impl_loadContent() (this=0x7fffad9fcbb8) at /home/michi/development/git/libreoffice/framework/source/loadenv/loadenv.cxx:1081
#24 0x00007ffff4dd48e4 in framework::LoadEnv::start() (this=0x7fffad9fcbb8) at /home/michi/development/git/libreoffice/framework/source/loadenv/loadenv.cxx:412
#25 0x00007ffff4dd21b2 in framework::LoadEnv::startLoading(rtl::OUString const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&, com::sun::star::uno::Reference<com::sun::star::frame::XFrame> const&, rtl::OUString const&, int, LoadEnvFeatures)
(this=0x7fffad9fcbb8, sURL="file:///home/michi/development/git/libreoffice/instdir/program/../program/opencl/cl-test.ods", lMediaDescriptor=uno::Sequence of length 1 = {...}, xBaseFrame=uno::Reference to (framework::Desktop *) 0x5555569d5c68, sTarget="_blank", nSearchFlags=0, eFeature=LoadEnvFeatures::NONE) at /home/michi/development/git/libreoffice/framework/source/loadenv/loadenv.cxx:308
#26 0x00007ffff4dd0998 in framework::LoadEnv::loadComponentFromURL(com::sun::star::uno::Reference<com::sun::star::frame::XComponentLoader> const&, com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> const&, rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)
(xLoader=uno::Reference to (framework::Desktop *) 0x5555569d5c78, xContext=uno::Reference to (cppu::(anonymous namespace)::ComponentContext *) 0x555555623d38, sURL="file:///home/michi/development/git/libreoffice/instdir/program/../program/opencl/cl-test.ods", sTarget="_blank", nSearchFlags=0, lArgs=uno::Sequence of length 1 = {...}) at /home/michi/development/git/libreoffice/framework/source/loadenv/loadenv.cxx:168
#27 0x00007ffff4e06a3f in framework::Desktop::loadComponentFromURL(rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)
(this=0x5555569d5c00, sURL="file:///home/michi/development/git/libreoffice/instdir/program/../program/opencl/cl-test.ods", sTargetFrameName="_blank", nSearchFlags=0, lArguments=uno::Sequence of length 1 = {...})
at /home/michi/development/git/libreoffice/framework/source/services/desktop.cxx:592
#28 0x00007ffff4e06b34 in non-virtual thunk to framework::Desktop::loadComponentFromURL(rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&) ()
at /home/michi/development/git/libreoffice/instdir/program/libfwklo.so
#29 0x00007ffff7ba9147 in desktop::testOpenCLCompute(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&, rtl::OUString const&)
(xDesktop=uno::Reference to (framework::Desktop *) 0x5555569d5c58, rURL="file:///home/michi/development/git/libreoffice/instdir/program/../program/opencl/cl-test.ods")
at /home/michi/development/git/libreoffice/desktop/source/app/opencl.cxx:132
#30 0x00007ffff7ba7f54 in desktop::Desktop::CheckOpenCLCompute(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&) (xDesktop=uno::Reference to (framework::Desktop *) 0x5555569d5c58)
at /home/michi/development/git/libreoffice/desktop/source/app/opencl.cxx:241
#31 0x00007ffff7b5719d in std::__invoke_impl<void, void (*)(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&), com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> >(std::__invoke_other, void (*&&)(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&), com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2>&&)
(__f=@0x555556fbe460: 0x7ffff7ba7760 <desktop::Desktop::CheckOpenCLCompute(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&)>, __args=...)
at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/invoke.h:61
#32 0x00007ffff7b5712d in std::__invoke<void (*)(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&), com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> >(void (*&&)(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&), com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2>&&)
(__fn=@0x555556fbe460: 0x7ffff7ba7760 <desktop::Desktop::CheckOpenCLCompute(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&)>, __args=...)
at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/invoke.h:96
#33 0x00007ffff7b57102 in std::thread::_Invoker<std::tuple<void (*)(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&), com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> > >::_M_invoke<0ul, 1ul>(std::_Index_tuple<0ul, 1ul>) (this=0x555556fbe458) at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_thread.h:292
#34 0x00007ffff7b570c5 in std::thread::_Invoker<std::tuple<void (*)(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&), com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> > >::operator()()
(this=0x555556fbe458) at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_thread.h:299
#35 0x00007ffff7b56e69 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&), com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> > > >::_M_run() (this=0x555556fbe450) at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_thread.h:244
#36 0x00007ffff74dee24 in () at /lib/x86_64-linux-gnu/libstdc++.so.6
#37 0x00007ffff78a4dbb in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:444
#38 0x00007ffff79269f8 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78
Change-Id: I35024670cf4e4a6c00762be71fa051cc9417ef75
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167779
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
2024-05-17 14:32:32 +02:00
|
|
|
{
|
2024-09-27 09:08:43 +02:00
|
|
|
rQtInstance.RunInMainThread([this, pState]() { SetWindowState(pState); });
|
qt: Run QtFrame::SetWindowState in main thread
Fixes this crash/assertion seen when starting Writer with
the qt6 VCL plugin with a fresh user profile with qtbase debug
build (as of commit 70a2e7f32b9f9ce19d1538f14fbde7b0d1e77ffd):
ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 0x0x7fff9c454020. Receiver 'QtMainWindowClassWindow' (of type 'QWidgetWindow') was created in thread 0x0x55555560dc50", file /home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp, line 547
Thread 19 "soffice.bin" received signal SIGABRT, Aborted.
[Switching to Thread 0x7fffada006c0 (LWP 10947)]
__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 0x00007ffff78a6b7f in __pthread_kill_internal (signo=6, threadid=<optimized out>) at ./nptl/pthread_kill.c:78
#2 0x00007ffff78584e2 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#3 0x00007ffff78414ed in __GI_abort () at ./stdlib/abort.c:79
#4 0x00007fffe34f95c9 in qAbort() () at /home/michi/development/git/qt5/qtbase/src/corelib/global/qassert.cpp:49
#5 0x00007fffe350d459 in qt_message_fatal<QString&>(QtMsgType, QMessageLogContext const&, QString&) (context=..., message=...) at /home/michi/development/git/qt5/qtbase/src/corelib/global/qlogging.cpp:2112
#6 0x00007fffe35063e6 in qt_message(QtMsgType, const QMessageLogContext &, const char *, typedef __va_list_tag __va_list_tag *)
(msgType=QtFatalMsg, context=..., msg=0x7fffe3b8afa8 "ASSERT failure in %s: \"%s\", file %s, line %d", ap=0x7fffad9fb108) at /home/michi/development/git/qt5/qtbase/src/corelib/global/qlogging.cpp:380
#7 0x00007fffe35084b1 in QMessageLogger::fatal(char const*, ...) const (this=0x7fffad9fb350, msg=0x7fffe3b8afa8 "ASSERT failure in %s: \"%s\", file %s, line %d")
at /home/michi/development/git/qt5/qtbase/src/corelib/global/qlogging.cpp:880
#8 0x00007fffe34f969c in qt_assert_x(char const*, char const*, char const*, int)
(where=0x7fffe3bae469 "QCoreApplication::sendEvent", what=0x7fff9cd289a0 "Cannot send events to objects owned by a different thread. Current thread 0x0x7fff9c454020. Receiver 'QtMainWindowClassWindow' (of type 'QWidgetWindow') was created in thread 0x0x55555560dc50", file=0x7fffe3bae098 "/home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp", line=547) at /home/michi/development/git/qt5/qtbase/src/corelib/global/qassert.cpp:114
#9 0x00007fffe35f54e6 in QCoreApplicationPrivate::checkReceiverThread(QObject*) (receiver=0x55555bb8b4a0) at /home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:547
#10 0x00007fffe15a786e in QApplication::notify(QObject*, QEvent*) (this=0x55555560d9d0, receiver=0x55555bb8b4a0, e=0x7fffad9fb7f0) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qapplication.cpp:2580
#11 0x00007fffe35f68be in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x55555bb8b4a0, event=0x7fffad9fb7f0) at /home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1154
#12 0x00007fffe35f7677 in QCoreApplication::sendEvent(QObject*, QEvent*) (receiver=0x55555bb8b4a0, event=0x7fffad9fb7f0) at /home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1598
#13 0x00007fffe24f6299 in QWindowPrivate::create(bool) (this=0x5555569bd9a0, recursive=false) at /home/michi/development/git/qt5/qtbase/src/gui/kernel/qwindow.cpp:589
#14 0x00007fffe24f6759 in QWindow::create() (this=0x55555bb8b4a0) at /home/michi/development/git/qt5/qtbase/src/gui/kernel/qwindow.cpp:720
#15 0x00007fffe1643f45 in QWidgetPrivate::create() (this=0x55555b24c140) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qwidget.cpp:1341
#16 0x00007fffe16433c3 in QWidget::create(unsigned long long, bool, bool) (this=0x5555572554a0, window=0, initializeWindow=true, destroyOldWindow=true) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qwidget.cpp:1206
#17 0x00007fffe1649dd5 in QWidget::setWindowState(QFlags<Qt::WindowState>) (this=0x5555572554a0, newstate=...) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qwidget.cpp:2946
#18 0x00007fffe4235db6 in QtFrame::SetWindowStateImpl(QFlags<Qt::WindowState>) (this=0x55555bba8cf0, eState=...) at vcl/qt6/../qt5/QtFrame.cxx:340
#19 0x00007fffe4237fc0 in QtFrame::SetWindowState(vcl::WindowData const*) (this=0x55555bba8cf0, pState=0x7fffad9fbdc0) at vcl/qt6/../qt5/QtFrame.cxx:677
#20 0x00007fffee0a4c63 in SystemWindow::SetWindowState(vcl::WindowData const&) (this=0x7fff9d689d50, rData=...) at /home/michi/development/git/libreoffice/vcl/source/window/syswin.cxx:708
#21 0x00007fffee0a5802 in SystemWindow::SetWindowState(std::basic_string_view<char16_t, std::char_traits<char16_t> >) (this=0x7fff9d689d50, rStr=u",,,;4;") at /home/michi/development/git/libreoffice/vcl/source/window/syswin.cxx:840
#22 0x00007ffff4ddc4c4 in framework::LoadEnv::impl_applyPersistentWindowState(com::sun::star::uno::Reference<com::sun::star::awt::XWindow> const&) (this=0x7fffad9fcbb8, xWindow=uno::Reference to (VCLXTopWindow *) 0x7fff9c003810)
at /home/michi/development/git/libreoffice/framework/source/loadenv/loadenv.cxx:1809
#23 0x00007ffff4dd6f5b in framework::LoadEnv::impl_loadContent() (this=0x7fffad9fcbb8) at /home/michi/development/git/libreoffice/framework/source/loadenv/loadenv.cxx:1081
#24 0x00007ffff4dd48e4 in framework::LoadEnv::start() (this=0x7fffad9fcbb8) at /home/michi/development/git/libreoffice/framework/source/loadenv/loadenv.cxx:412
#25 0x00007ffff4dd21b2 in framework::LoadEnv::startLoading(rtl::OUString const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&, com::sun::star::uno::Reference<com::sun::star::frame::XFrame> const&, rtl::OUString const&, int, LoadEnvFeatures)
(this=0x7fffad9fcbb8, sURL="file:///home/michi/development/git/libreoffice/instdir/program/../program/opencl/cl-test.ods", lMediaDescriptor=uno::Sequence of length 1 = {...}, xBaseFrame=uno::Reference to (framework::Desktop *) 0x5555569d5c68, sTarget="_blank", nSearchFlags=0, eFeature=LoadEnvFeatures::NONE) at /home/michi/development/git/libreoffice/framework/source/loadenv/loadenv.cxx:308
#26 0x00007ffff4dd0998 in framework::LoadEnv::loadComponentFromURL(com::sun::star::uno::Reference<com::sun::star::frame::XComponentLoader> const&, com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> const&, rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)
(xLoader=uno::Reference to (framework::Desktop *) 0x5555569d5c78, xContext=uno::Reference to (cppu::(anonymous namespace)::ComponentContext *) 0x555555623d38, sURL="file:///home/michi/development/git/libreoffice/instdir/program/../program/opencl/cl-test.ods", sTarget="_blank", nSearchFlags=0, lArgs=uno::Sequence of length 1 = {...}) at /home/michi/development/git/libreoffice/framework/source/loadenv/loadenv.cxx:168
#27 0x00007ffff4e06a3f in framework::Desktop::loadComponentFromURL(rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)
(this=0x5555569d5c00, sURL="file:///home/michi/development/git/libreoffice/instdir/program/../program/opencl/cl-test.ods", sTargetFrameName="_blank", nSearchFlags=0, lArguments=uno::Sequence of length 1 = {...})
at /home/michi/development/git/libreoffice/framework/source/services/desktop.cxx:592
#28 0x00007ffff4e06b34 in non-virtual thunk to framework::Desktop::loadComponentFromURL(rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&) ()
at /home/michi/development/git/libreoffice/instdir/program/libfwklo.so
#29 0x00007ffff7ba9147 in desktop::testOpenCLCompute(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&, rtl::OUString const&)
(xDesktop=uno::Reference to (framework::Desktop *) 0x5555569d5c58, rURL="file:///home/michi/development/git/libreoffice/instdir/program/../program/opencl/cl-test.ods")
at /home/michi/development/git/libreoffice/desktop/source/app/opencl.cxx:132
#30 0x00007ffff7ba7f54 in desktop::Desktop::CheckOpenCLCompute(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&) (xDesktop=uno::Reference to (framework::Desktop *) 0x5555569d5c58)
at /home/michi/development/git/libreoffice/desktop/source/app/opencl.cxx:241
#31 0x00007ffff7b5719d in std::__invoke_impl<void, void (*)(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&), com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> >(std::__invoke_other, void (*&&)(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&), com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2>&&)
(__f=@0x555556fbe460: 0x7ffff7ba7760 <desktop::Desktop::CheckOpenCLCompute(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&)>, __args=...)
at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/invoke.h:61
#32 0x00007ffff7b5712d in std::__invoke<void (*)(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&), com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> >(void (*&&)(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&), com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2>&&)
(__fn=@0x555556fbe460: 0x7ffff7ba7760 <desktop::Desktop::CheckOpenCLCompute(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&)>, __args=...)
at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/invoke.h:96
#33 0x00007ffff7b57102 in std::thread::_Invoker<std::tuple<void (*)(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&), com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> > >::_M_invoke<0ul, 1ul>(std::_Index_tuple<0ul, 1ul>) (this=0x555556fbe458) at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_thread.h:292
#34 0x00007ffff7b570c5 in std::thread::_Invoker<std::tuple<void (*)(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&), com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> > >::operator()()
(this=0x555556fbe458) at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_thread.h:299
#35 0x00007ffff7b56e69 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> const&), com::sun::star::uno::Reference<com::sun::star::frame::XDesktop2> > > >::_M_run() (this=0x555556fbe450) at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_thread.h:244
#36 0x00007ffff74dee24 in () at /lib/x86_64-linux-gnu/libstdc++.so.6
#37 0x00007ffff78a4dbb in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:444
#38 0x00007ffff79269f8 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78
Change-Id: I35024670cf4e4a6c00762be71fa051cc9417ef75
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167779
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
2024-05-17 14:32:32 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-08-09 17:14:14 +02:00
|
|
|
if (!isWindow() || !pState || isChild(true, false))
|
2017-10-30 18:33:06 +01:00
|
|
|
return;
|
|
|
|
|
2022-06-02 22:42:20 +02:00
|
|
|
const vcl::WindowDataMask nMaxGeometryMask
|
|
|
|
= vcl::WindowDataMask::PosSize | vcl::WindowDataMask::MaximizedX
|
|
|
|
| vcl::WindowDataMask::MaximizedY | vcl::WindowDataMask::MaximizedWidth
|
|
|
|
| vcl::WindowDataMask::MaximizedHeight;
|
2017-10-30 18:33:06 +01:00
|
|
|
|
2022-06-02 22:42:20 +02:00
|
|
|
if ((pState->mask() & vcl::WindowDataMask::State)
|
|
|
|
&& (pState->state() & vcl::WindowState::Maximized) && !isMaximized()
|
|
|
|
&& (pState->mask() & nMaxGeometryMask) == nMaxGeometryMask)
|
2019-02-11 11:22:30 +01:00
|
|
|
{
|
tdf#127687 Qt5 introduce basic HiDPI scaling
For tdf#124292, Qt's own HiDPI scaling was explicitly disabled,
but it turns out, you can't really scale QStyle painting then.
This patch series had a 2nd approach also used by Gtk+ currently,
which relied on the scaling of ths Cairo surface, which works
surprisingly good, but has to lie about the real DPI value, so
nothing is scaled twice. Also all icons are then scaled instead
of rendered with the proper resolution.
When HiDPI support in Qt is enabled, and the application is
started using QT_SCALE_FACTOR=1.25, Qt simply lowers the reported
resolution, keeps the logical DPI value of 96 and changes the
devicePixelRatio to the specified value. But LO still expects
the real DPI values and sizes, so we have to multiply a lot of
rectangles, sizes and positions.
The current result is far from perfect, which you can see with
the various graphics glitches, but it at least doesn't crash
anymore in the ControlType::Editbox sizing code.
The main problem is all the up and downscaling in the
getNativeControlRegion code, so LO knows the size of the widgets
for the correct layouting, since there seem to be no API to
get the scaled values from Qt / QStyle.
Change-Id: I687b1df6ef27724ce68326d256e9addccd72e759
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86239
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
2020-02-29 13:39:29 +01:00
|
|
|
const qreal fRatio = devicePixelRatioF();
|
2019-06-02 15:38:25 +00:00
|
|
|
QWidget* const pChild = asChild();
|
2022-06-02 22:42:20 +02:00
|
|
|
pChild->resize(ceil(pState->width() / fRatio), ceil(pState->height() / fRatio));
|
|
|
|
pChild->move(ceil(pState->x() / fRatio), ceil(pState->y() / fRatio));
|
2019-02-11 11:22:30 +01:00
|
|
|
SetWindowStateImpl(Qt::WindowMaximized);
|
|
|
|
}
|
2022-06-02 22:42:20 +02:00
|
|
|
else if (pState->mask() & vcl::WindowDataMask::PosSize)
|
2017-10-30 18:33:06 +01:00
|
|
|
{
|
2017-10-30 19:44:40 +01:00
|
|
|
sal_uInt16 nPosSizeFlags = 0;
|
2022-06-02 22:42:20 +02:00
|
|
|
if (pState->mask() & vcl::WindowDataMask::X)
|
2017-10-30 19:44:40 +01:00
|
|
|
nPosSizeFlags |= SAL_FRAME_POSSIZE_X;
|
2022-06-02 22:42:20 +02:00
|
|
|
if (pState->mask() & vcl::WindowDataMask::Y)
|
2017-10-30 19:44:40 +01:00
|
|
|
nPosSizeFlags |= SAL_FRAME_POSSIZE_Y;
|
2022-06-02 22:42:20 +02:00
|
|
|
if (pState->mask() & vcl::WindowDataMask::Width)
|
2017-10-30 19:44:40 +01:00
|
|
|
nPosSizeFlags |= SAL_FRAME_POSSIZE_WIDTH;
|
2022-06-02 22:42:20 +02:00
|
|
|
if (pState->mask() & vcl::WindowDataMask::Height)
|
2017-10-30 19:44:40 +01:00
|
|
|
nPosSizeFlags |= SAL_FRAME_POSSIZE_HEIGHT;
|
2022-06-02 22:42:20 +02:00
|
|
|
SetPosSize(pState->x(), pState->y(), pState->width(), pState->height(), nPosSizeFlags);
|
2017-10-30 18:33:06 +01:00
|
|
|
}
|
2022-06-02 22:42:20 +02:00
|
|
|
else if (pState->mask() & vcl::WindowDataMask::State && !isChild())
|
2017-10-30 18:33:06 +01:00
|
|
|
{
|
2022-06-02 22:42:20 +02:00
|
|
|
if (pState->state() & vcl::WindowState::Maximized)
|
2019-02-11 11:22:30 +01:00
|
|
|
SetWindowStateImpl(Qt::WindowMaximized);
|
2022-06-02 22:42:20 +02:00
|
|
|
else if (pState->state() & vcl::WindowState::Minimized)
|
2019-02-11 11:22:30 +01:00
|
|
|
SetWindowStateImpl(Qt::WindowMinimized);
|
2017-10-30 18:33:06 +01:00
|
|
|
else
|
2019-02-11 11:22:30 +01:00
|
|
|
SetWindowStateImpl(Qt::WindowNoState);
|
2017-10-30 18:33:06 +01:00
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2022-06-02 22:42:20 +02:00
|
|
|
bool QtFrame::GetWindowState(vcl::WindowData* pState)
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2022-06-02 22:42:20 +02:00
|
|
|
pState->setState(vcl::WindowState::Normal);
|
|
|
|
pState->setMask(vcl::WindowDataMask::State);
|
|
|
|
if (isMinimized())
|
|
|
|
pState->rState() |= vcl::WindowState::Minimized;
|
2018-10-25 11:45:13 +02:00
|
|
|
else if (isMaximized())
|
2022-06-02 22:42:20 +02:00
|
|
|
pState->rState() |= vcl::WindowState::Maximized;
|
2017-10-30 18:33:06 +01:00
|
|
|
else
|
|
|
|
{
|
2022-06-05 08:55:43 +02:00
|
|
|
// we want the frame position and the client area size
|
|
|
|
QRect rect = scaledQRect({ asChild()->pos(), asChild()->size() }, devicePixelRatioF());
|
2022-06-02 22:42:20 +02:00
|
|
|
pState->setPosSize(toRectangle(rect));
|
|
|
|
pState->rMask() |= vcl::WindowDataMask::PosSize;
|
2017-10-30 18:33:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::ShowFullScreen(bool bFullScreen, sal_Int32 nScreen)
|
2018-09-04 09:17:11 +02:00
|
|
|
{
|
2018-10-25 12:29:34 +02:00
|
|
|
// only top-level windows can go fullscreen
|
2018-09-04 09:17:11 +02:00
|
|
|
assert(m_pTopLevel);
|
|
|
|
|
2019-05-29 19:01:28 +02:00
|
|
|
if (m_bFullScreen == bFullScreen)
|
|
|
|
return;
|
|
|
|
|
2018-12-14 12:39:44 +03:00
|
|
|
m_bFullScreen = bFullScreen;
|
2019-05-29 19:01:28 +02:00
|
|
|
m_bFullScreenSpanAll = m_bFullScreen && (nScreen < 0);
|
2018-12-14 12:39:44 +03:00
|
|
|
|
2018-10-25 12:29:34 +02:00
|
|
|
// show it if it isn't shown yet
|
|
|
|
if (!isWindow())
|
|
|
|
m_pTopLevel->show();
|
2018-09-04 09:17:11 +02:00
|
|
|
|
2019-02-26 15:07:51 +01:00
|
|
|
if (m_bFullScreen)
|
|
|
|
{
|
|
|
|
m_aRestoreGeometry = m_pTopLevel->geometry();
|
2024-09-27 11:06:55 +02:00
|
|
|
m_nRestoreScreen = std::max(sal_Int32(0), screenNumber());
|
2019-05-29 19:01:28 +02:00
|
|
|
SetScreenNumber(m_bFullScreenSpanAll ? m_nRestoreScreen : nScreen);
|
|
|
|
if (!m_bFullScreenSpanAll)
|
|
|
|
windowHandle()->showFullScreen();
|
|
|
|
else
|
|
|
|
windowHandle()->showNormal();
|
2019-02-26 15:07:51 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-05-29 19:01:28 +02:00
|
|
|
SetScreenNumber(m_nRestoreScreen);
|
2019-02-26 15:07:51 +01:00
|
|
|
windowHandle()->showNormal();
|
|
|
|
m_pTopLevel->setGeometry(m_aRestoreGeometry);
|
|
|
|
}
|
2018-09-04 09:17:11 +02:00
|
|
|
}
|
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::StartPresentation(bool bStart)
|
2018-09-04 09:17:11 +02:00
|
|
|
{
|
Keep SessionManagerInhibitor disabled for Emscripten
...after 2f6f717073084b17e9be80e32a87200bacd1b74c "qt: Drop X11 condition for
session/screensaver inhibition" caused
> em++: warning: /home/tdf/lode/jenkins/workspace/lo_gerrit/tb/build_master/workdir/UnpackedTarball/argon2/libargon2.a: archive is missing an index; Use emar when creating libraries to ensure an index is created [-Wemcc]
> em++: warning: /home/tdf/lode/jenkins/workspace/lo_gerrit/tb/build_master/workdir/UnpackedTarball/argon2/libargon2.a: adding index [-Wemcc]
> wasm-ld: error: /home/tdf/lode/jenkins/workspace/lo_gerrit/tb/build_master/instdir/program/libvclplug_qt5lo.a(QtFrame.o): undefined symbol: SessionManagerInhibitor::inhibit(bool, std::__2::basic_string_view<char16_t, std::__2::char_traits<char16_t>>, ApplicationInhibitFlags, unsigned int, char const*)
> wasm-ld: error: /home/tdf/lode/jenkins/workspace/lo_gerrit/tb/build_master/instdir/program/libvclplug_qt5lo.a(QtFrame.o): undefined symbol: SessionManagerInhibitor::inhibit(bool, std::__2::basic_string_view<char16_t, std::__2::char_traits<char16_t>>, ApplicationInhibitFlags, unsigned int, char const*)
> em++: error: '/home/tdf/lode/emsdk/upstream/bin/wasm-ld @/tmp/emscripten_3x0hflai.rsp.utf-8' failed (returned 1)
> make[1]: *** [/home/tdf/lode/jenkins/workspace/lo_gerrit/tb/src_wasm/desktop/Executable_soffice_bin.mk:10: /home/tdf/lode/jenkins/workspace/lo_gerrit/tb/build_master/instdir/program/soffice.html] Error 1
(<https://ci.libreoffice.org/job/lo_daily_tb_linux_wasm/800/>). Most likely its
implementation would not work on Emscripten, anyway.
Change-Id: Ie7a643a8326df8c90645526930af21d54847a3ea
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171941
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
2024-08-16 09:52:41 +02:00
|
|
|
#if !defined EMSCRIPTEN
|
2022-06-15 23:34:01 +02:00
|
|
|
assert(m_aSystemData.platform != SystemEnvData::Platform::Invalid);
|
2019-06-14 02:08:22 +00:00
|
|
|
|
2022-06-15 23:34:01 +02:00
|
|
|
#if CHECK_QT5_USING_X11
|
2024-08-15 11:29:36 +02:00
|
|
|
unsigned int nRootWindow(0);
|
|
|
|
std::optional<Display*> aDisplay;
|
2019-06-14 02:08:22 +00:00
|
|
|
if (QX11Info::isPlatformX11())
|
|
|
|
{
|
2023-05-08 11:17:00 +01:00
|
|
|
nRootWindow = QX11Info::appRootWindow();
|
2019-06-14 02:08:22 +00:00
|
|
|
aDisplay = QX11Info::display();
|
|
|
|
}
|
2023-05-08 11:17:00 +01:00
|
|
|
m_SessionManagerInhibitor.inhibit(bStart, u"presentation", APPLICATION_INHIBIT_IDLE,
|
|
|
|
nRootWindow, aDisplay);
|
2022-06-18 21:11:28 +02:00
|
|
|
#else
|
2024-08-15 11:29:36 +02:00
|
|
|
m_SessionManagerInhibitor.inhibit(bStart, u"presentation", APPLICATION_INHIBIT_IDLE);
|
2022-06-18 21:11:28 +02:00
|
|
|
#endif
|
Keep SessionManagerInhibitor disabled for Emscripten
...after 2f6f717073084b17e9be80e32a87200bacd1b74c "qt: Drop X11 condition for
session/screensaver inhibition" caused
> em++: warning: /home/tdf/lode/jenkins/workspace/lo_gerrit/tb/build_master/workdir/UnpackedTarball/argon2/libargon2.a: archive is missing an index; Use emar when creating libraries to ensure an index is created [-Wemcc]
> em++: warning: /home/tdf/lode/jenkins/workspace/lo_gerrit/tb/build_master/workdir/UnpackedTarball/argon2/libargon2.a: adding index [-Wemcc]
> wasm-ld: error: /home/tdf/lode/jenkins/workspace/lo_gerrit/tb/build_master/instdir/program/libvclplug_qt5lo.a(QtFrame.o): undefined symbol: SessionManagerInhibitor::inhibit(bool, std::__2::basic_string_view<char16_t, std::__2::char_traits<char16_t>>, ApplicationInhibitFlags, unsigned int, char const*)
> wasm-ld: error: /home/tdf/lode/jenkins/workspace/lo_gerrit/tb/build_master/instdir/program/libvclplug_qt5lo.a(QtFrame.o): undefined symbol: SessionManagerInhibitor::inhibit(bool, std::__2::basic_string_view<char16_t, std::__2::char_traits<char16_t>>, ApplicationInhibitFlags, unsigned int, char const*)
> em++: error: '/home/tdf/lode/emsdk/upstream/bin/wasm-ld @/tmp/emscripten_3x0hflai.rsp.utf-8' failed (returned 1)
> make[1]: *** [/home/tdf/lode/jenkins/workspace/lo_gerrit/tb/src_wasm/desktop/Executable_soffice_bin.mk:10: /home/tdf/lode/jenkins/workspace/lo_gerrit/tb/build_master/instdir/program/soffice.html] Error 1
(<https://ci.libreoffice.org/job/lo_daily_tb_linux_wasm/800/>). Most likely its
implementation would not work on Emscripten, anyway.
Change-Id: Ie7a643a8326df8c90645526930af21d54847a3ea
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171941
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
2024-08-16 09:52:41 +02:00
|
|
|
#else
|
|
|
|
Q_UNUSED(bStart)
|
|
|
|
#endif
|
2018-09-04 09:17:11 +02:00
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::SetAlwaysOnTop(bool bOnTop)
|
2018-09-04 09:17:11 +02:00
|
|
|
{
|
2019-06-02 15:38:25 +00:00
|
|
|
QWidget* const pWidget = asChild();
|
2018-09-04 09:17:11 +02:00
|
|
|
const Qt::WindowFlags flags = pWidget->windowFlags();
|
|
|
|
if (bOnTop)
|
|
|
|
pWidget->setWindowFlags(flags | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint);
|
|
|
|
else
|
|
|
|
pWidget->setWindowFlags(flags & ~(Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint));
|
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::ToTop(SalFrameToTop nFlags)
|
2018-09-04 09:17:11 +02:00
|
|
|
{
|
2024-09-27 09:08:43 +02:00
|
|
|
GetQtInstance().RunInMainThread([this, 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
|
|
|
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);
|
2022-04-06 18:59:10 +02:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
});
|
2018-09-04 09:17:11 +02:00
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::SetPointer(PointerStyle ePointerStyle)
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2017-10-30 19:32:45 +01:00
|
|
|
if (ePointerStyle == m_ePointerStyle)
|
|
|
|
return;
|
|
|
|
m_ePointerStyle = ePointerStyle;
|
|
|
|
|
2022-05-27 23:36:20 +02:00
|
|
|
m_pQWidget->setCursor(GetQtData()->getCursor(ePointerStyle));
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::CaptureMouse(bool bMouse)
|
2018-09-04 09:17:11 +02:00
|
|
|
{
|
2018-09-04 21:05:03 +02:00
|
|
|
static const char* pEnv = getenv("SAL_NO_MOUSEGRABS");
|
|
|
|
if (pEnv && *pEnv)
|
|
|
|
return;
|
|
|
|
|
2018-09-04 09:17:11 +02:00
|
|
|
if (bMouse)
|
2018-09-04 21:05:03 +02:00
|
|
|
m_pQWidget->grabMouse();
|
2018-09-04 09:17:11 +02:00
|
|
|
else
|
2018-09-04 21:05:03 +02:00
|
|
|
m_pQWidget->releaseMouse();
|
2018-09-04 09:17:11 +02:00
|
|
|
}
|
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::SetPointerPos(tools::Long nX, tools::Long nY)
|
2018-09-04 09:17:11 +02:00
|
|
|
{
|
2019-04-01 09:41:39 +02:00
|
|
|
// some cursor already exists (and it has m_ePointerStyle shape)
|
|
|
|
// so here we just reposition it
|
2022-04-04 11:25:22 +02:00
|
|
|
QCursor::setPos(m_pQWidget->mapToGlobal(QPoint(nX, nY) / devicePixelRatioF()));
|
2018-09-04 09:17:11 +02:00
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::Flush()
|
2018-09-04 09:17:11 +02:00
|
|
|
{
|
2018-09-05 15:08:33 +02:00
|
|
|
// was: QGuiApplication::sync();
|
|
|
|
// but FIXME it causes too many issues, figure out sth better
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2018-09-04 09:17:11 +02:00
|
|
|
// unclear if we need to also flush cairo surface - gtk3 backend
|
2021-09-28 15:02:47 +02:00
|
|
|
// does not do it. QPainter in QtWidget::paintEvent() is
|
2018-09-04 09:17:11 +02:00
|
|
|
// destroyed, so that state should be safely flushed.
|
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
bool QtFrame::ShowTooltip(const OUString& rText, const tools::Rectangle& rHelpArea)
|
2018-12-11 12:12:52 +01:00
|
|
|
{
|
2019-06-22 02:25:24 +02:00
|
|
|
QRect aHelpArea(toQRect(rHelpArea));
|
|
|
|
if (QGuiApplication::isRightToLeft())
|
2024-09-26 15:20:57 +02:00
|
|
|
aHelpArea.moveLeft(GetWidth() - aHelpArea.width() - aHelpArea.left() - 1);
|
2022-04-12 00:29:56 +02:00
|
|
|
m_aTooltipText = rText;
|
|
|
|
m_aTooltipArea = aHelpArea;
|
2018-12-11 12:12:52 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::SetInputContext(SalInputContext* pContext)
|
2018-09-04 09:17:11 +02:00
|
|
|
{
|
2018-12-21 17:25:17 +01:00
|
|
|
if (!pContext)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!(pContext->mnOptions & InputContextFlags::Text))
|
|
|
|
return;
|
|
|
|
|
|
|
|
m_pQWidget->setAttribute(Qt::WA_InputMethodEnabled);
|
2018-09-04 09:17:11 +02:00
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::EndExtTextInput(EndExtTextInputFlags /*nFlags*/)
|
2018-09-04 09:17:11 +02:00
|
|
|
{
|
2022-04-07 01:07:43 +02:00
|
|
|
if (m_pQWidget)
|
|
|
|
m_pQWidget->endExtTextInput();
|
2018-09-04 09:17:11 +02:00
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
OUString QtFrame::GetKeyName(sal_uInt16 nKeyCode)
|
2018-10-23 15:46:09 +02:00
|
|
|
{
|
|
|
|
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;
|
2023-10-04 15:01:38 +03:00
|
|
|
case KEY_NUMBERSIGN:
|
|
|
|
nRetCode = Qt::Key_NumberSign;
|
|
|
|
break;
|
2023-12-03 11:07:23 +01:00
|
|
|
case KEY_XF86FORWARD:
|
|
|
|
nRetCode = Qt::Key_Forward;
|
|
|
|
break;
|
|
|
|
case KEY_XF86BACK:
|
|
|
|
nRetCode = Qt::Key_Back;
|
|
|
|
break;
|
2020-01-13 20:29:20 +01:00
|
|
|
case KEY_COLON:
|
|
|
|
nRetCode = Qt::Key_Colon;
|
|
|
|
break;
|
2018-10-23 15:46:09 +02:00
|
|
|
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;
|
2018-09-04 09:17:11 +02:00
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
bool QtFrame::MapUnicodeToKeyCode(sal_Unicode /*aUnicode*/, LanguageType /*aLangType*/,
|
|
|
|
vcl::KeyCode& /*rKeyCode*/)
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2018-09-04 09:17:11 +02:00
|
|
|
// not supported yet
|
2017-10-21 13:50:30 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
LanguageType QtFrame::GetInputLanguage() { return m_nInputLanguage; }
|
Qt5 report input method language
This is in the spirit of tdf#108151, based on the information Qt
provides for the IM setting. I don't know how correct it is,
especially looking at Caolans comment 3 in that bug report
regarding the assumed validity of GtkIMContextInfo. OTOH it seems
to work well enough for my simple tests.
Some BG info: while the QInputMethod object is a global one, it's
"bound" to the focused window. So you'll get change events, when
you change the input window, with the correct IM settings for the
new one, be it a real window or just the menu bar.
To prevent unneeded flushes of buffers and language lookup, this
caches the current IM language of a window.
The language is not affected just by changing keyboard mappings,
which the bug reporter requested! It just works with a configured
input method, like fcitx or ibus (which can have keyboard mappings
too, which work correctly).
Change-Id: Ia9133edf4d1ce77d29adbfe57c180db15db0a560
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106354
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
2020-11-22 14:53:14 +01:00
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::setInputLanguage(LanguageType nInputLanguage)
|
2018-09-04 09:17:11 +02:00
|
|
|
{
|
Qt5 report input method language
This is in the spirit of tdf#108151, based on the information Qt
provides for the IM setting. I don't know how correct it is,
especially looking at Caolans comment 3 in that bug report
regarding the assumed validity of GtkIMContextInfo. OTOH it seems
to work well enough for my simple tests.
Some BG info: while the QInputMethod object is a global one, it's
"bound" to the focused window. So you'll get change events, when
you change the input window, with the correct IM settings for the
new one, be it a real window or just the menu bar.
To prevent unneeded flushes of buffers and language lookup, this
caches the current IM language of a window.
The language is not affected just by changing keyboard mappings,
which the bug reporter requested! It just works with a configured
input method, like fcitx or ibus (which can have keyboard mappings
too, which work correctly).
Change-Id: Ia9133edf4d1ce77d29adbfe57c180db15db0a560
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106354
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
2020-11-22 14:53:14 +01:00
|
|
|
if (nInputLanguage == m_nInputLanguage)
|
|
|
|
return;
|
|
|
|
m_nInputLanguage = nInputLanguage;
|
|
|
|
CallCallback(SalEvent::InputLanguageChange, nullptr);
|
2018-09-04 09:17:11 +02:00
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2022-05-02 08:50:33 +02:00
|
|
|
static bool toVclFont(const QFont& rQFont, const css::lang::Locale& rLocale, vcl::Font& rVclFont)
|
|
|
|
{
|
2023-08-01 16:38:14 +00:00
|
|
|
FontAttributes aFA;
|
|
|
|
QtFontFace::fillAttributesFromQFont(rQFont, aFA);
|
2022-05-02 08:50:33 +02:00
|
|
|
|
2023-08-01 16:38:14 +00:00
|
|
|
bool bFound = psp::PrintFontManager::get().matchFont(aFA, rLocale);
|
2024-05-10 13:19:35 +02:00
|
|
|
SAL_INFO("vcl.qt",
|
|
|
|
"font match result for '"
|
|
|
|
<< rQFont.family() << "': "
|
|
|
|
<< (bFound ? OUString::Concat("'") + aFA.GetFamilyName() + "'" : u"failed"_ustr));
|
2022-05-02 08:50:33 +02:00
|
|
|
|
2023-08-01 16:38:14 +00:00
|
|
|
if (!bFound)
|
2022-05-02 08:50:33 +02:00
|
|
|
return false;
|
|
|
|
|
2023-08-01 16:38:14 +00:00
|
|
|
QFontInfo qFontInfo(rQFont);
|
2022-05-02 08:50:33 +02:00
|
|
|
int nPointHeight = qFontInfo.pointSize();
|
|
|
|
if (nPointHeight <= 0)
|
|
|
|
nPointHeight = rQFont.pointSize();
|
|
|
|
|
2023-08-01 16:38:14 +00:00
|
|
|
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());
|
2022-05-02 08:50:33 +02:00
|
|
|
|
|
|
|
rVclFont = aFont;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::UpdateSettings(AllSettings& rSettings)
|
2017-12-08 11:37:18 +00:00
|
|
|
{
|
2021-09-28 15:02:47 +02:00
|
|
|
if (QtData::noNativeControls())
|
2018-08-09 14:45:49 +02:00
|
|
|
return;
|
2024-11-05 15:25:24 +05:30
|
|
|
QtCustomStyle::LoadCustomStyle(GetUseDarkMode());
|
2018-08-09 14:45:49 +02:00
|
|
|
|
2017-12-08 11:37:18 +00:00
|
|
|
StyleSettings style(rSettings.GetStyleSettings());
|
2022-05-02 08:50:33 +02:00
|
|
|
const css::lang::Locale aLocale = rSettings.GetUILanguageTag().getLocale();
|
2017-12-08 11:37:18 +00:00
|
|
|
|
2018-08-09 14:51:41 +02:00
|
|
|
// 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));
|
2020-10-23 18:43:25 +02:00
|
|
|
Color aMid = toColor(pal.color(QPalette::Active, QPalette::Mid));
|
2018-08-09 14:51:41 +02:00
|
|
|
Color aHigh = toColor(pal.color(QPalette::Active, QPalette::Highlight));
|
|
|
|
Color aHighText = toColor(pal.color(QPalette::Active, QPalette::HighlightedText));
|
2019-03-23 16:02:38 +00:00
|
|
|
Color aLink = toColor(pal.color(QPalette::Active, QPalette::Link));
|
|
|
|
Color aVisitedLink = toColor(pal.color(QPalette::Active, QPalette::LinkVisited));
|
2018-08-09 14:51:41 +02:00
|
|
|
|
|
|
|
style.SetSkipDisabledInMenus(true);
|
|
|
|
|
|
|
|
// Foreground
|
|
|
|
style.SetRadioCheckTextColor(aFore);
|
|
|
|
style.SetLabelTextColor(aFore);
|
|
|
|
style.SetDialogTextColor(aFore);
|
|
|
|
style.SetGroupTextColor(aFore);
|
|
|
|
|
|
|
|
// Text
|
|
|
|
style.SetFieldTextColor(aText);
|
|
|
|
style.SetFieldRolloverTextColor(aText);
|
2022-07-01 10:45:13 +02:00
|
|
|
style.SetListBoxWindowTextColor(aText);
|
2018-08-09 14:51:41 +02:00
|
|
|
style.SetWindowTextColor(aText);
|
|
|
|
style.SetToolTextColor(aText);
|
|
|
|
|
|
|
|
// Base
|
|
|
|
style.SetFieldColor(aBase);
|
|
|
|
style.SetActiveTabColor(aBase);
|
2022-07-01 10:45:13 +02:00
|
|
|
style.SetListBoxWindowBackgroundColor(aBase);
|
2020-10-19 20:46:05 +02:00
|
|
|
style.SetAlternatingRowColor(toColor(pal.color(QPalette::Active, QPalette::AlternateBase)));
|
2018-08-09 14:51:41 +02:00
|
|
|
|
|
|
|
// Buttons
|
2020-02-23 21:11:05 +01:00
|
|
|
style.SetDefaultButtonTextColor(aButn);
|
2018-08-09 14:51:41 +02:00
|
|
|
style.SetButtonTextColor(aButn);
|
2019-11-10 12:34:54 +01:00
|
|
|
style.SetDefaultActionButtonTextColor(aButn);
|
|
|
|
style.SetActionButtonTextColor(aButn);
|
2020-02-23 21:11:05 +01:00
|
|
|
style.SetFlatButtonTextColor(aButn);
|
|
|
|
style.SetDefaultButtonRolloverTextColor(aButn);
|
2018-08-09 14:51:41 +02:00
|
|
|
style.SetButtonRolloverTextColor(aButn);
|
2020-02-23 21:11:05 +01:00
|
|
|
style.SetDefaultActionButtonRolloverTextColor(aButn);
|
|
|
|
style.SetActionButtonRolloverTextColor(aButn);
|
|
|
|
style.SetFlatButtonRolloverTextColor(aButn);
|
|
|
|
style.SetDefaultButtonPressedRolloverTextColor(aButn);
|
2018-08-09 14:51:41 +02:00
|
|
|
style.SetButtonPressedRolloverTextColor(aButn);
|
2020-02-23 21:11:05 +01:00
|
|
|
style.SetDefaultActionButtonPressedRolloverTextColor(aButn);
|
|
|
|
style.SetActionButtonPressedRolloverTextColor(aButn);
|
|
|
|
style.SetFlatButtonPressedRolloverTextColor(aButn);
|
2018-08-09 14:51:41 +02:00
|
|
|
|
|
|
|
// 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);
|
2024-09-05 01:37:44 +05:30
|
|
|
style.SetWindowColor(aBack);
|
2018-08-09 14:51:41 +02:00
|
|
|
|
2020-10-23 18:43:25 +02:00
|
|
|
// Workspace
|
|
|
|
style.SetWorkspaceColor(aMid);
|
|
|
|
|
2018-08-09 14:51:41 +02:00
|
|
|
// Selection
|
2023-05-17 16:48:30 +02:00
|
|
|
// https://invent.kde.org/plasma/plasma-workspace/-/merge_requests/305
|
|
|
|
style.SetAccentColor(aHigh);
|
2018-08-09 14:51:41 +02:00
|
|
|
style.SetHighlightColor(aHigh);
|
|
|
|
style.SetHighlightTextColor(aHighText);
|
2022-07-01 10:45:13 +02:00
|
|
|
style.SetListBoxWindowHighlightColor(aHigh);
|
|
|
|
style.SetListBoxWindowHighlightTextColor(aHighText);
|
2020-10-23 18:43:25 +02:00
|
|
|
style.SetActiveColor(aHigh);
|
|
|
|
style.SetActiveTextColor(aHighText);
|
2018-08-09 14:51:41 +02:00
|
|
|
|
2019-03-23 16:02:38 +00:00
|
|
|
// Links
|
|
|
|
style.SetLinkColor(aLink);
|
|
|
|
style.SetVisitedLinkColor(aVisitedLink);
|
|
|
|
|
2018-08-09 14:51:41 +02:00
|
|
|
// Tooltip
|
|
|
|
style.SetHelpColor(toColor(QToolTip::palette().color(QPalette::Active, QPalette::ToolTipBase)));
|
|
|
|
style.SetHelpTextColor(
|
|
|
|
toColor(QToolTip::palette().color(QPalette::Active, QPalette::ToolTipText)));
|
|
|
|
|
|
|
|
// Menu
|
2019-04-12 14:17:20 +02:00
|
|
|
std::unique_ptr<QMenuBar> pMenuBar = std::make_unique<QMenuBar>();
|
2018-08-09 14:51:41 +02:00
|
|
|
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);
|
2019-11-28 17:24:25 +01:00
|
|
|
style.SetMenuBarTextColor(style.GetPersonaMenuBarTextColor().value_or(aMenuFore));
|
2018-08-09 14:51:41 +02:00
|
|
|
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());
|
|
|
|
|
2022-05-02 08:50:33 +02:00
|
|
|
// 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);
|
|
|
|
|
2020-05-22 16:32:27 +03:00
|
|
|
// Icon theme
|
2023-09-02 10:37:47 +02:00
|
|
|
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);
|
2020-05-22 16:32:27 +03:00
|
|
|
|
2018-08-09 14:51:41 +02:00
|
|
|
// 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)));
|
|
|
|
|
2024-05-27 13:35:52 +02:00
|
|
|
// match native QComboBox behavior of putting text cursor to end of text
|
|
|
|
// without text selection when combobox entry is selected
|
|
|
|
style.SetComboBoxTextSelectionMode(ComboBoxTextSelectionMode::CursorToEnd);
|
|
|
|
|
2022-05-02 08:50:33 +02:00
|
|
|
// Cursor blink interval
|
|
|
|
int nFlashTime = QApplication::cursorFlashTime();
|
|
|
|
style.SetCursorBlinkTime(nFlashTime != 0 ? nFlashTime / 2 : STYLE_CURSOR_NOBLINKTIME);
|
|
|
|
|
2017-12-08 11:37:18 +00:00
|
|
|
rSettings.SetStyleSettings(style);
|
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::Beep() { QApplication::beep(); }
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
SalFrame::SalPointerState QtFrame::GetPointerState()
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2017-10-30 19:55:18 +01:00
|
|
|
SalPointerState aState;
|
tdf#127687 Qt5 introduce basic HiDPI scaling
For tdf#124292, Qt's own HiDPI scaling was explicitly disabled,
but it turns out, you can't really scale QStyle painting then.
This patch series had a 2nd approach also used by Gtk+ currently,
which relied on the scaling of ths Cairo surface, which works
surprisingly good, but has to lie about the real DPI value, so
nothing is scaled twice. Also all icons are then scaled instead
of rendered with the proper resolution.
When HiDPI support in Qt is enabled, and the application is
started using QT_SCALE_FACTOR=1.25, Qt simply lowers the reported
resolution, keeps the logical DPI value of 96 and changes the
devicePixelRatio to the specified value. But LO still expects
the real DPI values and sizes, so we have to multiply a lot of
rectangles, sizes and positions.
The current result is far from perfect, which you can see with
the various graphics glitches, but it at least doesn't crash
anymore in the ControlType::Editbox sizing code.
The main problem is all the up and downscaling in the
getNativeControlRegion code, so LO knows the size of the widgets
for the correct layouting, since there seem to be no API to
get the scaled values from Qt / QStyle.
Change-Id: I687b1df6ef27724ce68326d256e9addccd72e759
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86239
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
2020-02-29 13:39:29 +01:00
|
|
|
aState.maPos = toPoint(QCursor::pos() * devicePixelRatioF());
|
2024-09-26 15:20:57 +02:00
|
|
|
SalFrameGeometry aGeometry = GetUnmirroredGeometry();
|
|
|
|
aState.maPos.Move(-aGeometry.x(), -aGeometry.y());
|
2018-01-08 09:40:00 +02:00
|
|
|
aState.mnState = GetMouseModCode(QGuiApplication::mouseButtons())
|
|
|
|
| GetKeyModCode(QGuiApplication::keyboardModifiers());
|
2017-10-30 19:55:18 +01:00
|
|
|
return aState;
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
KeyIndicatorState QtFrame::GetIndicatorState() { return KeyIndicatorState(); }
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::SimulateKeyPress(sal_uInt16 nKeyCode)
|
2018-09-04 09:17:11 +02:00
|
|
|
{
|
2021-10-22 14:41:21 +02:00
|
|
|
SAL_WARN("vcl.qt", "missing simulate keypress " << nKeyCode);
|
2018-09-04 09:17:11 +02:00
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
tdf#144585 Qt fix Wayland LO fake popups
So Michael Weghorn was somehow reminded of an abandoned
commit from me ("Qt5 rework parent handling") archived in
https://gerrit.libreoffice.org/c/core/+/73463.
The bug introducing the new QWidget parenting, tdf#145363, was
resolved in a better way by explicitly setting parents for the
modal dialogs, so LO doesn't break Qt anymore. The actual problem
is, that an additional modal dialog needs to be stacked to the
previous modal dialog; no "parallel" modal dialogs are allowed,
which my original fix tried to enforce by reparenting.
Then there is the problem with Qt::Popup's focus grabbing on show,
which breaks LO's editable ComboBox. So LO's popup / FLOAT windows
are mapped to Qt::ToolTip, which are automatically advertised as
tooltips via accessibility. For X11 / xcb, Qt:Window with the
Qt::BypassWindowManagerHint works well enough as an alternative,
but WASM and Wayland don't seem to implement it correctly, so this
just handles popups as Qt::ToolTip on all platforms.
This reverts commit b00a68a8e19370e106cd76258a3c1825f43613ee
("tdf#145363 Qt reparent modal dialogs on show").
In addition the popup widgets are switched back to Qt::ToolTip.
Change-Id: If726771b4e9cc3f639f21cf502b3ec5985873643
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132526
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
2022-04-04 18:02:28 +02:00
|
|
|
// 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); }
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::SetPluginParent(SystemParentData* /*pNewParent*/)
|
2018-09-04 09:17:11 +02:00
|
|
|
{
|
2019-07-09 15:28:29 +00:00
|
|
|
//FIXME: no SetPluginParent impl. for qt5
|
2018-09-04 09:17:11 +02:00
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::ResetClipRegion() { m_bNullRegion = true; }
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::BeginSetClipRegion(sal_uInt32)
|
2018-09-04 09:17:11 +02:00
|
|
|
{
|
|
|
|
m_aRegion = QRegion(QRect(QPoint(0, 0), m_pQWidget->size()));
|
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::UnionClipRegion(tools::Long nX, tools::Long nY, tools::Long nWidth,
|
|
|
|
tools::Long nHeight)
|
2018-09-04 09:17:11 +02:00
|
|
|
{
|
tdf#127687 Qt5 introduce basic HiDPI scaling
For tdf#124292, Qt's own HiDPI scaling was explicitly disabled,
but it turns out, you can't really scale QStyle painting then.
This patch series had a 2nd approach also used by Gtk+ currently,
which relied on the scaling of ths Cairo surface, which works
surprisingly good, but has to lie about the real DPI value, so
nothing is scaled twice. Also all icons are then scaled instead
of rendered with the proper resolution.
When HiDPI support in Qt is enabled, and the application is
started using QT_SCALE_FACTOR=1.25, Qt simply lowers the reported
resolution, keeps the logical DPI value of 96 and changes the
devicePixelRatio to the specified value. But LO still expects
the real DPI values and sizes, so we have to multiply a lot of
rectangles, sizes and positions.
The current result is far from perfect, which you can see with
the various graphics glitches, but it at least doesn't crash
anymore in the ControlType::Editbox sizing code.
The main problem is all the up and downscaling in the
getNativeControlRegion code, so LO knows the size of the widgets
for the correct layouting, since there seem to be no API to
get the scaled values from Qt / QStyle.
Change-Id: I687b1df6ef27724ce68326d256e9addccd72e759
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86239
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
2020-02-29 13:39:29 +01:00
|
|
|
m_aRegion
|
|
|
|
= m_aRegion.united(scaledQRect(QRect(nX, nY, nWidth, nHeight), 1 / devicePixelRatioF()));
|
2018-09-04 09:17:11 +02:00
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::EndSetClipRegion() { m_bNullRegion = false; }
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::SetScreenNumber(unsigned int nScreen)
|
2018-09-04 09:17:11 +02:00
|
|
|
{
|
2020-08-04 09:22:10 +02:00
|
|
|
if (!isWindow())
|
|
|
|
return;
|
|
|
|
|
|
|
|
QWindow* const pWindow = windowHandle();
|
|
|
|
if (!pWindow)
|
|
|
|
return;
|
|
|
|
|
|
|
|
QList<QScreen*> screens = QApplication::screens();
|
2024-09-27 10:11:02 +02:00
|
|
|
if (static_cast<int>(nScreen) >= screens.size() && !m_bFullScreenSpanAll)
|
2018-09-04 09:17:11 +02:00
|
|
|
{
|
2024-09-27 10:11:02 +02:00
|
|
|
SAL_WARN("vcl.qt", "Ignoring request to set invalid screen number");
|
|
|
|
return;
|
|
|
|
}
|
2019-05-29 19:01:28 +02:00
|
|
|
|
2024-09-27 10:11:02 +02:00
|
|
|
QRect screenGeo;
|
2020-08-04 09:22:10 +02:00
|
|
|
|
2024-09-27 10:11:02 +02:00
|
|
|
if (!m_bFullScreenSpanAll)
|
|
|
|
{
|
|
|
|
screenGeo = QGuiApplication::screens().at(nScreen)->geometry();
|
|
|
|
pWindow->setScreen(QApplication::screens().at(nScreen));
|
2018-09-04 09:17:11 +02:00
|
|
|
}
|
2024-09-27 10:11:02 +02:00
|
|
|
else // special case: fullscreen over all available screens
|
2020-08-04 09:22:10 +02:00
|
|
|
{
|
2024-09-27 10:11:02 +02:00
|
|
|
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);
|
2020-08-04 09:22:10 +02:00
|
|
|
}
|
|
|
|
|
2024-09-27 10:11:02 +02:00
|
|
|
// setScreen by itself has no effect, explicitly move the widget to
|
|
|
|
// the new screen
|
|
|
|
asChild()->move(screenGeo.topLeft());
|
2018-09-04 09:17:11 +02:00
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::SetApplicationID(const OUString& rWMClass)
|
2018-09-04 09:17:11 +02:00
|
|
|
{
|
2021-12-01 08:53:25 +01:00
|
|
|
#if CHECK_QT5_USING_X11
|
2022-05-24 18:14:16 +02:00
|
|
|
assert(m_aSystemData.platform != SystemEnvData::Platform::Invalid);
|
2021-11-17 13:03:23 +01:00
|
|
|
if (m_aSystemData.platform != SystemEnvData::Platform::Xcb || !m_pTopLevel)
|
2019-06-14 00:46:32 +00:00
|
|
|
return;
|
|
|
|
|
2022-06-15 23:34:01 +02:00
|
|
|
QtX11Support::setApplicationID(m_pTopLevel->winId(), rWMClass);
|
2019-06-14 00:46:32 +00:00
|
|
|
#else
|
2022-06-15 23:34:01 +02:00
|
|
|
Q_UNUSED(rWMClass);
|
2019-06-14 00:46:32 +00:00
|
|
|
#endif
|
2018-09-04 09:17:11 +02:00
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2021-11-17 13:26:09 +01:00
|
|
|
void QtFrame::ResolveWindowHandle(SystemEnvData& rData) const
|
|
|
|
{
|
|
|
|
if (!rData.pWidget)
|
|
|
|
return;
|
2022-05-24 18:14:16 +02:00
|
|
|
assert(rData.platform != SystemEnvData::Platform::Invalid);
|
tdf#160565 tdf#145735 qt: Avoid native window handles for Qt 6
Similar to the tdf#122293 scenario with Qt 5 on Wayland,
using native windows causes unresponsive UI even with
the xcb Qt QPA plugin when using Qt 6.
Therefore, don't call `QWidget::winId()` at all when
using Qt 6, but just refuse to resolve a native window
handle, the same way that is already done here for the
wayland Qt QPA plugin with qt5.
Add a comment based on the one originally added with
commit 0e3c3b842e14b9646d3697cf1266be21359e0f13
Author: Michael Weghorn <m.weghorn@posteo.de>
Date: Sat May 11 21:31:33 2019 +0200
tdf#122293 qt5: Use "alien widgets" by default on Wayland
that was later dropped during a refactoring.
This code path is triggered when trying to resolve the
parent window for a file picker (s. `QtFilePicker::initialize`).
In a quick test in a KDE Plasma 5 Wayland session on Debian testing,
the modality behavior was unchanged with or without this change in
place:
* With qt6 xcb, the main window nicely gets grayed out and is
unresponsive while the file dialog gets shown when using
e.g. "File" -> "Open" in Writer.
* With qt6 wayland, the main window is not grayed out and looks
more "active" still, but doesn't actually accept keyboard
or mouse input.
This is basically the same in other Qt/KDE applications, e.g.
a self-compiled Kate from git master, so not LO-specific.
If resolving the parent for the file picker turns out to be necessary,
maybe something similar to what commit
commit 3ff4800fe400de916c97f587322104af06cc0879
Author: Caolán McNamara <caolanm@redhat.com>
Date: Wed Apr 4 10:22:34 2018 +0100
weld SvInsertOleDlg
and
weld SfxInsertFloatingFrameDialog
and smuggle in the parent widget for the Gtk File dialog via
an XWindow interface
did for gtk3 might be worth looking into.
However, I can at least not reproduce issues like the one described
for gtk3 in
commit 203d96787969f707c78101be18d51b44ace98f93
Author: Caolán McNamara <caolanm@redhat.com>
Date: Mon Jun 21 13:01:52 2021 +0100
give folderpicker an optional parent
so, like a file picker, it can make its parent modal while its
operating. Otherwise its possible to interact with the parent dialog in
undesirable ways, e.g. file, export as, export as epub, the folder
picker of 'media directory'
with the qt6 VCL plugin even with this commit in place.
Another scenario relying on a native window handle is video
playback with GStreamer's x11 video sink.
That still works for qt5 with the xcb plugin as the handle is
still returned for that one.
For qt6 with the xcb plugin, that didn't work properly
without this commit either (at least not in my tests with
current qtbase dev as of commit
70a2e7f32b9f9ce19d1538f14fbde7b0d1e77ffd), s.
tdf#145735 comment 7.
It's now broken a different way than before
(extra windows show up instead of no video being shown).
This will be further tracked together with a solution for
Wayland in tdf#125219.
As a side note, forcing native windows for everything
using `QT_USE_NATIVE_WINDOWS=1` as described at [1]
causes more sever brokenness with the qt6 xcb plugin
(mostly black window in Writer instead of showing the
actual content).
[1] https://doc.qt.io/qt-6/qwidget.html#native-widgets-vs-alien-widgets
Change-Id: I9718c680bd8bc4ff0574f171403d965c1beac781
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167783
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
2024-05-17 17:02:49 +02:00
|
|
|
// Calling QWidget::winId() implicitly enables native windows to be used instead
|
2024-05-20 07:48:25 +02:00
|
|
|
// of "alien widgets" that don't have a native widget associated with them,
|
tdf#160565 tdf#145735 qt: Avoid native window handles for Qt 6
Similar to the tdf#122293 scenario with Qt 5 on Wayland,
using native windows causes unresponsive UI even with
the xcb Qt QPA plugin when using Qt 6.
Therefore, don't call `QWidget::winId()` at all when
using Qt 6, but just refuse to resolve a native window
handle, the same way that is already done here for the
wayland Qt QPA plugin with qt5.
Add a comment based on the one originally added with
commit 0e3c3b842e14b9646d3697cf1266be21359e0f13
Author: Michael Weghorn <m.weghorn@posteo.de>
Date: Sat May 11 21:31:33 2019 +0200
tdf#122293 qt5: Use "alien widgets" by default on Wayland
that was later dropped during a refactoring.
This code path is triggered when trying to resolve the
parent window for a file picker (s. `QtFilePicker::initialize`).
In a quick test in a KDE Plasma 5 Wayland session on Debian testing,
the modality behavior was unchanged with or without this change in
place:
* With qt6 xcb, the main window nicely gets grayed out and is
unresponsive while the file dialog gets shown when using
e.g. "File" -> "Open" in Writer.
* With qt6 wayland, the main window is not grayed out and looks
more "active" still, but doesn't actually accept keyboard
or mouse input.
This is basically the same in other Qt/KDE applications, e.g.
a self-compiled Kate from git master, so not LO-specific.
If resolving the parent for the file picker turns out to be necessary,
maybe something similar to what commit
commit 3ff4800fe400de916c97f587322104af06cc0879
Author: Caolán McNamara <caolanm@redhat.com>
Date: Wed Apr 4 10:22:34 2018 +0100
weld SvInsertOleDlg
and
weld SfxInsertFloatingFrameDialog
and smuggle in the parent widget for the Gtk File dialog via
an XWindow interface
did for gtk3 might be worth looking into.
However, I can at least not reproduce issues like the one described
for gtk3 in
commit 203d96787969f707c78101be18d51b44ace98f93
Author: Caolán McNamara <caolanm@redhat.com>
Date: Mon Jun 21 13:01:52 2021 +0100
give folderpicker an optional parent
so, like a file picker, it can make its parent modal while its
operating. Otherwise its possible to interact with the parent dialog in
undesirable ways, e.g. file, export as, export as epub, the folder
picker of 'media directory'
with the qt6 VCL plugin even with this commit in place.
Another scenario relying on a native window handle is video
playback with GStreamer's x11 video sink.
That still works for qt5 with the xcb plugin as the handle is
still returned for that one.
For qt6 with the xcb plugin, that didn't work properly
without this commit either (at least not in my tests with
current qtbase dev as of commit
70a2e7f32b9f9ce19d1538f14fbde7b0d1e77ffd), s.
tdf#145735 comment 7.
It's now broken a different way than before
(extra windows show up instead of no video being shown).
This will be further tracked together with a solution for
Wayland in tdf#125219.
As a side note, forcing native windows for everything
using `QT_USE_NATIVE_WINDOWS=1` as described at [1]
causes more sever brokenness with the qt6 xcb plugin
(mostly black window in Writer instead of showing the
actual content).
[1] https://doc.qt.io/qt-6/qwidget.html#native-widgets-vs-alien-widgets
Change-Id: I9718c680bd8bc4ff0574f171403d965c1beac781
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167783
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
2024-05-17 17:02:49 +02:00
|
|
|
// s. https://doc.qt.io/qt-6/qwidget.html#native-widgets-vs-alien-widgets
|
|
|
|
// Avoid native widgets with Qt 5 on Wayland and with Qt 6 altogether as they
|
2024-05-20 07:48:51 +02:00
|
|
|
// cause unresponsive UI, s. tdf#122293/QTBUG-75766 and tdf#160565
|
tdf#160565 tdf#145735 qt: Avoid native window handles for Qt 6
Similar to the tdf#122293 scenario with Qt 5 on Wayland,
using native windows causes unresponsive UI even with
the xcb Qt QPA plugin when using Qt 6.
Therefore, don't call `QWidget::winId()` at all when
using Qt 6, but just refuse to resolve a native window
handle, the same way that is already done here for the
wayland Qt QPA plugin with qt5.
Add a comment based on the one originally added with
commit 0e3c3b842e14b9646d3697cf1266be21359e0f13
Author: Michael Weghorn <m.weghorn@posteo.de>
Date: Sat May 11 21:31:33 2019 +0200
tdf#122293 qt5: Use "alien widgets" by default on Wayland
that was later dropped during a refactoring.
This code path is triggered when trying to resolve the
parent window for a file picker (s. `QtFilePicker::initialize`).
In a quick test in a KDE Plasma 5 Wayland session on Debian testing,
the modality behavior was unchanged with or without this change in
place:
* With qt6 xcb, the main window nicely gets grayed out and is
unresponsive while the file dialog gets shown when using
e.g. "File" -> "Open" in Writer.
* With qt6 wayland, the main window is not grayed out and looks
more "active" still, but doesn't actually accept keyboard
or mouse input.
This is basically the same in other Qt/KDE applications, e.g.
a self-compiled Kate from git master, so not LO-specific.
If resolving the parent for the file picker turns out to be necessary,
maybe something similar to what commit
commit 3ff4800fe400de916c97f587322104af06cc0879
Author: Caolán McNamara <caolanm@redhat.com>
Date: Wed Apr 4 10:22:34 2018 +0100
weld SvInsertOleDlg
and
weld SfxInsertFloatingFrameDialog
and smuggle in the parent widget for the Gtk File dialog via
an XWindow interface
did for gtk3 might be worth looking into.
However, I can at least not reproduce issues like the one described
for gtk3 in
commit 203d96787969f707c78101be18d51b44ace98f93
Author: Caolán McNamara <caolanm@redhat.com>
Date: Mon Jun 21 13:01:52 2021 +0100
give folderpicker an optional parent
so, like a file picker, it can make its parent modal while its
operating. Otherwise its possible to interact with the parent dialog in
undesirable ways, e.g. file, export as, export as epub, the folder
picker of 'media directory'
with the qt6 VCL plugin even with this commit in place.
Another scenario relying on a native window handle is video
playback with GStreamer's x11 video sink.
That still works for qt5 with the xcb plugin as the handle is
still returned for that one.
For qt6 with the xcb plugin, that didn't work properly
without this commit either (at least not in my tests with
current qtbase dev as of commit
70a2e7f32b9f9ce19d1538f14fbde7b0d1e77ffd), s.
tdf#145735 comment 7.
It's now broken a different way than before
(extra windows show up instead of no video being shown).
This will be further tracked together with a solution for
Wayland in tdf#125219.
As a side note, forcing native windows for everything
using `QT_USE_NATIVE_WINDOWS=1` as described at [1]
causes more sever brokenness with the qt6 xcb plugin
(mostly black window in Writer instead of showing the
actual content).
[1] https://doc.qt.io/qt-6/qwidget.html#native-widgets-vs-alien-widgets
Change-Id: I9718c680bd8bc4ff0574f171403d965c1beac781
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167783
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
2024-05-17 17:02:49 +02:00
|
|
|
// (for qt5 xcb, they're needed for video playback)
|
|
|
|
if (rData.platform != SystemEnvData::Platform::Wayland
|
|
|
|
&& QLibraryInfo::version().majorVersion() < 6)
|
|
|
|
{
|
2021-11-17 13:26:09 +01:00
|
|
|
rData.SetWindowHandle(static_cast<QWidget*>(rData.pWidget)->winId());
|
tdf#160565 tdf#145735 qt: Avoid native window handles for Qt 6
Similar to the tdf#122293 scenario with Qt 5 on Wayland,
using native windows causes unresponsive UI even with
the xcb Qt QPA plugin when using Qt 6.
Therefore, don't call `QWidget::winId()` at all when
using Qt 6, but just refuse to resolve a native window
handle, the same way that is already done here for the
wayland Qt QPA plugin with qt5.
Add a comment based on the one originally added with
commit 0e3c3b842e14b9646d3697cf1266be21359e0f13
Author: Michael Weghorn <m.weghorn@posteo.de>
Date: Sat May 11 21:31:33 2019 +0200
tdf#122293 qt5: Use "alien widgets" by default on Wayland
that was later dropped during a refactoring.
This code path is triggered when trying to resolve the
parent window for a file picker (s. `QtFilePicker::initialize`).
In a quick test in a KDE Plasma 5 Wayland session on Debian testing,
the modality behavior was unchanged with or without this change in
place:
* With qt6 xcb, the main window nicely gets grayed out and is
unresponsive while the file dialog gets shown when using
e.g. "File" -> "Open" in Writer.
* With qt6 wayland, the main window is not grayed out and looks
more "active" still, but doesn't actually accept keyboard
or mouse input.
This is basically the same in other Qt/KDE applications, e.g.
a self-compiled Kate from git master, so not LO-specific.
If resolving the parent for the file picker turns out to be necessary,
maybe something similar to what commit
commit 3ff4800fe400de916c97f587322104af06cc0879
Author: Caolán McNamara <caolanm@redhat.com>
Date: Wed Apr 4 10:22:34 2018 +0100
weld SvInsertOleDlg
and
weld SfxInsertFloatingFrameDialog
and smuggle in the parent widget for the Gtk File dialog via
an XWindow interface
did for gtk3 might be worth looking into.
However, I can at least not reproduce issues like the one described
for gtk3 in
commit 203d96787969f707c78101be18d51b44ace98f93
Author: Caolán McNamara <caolanm@redhat.com>
Date: Mon Jun 21 13:01:52 2021 +0100
give folderpicker an optional parent
so, like a file picker, it can make its parent modal while its
operating. Otherwise its possible to interact with the parent dialog in
undesirable ways, e.g. file, export as, export as epub, the folder
picker of 'media directory'
with the qt6 VCL plugin even with this commit in place.
Another scenario relying on a native window handle is video
playback with GStreamer's x11 video sink.
That still works for qt5 with the xcb plugin as the handle is
still returned for that one.
For qt6 with the xcb plugin, that didn't work properly
without this commit either (at least not in my tests with
current qtbase dev as of commit
70a2e7f32b9f9ce19d1538f14fbde7b0d1e77ffd), s.
tdf#145735 comment 7.
It's now broken a different way than before
(extra windows show up instead of no video being shown).
This will be further tracked together with a solution for
Wayland in tdf#125219.
As a side note, forcing native windows for everything
using `QT_USE_NATIVE_WINDOWS=1` as described at [1]
causes more sever brokenness with the qt6 xcb plugin
(mostly black window in Writer instead of showing the
actual content).
[1] https://doc.qt.io/qt-6/qwidget.html#native-widgets-vs-alien-widgets
Change-Id: I9718c680bd8bc4ff0574f171403d965c1beac781
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167783
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
2024-05-17 17:02:49 +02:00
|
|
|
}
|
2021-11-17 13:26:09 +01:00
|
|
|
}
|
|
|
|
|
2024-09-27 09:08:43 +02:00
|
|
|
bool QtFrame::GetUseReducedAnimation() const { return GetQtInstance().GetUseReducedAnimation(); }
|
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
|
|
|
|
2018-10-04 17:12:40 +02:00
|
|
|
// Drag'n'drop foo
|
2018-12-03 16:40:27 +01:00
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::registerDragSource(QtDragSource* pDragSource)
|
2018-10-04 17:12:40 +02:00
|
|
|
{
|
|
|
|
assert(!m_pDragSource);
|
|
|
|
m_pDragSource = pDragSource;
|
|
|
|
}
|
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::deregisterDragSource(QtDragSource const* pDragSource)
|
2018-10-04 17:12:40 +02:00
|
|
|
{
|
|
|
|
assert(m_pDragSource == pDragSource);
|
|
|
|
(void)pDragSource;
|
|
|
|
m_pDragSource = nullptr;
|
|
|
|
}
|
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::registerDropTarget(QtDropTarget* pDropTarget)
|
2018-10-04 17:12:40 +02:00
|
|
|
{
|
|
|
|
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
|
|
|
|
2024-09-27 09:08:43 +02:00
|
|
|
GetQtInstance().RunInMainThread([this]() { m_pQWidget->setAcceptDrops(true); });
|
2018-10-04 17:12:40 +02:00
|
|
|
}
|
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::deregisterDropTarget(QtDropTarget const* pDropTarget)
|
2018-10-04 17:12:40 +02:00
|
|
|
{
|
|
|
|
assert(m_pDropTarget == pDropTarget);
|
|
|
|
(void)pDropTarget;
|
|
|
|
m_pDropTarget = nullptr;
|
|
|
|
}
|
|
|
|
|
2019-08-08 17:59:20 +00:00
|
|
|
static css::uno::Reference<css::datatransfer::XTransferable>
|
|
|
|
lcl_getXTransferable(const QMimeData* pMimeData)
|
2018-10-15 14:44:29 +02:00
|
|
|
{
|
2019-08-08 17:59:20 +00:00
|
|
|
css::uno::Reference<css::datatransfer::XTransferable> xTransferable;
|
2024-09-19 11:02:48 +02:00
|
|
|
const QtMimeData* pQtMimeData = qobject_cast<const QtMimeData*>(pMimeData);
|
2021-09-28 15:02:47 +02:00
|
|
|
if (!pQtMimeData)
|
|
|
|
xTransferable = new QtDnDTransferable(pMimeData);
|
2019-08-08 17:59:20 +00:00
|
|
|
else
|
2021-09-28 15:02:47 +02:00
|
|
|
xTransferable = pQtMimeData->xTransferable();
|
2019-08-08 17:59:20 +00:00
|
|
|
return xTransferable;
|
|
|
|
}
|
2018-10-15 14:44:29 +02:00
|
|
|
|
2019-08-08 17:59:20 +00:00
|
|
|
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
|
2019-08-08 17:59:20 +00:00
|
|
|
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
|
2019-08-08 17:59:20 +00:00
|
|
|
sal_Int8 nUserDropAction = 0;
|
2019-05-23 18:11:43 +02:00
|
|
|
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;
|
2019-08-15 10:35:33 +00:00
|
|
|
nUserDropAction &= nSourceActions;
|
2019-08-08 17:59:20 +00:00
|
|
|
|
|
|
|
// 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
|
2024-09-19 11:02:48 +02:00
|
|
|
nUserDropAction = qobject_cast<const QtMimeData*>(pMimeData)
|
2019-08-08 17:59:20 +00:00
|
|
|
? css::datatransfer::dnd::DNDConstants::ACTION_MOVE
|
|
|
|
: css::datatransfer::dnd::DNDConstants::ACTION_COPY;
|
2019-08-15 10:35:33 +00:00
|
|
|
nUserDropAction &= nSourceActions;
|
2019-08-08 17:59:20 +00:00
|
|
|
|
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::handleDragMove(QDragMoveEvent* pEvent)
|
2019-08-08 17:59:20 +00:00
|
|
|
{
|
|
|
|
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
|
tdf#127687 Qt5 introduce basic HiDPI scaling
For tdf#124292, Qt's own HiDPI scaling was explicitly disabled,
but it turns out, you can't really scale QStyle painting then.
This patch series had a 2nd approach also used by Gtk+ currently,
which relied on the scaling of ths Cairo surface, which works
surprisingly good, but has to lie about the real DPI value, so
nothing is scaled twice. Also all icons are then scaled instead
of rendered with the proper resolution.
When HiDPI support in Qt is enabled, and the application is
started using QT_SCALE_FACTOR=1.25, Qt simply lowers the reported
resolution, keeps the logical DPI value of 96 and changes the
devicePixelRatio to the specified value. But LO still expects
the real DPI values and sizes, so we have to multiply a lot of
rectangles, sizes and positions.
The current result is far from perfect, which you can see with
the various graphics glitches, but it at least doesn't crash
anymore in the ControlType::Editbox sizing code.
The main problem is all the up and downscaling in the
getNativeControlRegion code, so LO knows the size of the widgets
for the correct layouting, since there seem to be no API to
get the scaled values from Qt / QStyle.
Change-Id: I687b1df6ef27724ce68326d256e9addccd72e759
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86239
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
2020-02-29 13:39:29 +01:00
|
|
|
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
|
2019-05-23 18:11:43 +02:00
|
|
|
|
2018-10-15 14:44:29 +02:00
|
|
|
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);
|
tdf#127687 Qt5 introduce basic HiDPI scaling
For tdf#124292, Qt's own HiDPI scaling was explicitly disabled,
but it turns out, you can't really scale QStyle painting then.
This patch series had a 2nd approach also used by Gtk+ currently,
which relied on the scaling of ths Cairo surface, which works
surprisingly good, but has to lie about the real DPI value, so
nothing is scaled twice. Also all icons are then scaled instead
of rendered with the proper resolution.
When HiDPI support in Qt is enabled, and the application is
started using QT_SCALE_FACTOR=1.25, Qt simply lowers the reported
resolution, keeps the logical DPI value of 96 and changes the
devicePixelRatio to the specified value. But LO still expects
the real DPI values and sizes, so we have to multiply a lot of
rectangles, sizes and positions.
The current result is far from perfect, which you can see with
the various graphics glitches, but it at least doesn't crash
anymore in the ControlType::Editbox sizing code.
The main problem is all the up and downscaling in the
getNativeControlRegion code, so LO knows the size of the widgets
for the correct layouting, since there seem to be no API to
get the scaled values from Qt / QStyle.
Change-Id: I687b1df6ef27724ce68326d256e9addccd72e759
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86239
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
2020-02-29 13:39:29 +01:00
|
|
|
aEvent.LocationX = aPos.X();
|
|
|
|
aEvent.LocationY = aPos.Y();
|
2019-08-08 17:59:20 +00:00
|
|
|
aEvent.DropAction = nUserDropAction;
|
|
|
|
aEvent.SourceActions = nSourceActions;
|
2018-10-15 14:44:29 +02:00
|
|
|
|
2019-08-08 17:59:20 +00:00
|
|
|
// ask the drop target to accept our drop action
|
|
|
|
if (!m_bInDrag)
|
2018-10-15 14:44:29 +02:00
|
|
|
{
|
2019-08-08 17:59:20 +00:00
|
|
|
aEvent.SupportedDataFlavors = lcl_getXTransferable(pMimeData)->getTransferDataFlavors();
|
2018-10-15 14:44:29 +02:00
|
|
|
m_pDropTarget->fire_dragEnter(aEvent);
|
|
|
|
m_bInDrag = true;
|
|
|
|
}
|
2018-10-18 13:13:29 +02:00
|
|
|
else
|
|
|
|
m_pDropTarget->fire_dragOver(aEvent);
|
2019-08-08 17:59:20 +00:00
|
|
|
|
|
|
|
// 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();
|
2018-10-15 14:44:29 +02:00
|
|
|
}
|
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::handleDrop(QDropEvent* pEvent)
|
2018-10-18 01:01:14 +02:00
|
|
|
{
|
|
|
|
assert(m_pDropTarget);
|
|
|
|
|
2019-08-08 17:59:20 +00:00
|
|
|
// 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
|
tdf#127687 Qt5 introduce basic HiDPI scaling
For tdf#124292, Qt's own HiDPI scaling was explicitly disabled,
but it turns out, you can't really scale QStyle painting then.
This patch series had a 2nd approach also used by Gtk+ currently,
which relied on the scaling of ths Cairo surface, which works
surprisingly good, but has to lie about the real DPI value, so
nothing is scaled twice. Also all icons are then scaled instead
of rendered with the proper resolution.
When HiDPI support in Qt is enabled, and the application is
started using QT_SCALE_FACTOR=1.25, Qt simply lowers the reported
resolution, keeps the logical DPI value of 96 and changes the
devicePixelRatio to the specified value. But LO still expects
the real DPI values and sizes, so we have to multiply a lot of
rectangles, sizes and positions.
The current result is far from perfect, which you can see with
the various graphics glitches, but it at least doesn't crash
anymore in the ControlType::Editbox sizing code.
The main problem is all the up and downscaling in the
getNativeControlRegion code, so LO knows the size of the widgets
for the correct layouting, since there seem to be no API to
get the scaled values from Qt / QStyle.
Change-Id: I687b1df6ef27724ce68326d256e9addccd72e759
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86239
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
2020-02-29 13:39:29 +01:00
|
|
|
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
|
2019-08-08 17:59:20 +00:00
|
|
|
|
2018-10-18 01:01:14 +02:00
|
|
|
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);
|
tdf#127687 Qt5 introduce basic HiDPI scaling
For tdf#124292, Qt's own HiDPI scaling was explicitly disabled,
but it turns out, you can't really scale QStyle painting then.
This patch series had a 2nd approach also used by Gtk+ currently,
which relied on the scaling of ths Cairo surface, which works
surprisingly good, but has to lie about the real DPI value, so
nothing is scaled twice. Also all icons are then scaled instead
of rendered with the proper resolution.
When HiDPI support in Qt is enabled, and the application is
started using QT_SCALE_FACTOR=1.25, Qt simply lowers the reported
resolution, keeps the logical DPI value of 96 and changes the
devicePixelRatio to the specified value. But LO still expects
the real DPI values and sizes, so we have to multiply a lot of
rectangles, sizes and positions.
The current result is far from perfect, which you can see with
the various graphics glitches, but it at least doesn't crash
anymore in the ControlType::Editbox sizing code.
The main problem is all the up and downscaling in the
getNativeControlRegion code, so LO knows the size of the widgets
for the correct layouting, since there seem to be no API to
get the scaled values from Qt / QStyle.
Change-Id: I687b1df6ef27724ce68326d256e9addccd72e759
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86239
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
2020-02-29 13:39:29 +01:00
|
|
|
aEvent.LocationX = aPos.X();
|
|
|
|
aEvent.LocationY = aPos.Y();
|
2019-08-08 17:59:20 +00:00
|
|
|
aEvent.SourceActions = nSourceActions;
|
|
|
|
aEvent.DropAction = nUserDropAction;
|
|
|
|
aEvent.Transferable = lcl_getXTransferable(pEvent->mimeData());
|
2018-10-18 01:01:14 +02:00
|
|
|
|
2019-08-08 17:59:20 +00:00
|
|
|
// ask the drop target to accept our drop action
|
2018-10-18 01:01:14 +02:00
|
|
|
m_pDropTarget->fire_drop(aEvent);
|
2018-10-18 13:13:29 +02:00
|
|
|
m_bInDrag = false;
|
|
|
|
|
2019-08-08 17:59:20 +00:00
|
|
|
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())
|
2018-10-18 13:13:29 +02:00
|
|
|
{
|
2024-09-19 11:13:24 +02:00
|
|
|
QtWidget* pWidget = qobject_cast<QtWidget*>(pEvent->source());
|
2019-08-08 17:59:20 +00:00
|
|
|
assert(pWidget); // AFAIK there shouldn't be any non-Qt5Widget as source in LO itself
|
|
|
|
if (pWidget)
|
2019-08-15 10:35:33 +00:00
|
|
|
pWidget->frame().m_pDragSource->fire_dragEnd(nDropAction, bDropSuccessful);
|
2018-10-18 13:13:29 +02:00
|
|
|
}
|
2019-08-08 17:59:20 +00:00
|
|
|
|
|
|
|
// 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();
|
|
|
|
}
|
|
|
|
|
2021-09-28 15:02:47 +02:00
|
|
|
void QtFrame::handleDragLeave()
|
2019-08-08 17:59:20 +00:00
|
|
|
{
|
|
|
|
css::datatransfer::dnd::DropTargetEvent aEvent;
|
|
|
|
aEvent.Source = static_cast<css::datatransfer::dnd::XDropTarget*>(m_pDropTarget);
|
|
|
|
m_pDropTarget->fire_dragExit(aEvent);
|
|
|
|
m_bInDrag = false;
|
2018-10-18 01:01:14 +02:00
|
|
|
}
|
|
|
|
|
tdf#160837 qt: Rely on toolkit for frame positions, drop menubar hack
Make `SalFrame::GetUnmirroredGeometry` overridable
(and let it return a copy of the SalFrameGeometry
instead of a const reference) and document that
subclasses can either make sure to keep the
`SalFrame::maGeometry` member (which is returned by
the default implementation of
`SalFrame::GetUnmirroredGeometry`) up to date or override
the latter in order to always return the current
geometry.
Override the method in `QtFrame` and fully rely on Qt
to report and set the position of the frame, via
the corresponding QWidget: Set the position, width
and height in the returned `SalFrameGeometry`
to the ones of the widget (factoring in the
scale factor).
Stop updating `maGeometry` size/position whenever
the widget position or size changes, as that is no
longer used anymore now that `GetUnmirroredGeometry`
is overriden.
This also allows to drop earlier hacks where
position calculation in some places had to be adjusted
by the height of the native menu bar, as that one
doesn't have a corresponding vcl::Window, but results
in everything else being shifted down a bit.
Using Qt directly to set other members of the
returned `SalFrameGeometry` (like the screen number)
would probably be possible, but is not included
in this change. (It can still be done separately
later.)
This makes Accerciser highlight the correct area
when using the qt6 VCL plugin and using Writer
with the standard interface (where the y position
reported via AT-SPI2 would previously always be
too small, missing the menu bar height) and thus
e.g. also allows to make use of it's "select object
under mouse" feature (s. tdf#160837).
The position via AT-SPI is however currently only
correct on X11/XWayland where global/screen coordinates
are reported via AT-SPI2.
Wayland, where window-relative coordinates are used,
still suffers from another issue that will be addressed
in a separate commit.
The highlighting in Accerciser is also still wrong
when a screen scaling factor other than 100% is set,
but that's broken for other applications (e.g. gtk3-demo)
just the same, so might be an issue in Accerciser instead.
I successfully tested that these behave as expected
when using the qt6 VCL plugin with this change in place:
* Combobox popup positions, with either 100% screen scaling
or a scaling factor of 150% or 200% on both, X11 and
Wayland.
* When enabling RTL mode via env var `SAL_RTL_ENABLED=1`,
RTL layout is used and things look OK at a quick glance.
* The following bugs (somewhat related to positioning and/or
the now dropped menu bar hacks) are still fixed, i.e. don't
reappear:
* tdf#149805 "kf5: Gap when expanding comboboxes in toolbar"
* tdf#151677 "tip on "formula bar" for "formula making" is
displaying over the formula itself."
* tdf#152217 "Black box in Basic IDE where the status bar
should be (kf5 only)"
* tdf#153458 "Connecting to database: wrong cursor position
for dropping data to Calc sheet"
* tdf#153800 "Calc sheet tab drag-and-drop target area has
shifted vertically (kf5-only)"
* tdf#154043 "Change object layer via drag and drop has target
shifted down (KF5-only)"
* tdf#154447 "Clicking a dropdown tool button shouldn't
place the context menu on top of the button (kf5)"
Unrelated to this commit, popup positioning and rendering in
in a multi-screen setup on Wayland with different scaling
factors set for the single screens is still broken (see
tdf#141578).
Change-Id: Ifa0eff271c7d3fa2b6db9bdc1669e62333bd3094
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173996
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
2024-09-26 18:22:12 +02:00
|
|
|
void QtFrame::handleMoveEvent(QMoveEvent*) { CallCallback(SalEvent::Move, nullptr); }
|
2024-09-25 15:06:21 +02:00
|
|
|
|
2024-09-25 15:36:49 +02:00
|
|
|
void QtFrame::handlePaintEvent(QPaintEvent* pEvent, QWidget* pWidget)
|
|
|
|
{
|
|
|
|
QPainter p(pWidget);
|
|
|
|
if (!m_bNullRegion)
|
|
|
|
p.setClipRegion(m_aRegion);
|
|
|
|
|
|
|
|
QImage aImage;
|
|
|
|
if (m_bUseCairo)
|
|
|
|
{
|
|
|
|
cairo_surface_t* pSurface = m_pSurface.get();
|
|
|
|
cairo_surface_flush(pSurface);
|
|
|
|
|
|
|
|
aImage = QImage(cairo_image_surface_get_data(pSurface),
|
|
|
|
cairo_image_surface_get_width(pSurface),
|
|
|
|
cairo_image_surface_get_height(pSurface), Qt_DefaultFormat32);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
aImage = *m_pQImage;
|
|
|
|
|
|
|
|
const qreal fRatio = devicePixelRatioF();
|
|
|
|
aImage.setDevicePixelRatio(fRatio);
|
|
|
|
QRectF source(pEvent->rect().topLeft() * fRatio, pEvent->rect().size() * fRatio);
|
|
|
|
p.drawImage(pEvent->rect(), aImage, source);
|
|
|
|
}
|
|
|
|
|
2024-09-25 15:20:37 +02:00
|
|
|
void QtFrame::handleResizeEvent(QResizeEvent* pEvent)
|
|
|
|
{
|
|
|
|
const qreal fRatio = devicePixelRatioF();
|
|
|
|
const int nWidth = ceil(pEvent->size().width() * fRatio);
|
|
|
|
const int nHeight = ceil(pEvent->size().height() * fRatio);
|
|
|
|
|
|
|
|
if (m_bUseCairo)
|
|
|
|
{
|
|
|
|
if (m_pSurface)
|
|
|
|
{
|
|
|
|
const int nOldWidth = cairo_image_surface_get_width(m_pSurface.get());
|
|
|
|
const int nOldHeight = cairo_image_surface_get_height(m_pSurface.get());
|
|
|
|
if (nOldWidth != nWidth || nOldHeight != nHeight)
|
|
|
|
{
|
|
|
|
cairo_surface_t* pSurface
|
|
|
|
= cairo_image_surface_create(CAIRO_FORMAT_ARGB32, nWidth, nHeight);
|
|
|
|
cairo_surface_set_user_data(pSurface, SvpSalGraphics::getDamageKey(),
|
|
|
|
&m_aDamageHandler, nullptr);
|
|
|
|
m_pSvpGraphics->setSurface(pSurface, basegfx::B2IVector(nWidth, nHeight));
|
|
|
|
UniqueCairoSurface old_surface(m_pSurface.release());
|
|
|
|
m_pSurface.reset(pSurface);
|
|
|
|
|
|
|
|
const int nMinWidth = qMin(nOldWidth, nWidth);
|
|
|
|
const int nMinHeight = qMin(nOldHeight, nHeight);
|
|
|
|
SalTwoRect rect(0, 0, nMinWidth, nMinHeight, 0, 0, nMinWidth, nMinHeight);
|
|
|
|
m_pSvpGraphics->copySource(rect, old_surface.get());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (m_pQImage && m_pQImage->size() != QSize(nWidth, nHeight))
|
|
|
|
{
|
|
|
|
QImage* pImage = new QImage(m_pQImage->copy(0, 0, nWidth, nHeight));
|
|
|
|
m_pQtGraphics->ChangeQImage(pImage);
|
|
|
|
m_pQImage.reset(pImage);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CallCallback(SalEvent::Resize, nullptr);
|
|
|
|
}
|
|
|
|
|
2024-11-18 09:33:05 +01:00
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|