Merge remote-tracking branch 'origin/5.11' into dev

Conflicts:
	examples/widgets/graphicsview/elasticnodes/graphwidget.cpp
	examples/widgets/graphicsview/elasticnodes/node.cpp
	examples/widgets/graphicsview/elasticnodes/node.h
	src/plugins/platforms/cocoa/qnsview.mm
	src/plugins/platforms/cocoa/qnsview_drawing.mm
	src/widgets/kernel/qmacgesturerecognizer_p.h

Change-Id: I13cf06bac75d48d779d8ee7b5c91bfc976f2a32c
bb10
Liang Qi 2018-05-03 14:26:01 +02:00
commit 60fefff22f
37 changed files with 335 additions and 117 deletions

View File

@ -174,7 +174,7 @@ void GraphWidget::timerEvent(QTimerEvent *event)
bool itemsMoved = false;
foreach (Node *node, nodes) {
if (node->advanceNext())
if (node->advancePosition())
itemsMoved = true;
}

View File

@ -138,7 +138,7 @@ void Node::calculateForces()
//! [6]
//! [7]
bool Node::advanceNext()
bool Node::advancePosition()
{
if (newPos == pos())
return false;

View File

@ -73,7 +73,7 @@ public:
int type() const override { return Type; }
void calculateForces();
bool advanceNext();
bool advancePosition();
QRectF boundingRect() const override;
QPainterPath shape() const override;

View File

@ -188,6 +188,13 @@ void MainWindow::setupMenuBar()
#endif
dockWidgetMenu = menuBar()->addMenu(tr("&Dock Widgets"));
QMenu *aboutMenu = menuBar()->addMenu(tr("About"));
QAction *aboutAct = aboutMenu->addAction(tr("&About"), this, &MainWindow::about);
aboutAct->setStatusTip(tr("Show the application's About box"));
QAction *aboutQtAct = aboutMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt);
aboutQtAct->setStatusTip(tr("Show the Qt library's About box"));
}
void MainWindow::setDockOptions()
@ -477,3 +484,8 @@ void MainWindow::destroyDockWidget(QAction *action)
if (destroyDockWidgetMenu->isEmpty())
destroyDockWidgetMenu->setEnabled(false);
}
void MainWindow::about()
{
QMessageBox::about(this, tr("About MainWindows"), message);
}

View File

@ -77,6 +77,8 @@ public slots:
void createDockWidget();
void destroyDockWidget(QAction *action);
void about();
private:
void setupToolBar();
void setupMenuBar();

View File

@ -55,10 +55,6 @@
#include <QStandardItem>
#include "mainwindow.h"
const int ROWS = 2;
const int COLUMNS = 3;
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{

View File

@ -499,8 +499,13 @@ void QProcessPrivate::startProcess()
if (!openChannel(stdinChannel) ||
!openChannel(stdoutChannel) ||
!openChannel(stderrChannel))
!openChannel(stderrChannel)) {
QString errorString = QProcess::tr("Process failed to start: %1").arg(qt_error_string());
cleanup();
setErrorAndEmit(QProcess::FailedToStart, errorString);
q->setProcessState(QProcess::NotRunning);
return;
}
const QString args = qt_create_commandline(program, arguments, nativeArguments);
QByteArray envlist;

View File

@ -109,30 +109,9 @@ Qt::KeyboardModifiers QInputDeviceManager::keyboardModifiers() const
return d->keyboardModifiers;
}
void QInputDeviceManager::setKeyboardModifiers(Qt::KeyboardModifiers modsBeforeEvent, int key)
void QInputDeviceManager::setKeyboardModifiers(Qt::KeyboardModifiers mods)
{
Q_D(QInputDeviceManager);
Qt::KeyboardModifiers mods;
switch (key) {
case Qt::Key_Shift:
mods = Qt::KeyboardModifiers(modsBeforeEvent ^ Qt::ShiftModifier);
break;
case Qt::Key_Control:
mods = Qt::KeyboardModifiers(modsBeforeEvent ^ Qt::ControlModifier);
break;
case Qt::Key_Alt:
mods = Qt::KeyboardModifiers(modsBeforeEvent ^ Qt::AltModifier);
break;
case Qt::Key_Meta:
mods = Qt::KeyboardModifiers(modsBeforeEvent ^ Qt::MetaModifier);
break;
case Qt::Key_AltGr:
mods = Qt::KeyboardModifiers(modsBeforeEvent ^ Qt::GroupSwitchModifier);
break;
default:
mods = modsBeforeEvent;
break;
}
d->keyboardModifiers = mods;
}

View File

@ -79,7 +79,7 @@ public:
void setCursorPos(const QPoint &pos);
Qt::KeyboardModifiers keyboardModifiers() const;
void setKeyboardModifiers(Qt::KeyboardModifiers modsBeforeEvent, int key);
void setKeyboardModifiers(Qt::KeyboardModifiers mods);
signals:
void deviceListChanged(QInputDeviceManager::DeviceType type);

View File

@ -90,6 +90,12 @@
\preliminary
*/
/*!
\fn bool QEglFSFunctions::vsp2SetLayerAlpha(const QScreen *screen, int id, qreal alpha)
\internal
\preliminary
*/
/*!
\fn void QEglFSFunctions::vsp2AddBlendListener(const QScreen *screen, void(*callback)())
\internal
@ -121,6 +127,11 @@
\internal
*/
/*!
\typedef QEglFSFunctions::Vsp2SetLayerAlphaType
\internal
*/
/*! \fn QByteArray QEglFSFunctions::vsp2AddBlendListenerTypeIdentifier()
\internal
*/
@ -140,3 +151,7 @@
/*! \fn QByteArray QEglFSFunctions::vsp2SetLayerPositionTypeIdentifier()
\internal
*/
/*! \fn QByteArray QEglFSFunctions::vsp2SetLayerAlphaTypeIdentifier()
\internal
*/

View File

@ -225,7 +225,8 @@ void QEvdevKeyboardHandler::readKeycode()
void QEvdevKeyboardHandler::processKeyEvent(int nativecode, int unicode, int qtcode,
Qt::KeyboardModifiers modifiers, bool isPress, bool autoRepeat)
{
QGuiApplicationPrivate::inputDeviceManager()->setKeyboardModifiers(modifiers, qtcode);
if (!autoRepeat)
QGuiApplicationPrivate::inputDeviceManager()->setKeyboardModifiers(QEvdevKeyboardHandler::toQtModifiers(m_modifiers));
QWindowSystemInterface::handleExtendedKeyEvent(0, (isPress ? QEvent::KeyPress : QEvent::KeyRelease),
qtcode, modifiers, nativecode + 8, 0, int(modifiers),

View File

@ -148,14 +148,13 @@ void QEvdevMouseManager::handleMouseEvent(int x, int y, bool abs, Qt::MouseButto
QPoint pos(m_x + m_xoffset, m_y + m_yoffset);
// Cannot track the keyboard modifiers ourselves here. Instead, report the
// modifiers from the last key event that has been seen by QGuiApplication.
Qt::KeyboardModifiers mods = QGuiApplication::keyboardModifiers();
QWindowSystemInterface::handleMouseEvent(0, pos, pos, buttons, button, type, mods);
QWindowSystemInterface::handleMouseEvent(0, pos, pos, buttons, button, type, QGuiApplicationPrivate::inputDeviceManager()->keyboardModifiers());
}
void QEvdevMouseManager::handleWheelEvent(QPoint delta)
{
QPoint pos(m_x + m_xoffset, m_y + m_yoffset);
QWindowSystemInterface::handleWheelEvent(0, pos, pos, QPoint(), delta, QGuiApplication::keyboardModifiers());
QWindowSystemInterface::handleWheelEvent(0, pos, pos, QPoint(), delta, QGuiApplicationPrivate::inputDeviceManager()->keyboardModifiers());
}
void QEvdevMouseManager::addMouse(const QString &deviceNode)

View File

@ -135,7 +135,8 @@ QLibInputKeyboard::QLibInputKeyboard()
#ifndef QT_NO_XKBCOMMON_EVDEV
: m_ctx(0),
m_keymap(0),
m_state(0)
m_state(0),
m_mods(Qt::NoModifier)
#endif
{
#ifndef QT_NO_XKBCOMMON_EVDEV
@ -203,22 +204,27 @@ void QLibInputKeyboard::processKey(libinput_event_keyboard *e)
Qt::KeyboardModifiers mods = Qt::NoModifier;
const int qtkey = keysymToQtKey(sym, &mods, text);
xkb_state_component modtype = xkb_state_component(XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED);
if (xkb_state_mod_index_is_active(m_state, m_modindex[0], modtype) && (qtkey != Qt::Key_Control || !pressed))
if (qtkey == Qt::Key_Control)
mods |= Qt::ControlModifier;
if (xkb_state_mod_index_is_active(m_state, m_modindex[1], modtype) && (qtkey != Qt::Key_Alt || !pressed))
if (qtkey == Qt::Key_Alt)
mods |= Qt::AltModifier;
if (xkb_state_mod_index_is_active(m_state, m_modindex[2], modtype) && (qtkey != Qt::Key_Shift || !pressed))
if (qtkey == Qt::Key_Shift)
mods |= Qt::ShiftModifier;
if (xkb_state_mod_index_is_active(m_state, m_modindex[3], modtype) && (qtkey != Qt::Key_Meta || !pressed))
if (qtkey == Qt::Key_Meta)
mods |= Qt::MetaModifier;
xkb_state_update_key(m_state, k, pressed ? XKB_KEY_DOWN : XKB_KEY_UP);
QGuiApplicationPrivate::inputDeviceManager()->setKeyboardModifiers(mods, qtkey);
if (mods != Qt::NoModifier) {
if (pressed)
m_mods |= mods;
else
m_mods &= ~mods;
QGuiApplicationPrivate::inputDeviceManager()->setKeyboardModifiers(m_mods);
}
QWindowSystemInterface::handleExtendedKeyEvent(nullptr,
pressed ? QEvent::KeyPress : QEvent::KeyRelease,
qtkey, mods, k, sym, mods, text);
qtkey, m_mods, k, sym, m_mods, text);
if (pressed && xkb_keymap_key_repeats(m_keymap, k)) {
m_repeatData.qtkey = qtkey;

View File

@ -93,6 +93,7 @@ private:
QString unicodeText;
int repeatCount;
} m_repeatData;
Qt::KeyboardModifiers m_mods;
#endif
};

View File

@ -125,7 +125,7 @@ void QLibInputPointer::processAxis(libinput_event_pointer *e)
#endif
const int factor = 8;
angleDelta *= -factor;
Qt::KeyboardModifiers mods = QGuiApplication::keyboardModifiers();
Qt::KeyboardModifiers mods = QGuiApplicationPrivate::inputDeviceManager()->keyboardModifiers();
QWindowSystemInterface::handleWheelEvent(nullptr, m_pos, m_pos, QPoint(), angleDelta, mods);
}

View File

@ -261,6 +261,16 @@ QRectF qt_mac_flip(const QRectF &rect, const QRectF &reference)
// -------------------------------------------------------------------------
/*!
\fn Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum)
Returns the Qt::Button that corresponds to an NSEvent.buttonNumber.
\note AppKit will use buttonNumber 0 to indicate both "left button"
and "no button". Only NSEvents that describes mouse press/release
events (e.g NSEventTypeOtherMouseDown) will contain a valid
button number.
*/
Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum)
{
if (buttonNum >= 0 && buttonNum <= 31)

View File

@ -394,10 +394,10 @@ void QCocoaWindow::setVisible(bool visible)
removeMonitor();
monitor = [NSEvent addGlobalMonitorForEventsMatchingMask:NSLeftMouseDownMask|NSRightMouseDownMask|NSOtherMouseDownMask|NSMouseMovedMask handler:^(NSEvent *e) {
QPointF localPoint = QCocoaScreen::mapFromNative([NSEvent mouseLocation]);
const auto eventType = e.type == NSMouseMoved ? QEvent::MouseMove : QEvent::MouseButtonPress;
const auto button = e.type == NSEventTypeMouseMoved ? Qt::NoButton : cocoaButton2QtButton([e buttonNumber]);
const auto eventType = e.type == NSEventTypeMouseMoved ? QEvent::MouseMove : QEvent::MouseButtonPress;
QWindowSystemInterface::handleMouseEvent(window(), window()->mapFromGlobal(localPoint.toPoint()), localPoint,
Qt::MouseButtons(uint(NSEvent.pressedMouseButtons & 0xFFFF)),
cocoaButton2QtButton(e.buttonNumber), eventType);
Qt::MouseButtons(uint(NSEvent.pressedMouseButtons & 0xFFFF)), button, eventType);
}];
}
}

View File

@ -123,7 +123,7 @@
m_platformWindow->handleExposeEvent(dirtyRegion);
}
if (m_platformWindow->hasPendingUpdateRequest()) {
if (m_updateRequested && m_platformWindow->hasPendingUpdateRequest()) {
// A call to QWindow::requestUpdate was issued during event delivery above,
// but AppKit will reset the needsDisplay state of the view after completing
// the current display cycle, so we need to defer the request to redisplay.

View File

@ -574,6 +574,11 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va
d->setPageSize(QPageSize(QPageSize::id(value.toInt())));
break;
case PPK_PrinterName: {
QVariant pageSize = QVariant::fromValue(d->m_pageLayout.pageSize());
const bool isFullPage = d->m_pageLayout.mode() == QPageLayout::FullPageMode;
QVariant orientation = QVariant::fromValue(d->m_pageLayout.orientation());
QVariant margins = QVariant::fromValue(QPair<QMarginsF, QPageLayout::Unit>(d->m_pageLayout.margins(),
d->m_pageLayout.units()));
QString id = value.toString();
if (id.isEmpty())
id = QCocoaPrinterSupport().defaultPrintDeviceId();
@ -583,7 +588,14 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va
PMPrinter printer = d->m_printDevice->macPrinter();
PMRetain(printer);
PMSessionSetCurrentPMPrinter(d->session(), printer);
// TODO Do we need to check if the page size, etc, are valid on new printer?
// Ensure the settings are up to date and valid
if (d->m_printDevice->supportedPageSize(pageSize.value<QPageSize>()).isValid())
setProperty(PPK_QPageSize, pageSize);
else
setProperty(PPK_CustomPaperSize, pageSize.value<QPageSize>().size(QPageSize::Point));
setProperty(PPK_FullPage, QVariant(isFullPage));
setProperty(PPK_Orientation, orientation);
setProperty(PPK_QPageMargins, margins);
break;
}
case PPK_CustomPaperSize:

View File

@ -52,12 +52,28 @@ QT_BEGIN_NAMESPACE
void QEglFSRcarIntegration::platformInit()
{
bool ok;
QEglFSDeviceIntegration::platformInit();
PVRGrfxServerInit();
mScreenSize = q_screenSizeFromFb(0);
mNativeDisplay = (NativeDisplayType)EGL_DEFAULT_DISPLAY;
mNativeDisplayID = qEnvironmentVariableIntValue("QT_QPA_WM_DISP_ID", &ok);
if (!ok)
mNativeDisplayID = RCAR_DEFAULT_DISPLAY;
r_wm_Error_t wm_err = R_WM_DevInit(mNativeDisplayID);
if (wm_err != R_WM_ERR_OK)
qFatal("Failed to init WM Dev: %d, error: %d", mNativeDisplayID, wm_err);
wm_err = R_WM_ScreenBgColorSet(mNativeDisplayID, 0x20, 0x20, 0x20); // Grey
if (wm_err != R_WM_ERR_OK)
qFatal("Failed to set screen background: %d", wm_err);
wm_err = R_WM_ScreenEnable(mNativeDisplayID);
if (wm_err != R_WM_ERR_OK)
qFatal("Failed to enable screen: %d", wm_err);
}
QSize QEglFSRcarIntegration::screenSize() const
@ -104,14 +120,6 @@ EGLNativeWindowType QEglFSRcarIntegration::createNativeWindow(QPlatformWindow *w
{
bool ok;
mNativeDisplayID = qEnvironmentVariableIntValue("QT_QPA_WM_DISP_ID", &ok);
if (!ok)
mNativeDisplayID = RCAR_DEFAULT_DISPLAY;
r_wm_Error_t wm_err = R_WM_DevInit(mNativeDisplayID);
if (wm_err != R_WM_ERR_OK)
qFatal("Failed to init WM Dev: %d, error: %d", mNativeDisplayID, wm_err);
mNativeWindow = (EGLNativeWindowTypeREL*)malloc(sizeof(EGLNativeWindowTypeREL));
memset(mNativeWindow, 0, sizeof(EGLNativeWindowTypeREL));
@ -134,7 +142,7 @@ EGLNativeWindowType QEglFSRcarIntegration::createNativeWindow(QPlatformWindow *w
mNativeWindow->Surface.Type = R_WM_SURFACE_FB;
mNativeWindow->Surface.BufMode = R_WM_WINBUF_ALLOC_INTERNAL;
wm_err = R_WM_WindowCreate(mNativeDisplayID, mNativeWindow);
r_wm_Error_t wm_err = R_WM_WindowCreate(mNativeDisplayID, mNativeWindow);
if (wm_err != R_WM_ERR_OK)
qFatal("Failed to create window layer: %d", wm_err);
wm_err = R_WM_DevEventRegister(mNativeDisplayID, R_WM_EVENT_VBLANK, 0);

View File

@ -91,6 +91,9 @@ void *QQnxNativeInterface::nativeResourceForScreen(const QByteArray &resource, Q
void *QQnxNativeInterface::nativeResourceForIntegration(const QByteArray &resource)
{
if (resource == "screenContext")
return m_integration->screenContext();
return 0;
}

View File

@ -158,7 +158,7 @@ QQnxBuffer &QQnxRasterWindow::renderBuffer()
"Failed to clear window buffer");
}
Q_SCREEN_CHECKERROR(screen_flush_blits(platformScreen->nativeContext(), 0),
Q_SCREEN_CHECKERROR(screen_flush_blits(platformScreen->nativeContext(), SCREEN_WAIT_IDLE),
"Failed to flush blits");
// Use the first available render buffer

View File

@ -591,6 +591,10 @@ void QQnxScreenEventHandler::handlePropertyEvent(screen_event_t event)
case SCREEN_PROPERTY_FOCUS:
handleKeyboardFocusPropertyEvent(window);
break;
case SCREEN_PROPERTY_SIZE:
case SCREEN_PROPERTY_POSITION:
handleGeometryPropertyEvent(window);
break;
default:
// event ignored
qScreenEventDebug() << "Ignore property event for property: " << property;
@ -617,6 +621,28 @@ void QQnxScreenEventHandler::handleKeyboardFocusPropertyEvent(screen_window_t wi
m_focusLostTimer = startTimer(50);
}
void QQnxScreenEventHandler::handleGeometryPropertyEvent(screen_window_t window)
{
int pos[2];
if (screen_get_window_property_iv(window, SCREEN_PROPERTY_POSITION, pos) != 0) {
qFatal("QQnx: failed to query window property, errno=%d", errno);
}
int size[2];
if (screen_get_window_property_iv(window, SCREEN_PROPERTY_SIZE, size) != 0) {
qFatal("QQnx: failed to query window property, errno=%d", errno);
}
QRect rect(pos[0], pos[1], size[0], size[1]);
QWindow *qtWindow = QQnxIntegration::window(window);
if (qtWindow) {
qtWindow->setGeometry(rect);
QWindowSystemInterface::handleGeometryChange(qtWindow, rect);
}
qScreenEventDebug() << qtWindow << "moved to" << rect;
}
void QQnxScreenEventHandler::timerEvent(QTimerEvent *event)
{
if (event->timerId() == m_focusLostTimer) {

View File

@ -85,6 +85,7 @@ private:
void handleDisplayEvent(screen_event_t event);
void handlePropertyEvent(screen_event_t event);
void handleKeyboardFocusPropertyEvent(screen_window_t window);
void handleGeometryPropertyEvent(screen_window_t window);
private:
enum {

View File

@ -750,7 +750,12 @@ void QXcbScreen::updateGeometry(const QRect &geometry, uint8_t rotation)
m_sizeMillimeters = sizeInMillimeters(geometry.size(), virtualDpi());
qreal dpi = geometry.width() / physicalSize().width() * qreal(25.4);
m_pixelDensity = qMax(1, qRound(dpi/96));
qreal rawFactor = dpi/96;
int roundedFactor = qFloor(rawFactor);
// Round up for .8 and higher. This favors "small UI" over "large UI".
if (rawFactor - roundedFactor >= 0.8)
roundedFactor = qCeil(rawFactor);
m_pixelDensity = qMax(1, roundedFactor);
m_geometry = geometry;
m_availableGeometry = geometry & m_virtualDesktop->workArea();
QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), m_geometry, m_availableGeometry);

View File

@ -285,7 +285,10 @@ void QCupsPrintEnginePrivate::changePrinter(const QString &newPrinter)
grayscale = m_printDevice.defaultColorMode() == QPrint::GrayScale;
// Get the equivalent page size for this printer as supported names may be different
setPageSize(m_pageLayout.pageSize());
if (m_printDevice.supportedPageSize(m_pageLayout.pageSize()).isValid())
setPageSize(m_pageLayout.pageSize());
else
setPageSize(QPageSize(m_pageLayout.pageSize().size(QPageSize::Point), QPageSize::Point));
}
void QCupsPrintEnginePrivate::setPageSize(const QPageSize &pageSize)

View File

@ -1234,7 +1234,10 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &
if (printDevice.isValid()) {
d->m_printDevice = printDevice;
d->initialize();
setProperty(PPK_QPageSize, pageSize);
if (d->m_printDevice.supportedPageSize(pageSize.value<QPageSize>()).isValid())
setProperty(PPK_QPageSize, pageSize);
else
setProperty(PPK_CustomPaperSize, pageSize.value<QPageSize>().size(QPageSize::Point));
setProperty(PPK_FullPage, QVariant(isFullPage));
setProperty(PPK_Orientation, orientation);
setProperty(PPK_QPageMargins, margins);

View File

@ -110,23 +110,7 @@ namespace QTest
#ifdef QT_GUI_LIB
Q_REQUIRED_RESULT inline static bool qWaitForWindowActive(QWindow *window, int timeout = 5000)
{
bool becameActive = qWaitFor([&]() { return window->isActive(); }, timeout);
// Try ensuring the platform window receives the real position.
// (i.e. that window->pos() reflects reality)
// isActive() ( == FocusIn in case of X) does not guarantee this. It seems some WMs randomly
// send the final ConfigureNotify (the one with the non-bogus 0,0 position) after the FocusIn.
// If we just let things go, every mapTo/FromGlobal call the tests perform directly after
// qWaitForWindowShown() will generate bogus results.
if (becameActive) {
int waitNo = 0; // 0, 0 might be a valid position after all, so do not wait for ever
while (window->position().isNull()) {
if (waitNo++ > timeout / 10)
break;
qWait(10);
}
}
return window->isActive();
return qWaitFor([&]() { return window->isActive(); }, timeout);
}
Q_REQUIRED_RESULT inline static bool qWaitForWindowExposed(QWindow *window, int timeout = 5000)

View File

@ -43,6 +43,7 @@
#include "qevent.h"
#include "qwidget.h"
#include "qdebug.h"
#include <QtCore/qcoreapplication.h>
#ifndef QT_NO_GESTURES
@ -181,6 +182,16 @@ QGesture *QMacPanGestureRecognizer::create(QObject *target)
return 0;
}
void QMacPanGestureRecognizer::timerEvent(QTimerEvent *ev)
{
if (ev->timerId() == _panTimer.timerId()) {
if (_panTimer.isActive())
_panTimer.stop();
if (_target)
QCoreApplication::sendEvent(_target, ev);
}
}
QGestureRecognizer::Result
QMacPanGestureRecognizer::recognize(QGesture *gesture, QObject *target, QEvent *event)
{
@ -195,7 +206,8 @@ QMacPanGestureRecognizer::recognize(QGesture *gesture, QObject *target, QEvent *
if (ev->touchPoints().size() == 1) {
reset(gesture);
_startPos = QCursor::pos();
_panTimer.start(panBeginDelay, target);
_target = target;
_panTimer.start(panBeginDelay, this);
_panCanceled = false;
return QGestureRecognizer::MayBeGesture;
}
@ -242,7 +254,6 @@ QMacPanGestureRecognizer::recognize(QGesture *gesture, QObject *target, QEvent *
case QEvent::Timer: {
QTimerEvent *ev = static_cast<QTimerEvent *>(event);
if (ev->timerId() == _panTimer.timerId()) {
_panTimer.stop();
if (_panCanceled)
break;
// Begin new pan session!

View File

@ -55,6 +55,7 @@
#include "qtimer.h"
#include "qpoint.h"
#include "qgesturerecognizer.h"
#include <QtCore/qpointer.h>
#ifndef QT_NO_GESTURES
@ -65,9 +66,9 @@ class QMacSwipeGestureRecognizer : public QGestureRecognizer
public:
QMacSwipeGestureRecognizer();
QGesture *create(QObject *target);
QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event);
void reset(QGesture *gesture);
QGesture *create(QObject *target) override;
QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event) override;
void reset(QGesture *gesture) override;
};
class QMacPinchGestureRecognizer : public QGestureRecognizer
@ -75,9 +76,9 @@ class QMacPinchGestureRecognizer : public QGestureRecognizer
public:
QMacPinchGestureRecognizer();
QGesture *create(QObject *target);
QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event);
void reset(QGesture *gesture);
QGesture *create(QObject *target) override;
QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event) override;
void reset(QGesture *gesture) override;
};
class QMacPanGestureRecognizer : public QObject, public QGestureRecognizer
@ -85,13 +86,16 @@ class QMacPanGestureRecognizer : public QObject, public QGestureRecognizer
public:
QMacPanGestureRecognizer();
QGesture *create(QObject *target);
QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event);
void reset(QGesture *gesture);
QGesture *create(QObject *target) override;
QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event) override;
void reset(QGesture *gesture) override;
protected:
void timerEvent(QTimerEvent *ev) override;
private:
QPointF _startPos;
QBasicTimer _panTimer;
bool _panCanceled;
QPointer<QObject> _target;
};
QT_END_NAMESPACE

View File

@ -166,9 +166,6 @@ void tst_QLine::testIntersection_data()
<< 100.1599256468622
<< 50.0;
QLineF baseA(0, -50, 0, 50);
QLineF baseB(-50, 0, 50, 0);
for (int i = 0; i < 1000; ++i) {
QLineF a = QLineF::fromPolar(50, i);
a.setP1(-a.p2());

View File

@ -3,8 +3,6 @@ linux
osx-10.12 ci
[positioning:fake]
osx-10.12 ci
[modalWindowPosition]
ubuntu-16.04
[modalWithChildWindow]
ubuntu-16.04
# QTBUG-66851

View File

@ -962,8 +962,10 @@ void tst_QUdpSocket::bindMode()
// Depending on the user's privileges, this or will succeed or
// fail. Admins are allowed to reuse the address, but nobody else.
if (!socket2.bind(socket.localPort(), QUdpSocket::ReuseAddressHint), socket2.errorString().toLatin1().constData())
qWarning("Failed to bind with QUdpSocket::ReuseAddressHint, user isn't an administrator?");
if (!socket2.bind(socket.localPort(), QUdpSocket::ReuseAddressHint)) {
qWarning("Failed to bind with QUdpSocket::ReuseAddressHint(%s), user isn't an administrator?",
qPrintable(socket2.errorString()));
}
socket.close();
QVERIFY2(socket.bind(0, QUdpSocket::ShareAddress), socket.errorString().toLatin1().constData());
QVERIFY(!socket2.bind(socket.localPort()));

View File

@ -331,6 +331,9 @@ private slots:
void graphicsViewParentPropagation();
void panelPropagation();
void panelStacksBehindParent();
#ifdef Q_OS_MACOS
void deleteMacPanGestureRecognizerTargetWidget();
#endif
void deleteGestureTargetWidget();
void deleteGestureTargetItem_data();
void deleteGestureTargetItem();
@ -1807,6 +1810,31 @@ void tst_Gestures::panelStacksBehindParent()
QCOMPARE(panel->gestureOverrideEventsReceived, 0);
}
#ifdef Q_OS_MACOS
void tst_Gestures::deleteMacPanGestureRecognizerTargetWidget()
{
QWidget window;
window.resize(400,400);
QGraphicsScene scene;
QGraphicsView *view = new QGraphicsView(&scene, &window);
view->resize(400, 400);
window.show();
QVERIFY(QTest::qWaitForWindowExposed(&window));
QTouchDevice *device = QTest::createTouchDevice();
// QMacOSPenGestureRecognizer will start a timer on a touch press event
QTest::touchEvent(&window, device).press(1, QPoint(100, 100), &window);
delete view;
// wait until after that the QMacOSPenGestureRecognizer timer (300ms) is triggered.
// This is needed so that the whole test does not finish before the timer triggers
// and to make sure it crashes while executing *this* function. (otherwise it might give the
// impression that some of the subsequent test function caused the crash...)
QTest::qWait(400); // DO NOT CRASH while waiting
}
#endif
void tst_Gestures::deleteGestureTargetWidget()
{
}

View File

@ -122,6 +122,7 @@ private slots:
void testPageMetrics_data();
void testPageMetrics();
void reusePageMetrics();
#endif
private:
QString testFileName(const QString &prefix, const QString &suffix);
@ -1955,6 +1956,50 @@ QString tst_QPrinter::testFileName(const QString &prefix, const QString &suffix)
return result;
}
void tst_QPrinter::reusePageMetrics()
{
QList<QPrinterInfo> availablePrinters = QPrinterInfo::availablePrinters();
if (availablePrinters.size() < 2)
QSKIP("Not enough printers to do this test with, need at least 2 setup");
QPrinter defaultP;
QPrinterInfo info(defaultP);
QString otherPrinterName;
for (QPrinterInfo i : qAsConst(availablePrinters)) {
if (i.printerName() != defaultP.printerName()) {
otherPrinterName = i.printerName();
break;
}
}
QPrinter otherP(QPrinterInfo::printerInfo(otherPrinterName));
QList<QPageSize> defaultPageSizes = info.supportedPageSizes();
QList<QPageSize> otherPageSizes = QPrinterInfo(otherP).supportedPageSizes();
QPageSize unavailableSizeToSet;
for (QPageSize s : qAsConst(defaultPageSizes)) {
bool found = false;
for (QPageSize os : qAsConst(otherPageSizes)) {
if (os.isEquivalentTo(s)) {
found = true;
break;
}
}
const QPageSize tmpSize(s.size(QPageSize::Point), QPageSize::Point);
if (!tmpSize.name().startsWith("Custom"))
found = true;
if (!found) {
unavailableSizeToSet = s;
break;
}
}
if (!unavailableSizeToSet.isValid())
QSKIP("Could not find a size that was not available on the non default printer. The test "
"requires this");
defaultP.setPageSize(unavailableSizeToSet);
defaultP.setPrinterName(otherP.printerName());
QVERIFY(defaultP.pageLayout().pageSize().isEquivalentTo(unavailableSizeToSet));
QVERIFY(defaultP.pageLayout().pageSize().name() != unavailableSizeToSet.name());
QCOMPARE(defaultP.pageLayout().pageSize().sizePoints(), unavailableSizeToSet.sizePoints());
}
#endif // QT_CONFIG(printer)
QTEST_MAIN(tst_QPrinter)

View File

@ -3326,7 +3326,7 @@ void tst_QHeaderView::testMinMaxSectionSize(bool stretchLastSection)
header.resizeSection(0, sectionSizeMax);
QCOMPARE(header.sectionSize(0), sectionSizeMax);
header.setMaximumSectionSize(defaultSectionSize);
waitFor([this, &header, defaultSectionSize]() { return header.sectionSize(0) == defaultSectionSize; });
waitFor([&header, defaultSectionSize]() { return header.sectionSize(0) == defaultSectionSize; });
QCOMPARE(header.sectionSize(0), defaultSectionSize);
// change section size on min change
@ -3335,7 +3335,7 @@ void tst_QHeaderView::testMinMaxSectionSize(bool stretchLastSection)
header.resizeSection(0, sectionSizeMin);
QCOMPARE(header.sectionSize(0), sectionSizeMin);
header.setMinimumSectionSize(defaultSectionSize);
waitFor([this, &header, defaultSectionSize]() { return header.sectionSize(0) == defaultSectionSize; });
waitFor([&header, defaultSectionSize]() { return header.sectionSize(0) == defaultSectionSize; });
QCOMPARE(header.sectionSize(0), defaultSectionSize);
}

View File

@ -34,6 +34,7 @@
#include <QAction>
#include <QMainWindow>
#include <QSplitter>
#include <QStatusBar>
#include <QToolBar>
#include <QVector>
#include <QCommandLineOption>
@ -43,6 +44,7 @@
#include <QPainterPath>
#include <QPaintEvent>
#include <QScreen>
#include <QWindow>
#include <QSharedPointer>
#include <QDebug>
#include <QTextStream>
@ -50,6 +52,8 @@
static bool optIgnoreTouch = false;
static QVector<Qt::GestureType> optGestures;
static QWidgetList mainWindows;
static inline void drawEllipse(const QPointF &center, qreal hDiameter, qreal vDiameter, const QColor &color, QPainter &painter)
{
const QPen oldPen = painter.pen();
@ -191,6 +195,7 @@ typedef QSharedPointer<Gesture> GesturePtr;
typedef QVector<GesturePtr> GesturePtrs;
typedef QVector<QEvent::Type> EventTypeVector;
static EventTypeVector eventTypes;
class EventFilter : public QObject {
Q_OBJECT
@ -206,6 +211,8 @@ private:
const EventTypeVector m_types;
};
static EventFilter *globalEventFilter = nullptr;
bool EventFilter::eventFilter(QObject *o, QEvent *e)
{
static int n = 0;
@ -406,29 +413,67 @@ void TouchTestWidget::paintEvent(QPaintEvent *)
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow();
public:
static MainWindow *createMainWindow();
QWidget *touchWidget() const { return m_touchWidget; }
void setVisible(bool visible) override;
public slots:
void appendToLog(const QString &text) { m_logTextEdit->appendPlainText(text); }
void dumpTouchDevices();
private:
void updateScreenLabel();
void newWindow() { MainWindow::createMainWindow(); }
TouchTestWidget *m_touchWidget;
QPlainTextEdit *m_logTextEdit;
QLabel *m_screenLabel;
};
MainWindow *MainWindow::createMainWindow()
{
MainWindow *result = new MainWindow;
const QSize screenSize = QGuiApplication::primaryScreen()->availableGeometry().size();
result->resize(screenSize / 2);
const QSize sizeDiff = screenSize - result->size();
const QPoint pos = QPoint(sizeDiff.width() / 2, sizeDiff.height() / 2)
+ mainWindows.size() * QPoint(30, 10);
result->move(pos);
result->show();
EventFilter *eventFilter = globalEventFilter;
if (!eventFilter) {
eventFilter = new EventFilter(eventTypes, result->touchWidget());
result->touchWidget()->installEventFilter(eventFilter);
}
QObject::connect(eventFilter, &EventFilter::eventReceived, result, &MainWindow::appendToLog);
mainWindows.append(result);
return result;
}
MainWindow::MainWindow()
: m_touchWidget(new TouchTestWidget)
, m_logTextEdit(new QPlainTextEdit)
, m_screenLabel(new QLabel)
{
setWindowTitle(QStringLiteral("Touch Event Tester ") + QT_VERSION_STR);
QString title;
QTextStream(&title) << "Touch Event Tester " << QT_VERSION_STR << ' '
<< qApp->platformName() << " #" << (mainWindows.size() + 1);
setWindowTitle(title);
setObjectName("MainWin");
QToolBar *toolBar = new QToolBar(this);
addToolBar(Qt::TopToolBarArea, toolBar);
QMenu *fileMenu = menuBar()->addMenu("File");
QAction *newWindowAction = fileMenu->addAction(QStringLiteral("New Window"), this, &MainWindow::newWindow);
newWindowAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_N));
toolBar->addAction(newWindowAction);
fileMenu->addSeparator();
QAction *dumpDeviceAction = fileMenu->addAction(QStringLiteral("Dump devices"));
dumpDeviceAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_D));
connect(dumpDeviceAction, &QAction::triggered, this, &MainWindow::dumpTouchDevices);
@ -461,9 +506,32 @@ MainWindow::MainWindow()
mainSplitter->addWidget(m_logTextEdit);
setCentralWidget(mainSplitter);
statusBar()->addPermanentWidget(m_screenLabel);
dumpTouchDevices();
}
void MainWindow::setVisible(bool visible)
{
QMainWindow::setVisible(visible);
connect(windowHandle(), &QWindow::screenChanged, this, &MainWindow::updateScreenLabel);
updateScreenLabel();
}
void MainWindow::updateScreenLabel()
{
QString text;
QTextStream str(&text);
const QScreen *screen = windowHandle()->screen();
const QRect geometry = screen->geometry();
const qreal dpr = screen->devicePixelRatio();
str << '"' << screen->name() << "\" " << geometry.width() << 'x' << geometry.height()
<< forcesign << geometry.x() << geometry.y() << noforcesign;
if (!qFuzzyCompare(dpr, qreal(1)))
str << ", dpr=" << dpr;
m_screenLabel->setText(text);
}
void MainWindow::dumpTouchDevices()
{
QString message;
@ -522,14 +590,6 @@ int main(int argc, char *argv[])
if (parser.isSet(swipeGestureOption))
optGestures.append(Qt::SwipeGesture);
MainWindow w;
const QSize screenSize = QGuiApplication::primaryScreen()->availableGeometry().size();
w.resize(screenSize / 2);
const QSize sizeDiff = screenSize - w.size();
w.move(sizeDiff.width() / 2, sizeDiff.height() / 2);
w.show();
EventTypeVector eventTypes;
if (!parser.isSet(noMouseLogOption))
eventTypes << QEvent::MouseButtonPress << QEvent::MouseButtonRelease << QEvent::MouseButtonDblClick;
if (parser.isSet(mouseMoveOption))
@ -538,14 +598,16 @@ int main(int argc, char *argv[])
eventTypes << QEvent::TouchBegin << QEvent::TouchUpdate << QEvent::TouchEnd;
if (!optGestures.isEmpty())
eventTypes << QEvent::Gesture << QEvent::GestureOverride;
QObject *filterTarget = parser.isSet(globalFilterOption)
? static_cast<QObject *>(&a)
: static_cast<QObject *>(w.touchWidget());
EventFilter *filter = new EventFilter(eventTypes, filterTarget);
filterTarget->installEventFilter(filter);
QObject::connect(filter, &EventFilter::eventReceived, &w, &MainWindow::appendToLog);
if (parser.isSet(globalFilterOption)) {
globalEventFilter = new EventFilter(eventTypes, &a);
a.installEventFilter(globalEventFilter);
}
return a.exec();
MainWindow::createMainWindow();
const int exitCode = a.exec();
qDeleteAll(mainWindows);
return exitCode;
}
#include "main.moc"