summaryrefslogtreecommitdiff
path: root/vcl/qt5/Qt5Frame.cxx
diff options
context:
space:
mode:
authorLuca Carlon <carlon.luca@gmail.com>2020-02-29 13:39:29 +0100
committerJan-Marek Glogowski <glogow@fbihome.de>2020-03-09 14:19:49 +0100
commit358991e3b0a49bb201c2f1e4be900ee99aac9aa8 (patch)
tree320852cd425045cbd1eff4198357bbaa05f348fe /vcl/qt5/Qt5Frame.cxx
parent2c5655d72401e6b6e917ece381e879b30680d20f (diff)
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>
Diffstat (limited to 'vcl/qt5/Qt5Frame.cxx')
-rw-r--r--vcl/qt5/Qt5Frame.cxx60
1 files changed, 39 insertions, 21 deletions
diff --git a/vcl/qt5/Qt5Frame.cxx b/vcl/qt5/Qt5Frame.cxx
index 722dca9467db..2d780c7bd4ee 100644
--- a/vcl/qt5/Qt5Frame.cxx
+++ b/vcl/qt5/Qt5Frame.cxx
@@ -284,7 +284,8 @@ Qt5Frame::~Qt5Frame()
void Qt5Frame::Damage(sal_Int32 nExtentsX, sal_Int32 nExtentsY, sal_Int32 nExtentsWidth,
sal_Int32 nExtentsHeight) const
{
- m_pQWidget->update(nExtentsX, nExtentsY, nExtentsWidth, nExtentsHeight);
+ m_pQWidget->update(scaledQRect(QRect(nExtentsX, nExtentsY, nExtentsWidth, nExtentsHeight),
+ 1 / devicePixelRatioF()));
}
void Qt5Frame::InitQt5SvpGraphics(Qt5SvpGraphics* pQt5SvpGraphics)
@@ -320,7 +321,8 @@ SalGraphics* Qt5Frame::AcquireGraphics()
if (!m_pQt5Graphics.get() || m_bGraphicsInvalid)
{
m_pQt5Graphics.reset(new Qt5Graphics(this));
- m_pQImage.reset(new QImage(m_pQWidget->size(), Qt5_DefaultFormat32));
+ m_pQImage.reset(
+ new QImage(m_pQWidget->size() * devicePixelRatioF(), Qt5_DefaultFormat32));
m_pQImage->fill(Qt::transparent);
m_pQt5Graphics->ChangeQImage(m_pQImage.get());
m_bGraphicsInvalid = false;
@@ -348,6 +350,8 @@ bool Qt5Frame::PostEvent(std::unique_ptr<ImplSVEvent> pData)
QWidget* Qt5Frame::asChild() const { return m_pTopLevel ? m_pTopLevel : m_pQWidget; }
+qreal Qt5Frame::devicePixelRatioF() const { return asChild()->devicePixelRatioF(); }
+
bool Qt5Frame::isWindow() const { return asChild()->isWindow(); }
QWindow* Qt5Frame::windowHandle() const
@@ -429,13 +433,19 @@ void Qt5Frame::Show(bool bVisible, bool /*bNoActivate*/)
void Qt5Frame::SetMinClientSize(long nWidth, long nHeight)
{
if (!isChild())
- asChild()->setMinimumSize(nWidth, nHeight);
+ {
+ const qreal fRatio = devicePixelRatioF();
+ asChild()->setMinimumSize(round(nWidth / fRatio), round(nHeight / fRatio));
+ }
}
void Qt5Frame::SetMaxClientSize(long nWidth, long nHeight)
{
if (!isChild())
- asChild()->setMaximumSize(nWidth, nHeight);
+ {
+ const qreal fRatio = devicePixelRatioF();
+ asChild()->setMaximumSize(round(nWidth / fRatio), round(nHeight / fRatio));
+ }
}
void Qt5Frame::SetDefaultPos()
@@ -446,10 +456,12 @@ void Qt5Frame::SetDefaultPos()
// center on parent
if (m_pParent)
{
+ const qreal fRatio = devicePixelRatioF();
QWidget* const pWindow = m_pParent->GetQWidget()->window();
QWidget* const pWidget = asChild();
QPoint aPos = pWindow->rect().center() - pWidget->rect().center();
- SetPosSize(aPos.x(), aPos.y(), 0, 0, SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y);
+ SetPosSize(round(aPos.x() * fRatio), round(aPos.y() * fRatio), 0, 0,
+ SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y);
assert(!m_bDefaultPos);
}
else
@@ -518,10 +530,12 @@ void Qt5Frame::SetPosSize(long nX, long nY, long nWidth, long nHeight, sal_uInt1
if (nWidth > 0 && nHeight > 0)
{
m_bDefaultSize = false;
+ const int nNewWidth = round(nWidth / devicePixelRatioF());
+ const int nNewHeight = round(nHeight / devicePixelRatioF());
if (m_nStyle & SalFrameStyleFlags::SIZEABLE)
- asChild()->resize(nWidth, nHeight);
+ asChild()->resize(nNewWidth, nNewHeight);
else
- asChild()->setFixedSize(nWidth, nHeight);
+ asChild()->setFixedSize(nNewWidth, nNewHeight);
}
// assume the resize happened
@@ -546,7 +560,7 @@ void Qt5Frame::SetPosSize(long nX, long nY, long nWidth, long nHeight, sal_uInt1
Qt5MainWindow* pTopLevel = m_pParent->GetTopLevelWindow();
if (pTopLevel && pTopLevel->menuBar() && pTopLevel->menuBar()->isVisible())
- nY += pTopLevel->menuBar()->geometry().height();
+ nY += round(pTopLevel->menuBar()->geometry().height() * devicePixelRatioF());
}
if (!(nFlags & SAL_FRAME_POSSIZE_X))
@@ -560,14 +574,14 @@ void Qt5Frame::SetPosSize(long nX, long nY, long nWidth, long nHeight, sal_uInt1
maGeometry.nY = nY;
m_bDefaultPos = false;
- asChild()->move(nX, nY);
+ asChild()->move(round(nX / devicePixelRatioF()), round(nY / devicePixelRatioF()));
}
}
void Qt5Frame::GetClientSize(long& rWidth, long& rHeight)
{
- rWidth = m_pQWidget->width();
- rHeight = m_pQWidget->height();
+ rWidth = round(m_pQWidget->width() * devicePixelRatioF());
+ rHeight = round(m_pQWidget->height() * devicePixelRatioF());
}
void Qt5Frame::GetWorkArea(tools::Rectangle& rRect)
@@ -578,7 +592,7 @@ void Qt5Frame::GetWorkArea(tools::Rectangle& rRect)
if (!pScreen)
return;
- QSize aSize = pScreen->availableVirtualSize();
+ QSize aSize = pScreen->availableVirtualSize() * devicePixelRatioF();
rRect = tools::Rectangle(0, 0, aSize.width(), aSize.height());
}
@@ -622,9 +636,10 @@ void Qt5Frame::SetWindowState(const SalFrameState* pState)
if ((pState->mnMask & WindowStateMask::State) && (pState->mnState & WindowStateState::Maximized)
&& !isMaximized() && (pState->mnMask & nMaxGeometryMask) == nMaxGeometryMask)
{
+ const qreal fRatio = devicePixelRatioF();
QWidget* const pChild = asChild();
- pChild->resize(pState->mnWidth, pState->mnHeight);
- pChild->move(pState->mnX, pState->mnY);
+ pChild->resize(ceil(pState->mnWidth / fRatio), ceil(pState->mnHeight / fRatio));
+ pChild->move(ceil(pState->mnX / fRatio), ceil(pState->mnY / fRatio));
SetWindowStateImpl(Qt::WindowMaximized);
}
else if (pState->mnMask
@@ -666,7 +681,7 @@ bool Qt5Frame::GetWindowState(SalFrameState* pState)
else
{
// geometry() is the drawable area, which is wanted here
- QRect rect = asChild()->geometry();
+ QRect rect = scaledQRect(asChild()->geometry(), devicePixelRatioF());
pState->mnX = rect.x();
pState->mnY = rect.y();
pState->mnWidth = rect.width();
@@ -1132,7 +1147,7 @@ void Qt5Frame::Beep() { QApplication::beep(); }
SalFrame::SalPointerState Qt5Frame::GetPointerState()
{
SalPointerState aState;
- aState.maPos = toPoint(QCursor::pos());
+ aState.maPos = toPoint(QCursor::pos() * devicePixelRatioF());
aState.maPos.Move(-maGeometry.nX, -maGeometry.nY);
aState.mnState = GetMouseModCode(QGuiApplication::mouseButtons())
| GetKeyModCode(QGuiApplication::keyboardModifiers());
@@ -1163,7 +1178,8 @@ void Qt5Frame::BeginSetClipRegion(sal_uInt32)
void Qt5Frame::UnionClipRegion(long nX, long nY, long nWidth, long nHeight)
{
- m_aRegion = m_aRegion.united(QRegion(nX, nY, nWidth, nHeight));
+ m_aRegion
+ = m_aRegion.united(scaledQRect(QRect(nX, nY, nWidth, nHeight), 1 / devicePixelRatioF()));
}
void Qt5Frame::EndSetClipRegion() { m_bNullRegion = false; }
@@ -1330,12 +1346,13 @@ void Qt5Frame::handleDragMove(QDragMoveEvent* pEvent)
const sal_Int8 nSourceActions = toVclDropActions(pEvent->possibleActions());
const QMimeData* pMimeData = pEvent->mimeData();
const sal_Int8 nUserDropAction = lcl_getUserDropAction(pEvent, nSourceActions, pMimeData);
+ const Point aPos = toPoint(pEvent->pos() * devicePixelRatioF());
css::datatransfer::dnd::DropTargetDragEnterEvent aEvent;
aEvent.Source = static_cast<css::datatransfer::dnd::XDropTarget*>(m_pDropTarget);
aEvent.Context = static_cast<css::datatransfer::dnd::XDropTargetDragContext*>(m_pDropTarget);
- aEvent.LocationX = pEvent->pos().x();
- aEvent.LocationY = pEvent->pos().y();
+ aEvent.LocationX = aPos.X();
+ aEvent.LocationY = aPos.Y();
aEvent.DropAction = nUserDropAction;
aEvent.SourceActions = nSourceActions;
@@ -1367,12 +1384,13 @@ void Qt5Frame::handleDrop(QDropEvent* pEvent)
const sal_Int8 nSourceActions = toVclDropActions(pEvent->possibleActions());
const sal_Int8 nUserDropAction
= lcl_getUserDropAction(pEvent, nSourceActions, pEvent->mimeData());
+ const Point aPos = toPoint(pEvent->pos() * devicePixelRatioF());
css::datatransfer::dnd::DropTargetDropEvent aEvent;
aEvent.Source = static_cast<css::datatransfer::dnd::XDropTarget*>(m_pDropTarget);
aEvent.Context = static_cast<css::datatransfer::dnd::XDropTargetDropContext*>(m_pDropTarget);
- aEvent.LocationX = pEvent->pos().x();
- aEvent.LocationY = pEvent->pos().y();
+ aEvent.LocationX = aPos.X();
+ aEvent.LocationY = aPos.Y();
aEvent.SourceActions = nSourceActions;
aEvent.DropAction = nUserDropAction;
aEvent.Transferable = lcl_getXTransferable(pEvent->mimeData());