Add devicePixelRatio support to the Windows QPA plugin.
This adds support for the environment variable QT_DEVICE_PIXEL_RATIO for the Windows platform plugin. Task-number: QTBUG-38993 Task-number: QTBUG-38858 Change-Id: I6831eb6d3a09a80be7bbef46395e91531b61cc50 Reviewed-by: Alessandro Portale <alessandro.portale@digia.com> Reviewed-by: Paul Olav Tvete <paul.tvete@digia.com>bb10
parent
d8168f10a1
commit
c47b04696a
|
|
@ -43,6 +43,7 @@
|
|||
#include "qwindowswindow.h"
|
||||
#include "qwindowsnativeimage.h"
|
||||
#include "qwindowscontext.h"
|
||||
#include "qwindowsscaling.h"
|
||||
|
||||
#include <QtGui/QWindow>
|
||||
#include <QtGui/QPainter>
|
||||
|
|
@ -75,12 +76,10 @@ QPaintDevice *QWindowsBackingStore::paintDevice()
|
|||
return &m_image->image();
|
||||
}
|
||||
|
||||
void QWindowsBackingStore::flush(QWindow *window, const QRegion ®ion,
|
||||
const QPoint &offset)
|
||||
void QWindowsBackingStore::flushDp(QWindow *window, const QRect &br, const QPoint &offset)
|
||||
{
|
||||
Q_ASSERT(window);
|
||||
|
||||
const QRect br = region.boundingRect();
|
||||
if (QWindowsContext::verbose > 1)
|
||||
qCDebug(lcQpaBackingStore) << __FUNCTION__ << this << window << offset << br;
|
||||
QWindowsWindow *rw = QWindowsWindow::baseWindowOf(window);
|
||||
|
|
@ -90,8 +89,9 @@ void QWindowsBackingStore::flush(QWindow *window, const QRegion ®ion,
|
|||
const Qt::WindowFlags flags = window->flags();
|
||||
if ((flags & Qt::FramelessWindowHint) && QWindowsWindow::setWindowLayered(rw->handle(), flags, hasAlpha, rw->opacity()) && hasAlpha) {
|
||||
// Windows with alpha: Use blend function to update.
|
||||
QRect r = window->frameGeometry();
|
||||
QPoint frameOffset(window->frameMargins().left(), window->frameMargins().top());
|
||||
const QMargins marginsDP = rw->frameMarginsDp();
|
||||
const QRect r = rw->geometryDp() + marginsDP;
|
||||
const QPoint frameOffset(marginsDP.left(), marginsDP.top());
|
||||
QRect dirtyRect = br.translated(offset + frameOffset);
|
||||
|
||||
SIZE size = {r.width(), r.height()};
|
||||
|
|
@ -135,14 +135,15 @@ void QWindowsBackingStore::flush(QWindow *window, const QRegion ®ion,
|
|||
}
|
||||
}
|
||||
|
||||
void QWindowsBackingStore::resize(const QSize &size, const QRegion ®ion)
|
||||
void QWindowsBackingStore::resize(const QSize &sizeDip, const QRegion ®ionDip)
|
||||
{
|
||||
const QSize size = sizeDip * QWindowsScaling::factor();
|
||||
if (m_image.isNull() || m_image->image().size() != size) {
|
||||
#ifndef QT_NO_DEBUG_OUTPUT
|
||||
if (QWindowsContext::verbose && lcQpaBackingStore().isDebugEnabled()) {
|
||||
qCDebug(lcQpaBackingStore)
|
||||
<< __FUNCTION__ << ' ' << window() << ' ' << size << ' ' << region
|
||||
<< " from: " << (m_image.isNull() ? QSize() : m_image->image().size());
|
||||
<< __FUNCTION__ << ' ' << window() << ' ' << size << ' ' << sizeDip << ' '
|
||||
<< regionDip << " from: " << (m_image.isNull() ? QSize() : m_image->image().size());
|
||||
}
|
||||
#endif
|
||||
const QImage::Format format = window()->format().hasAlpha() ?
|
||||
|
|
@ -151,10 +152,10 @@ void QWindowsBackingStore::resize(const QSize &size, const QRegion ®ion)
|
|||
QWindowsNativeImage *oldwni = m_image.data();
|
||||
QWindowsNativeImage *newwni = new QWindowsNativeImage(size.width(), size.height(), format);
|
||||
|
||||
if (oldwni && !region.isEmpty()) {
|
||||
if (oldwni && !regionDip.isEmpty()) {
|
||||
const QImage &oldimg(oldwni->image());
|
||||
QImage &newimg(newwni->image());
|
||||
QRegion staticRegion(region);
|
||||
QRegion staticRegion = QWindowsScaling::mapToNative(regionDip);
|
||||
staticRegion &= QRect(0, 0, oldimg.width(), oldimg.height());
|
||||
staticRegion &= QRect(0, 0, newimg.width(), newimg.height());
|
||||
QPainter painter(&newimg);
|
||||
|
|
@ -163,35 +164,38 @@ void QWindowsBackingStore::resize(const QSize &size, const QRegion ®ion)
|
|||
painter.drawImage(rect, oldimg, rect);
|
||||
}
|
||||
|
||||
if (QWindowsScaling::isActive())
|
||||
newwni->setDevicePixelRatio(QWindowsScaling::factor());
|
||||
m_image.reset(newwni);
|
||||
}
|
||||
}
|
||||
|
||||
Q_GUI_EXPORT void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset);
|
||||
|
||||
bool QWindowsBackingStore::scroll(const QRegion &area, int dx, int dy)
|
||||
bool QWindowsBackingStore::scroll(const QRegion &areaDip, int dxDip, int dyDip)
|
||||
{
|
||||
if (m_image.isNull() || m_image->image().isNull())
|
||||
return false;
|
||||
|
||||
const QVector<QRect> rects = area.rects();
|
||||
const QPoint dp = QPoint(dxDip, dyDip) * QWindowsScaling::factor();
|
||||
const QVector<QRect> rects = areaDip.rects();
|
||||
for (int i = 0; i < rects.size(); ++i)
|
||||
qt_scrollRectInImage(m_image->image(), rects.at(i), QPoint(dx, dy));
|
||||
qt_scrollRectInImage(m_image->image(), QWindowsScaling::mapToNative(rects.at(i)), dp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void QWindowsBackingStore::beginPaint(const QRegion ®ion)
|
||||
void QWindowsBackingStore::beginPaint(const QRegion ®ionDip)
|
||||
{
|
||||
if (QWindowsContext::verbose > 1)
|
||||
qCDebug(lcQpaBackingStore) <<__FUNCTION__ << region;
|
||||
qCDebug(lcQpaBackingStore) <<__FUNCTION__ << regionDip;
|
||||
|
||||
if (m_image->image().hasAlphaChannel()) {
|
||||
QPainter p(&m_image->image());
|
||||
p.setCompositionMode(QPainter::CompositionMode_Source);
|
||||
const QColor blank = Qt::transparent;
|
||||
foreach (const QRect &r, region.rects())
|
||||
p.fillRect(r, blank);
|
||||
foreach (const QRect &r, regionDip.rects())
|
||||
p.fillRect(QWindowsScaling::mapToNative(r), blank);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
#define QWINDOWSBACKINGSTORE_H
|
||||
|
||||
#include "qtwindows_additional.h"
|
||||
#include "qwindowsscaling.h"
|
||||
|
||||
#include <qpa/qplatformbackingstore.h>
|
||||
#include <QtCore/QScopedPointer>
|
||||
|
|
@ -60,7 +61,12 @@ public:
|
|||
~QWindowsBackingStore();
|
||||
|
||||
QPaintDevice *paintDevice() Q_DECL_OVERRIDE;
|
||||
void flush(QWindow *window, const QRegion ®ion, const QPoint &offset) Q_DECL_OVERRIDE;
|
||||
void flush(QWindow *window, const QRegion ®ion, const QPoint &offset) Q_DECL_OVERRIDE
|
||||
{
|
||||
flushDp(window, QWindowsScaling::mapToNative(region.boundingRect()),
|
||||
offset * QWindowsScaling::factor());
|
||||
}
|
||||
void flushDp(QWindow *window, const QRect &boundingRect, const QPoint &offset);
|
||||
void resize(const QSize &size, const QRegion &r) Q_DECL_OVERRIDE;
|
||||
bool scroll(const QRegion &area, int dx, int dy) Q_DECL_OVERRIDE;
|
||||
void beginPaint(const QRegion &) Q_DECL_OVERRIDE;
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@
|
|||
#endif
|
||||
#include "qwindowsscreen.h"
|
||||
#include "qwindowstheme.h"
|
||||
#include "qwindowsscaling.h"
|
||||
|
||||
#include <QtGui/QWindow>
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
|
|
@ -1212,7 +1213,9 @@ bool QWindowsContext::handleContextMenuEvent(QWindow *window, const MSG &msg)
|
|||
}
|
||||
}
|
||||
|
||||
QWindowSystemInterface::handleContextMenuEvent(window, mouseTriggered, pos, globalPos,
|
||||
QWindowSystemInterface::handleContextMenuEvent(window, mouseTriggered,
|
||||
pos / QWindowsScaling::factor(),
|
||||
globalPos / QWindowsScaling::factor(),
|
||||
QWindowsKeyMapper::queryKeyboardModifiers());
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
#include "qwindowsdrag.h"
|
||||
#include "qwindowscontext.h"
|
||||
#include "qwindowsscaling.h"
|
||||
#ifndef QT_NO_CLIPBOARD
|
||||
# include "qwindowsclipboard.h"
|
||||
#endif
|
||||
|
|
@ -50,6 +51,7 @@
|
|||
#include "qwindowswindow.h"
|
||||
#include "qwindowsmousehandler.h"
|
||||
#include "qwindowscursor.h"
|
||||
#include "qwindowsscaling.h"
|
||||
|
||||
#include <QtGui/QMouseEvent>
|
||||
#include <QtGui/QPixmap>
|
||||
|
|
@ -295,12 +297,19 @@ void QWindowsOleDropSource::createCursors()
|
|||
const QDrag *drag = m_drag->currentDrag();
|
||||
const QPixmap pixmap = drag->pixmap();
|
||||
const bool hasPixmap = !pixmap.isNull();
|
||||
const int scaleFactor = QWindowsScaling::factor();
|
||||
const QSize pixmapSizeDp = pixmap.size() * scaleFactor;
|
||||
const bool scalePixmap = hasPixmap
|
||||
&& m_mode != TouchDrag // Touch drag: pixmap is shown in a separate QWindow, which will be scaled.
|
||||
&& (scaleFactor != 1 && scaleFactor != qRound(pixmap.devicePixelRatio()));
|
||||
const QPixmap drawPixmap = scalePixmap
|
||||
? pixmap.scaled(pixmapSizeDp, Qt::KeepAspectRatio, Qt::SmoothTransformation) : pixmap;
|
||||
|
||||
Qt::DropAction actions[] = { Qt::MoveAction, Qt::CopyAction, Qt::LinkAction, Qt::IgnoreAction };
|
||||
int actionCount = int(sizeof(actions) / sizeof(actions[0]));
|
||||
if (!hasPixmap)
|
||||
--actionCount; // No Qt::IgnoreAction unless pixmap
|
||||
const QPoint hotSpot = drag->hotSpot();
|
||||
const QPoint hotSpot = drag->hotSpot() * scaleFactor;
|
||||
for (int cnum = 0; cnum < actionCount; ++cnum) {
|
||||
const Qt::DropAction action = actions[cnum];
|
||||
QPixmap cursorPixmap = drag->dragCursor(action);
|
||||
|
|
@ -320,15 +329,14 @@ void QWindowsOleDropSource::createCursors()
|
|||
|
||||
if (hasPixmap) {
|
||||
const int x1 = qMin(-hotSpot.x(), 0);
|
||||
const int x2 = qMax(pixmap.width() - hotSpot.x(), cursorPixmap.width());
|
||||
const int x2 = qMax(pixmapSizeDp.width() - hotSpot.x(), cursorPixmap.width());
|
||||
const int y1 = qMin(-hotSpot.y(), 0);
|
||||
const int y2 = qMax(pixmap.height() - hotSpot.y(), cursorPixmap.height());
|
||||
const int y2 = qMax(pixmapSizeDp.height() - hotSpot.y(), cursorPixmap.height());
|
||||
QPixmap newCursor(x2 - x1 + 1, y2 - y1 + 1);
|
||||
newCursor.fill(Qt::transparent);
|
||||
QPainter p(&newCursor);
|
||||
const QRect srcRect = pixmap.rect();
|
||||
const QPoint pmDest = QPoint(qMax(0, -hotSpot.x()), qMax(0, -hotSpot.y()));
|
||||
p.drawPixmap(pmDest, pixmap, srcRect);
|
||||
p.drawPixmap(pmDest, drawPixmap);
|
||||
p.drawPixmap(qMax(0, hotSpot.x()),qMax(0, hotSpot.y()), cursorPixmap);
|
||||
newPixmap = newCursor;
|
||||
newHotSpot = QPoint(qMax(0, hotSpot.x()), qMax(0, hotSpot.y()));
|
||||
|
|
@ -454,7 +462,7 @@ QWindowsOleDropSource::GiveFeedback(DWORD dwEffect)
|
|||
if (!m_touchDragWindow)
|
||||
m_touchDragWindow = new QWindowsDragCursorWindow;
|
||||
m_touchDragWindow->setPixmap(e.pixmap);
|
||||
m_touchDragWindow->setFramePosition(QWindowsCursor::mousePosition() - e.hotSpot);
|
||||
m_touchDragWindow->setFramePosition((QWindowsCursor::mousePosition() - e.hotSpot) / QWindowsScaling::factor());
|
||||
if (!m_touchDragWindow->isVisible())
|
||||
m_touchDragWindow->show();
|
||||
break;
|
||||
|
|
@ -530,7 +538,9 @@ void QWindowsOleDropTarget::handleDrag(QWindow *window, DWORD grfKeyState,
|
|||
QGuiApplicationPrivate::mouse_buttons = QWindowsMouseHandler::keyStateToMouseButtons(grfKeyState);
|
||||
|
||||
const QPlatformDragQtResponse response =
|
||||
QWindowSystemInterface::handleDrag(window, windowsDrag->dropData(), m_lastPoint, actions);
|
||||
QWindowSystemInterface::handleDrag(window, windowsDrag->dropData(),
|
||||
m_lastPoint / QWindowsScaling::factor(),
|
||||
actions);
|
||||
|
||||
m_answerRect = response.answerRect();
|
||||
const Qt::DropAction action = response.acceptedAction();
|
||||
|
|
@ -622,7 +632,8 @@ QWindowsOleDropTarget::Drop(LPDATAOBJECT pDataObj, DWORD grfKeyState,
|
|||
QWindowsDrag *windowsDrag = QWindowsDrag::instance();
|
||||
|
||||
const QPlatformDropQtResponse response =
|
||||
QWindowSystemInterface::handleDrop(m_window, windowsDrag->dropData(), m_lastPoint,
|
||||
QWindowSystemInterface::handleDrop(m_window, windowsDrag->dropData(),
|
||||
m_lastPoint / QWindowsScaling::factor(),
|
||||
translateToQDragDropActions(*pdwEffect));
|
||||
|
||||
if (response.isAccepted()) {
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include "qwindowswindow.h"
|
||||
#include "qwindowsintegration.h"
|
||||
#include "qwindowsmousehandler.h"
|
||||
#include "qwindowsscaling.h"
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QObject>
|
||||
|
|
@ -214,9 +215,10 @@ void QWindowsInputContext::cursorRectChanged()
|
|||
if (!m_compositionContext.hwnd)
|
||||
return;
|
||||
const QInputMethod *inputMethod = QGuiApplication::inputMethod();
|
||||
QRect cursorRectangle = inputMethod->cursorRectangle().toRect();
|
||||
if (!cursorRectangle.isValid())
|
||||
const QRect cursorRectangleDip = inputMethod->cursorRectangle().toRect();
|
||||
if (!cursorRectangleDip.isValid())
|
||||
return;
|
||||
const QRect cursorRectangle = QWindowsScaling::mapToNative(cursorRectangleDip);
|
||||
|
||||
qCDebug(lcQpaInputMethods) << __FUNCTION__<< cursorRectangle;
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include "qwindowsintegration.h"
|
||||
#include "qwindowsscaling.h"
|
||||
#include "qwindowswindow.h"
|
||||
#include "qwindowscontext.h"
|
||||
#include "qwindowsopenglcontext.h"
|
||||
|
|
@ -229,6 +230,12 @@ QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(const QStringList ¶mL
|
|||
m_context.setProcessDpiAwareness(dpiAwareness);
|
||||
dpiAwarenessSet = true;
|
||||
}
|
||||
// Determine suitable scale factor, don't mix Windows and Qt scaling
|
||||
if (dpiAwareness != QtWindows::ProcessDpiUnaware)
|
||||
QWindowsScaling::setFactor(QWindowsScaling::determineUiScaleFactor());
|
||||
qCDebug(lcQpaWindows)
|
||||
<< __FUNCTION__ << "DpiAwareness=" << dpiAwareness <<",Scaling="
|
||||
<< QWindowsScaling::factor();
|
||||
}
|
||||
|
||||
QWindowsIntegrationPrivate::~QWindowsIntegrationPrivate()
|
||||
|
|
@ -289,7 +296,7 @@ QWindowsWindowData QWindowsIntegration::createWindowData(QWindow *window) const
|
|||
{
|
||||
QWindowsWindowData requested;
|
||||
requested.flags = window->flags();
|
||||
requested.geometry = window->geometry();
|
||||
requested.geometry = QWindowsScaling::mapToNative(window->geometry());
|
||||
// Apply custom margins (see QWindowsWindow::setCustomMargins())).
|
||||
const QVariant customMarginsV = window->property("_q_windowsCustomMargins");
|
||||
if (customMarginsV.isValid())
|
||||
|
|
@ -310,7 +317,7 @@ QWindowsWindowData QWindowsIntegration::createWindowData(QWindow *window) const
|
|||
window->setFlags(obtained.flags);
|
||||
// Trigger geometry change signals of QWindow.
|
||||
if ((obtained.flags & Qt::Desktop) != Qt::Desktop && requested.geometry != obtained.geometry)
|
||||
QWindowSystemInterface::handleGeometryChange(window, obtained.geometry);
|
||||
QWindowSystemInterface::handleGeometryChange(window, QWindowsScaling::mapFromNative(obtained.geometry));
|
||||
}
|
||||
|
||||
#ifndef QT_NO_OPENGL
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
#include "qwindowscontext.h"
|
||||
#include "qwindowswindow.h"
|
||||
#include "qwindowsguieventdispatcher.h"
|
||||
#include "qwindowsscaling.h"
|
||||
|
||||
#include <QtGui/QWindow>
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
|
|
@ -767,11 +768,10 @@ static void showSystemMenu(QWindow* w)
|
|||
#undef enabled
|
||||
#undef disabled
|
||||
#endif // !Q_OS_WINCE
|
||||
const QPoint topLeft = topLevel->geometry().topLeft() * QWindowsScaling::factor();
|
||||
const int ret = TrackPopupMenuEx(menu,
|
||||
TPM_LEFTALIGN | TPM_TOPALIGN | TPM_NONOTIFY | TPM_RETURNCMD,
|
||||
topLevel->geometry().x(), topLevel->geometry().y(),
|
||||
topLevelHwnd,
|
||||
0);
|
||||
topLeft.x(), topLeft.y(), topLevelHwnd, 0);
|
||||
if (ret)
|
||||
qWindowsWndProc(topLevelHwnd, WM_SYSCOMMAND, ret, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -191,8 +191,10 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
|
|||
const QPoint globalPosition = winEventPosition;
|
||||
const QPoint clientPosition = QWindowsGeometryHint::mapFromGlobal(hwnd, globalPosition);
|
||||
const Qt::MouseButtons buttons = QWindowsMouseHandler::queryMouseButtons();
|
||||
QWindowSystemInterface::handleFrameStrutMouseEvent(window, clientPosition,
|
||||
globalPosition, buttons,
|
||||
QWindowSystemInterface::handleFrameStrutMouseEvent(window,
|
||||
clientPosition / QWindowsScaling::factor(),
|
||||
globalPosition / QWindowsScaling::factor(),
|
||||
buttons,
|
||||
QWindowsKeyMapper::queryKeyboardModifiers(),
|
||||
source);
|
||||
return false; // Allow further event processing (dragging of windows).
|
||||
|
|
@ -334,7 +336,10 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
|
|||
m_windowUnderMouse = currentWindowUnderMouse;
|
||||
}
|
||||
|
||||
QWindowSystemInterface::handleMouseEvent(window, winEventPosition, globalPosition, buttons,
|
||||
QWindowSystemInterface::handleMouseEvent(window,
|
||||
winEventPosition / QWindowsScaling::factor(),
|
||||
globalPosition / QWindowsScaling::factor(),
|
||||
buttons,
|
||||
QWindowsKeyMapper::queryKeyboardModifiers(),
|
||||
source);
|
||||
m_previousCaptureWindow = hasCapture ? window : 0;
|
||||
|
|
@ -388,10 +393,11 @@ bool QWindowsMouseHandler::translateMouseWheelEvent(QWindow *window, HWND,
|
|||
}
|
||||
|
||||
if (handleEvent) {
|
||||
const QPoint posDip = QWindowsGeometryHint::mapFromGlobal(receiver, globalPos) / QWindowsScaling::factor();
|
||||
QWindowSystemInterface::handleWheelEvent(receiver,
|
||||
QWindowsGeometryHint::mapFromGlobal(receiver, globalPos),
|
||||
globalPos,
|
||||
delta, orientation, mods);
|
||||
posDip, globalPos / QWindowsScaling::factor(),
|
||||
delta / QWindowsScaling::factor(),
|
||||
orientation, mods);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -419,6 +425,7 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND,
|
|||
Q_ASSERT(QWindowsContext::user32dll.getTouchInputInfo);
|
||||
|
||||
QWindowsContext::user32dll.getTouchInputInfo((HANDLE) msg.lParam, msg.wParam, winTouchInputs.data(), sizeof(TOUCHINPUT));
|
||||
const qreal screenPosFactor = 0.01 / qreal(QWindowsScaling::factor());
|
||||
for (int i = 0; i < winTouchPointCount; ++i) {
|
||||
const TOUCHINPUT &winTouchInput = winTouchInputs[i];
|
||||
int id = m_touchInputIDToTouchPointID.value(winTouchInput.dwID, -1);
|
||||
|
|
@ -432,10 +439,9 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND,
|
|||
if (m_lastTouchPositions.contains(id))
|
||||
touchPoint.normalPosition = m_lastTouchPositions.value(id);
|
||||
|
||||
QPointF screenPos = QPointF(qreal(winTouchInput.x) / qreal(100.), qreal(winTouchInput.y) / qreal(100.));
|
||||
const QPointF screenPos = QPointF(winTouchInput.x, winTouchInput.y) * screenPosFactor;
|
||||
if (winTouchInput.dwMask & TOUCHINPUTMASKF_CONTACTAREA)
|
||||
touchPoint.area.setSize(QSizeF(qreal(winTouchInput.cxContact) / qreal(100.),
|
||||
qreal(winTouchInput.cyContact) / qreal(100.)));
|
||||
touchPoint.area.setSize(QSizeF(winTouchInput.cxContact, winTouchInput.cyContact) * screenPosFactor);
|
||||
touchPoint.area.moveCenter(screenPos);
|
||||
QPointF normalPosition = QPointF(screenPos.x() / screenGeometry.width(),
|
||||
screenPos.y() / screenGeometry.height());
|
||||
|
|
|
|||
|
|
@ -67,6 +67,8 @@ public:
|
|||
|
||||
HDC hdc() const { return m_hdc; }
|
||||
|
||||
void setDevicePixelRatio(qreal scaleFactor) { m_image.setDevicePixelRatio(scaleFactor); }
|
||||
|
||||
static QImage::Format systemFormat();
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qwindowsscaling.h"
|
||||
#include "qwindowsscreen.h"
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QCoreApplication>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
/*!
|
||||
\class QWindowsScaling
|
||||
\brief Windows scaling utilities
|
||||
|
||||
\internal
|
||||
\ingroup qt-lighthouse-win
|
||||
*/
|
||||
|
||||
int QWindowsScaling::m_factor = 1;
|
||||
|
||||
static const char devicePixelRatioEnvVar[] = "QT_DEVICE_PIXEL_RATIO";
|
||||
|
||||
// Suggest a scale factor by checking monitor sizes.
|
||||
int QWindowsScaling::determineUiScaleFactor()
|
||||
{
|
||||
if (!qEnvironmentVariableIsSet(devicePixelRatioEnvVar))
|
||||
return 1;
|
||||
const QByteArray envDevicePixelRatioEnv = qgetenv(devicePixelRatioEnvVar);
|
||||
// Auto: Suggest a scale factor by checking monitor resolution.
|
||||
if (envDevicePixelRatioEnv == QByteArrayLiteral("auto")) {
|
||||
const int maxResolution = QWindowsScreen::maxMonitorHorizResolution();
|
||||
return maxResolution > 180 ? maxResolution / 96 : 1;
|
||||
}
|
||||
// Get factor from environment
|
||||
bool ok = false;
|
||||
const int envFactor = envDevicePixelRatioEnv.toInt(&ok);
|
||||
return ok && envFactor > 0 ? envFactor : 1;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QWINDOWSSCALING_H
|
||||
#define QWINDOWSSCALING_H
|
||||
|
||||
#include <QtGui/QRegion>
|
||||
#include <QtCore/QVector>
|
||||
#include <QtCore/QRect>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
enum
|
||||
#if defined(Q_COMPILER_CLASS_ENUM) || defined(Q_CC_MSVC)
|
||||
: int
|
||||
#endif
|
||||
{ QWINDOWSIZE_MAX = 16777215 };
|
||||
|
||||
class QWindowsScaling {
|
||||
public:
|
||||
static bool isActive() { return m_factor > 1; }
|
||||
static int factor() { return m_factor; }
|
||||
static void setFactor(int factor) { m_factor = factor; }
|
||||
static int determineUiScaleFactor();
|
||||
|
||||
// Scaling helpers for size constraints.
|
||||
static int mapToNativeConstrained(int qt)
|
||||
{ return m_factor != 1 && qt > 0 && qt < QWINDOWSIZE_MAX ? qt * m_factor : qt; }
|
||||
|
||||
static int mapFromNativeConstrained(int dp)
|
||||
{ return m_factor != 1 && dp > 0 && dp < QWINDOWSIZE_MAX ? dp / m_factor : dp; }
|
||||
|
||||
static QSize mapToNativeConstrained(const QSize &qt)
|
||||
{ return QSize(mapToNativeConstrained(qt.width()), mapToNativeConstrained(qt.height())); }
|
||||
|
||||
static QRect mapToNative(const QRect &qRect)
|
||||
{
|
||||
return QRect(qRect.x() * m_factor, qRect.y() * m_factor, qRect.width() * m_factor, qRect.height() * m_factor);
|
||||
}
|
||||
|
||||
static QRect mapFromNative(const QRect &dp)
|
||||
{
|
||||
return isActive() ?
|
||||
QRect(dp.x() / m_factor, dp.y() / m_factor, (dp.width() + 1) / m_factor, (dp.height() + 1) / m_factor) :
|
||||
dp;
|
||||
}
|
||||
|
||||
static QRegion mapToNative(const QRegion ®ionQt)
|
||||
{
|
||||
if (!QWindowsScaling::isActive() || regionQt.isEmpty())
|
||||
return regionQt;
|
||||
|
||||
QRegion result;
|
||||
foreach (const QRect &rectQt, regionQt.rects())
|
||||
result += QWindowsScaling::mapToNative(rectQt);
|
||||
return result;
|
||||
}
|
||||
|
||||
static QRegion mapFromNative(const QRegion ®ionDp)
|
||||
{
|
||||
if (!QWindowsScaling::isActive() || regionDp.isEmpty())
|
||||
return regionDp;
|
||||
|
||||
QRegion result;
|
||||
foreach (const QRect &rectDp, regionDp.rects())
|
||||
result += QWindowsScaling::mapFromNative(rectDp);
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
static int m_factor;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QWINDOWSSCALING_H
|
||||
|
|
@ -101,21 +101,19 @@ static inline QDpi deviceDPI(const QSize &pixels, const QSizeF &physicalSizeMM)
|
|||
|
||||
typedef QList<QWindowsScreenData> WindowsScreenDataList;
|
||||
|
||||
// from QDesktopWidget, taking WindowsScreenDataList as LPARAM
|
||||
BOOL QT_WIN_CALLBACK monitorEnumCallback(HMONITOR hMonitor, HDC, LPRECT, LPARAM p)
|
||||
static bool monitorData(HMONITOR hMonitor, QWindowsScreenData *data)
|
||||
{
|
||||
MONITORINFOEX info;
|
||||
memset(&info, 0, sizeof(MONITORINFOEX));
|
||||
info.cbSize = sizeof(MONITORINFOEX);
|
||||
if (GetMonitorInfo(hMonitor, &info) == FALSE)
|
||||
return TRUE;
|
||||
return false;
|
||||
|
||||
WindowsScreenDataList *result = reinterpret_cast<WindowsScreenDataList *>(p);
|
||||
QWindowsScreenData data;
|
||||
data.geometry = QRect(QPoint(info.rcMonitor.left, info.rcMonitor.top), QPoint(info.rcMonitor.right - 1, info.rcMonitor.bottom - 1));
|
||||
data.name = QString::fromWCharArray(info.szDevice);
|
||||
if (data.name == QLatin1String("WinDisc")) {
|
||||
data.flags |= QWindowsScreenData::LockScreen;
|
||||
data->geometry = QRect(QPoint(info.rcMonitor.left, info.rcMonitor.top), QPoint(info.rcMonitor.right - 1, info.rcMonitor.bottom - 1));
|
||||
data->availableGeometry = QRect(QPoint(info.rcWork.left, info.rcWork.top), QPoint(info.rcWork.right - 1, info.rcWork.bottom - 1));
|
||||
data->name = QString::fromWCharArray(info.szDevice);
|
||||
if (data->name == QLatin1String("WinDisc")) {
|
||||
data->flags |= QWindowsScreenData::LockScreen;
|
||||
} else {
|
||||
#ifdef Q_OS_WINCE
|
||||
//Windows CE, just supports one Display and expects to get only DISPLAY,
|
||||
|
|
@ -127,40 +125,48 @@ BOOL QT_WIN_CALLBACK monitorEnumCallback(HMONITOR hMonitor, HDC, LPRECT, LPARAM
|
|||
if (hdc) {
|
||||
#ifndef Q_OS_WINCE
|
||||
const QDpi dpi = monitorDPI(hMonitor);
|
||||
data.dpi = dpi.first ? dpi : deviceDPI(hdc);
|
||||
data->dpi = dpi.first ? dpi : deviceDPI(hdc);
|
||||
#else
|
||||
data.dpi = deviceDPI(hdc);
|
||||
data->dpi = deviceDPI(hdc);
|
||||
#endif
|
||||
data.depth = GetDeviceCaps(hdc, BITSPIXEL);
|
||||
data.format = data.depth == 16 ? QImage::Format_RGB16 : QImage::Format_RGB32;
|
||||
data.physicalSizeMM = QSizeF(GetDeviceCaps(hdc, HORZSIZE), GetDeviceCaps(hdc, VERTSIZE));
|
||||
data->depth = GetDeviceCaps(hdc, BITSPIXEL);
|
||||
data->format = data->depth == 16 ? QImage::Format_RGB16 : QImage::Format_RGB32;
|
||||
data->physicalSizeMM = QSizeF(GetDeviceCaps(hdc, HORZSIZE), GetDeviceCaps(hdc, VERTSIZE));
|
||||
const int refreshRate = GetDeviceCaps(hdc, VREFRESH);
|
||||
if (refreshRate > 1) // 0,1 means hardware default.
|
||||
data.refreshRateHz = refreshRate;
|
||||
data->refreshRateHz = refreshRate;
|
||||
DeleteDC(hdc);
|
||||
} else {
|
||||
qWarning("%s: Unable to obtain handle for monitor '%s', defaulting to %g DPI.",
|
||||
__FUNCTION__, qPrintable(QString::fromWCharArray(info.szDevice)),
|
||||
data.dpi.first);
|
||||
data->dpi.first);
|
||||
} // CreateDC() failed
|
||||
} // not lock screen
|
||||
data.geometry = QRect(QPoint(info.rcMonitor.left, info.rcMonitor.top), QPoint(info.rcMonitor.right - 1, info.rcMonitor.bottom - 1));
|
||||
data.availableGeometry = QRect(QPoint(info.rcWork.left, info.rcWork.top), QPoint(info.rcWork.right - 1, info.rcWork.bottom - 1));
|
||||
data.orientation = data.geometry.height() > data.geometry.width() ?
|
||||
data->orientation = data->geometry.height() > data->geometry.width() ?
|
||||
Qt::PortraitOrientation : Qt::LandscapeOrientation;
|
||||
// EnumDisplayMonitors (as opposed to EnumDisplayDevices) enumerates only
|
||||
// virtual desktop screens.
|
||||
data.flags |= QWindowsScreenData::VirtualDesktop;
|
||||
if (info.dwFlags & MONITORINFOF_PRIMARY) {
|
||||
data.flags |= QWindowsScreenData::PrimaryScreen;
|
||||
data->flags |= QWindowsScreenData::VirtualDesktop;
|
||||
if (info.dwFlags & MONITORINFOF_PRIMARY)
|
||||
data->flags |= QWindowsScreenData::PrimaryScreen;
|
||||
return true;
|
||||
}
|
||||
|
||||
// from QDesktopWidget, taking WindowsScreenDataList as LPARAM
|
||||
BOOL QT_WIN_CALLBACK monitorEnumCallback(HMONITOR hMonitor, HDC, LPRECT, LPARAM p)
|
||||
{
|
||||
QWindowsScreenData data;
|
||||
if (monitorData(hMonitor, &data)) {
|
||||
WindowsScreenDataList *result = reinterpret_cast<WindowsScreenDataList *>(p);
|
||||
// QPlatformIntegration::screenAdded() documentation specifies that first
|
||||
// added screen will be the primary screen, so order accordingly.
|
||||
// Note that the side effect of this policy is that there is no way to change primary
|
||||
// screen reported by Qt, unless we want to delete all existing screens and add them
|
||||
// again whenever primary screen changes.
|
||||
result->prepend(data);
|
||||
} else {
|
||||
result->append(data);
|
||||
if (data.flags & QWindowsScreenData::PrimaryScreen)
|
||||
result->prepend(data);
|
||||
else
|
||||
result->append(data);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -217,14 +223,36 @@ QWindowsScreen::QWindowsScreen(const QWindowsScreenData &data) :
|
|||
{
|
||||
}
|
||||
|
||||
BOOL QT_WIN_CALLBACK monitorResolutionEnumCallback(HMONITOR hMonitor, HDC, LPRECT, LPARAM p)
|
||||
{
|
||||
QWindowsScreenData data;
|
||||
if (monitorData(hMonitor, &data)) {
|
||||
int *maxHorizResolution = reinterpret_cast<int *>(p);
|
||||
const int horizResolution = qRound(data.dpi.first);
|
||||
if (horizResolution > *maxHorizResolution)
|
||||
*maxHorizResolution = horizResolution;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int QWindowsScreen::maxMonitorHorizResolution()
|
||||
{
|
||||
int result = 0;
|
||||
EnumDisplayMonitors(0, 0, monitorResolutionEnumCallback, (LPARAM)&result);
|
||||
return result;
|
||||
}
|
||||
|
||||
Q_GUI_EXPORT QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat = 0);
|
||||
|
||||
QPixmap QWindowsScreen::grabWindow(WId window, int x, int y, int width, int height) const
|
||||
QPixmap QWindowsScreen::grabWindow(WId window, int qX, int qY, int qWidth, int qHeight) const
|
||||
{
|
||||
RECT r;
|
||||
HWND hwnd = window ? (HWND)window : GetDesktopWindow();
|
||||
GetClientRect(hwnd, &r);
|
||||
|
||||
const int x = qX * QWindowsScaling::factor();
|
||||
const int y = qY * QWindowsScaling::factor();
|
||||
int width = qWidth * QWindowsScaling::factor();
|
||||
int height = qHeight * QWindowsScaling::factor();
|
||||
if (width < 0) width = r.right - r.left;
|
||||
if (height < 0) height = r.bottom - r.top;
|
||||
|
||||
|
|
@ -248,6 +276,10 @@ QPixmap QWindowsScreen::grabWindow(WId window, int x, int y, int width, int heig
|
|||
DeleteObject(bitmap);
|
||||
ReleaseDC(0, display_dc);
|
||||
|
||||
if (QWindowsScaling::isActive()) {
|
||||
const qreal factor = 1.0 / qreal(QWindowsScaling::factor());
|
||||
return pixmap.transformed(QTransform::fromScale(factor, factor));
|
||||
}
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,11 +43,13 @@
|
|||
#define QWINDOWSSCREEN_H
|
||||
|
||||
#include "qwindowscursor.h"
|
||||
#include "qwindowsscaling.h"
|
||||
#ifdef Q_OS_WINCE
|
||||
# include "qplatformfunctions_wince.h"
|
||||
#endif
|
||||
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QVector>
|
||||
#include <QtCore/QPair>
|
||||
#include <QtCore/QSharedPointer>
|
||||
#include <qpa/qplatformscreen.h>
|
||||
|
|
@ -88,24 +90,28 @@ public:
|
|||
|
||||
static QWindowsScreen *screenOf(const QWindow *w = 0);
|
||||
|
||||
QRect geometry() const Q_DECL_OVERRIDE { return m_data.geometry; }
|
||||
QRect availableGeometry() const Q_DECL_OVERRIDE { return m_data.availableGeometry; }
|
||||
QRect geometryDp() const { return m_data.geometry; }
|
||||
QRect geometry() const Q_DECL_OVERRIDE { return QWindowsScaling::mapFromNative(geometryDp()); }
|
||||
QRect availableGeometryDp() const { return m_data.availableGeometry; }
|
||||
QRect availableGeometry() const Q_DECL_OVERRIDE { return QWindowsScaling::mapFromNative(availableGeometryDp()); }
|
||||
int depth() const Q_DECL_OVERRIDE { return m_data.depth; }
|
||||
QImage::Format format() const Q_DECL_OVERRIDE { return m_data.format; }
|
||||
QSizeF physicalSize() const Q_DECL_OVERRIDE { return m_data.physicalSizeMM; }
|
||||
QDpi logicalDpi() const Q_DECL_OVERRIDE { return m_data.dpi; }
|
||||
QDpi logicalDpi() const Q_DECL_OVERRIDE
|
||||
{ return QDpi(m_data.dpi.first / QWindowsScaling::factor(), m_data.dpi.second / QWindowsScaling::factor()); }
|
||||
qreal devicePixelRatio() const Q_DECL_OVERRIDE { return QWindowsScaling::factor(); }
|
||||
qreal refreshRate() const Q_DECL_OVERRIDE { return m_data.refreshRateHz; }
|
||||
QString name() const Q_DECL_OVERRIDE { return m_data.name; }
|
||||
Qt::ScreenOrientation orientation() const Q_DECL_OVERRIDE { return m_data.orientation; }
|
||||
QList<QPlatformScreen *> virtualSiblings() const Q_DECL_OVERRIDE;
|
||||
QWindow *topLevelAt(const QPoint &point) const Q_DECL_OVERRIDE
|
||||
{ return QWindowsScreen::findTopLevelAt(point, CWP_SKIPINVISIBLE); }
|
||||
{ return QWindowsScreen::findTopLevelAt(point * QWindowsScaling::factor() , CWP_SKIPINVISIBLE); }
|
||||
|
||||
static QWindow *findTopLevelAt(const QPoint &point, unsigned flags);
|
||||
static QWindow *windowAt(const QPoint &point, unsigned flags = CWP_SKIPINVISIBLE);
|
||||
static QWindow *windowUnderMouse(unsigned flags = CWP_SKIPINVISIBLE);
|
||||
|
||||
QPixmap grabWindow(WId window, int x, int y, int width, int height) const Q_DECL_OVERRIDE;
|
||||
QPixmap grabWindow(WId window, int qX, int qY, int qWidth, int qHeight) const Q_DECL_OVERRIDE;
|
||||
|
||||
inline void handleChanges(const QWindowsScreenData &newData);
|
||||
|
||||
|
|
@ -117,6 +123,7 @@ public:
|
|||
#endif // !QT_NO_CURSOR
|
||||
|
||||
const QWindowsScreenData &data() const { return m_data; }
|
||||
static int maxMonitorHorizResolution();
|
||||
|
||||
private:
|
||||
QWindowsScreenData m_data;
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include "qwindowstabletsupport.h"
|
||||
#include "qwindowsscaling.h"
|
||||
|
||||
#ifndef QT_NO_TABLETEVENT
|
||||
|
||||
|
|
@ -403,7 +404,8 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
|
|||
// in which case we snap the position to the mouse position.
|
||||
// It seems there is no way to find out the mode programmatically, the LOGCONTEXT orgX/Y/Ext
|
||||
// area is always the virtual desktop.
|
||||
const QRect virtualDesktopArea = QGuiApplication::primaryScreen()->virtualGeometry();
|
||||
const QRect virtualDesktopArea
|
||||
= QWindowsScaling::mapToNative(QGuiApplication::primaryScreen()->virtualGeometry());
|
||||
|
||||
qCDebug(lcQpaTablet) << __FUNCTION__ << "processing " << packetCount
|
||||
<< "target:" << QGuiApplicationPrivate::tabletPressTarget;
|
||||
|
|
@ -423,7 +425,7 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
|
|||
QPoint globalPos = globalPosF.toPoint();
|
||||
|
||||
// Get Mouse Position and compare to tablet info
|
||||
const QPoint mouseLocation = QWindowsCursor::mousePosition();
|
||||
QPoint mouseLocation = QWindowsCursor::mousePosition();
|
||||
|
||||
// Positions should be almost the same if we are in absolute
|
||||
// mode. If they are not, use the mouse location.
|
||||
|
|
@ -479,7 +481,9 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
|
|||
<< tiltY << "tanP:" << tangentialPressure << "rotation:" << rotation;
|
||||
}
|
||||
|
||||
QWindowSystemInterface::handleTabletEvent(target, QPointF(localPos), globalPosF,
|
||||
const QPointF localPosDip = QPointF(localPos / QWindowsScaling::factor());
|
||||
const QPointF globalPosDip = globalPosF / qreal(QWindowsScaling::factor());
|
||||
QWindowSystemInterface::handleTabletEvent(target, localPosDip, globalPosDip,
|
||||
currentDevice, currentPointer,
|
||||
static_cast<Qt::MouseButtons>(packet.pkButtons),
|
||||
pressureNew, tiltX, tiltY,
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include "qwindowscontext.h"
|
||||
#include "qwindowsdrag.h"
|
||||
#include "qwindowsscreen.h"
|
||||
#include "qwindowsscaling.h"
|
||||
#ifdef QT_NO_CURSOR
|
||||
# include "qwindowscursor.h"
|
||||
#endif
|
||||
|
|
@ -576,7 +577,9 @@ QWindowsWindowData
|
|||
|
||||
const QString windowClassName = QWindowsContext::instance()->registerWindowClass(w, isGL);
|
||||
|
||||
QRect rect = QPlatformWindow::initialGeometry(w, data.geometry, defaultWindowWidth, defaultWindowHeight);
|
||||
const QRect geometryDip = QWindowsScaling::mapFromNative(data.geometry);
|
||||
QRect fixedGeometryDip = QPlatformWindow::initialGeometry(w, geometryDip, defaultWindowWidth, defaultWindowHeight);
|
||||
const QRect rect = fixedGeometryDip != geometryDip ? QWindowsScaling::mapToNative(fixedGeometryDip) : data.geometry;
|
||||
|
||||
if (title.isEmpty() && (result.flags & Qt::WindowTitleHint))
|
||||
title = topLevel ? qAppName() : w->objectName();
|
||||
|
|
@ -683,11 +686,9 @@ void WindowCreationData::initialize(HWND hwnd, bool frameChange, qreal opacityLe
|
|||
\ingroup qt-lighthouse-win
|
||||
*/
|
||||
|
||||
#define QWINDOWSIZE_MAX ((1<<24)-1)
|
||||
|
||||
QWindowsGeometryHint::QWindowsGeometryHint(const QWindow *w, const QMargins &cm) :
|
||||
minimumSize(w->minimumSize()),
|
||||
maximumSize(w->maximumSize()),
|
||||
minimumSize(QWindowsScaling::mapToNativeConstrained(w->minimumSize())),
|
||||
maximumSize(QWindowsScaling::mapToNativeConstrained(w->maximumSize())),
|
||||
customMargins(cm)
|
||||
{
|
||||
}
|
||||
|
|
@ -930,7 +931,8 @@ void QWindowsWindow::fireExpose(const QRegion ®ion, bool force)
|
|||
clearFlag(Exposed);
|
||||
else
|
||||
setFlag(Exposed);
|
||||
QWindowSystemInterface::handleExposeEvent(window(), region);
|
||||
QWindowSystemInterface::handleExposeEvent(window(),
|
||||
QWindowsScaling::mapFromNative(region));
|
||||
}
|
||||
|
||||
static inline QWindow *findTransientChild(const QWindow *parent)
|
||||
|
|
@ -1106,7 +1108,7 @@ bool QWindowsWindow::isEmbedded(const QPlatformWindow *parentWindow) const
|
|||
return m_data.embedded;
|
||||
}
|
||||
|
||||
QPoint QWindowsWindow::mapToGlobal(const QPoint &pos) const
|
||||
QPoint QWindowsWindow::mapToGlobalDp(const QPoint &pos) const
|
||||
{
|
||||
if (m_data.hwnd)
|
||||
return QWindowsGeometryHint::mapToGlobal(m_data.hwnd, pos);
|
||||
|
|
@ -1114,7 +1116,7 @@ QPoint QWindowsWindow::mapToGlobal(const QPoint &pos) const
|
|||
return pos;
|
||||
}
|
||||
|
||||
QPoint QWindowsWindow::mapFromGlobal(const QPoint &pos) const
|
||||
QPoint QWindowsWindow::mapFromGlobalDp(const QPoint &pos) const
|
||||
{
|
||||
if (m_data.hwnd)
|
||||
return QWindowsGeometryHint::mapFromGlobal(m_data.hwnd, pos);
|
||||
|
|
@ -1286,22 +1288,22 @@ static QRect normalFrameGeometry(HWND hwnd)
|
|||
return QRect();
|
||||
}
|
||||
|
||||
QRect QWindowsWindow::normalGeometry() const
|
||||
QRect QWindowsWindow::normalGeometryDp() const
|
||||
{
|
||||
// Check for fake 'fullscreen' mode.
|
||||
const bool fakeFullScreen = m_savedFrameGeometry.isValid() && window()->windowState() == Qt::WindowFullScreen;
|
||||
const QRect frame = fakeFullScreen ? m_savedFrameGeometry : normalFrameGeometry(m_data.hwnd);
|
||||
const QMargins margins = fakeFullScreen ? QWindowsGeometryHint::frame(m_savedStyle, 0) : frameMargins();
|
||||
const QMargins margins = fakeFullScreen ? QWindowsGeometryHint::frame(m_savedStyle, 0) : frameMarginsDp();
|
||||
return frame.isValid() ? frame.marginsRemoved(margins) : frame;
|
||||
}
|
||||
|
||||
void QWindowsWindow::setGeometry(const QRect &rectIn)
|
||||
void QWindowsWindow::setGeometryDp(const QRect &rectIn)
|
||||
{
|
||||
QRect rect = rectIn;
|
||||
// This means it is a call from QWindow::setFramePosition() and
|
||||
// the coordinates include the frame (size is still the contents rectangle).
|
||||
if (QWindowsGeometryHint::positionIncludesFrame(window())) {
|
||||
const QMargins margins = frameMargins();
|
||||
const QMargins margins = frameMarginsDp();
|
||||
rect.moveTopLeft(rect.topLeft() + QPoint(margins.left(), margins.top()));
|
||||
}
|
||||
const QSize oldSize = m_data.geometry.size();
|
||||
|
|
@ -1383,8 +1385,9 @@ void QWindowsWindow::handleGeometryChange()
|
|||
return;
|
||||
const QRect previousGeometry = m_data.geometry;
|
||||
m_data.geometry = geometry_sys();
|
||||
QPlatformWindow::setGeometry(m_data.geometry);
|
||||
QWindowSystemInterface::handleGeometryChange(window(), m_data.geometry);
|
||||
const QRect geometryDip = QWindowsScaling::mapFromNative(m_data.geometry);
|
||||
QPlatformWindow::setGeometry(geometryDip);
|
||||
QWindowSystemInterface::handleGeometryChange(window(), geometryDip);
|
||||
// QTBUG-32121: OpenGL/normal windows (with exception of ANGLE) do not receive
|
||||
// expose events when shrinking, synthesize.
|
||||
if (!testFlag(OpenGL_ES2) && isExposed()
|
||||
|
|
@ -1404,7 +1407,7 @@ void QWindowsWindow::handleGeometryChange()
|
|||
|
||||
void QWindowsWindow::setGeometry_sys(const QRect &rect) const
|
||||
{
|
||||
const QMargins margins = frameMargins();
|
||||
const QMargins margins = frameMarginsDp();
|
||||
const QRect frameGeometry = rect + margins;
|
||||
|
||||
qCDebug(lcQpaWindows) << '>' << __FUNCTION__ << this << window()
|
||||
|
|
@ -1441,7 +1444,7 @@ QRect QWindowsWindow::frameGeometry_sys() const
|
|||
|
||||
QRect QWindowsWindow::geometry_sys() const
|
||||
{
|
||||
return frameGeometry_sys().marginsRemoved(frameMargins());
|
||||
return frameGeometry_sys().marginsRemoved(frameMarginsDp());
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -1514,7 +1517,7 @@ void QWindowsWindow::setWindowFlags(Qt::WindowFlags flags)
|
|||
qCDebug(lcQpaWindows) << '>' << __FUNCTION__ << this << window() << "\n from: "
|
||||
<< QWindowsWindow::debugWindowFlags(m_data.flags)
|
||||
<< "\n to: " << QWindowsWindow::debugWindowFlags(flags);
|
||||
const QRect oldGeometry = geometry();
|
||||
const QRect oldGeometry = geometryDp();
|
||||
if (m_data.flags != flags) {
|
||||
m_data.flags = flags;
|
||||
if (m_data.hwnd) {
|
||||
|
|
@ -1602,7 +1605,8 @@ void QWindowsWindow::setWindowState(Qt::WindowState state)
|
|||
|
||||
bool QWindowsWindow::isFullScreen_sys() const
|
||||
{
|
||||
return window()->isTopLevel() && geometry_sys() == window()->screen()->geometry();
|
||||
return window()->isTopLevel()
|
||||
&& geometry_sys() == QWindowsScaling::mapToNative(window()->screen()->geometry());
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -1683,14 +1687,15 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState)
|
|||
// Use geometry of QWindow::screen() within creation or the virtual screen the
|
||||
// window is in (QTBUG-31166, QTBUG-30724).
|
||||
const QScreen *screen = window()->screen();
|
||||
const QRect r = screen->geometry();
|
||||
const QRect rDip = screen->geometry();
|
||||
const QRect r = QWindowsScaling::mapToNative(rDip);
|
||||
const UINT swpf = SWP_FRAMECHANGED | SWP_NOACTIVATE;
|
||||
const bool wasSync = testFlag(SynchronousGeometryChangeEvent);
|
||||
setFlag(SynchronousGeometryChangeEvent);
|
||||
SetWindowPos(m_data.hwnd, HWND_TOP, r.left(), r.top(), r.width(), r.height(), swpf);
|
||||
if (!wasSync)
|
||||
clearFlag(SynchronousGeometryChangeEvent);
|
||||
QWindowSystemInterface::handleGeometryChange(window(), r);
|
||||
QWindowSystemInterface::handleGeometryChange(window(), rDip);
|
||||
QWindowSystemInterface::flushWindowSystemEvents();
|
||||
} else if (newState != Qt::WindowMinimized) {
|
||||
// Restore saved state.
|
||||
|
|
@ -1778,7 +1783,7 @@ void QWindowsWindow::propagateSizeHints()
|
|||
qCDebug(lcQpaWindows) << __FUNCTION__ << this << window();
|
||||
}
|
||||
|
||||
QMargins QWindowsWindow::frameMargins() const
|
||||
QMargins QWindowsWindow::frameMarginsDp() const
|
||||
{
|
||||
// Frames are invalidated by style changes (window state, flags).
|
||||
// As they are also required for geometry calculations in resize
|
||||
|
|
@ -1820,17 +1825,17 @@ static inline void addRectToWinRegion(const QRect &rect, HRGN *winRegion)
|
|||
}
|
||||
}
|
||||
|
||||
static HRGN qRegionToWinRegion(const QRegion ®ion)
|
||||
static HRGN qRegionToWinRegion(const QRegion ®ionDip)
|
||||
{
|
||||
const QVector<QRect> rects = region.rects();
|
||||
const QVector<QRect> rects = regionDip.rects();
|
||||
if (rects.isEmpty())
|
||||
return NULL;
|
||||
const int rectCount = rects.size();
|
||||
if (rectCount == 1)
|
||||
return createRectRegion(region.boundingRect());
|
||||
return createRectRegion(QWindowsScaling::mapToNative(regionDip.boundingRect()));
|
||||
HRGN hRegion = createRectRegion(rects.front());
|
||||
for (int i = 1; i < rectCount; ++i)
|
||||
addRectToWinRegion(rects.at(i), &hRegion);
|
||||
addRectToWinRegion(QWindowsScaling::mapToNative(rects.at(i)), &hRegion);
|
||||
return hRegion;
|
||||
}
|
||||
|
||||
|
|
@ -1844,7 +1849,7 @@ void QWindowsWindow::setMask(const QRegion ®ion)
|
|||
|
||||
// Mask is in client area coordinates, so offset it in case we have a frame
|
||||
if (window()->isTopLevel()) {
|
||||
const QMargins margins = frameMargins();
|
||||
const QMargins margins = frameMarginsDp();
|
||||
OffsetRgn(winRegion, margins.left(), margins.top());
|
||||
}
|
||||
|
||||
|
|
@ -1981,23 +1986,23 @@ bool QWindowsWindow::handleNonClientHitTest(const QPoint &globalPos, LRESULT *re
|
|||
|| (m_data.flags & Qt::FramelessWindowHint)) {
|
||||
return false;
|
||||
}
|
||||
const QSize minimumSize = w->minimumSize();
|
||||
const QSize minimumSize = QWindowsScaling::mapToNativeConstrained(w->minimumSize());
|
||||
if (minimumSize.isEmpty())
|
||||
return false;
|
||||
const QSize maximumSize = w->maximumSize();
|
||||
const QSize maximumSize = QWindowsScaling::mapToNativeConstrained(w->maximumSize());
|
||||
const bool fixedWidth = minimumSize.width() == maximumSize.width();
|
||||
const bool fixedHeight = minimumSize.height() == maximumSize.height();
|
||||
if (!fixedWidth && !fixedHeight)
|
||||
return false;
|
||||
const QPoint localPos = w->mapFromGlobal(globalPos);
|
||||
const QSize size = w->size();
|
||||
const QPoint localPos = mapFromGlobalDp(globalPos);
|
||||
const QSize size = w->size() * QWindowsScaling::factor();
|
||||
if (fixedHeight) {
|
||||
if (localPos.y() >= size.height()) {
|
||||
*result = HTBORDER; // Unspecified border, no resize cursor.
|
||||
return true;
|
||||
}
|
||||
if (localPos.y() < 0) {
|
||||
const QMargins margins = frameMargins();
|
||||
const QMargins margins = frameMarginsDp();
|
||||
const int topResizeBarPos = margins.left() - margins.top();
|
||||
if (localPos.y() < topResizeBarPos) {
|
||||
*result = HTCAPTION; // Extend caption over top resize bar, let's user move the window.
|
||||
|
|
@ -2249,6 +2254,10 @@ void QWindowsWindow::setWindowIcon(const QIcon &icon)
|
|||
The property can be set using QPlatformNativeInterface::setWindowProperty() or,
|
||||
before platform window creation, by setting a dynamic property
|
||||
on the QWindow (see QWindowsIntegration::createPlatformWindow()).
|
||||
|
||||
Note: The function uses (unscaled) device pixels since the QWizard also
|
||||
uses AdjustWindowRect() and using device independent pixels would introduce
|
||||
rounding errors.
|
||||
*/
|
||||
|
||||
void QWindowsWindow::setCustomMargins(const QMargins &newCustomMargins)
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
#ifdef Q_OS_WINCE
|
||||
# include "qplatformfunctions_wince.h"
|
||||
#endif
|
||||
#include "qwindowsscaling.h"
|
||||
#include "qwindowscursor.h"
|
||||
#include "qwindowsopenglcontext.h"
|
||||
|
||||
|
|
@ -152,18 +153,28 @@ public:
|
|||
~QWindowsWindow();
|
||||
|
||||
QSurfaceFormat format() const Q_DECL_OVERRIDE { return m_format; }
|
||||
void setGeometry(const QRect &rect) Q_DECL_OVERRIDE;
|
||||
QRect geometry() const Q_DECL_OVERRIDE { return m_data.geometry; }
|
||||
QRect normalGeometry() const Q_DECL_OVERRIDE;
|
||||
|
||||
void setGeometryDp(const QRect &rectIn);
|
||||
void setGeometry(const QRect &rect) Q_DECL_OVERRIDE
|
||||
{ setGeometryDp(QWindowsScaling::mapToNative(rect)); }
|
||||
QRect geometryDp() const { return m_data.geometry; }
|
||||
QRect geometry() const Q_DECL_OVERRIDE
|
||||
{ return QWindowsScaling::mapFromNative(geometryDp()); }
|
||||
QRect normalGeometryDp() const;
|
||||
QRect normalGeometry() const Q_DECL_OVERRIDE
|
||||
{ return QWindowsScaling::mapFromNative(normalGeometryDp()); }
|
||||
qreal devicePixelRatio() const Q_DECL_OVERRIDE
|
||||
{ return qreal(QWindowsScaling::factor()); }
|
||||
void setVisible(bool visible) Q_DECL_OVERRIDE;
|
||||
bool isVisible() const;
|
||||
bool isExposed() const Q_DECL_OVERRIDE { return testFlag(Exposed); }
|
||||
bool isActive() const Q_DECL_OVERRIDE;
|
||||
bool isEmbedded(const QPlatformWindow *parentWindow) const Q_DECL_OVERRIDE;
|
||||
QPoint mapToGlobal(const QPoint &pos) const Q_DECL_OVERRIDE;
|
||||
QPoint mapFromGlobal(const QPoint &pos) const Q_DECL_OVERRIDE;
|
||||
|
||||
QPoint mapToGlobalDp(const QPoint &pos) const;
|
||||
QPoint mapToGlobal(const QPoint &pos) const Q_DECL_OVERRIDE
|
||||
{ return mapToGlobalDp(pos * QWindowsScaling::factor()) / QWindowsScaling::factor(); }
|
||||
QPoint mapFromGlobalDp(const QPoint &pos) const;
|
||||
QPoint mapFromGlobal(const QPoint &pos) const Q_DECL_OVERRIDE
|
||||
{ return mapFromGlobalDp(pos * QWindowsScaling::factor()) / QWindowsScaling::factor(); }
|
||||
void setWindowFlags(Qt::WindowFlags flags) Q_DECL_OVERRIDE;
|
||||
void setWindowState(Qt::WindowState state) Q_DECL_OVERRIDE;
|
||||
|
||||
|
|
@ -179,7 +190,8 @@ public:
|
|||
void windowEvent(QEvent *event);
|
||||
|
||||
void propagateSizeHints() Q_DECL_OVERRIDE;
|
||||
QMargins frameMargins() const Q_DECL_OVERRIDE;
|
||||
QMargins frameMarginsDp() const;
|
||||
QMargins frameMargins() const Q_DECL_OVERRIDE { return frameMarginsDp() / QWindowsScaling::factor(); }
|
||||
|
||||
void setOpacity(qreal level) Q_DECL_OVERRIDE;
|
||||
void setMask(const QRegion ®ion) Q_DECL_OVERRIDE;
|
||||
|
|
@ -190,7 +202,7 @@ public:
|
|||
bool setMouseGrabEnabled(bool grab) Q_DECL_OVERRIDE;
|
||||
inline bool hasMouseCapture() const { return GetCapture() == m_data.hwnd; }
|
||||
|
||||
bool startSystemResize(const QPoint &pos, Qt::Corner corner) Q_DECL_OVERRIDE;
|
||||
bool startSystemResize(const QPoint &, Qt::Corner corner) Q_DECL_OVERRIDE;
|
||||
|
||||
void setFrameStrutEventsEnabled(bool enabled);
|
||||
bool frameStrutEventsEnabled() const { return testFlag(FrameStrutEventsEnabled); }
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@ SOURCES += \
|
|||
$$PWD/qwindowsdialoghelpers.cpp \
|
||||
$$PWD/qwindowsservices.cpp \
|
||||
$$PWD/qwindowsnativeimage.cpp \
|
||||
$$PWD/qwindowsnativeinterface.cpp
|
||||
$$PWD/qwindowsnativeinterface.cpp \
|
||||
$$PWD/qwindowsscaling.cpp
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/qwindowswindow.h \
|
||||
|
|
@ -64,7 +65,8 @@ HEADERS += \
|
|||
$$PWD/qwindowsservices.h \
|
||||
$$PWD/qplatformfunctions_wince.h \
|
||||
$$PWD/qwindowsnativeimage.h \
|
||||
$$PWD/qwindowsnativeinterface.h
|
||||
$$PWD/qwindowsnativeinterface.h \
|
||||
$$PWD/qwindowsscaling.h
|
||||
|
||||
!wince: HEADERS += $$PWD/qwindowsopengltester.h
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue