diff --git a/3rdparty/ext_qt/0010-Fix-tablet-jitter-on-X11.patch b/3rdparty/ext_qt/0010-Fix-tablet-jitter-on-X11.patch new file mode 100644 index 0000000000..16eac9379d --- /dev/null +++ b/3rdparty/ext_qt/0010-Fix-tablet-jitter-on-X11.patch @@ -0,0 +1,59 @@ +From 999992ae79d1bc17bc4d7cbd49a8cd94cfce4e22 Mon Sep 17 00:00:00 2001 +From: Dmitry Kazakov +Date: Sun, 10 Mar 2019 14:48:58 +0300 +Subject: [PATCH] Fix tablet jitter on X11 + +We should get the correct stylus position from the valuators, +not from the X11-provided global position. Global position is rounded +to the nearest FP16 values, which is not enough for smooth painting. +--- + src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +index 04ddd3c..8b79f2d 100644 +--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp ++++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +@@ -1208,6 +1208,11 @@ bool QXcbConnection::xi2HandleTabletEvent(const void *event, TabletData *tabletD + return handled; + } + ++inline qreal scaleOneValuator(qreal normValue, qreal screenMin, qreal screenSize) ++{ ++ return screenMin + normValue * screenSize; ++} ++ + void QXcbConnection::xi2ReportTabletEvent(const void *event, TabletData *tabletData) + { + auto *ev = reinterpret_cast(event); +@@ -1221,6 +1226,8 @@ void QXcbConnection::xi2ReportTabletEvent(const void *event, TabletData *tabletD + double pressure = 0, rotation = 0, tangentialPressure = 0; + int xTilt = 0, yTilt = 0; + ++ const QRect screenArea = window->screen()->virtualGeometry(); ++ + for (QHash::iterator it = tabletData->valuatorInfo.begin(), + ite = tabletData->valuatorInfo.end(); it != ite; ++it) { + int valuator = it.key(); +@@ -1228,6 +1235,18 @@ void QXcbConnection::xi2ReportTabletEvent(const void *event, TabletData *tabletD + xi2GetValuatorValueIfSet(event, classInfo.number, &classInfo.curVal); + double normalizedValue = (classInfo.curVal - classInfo.minVal) / (classInfo.maxVal - classInfo.minVal); + switch (valuator) { ++ case QXcbAtom::AbsX: { ++ const qreal value = scaleOneValuator(normalizedValue, screenArea.x(), screenArea.width()); ++ global.rx() = value; ++ local.rx() = value - window->geometry().x(); ++ break; ++ } ++ case QXcbAtom::AbsY: { ++ qreal value = scaleOneValuator(normalizedValue, screenArea.y(), screenArea.height()); ++ global.ry() = value; ++ local.ry() = value - window->geometry().y(); ++ break; ++ } + case QXcbAtom::AbsPressure: + pressure = normalizedValue; + break; +-- +2.7.4 + diff --git a/3rdparty/ext_qt/0011-Add-an-ID-for-recognition-of-UGEE-tablets.patch b/3rdparty/ext_qt/0011-Add-an-ID-for-recognition-of-UGEE-tablets.patch new file mode 100644 index 0000000000..95c78d5263 --- /dev/null +++ b/3rdparty/ext_qt/0011-Add-an-ID-for-recognition-of-UGEE-tablets.patch @@ -0,0 +1,27 @@ +From 421860a79b6cab0ca67884314aadd9a2e2ece55f Mon Sep 17 00:00:00 2001 +From: Dmitry Kazakov +Date: Sun, 10 Mar 2019 14:51:28 +0300 +Subject: [PATCH] Add an ID for recognition of UGEE tablets + +--- + src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +index 8b79f2d..b8a83ba 100644 +--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp ++++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +@@ -240,6 +240,10 @@ void QXcbConnection::xi2SetupDevice(void *info, bool removeExisting) + } else if (name.contains("uc-logic") && isTablet) { + tabletData.pointerType = QTabletEvent::Pen; + dbgType = QLatin1String("pen"); ++ } else if (name.contains("ugee")) { ++ isTablet = true; ++ tabletData.pointerType = QTabletEvent::Pen; ++ dbgType = QLatin1String("pen"); + } else { + isTablet = false; + } +-- +2.7.4 + diff --git a/3rdparty/ext_qt/0012-Synthesize-Enter-LeaveEvent-when-QTabletEvent-is-acc.patch b/3rdparty/ext_qt/0012-Synthesize-Enter-LeaveEvent-when-QTabletEvent-is-acc.patch new file mode 100644 index 0000000000..55c148f892 --- /dev/null +++ b/3rdparty/ext_qt/0012-Synthesize-Enter-LeaveEvent-when-QTabletEvent-is-acc.patch @@ -0,0 +1,38 @@ +From 2365cd9067491214b4bc27b193813d9a5f527755 Mon Sep 17 00:00:00 2001 +From: Dmitry Kazakov +Date: Sun, 10 Mar 2019 19:41:33 +0300 +Subject: [PATCH] Synthesize Enter/LeaveEvent when QTabletEvent is accepted by + the receiver + +When the tablet event is accepted, then Qt doesn't synthesize a mouse +event, it means that QApplicationPrivate::sendMouseEvent() will not be +called, and, therefore, enter/leave events will not be dispatched. + +The patch looks a bit hackish. Ideally, the synthesize should happen +in QGuiApplicationPrivate::processTabletEvent(), which takes the decision +about synthesizing mouse events. But there is not enough information +on this level: neither qt_last_mouse_receiver nor the reciever widget +are known at this stage. +--- + src/widgets/kernel/qwidgetwindow.cpp | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp +index 991a05f..cafb79e 100644 +--- a/src/widgets/kernel/qwidgetwindow.cpp ++++ b/src/widgets/kernel/qwidgetwindow.cpp +@@ -1053,6 +1053,11 @@ void QWidgetWindow::handleTabletEvent(QTabletEvent *event) + event->setAccepted(ev.isAccepted()); + } + ++ if (event->isAccepted() && widget != qt_last_mouse_receiver) { ++ QApplicationPrivate::dispatchEnterLeave(widget, qt_last_mouse_receiver, event->globalPos()); ++ qt_last_mouse_receiver = widget; ++ } ++ + if (event->type() == QEvent::TabletRelease && event->buttons() == Qt::NoButton) + qt_tablet_target = 0; + } +-- +2.7.4 + diff --git a/3rdparty/ext_qt/CMakeLists.txt b/3rdparty/ext_qt/CMakeLists.txt index 03c6b5955a..f2d4ccf785 100644 --- a/3rdparty/ext_qt/CMakeLists.txt +++ b/3rdparty/ext_qt/CMakeLists.txt @@ -1,213 +1,219 @@ SET(EXTPREFIX_qt "${EXTPREFIX}") if (WIN32) list(APPEND _QT_conf -skip qt3d -skip qtactiveqt -skip qtcanvas3d -skip qtconnectivity -skip qtdoc -skip qtgraphicaleffects -skip qtlocation -skip qtsensors -skip qtserialport -skip qtwayland -skip qtwebchannel -skip qtwebengine -skip qtwebsockets -skip qtwebview -skip qtxmlpatterns -no-sql-sqlite -nomake examples -nomake tools -no-compile-examples -no-dbus -no-iconv -no-qml-debug -no-ssl -no-libproxy -no-system-proxies -no-icu -no-mtdev -skip qtcharts -skip qtdatavis3d -skip qtgamepad -skip qtnetworkauth -skip qtpurchasing -skip qtremoteobjects -skip qtscxml -skip qtserialbus -skip qtspeech -skip qtvirtualkeyboard # -qt-zlib -qt-pcre -qt-libpng -qt-libjpeg # -opensource -confirm-license # -release -platform win32-g++ -prefix ${EXTPREFIX_qt} QMAKE_LFLAGS_APP+=${SECURITY_EXE_LINKER_FLAGS} QMAKE_LFLAGS_SHLIB+=${SECURITY_SHARED_LINKER_FLAGS} QMAKE_LFLAGS_SONAME+=${SECURITY_SHARED_LINKER_FLAGS} ) if (QT_ENABLE_DEBUG_INFO) # Set the option to build Qt with debugging info enabled list(APPEND _QT_conf -force-debug-info) endif(QT_ENABLE_DEBUG_INFO) if (QT_ENABLE_DYNAMIC_OPENGL) list(APPEND _QT_conf -opengl dynamic -angle) else (QT_ENABLE_DYNAMIC_OPENGL) list(APPEND _QT_conf -opengl desktop -no-angle) endif (QT_ENABLE_DYNAMIC_OPENGL) ExternalProject_Add( ext_qt DOWNLOAD_DIR ${EXTERNALS_DOWNLOAD_DIR} URL https://download.qt.io/archive/qt/5.12/5.12.1/single/qt-everywhere-src-5.12.1.tar.xz URL_HASH SHA1=018b7467faeda9979fe6b4a435214903c3a20018 PATCH_COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0001-disable-wintab.patch COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0002-Don-t-request-the-MIME-image-every-time-Windows-asks.patch COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0003-Hack-always-return-we-support-DIBV5.patch COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0004-Fix-debug-on-openGL-ES.patch COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0005-cumulative-patch-for-hdr.patch INSTALL_DIR ${EXTPREFIX_qt} CONFIGURE_COMMAND /configure.bat ${_QT_conf} BUILD_COMMAND mingw32-make -j${SUBMAKE_JOBS} INSTALL_COMMAND mingw32-make -j${SUBMAKE_JOBS} install UPDATE_COMMAND "" # Use a short name to reduce the chance of exceeding path length limit SOURCE_DIR s BINARY_DIR b DEPENDS ext_patch ) elseif (NOT APPLE) ExternalProject_Add( ext_qt DOWNLOAD_DIR ${EXTERNALS_DOWNLOAD_DIR} URL https://download.qt.io/archive/qt/5.12/5.12.1/single/qt-everywhere-src-5.12.1.tar.xz URL_HASH SHA1=018b7467faeda9979fe6b4a435214903c3a20018 - URL_MD5 c5e275ab0ed7ee61d0f4b82cd471770d + PATCH_COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0010-Fix-tablet-jitter-on-X11.patch + COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0011-Add-an-ID-for-recognition-of-UGEE-tablets.patch + COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0012-Synthesize-Enter-LeaveEvent-when-QTabletEvent-is-acc.patch + CONFIGURE_COMMAND /configure -prefix ${EXTPREFIX_qt} -opensource -confirm-license -verbose -nomake examples -skip qt3d -skip qtactiveqt -skip qtcanvas3d -skip qtconnectivity -skip qtgraphicaleffects -skip qtlocation -skip qtwayland -skip qtwebchannel -skip qtwebengine -skip qtwebsockets -skip qtwebview -skip qtandroidextras -skip qtserialport -skip qtdatavis3d -skip qtvirtualkeyboard -skip qtspeech -skip qtsensors -skip qtgamepad -skip qtscxml -skip qtremoteobjects -skip qtxmlpatterns -skip qtnetworkauth -skip qtcharts -skip qtdatavis3d -skip qtgamepad -skip qtpurchasing -skip qtscxml -skip qtserialbus -skip qtspeech -skip qtvirtualkeyboard -xcb INSTALL_DIR ${EXTPREFIX_qt} BUILD_COMMAND $(MAKE) INSTALL_COMMAND $(MAKE) install UPDATE_COMMAND "" BUILD_IN_SOURCE 1 ) else( APPLE ) # XCODE_VERSION is set by CMake when using the Xcode generator, otherwise we need # to detect it manually here. if (NOT XCODE_VERSION) execute_process( COMMAND xcodebuild -version OUTPUT_VARIABLE xcodebuild_version OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_FILE /dev/null ) string(REGEX MATCH "Xcode ([0-9]([.][0-9])+)" version_match ${xcodebuild_version}) if (version_match) message(STATUS "${EXTPREFIX_qt}:Identified Xcode Version: ${CMAKE_MATCH_1}") set(XCODE_VERSION ${CMAKE_MATCH_1}) else() # If detecting Xcode version failed, set a crazy high version so we default # to the newest. set(XCODE_VERSION 99) message(WARNING "${EXTPREFIX_qt}:Failed to detect the version of an installed copy of Xcode, falling back to highest supported version. Set XCODE_VERSION to override.") endif(version_match) endif(NOT XCODE_VERSION) # ------------------------------------------------------------------------------- # Verify the Xcode installation on Mac OS like Qt5.7 does/will # If not stop now, the system isn't configured correctly for Qt. # No reason to even proceed. # ------------------------------------------------------------------------------- set(XCSELECT_OUTPUT) find_program(XCSELECT_PROGRAM "xcode-select") if(XCSELECT_PROGRAM) message(STATUS "${EXTPREFIX_qt}:Found XCSELECT_PROGRAM as ${XCSELECT_PROGRAM}") set(XCSELECT_COMMAND ${XCSELECT_PROGRAM} "--print-path") execute_process( COMMAND ${XCSELECT_COMMAND} RESULT_VARIABLE XCSELECT_COMMAND_RESULT OUTPUT_VARIABLE XCSELECT_COMMAND_OUTPUT ERROR_FILE /dev/null ) if(NOT XCSELECT_COMMAND_RESULT) # returned 0, we're ok. string(REGEX REPLACE "[ \t]*[\r\n]+[ \t]*" ";" XCSELECT_COMMAND_OUTPUT ${XCSELECT_COMMAND_OUTPUT}) else() string(REPLACE ";" " " XCSELECT_COMMAND_STR "${XCSELECT_COMMAND}") # message(STATUS "${XCSELECT_COMMAND_STR}") message(FATAL_ERROR "${EXTPREFIX_qt}:${XCSELECT_PROGRAM} test failed with status ${XCSELECT_COMMAND_RESULT}") endif() else() message(FATAL_ERROR "${EXTPREFIX_qt}:${XCSELECT_PROGRAM} not found. No Xcode is selected. Use xcode-select -switch to choose an Xcode version") endif() # Belts and suspenders # Beyond all the Xcode and Qt version checking, the proof of the pudding # lies in the success/failure of this command: xcrun --find xcrun. # On failure a patch is necessary, otherwise we're ok # So hard check xcrun now... set(XCRUN_OUTPUT) find_program(XCRUN_PROGRAM "xcrun") if(XCRUN_PROGRAM) message(STATUS "${EXTPREFIX_qt}:Found XCRUN_PROGRAM as ${XCRUN_PROGRAM}") set(XCRUN_COMMAND ${XCRUN_PROGRAM} "--find xcrun") execute_process( COMMAND ${XCRUN_COMMAND} RESULT_VARIABLE XCRUN_COMMAND_RESULT OUTPUT_VARIABLE XCRUN_COMMAND_OUTPUT ERROR_FILE /dev/null ) if(NOT XCRUN_COMMAND_RESULT) # returned 0, we're ok. string(REGEX REPLACE "[ \t]*[\r\n]+[ \t]*" ";" XCRUN_COMMAND_OUTPUT ${XCRUN_COMMAND_OUTPUT}) else() string(REPLACE ";" " " XCRUN_COMMAND_STR "${XCRUN_COMMAND}") # message(STATUS "${XCRUN_COMMAND_STR}") message(STATUS "${EXTPREFIX_qt}:xcrun test failed with status ${XCRUN_COMMAND_RESULT}") endif() else() message(STATUS "${EXTPREFIX_qt}:xcrun not found -- ${XCRUN_PROGRAM}") endif() # # Now configure ext_qt accordingly # if ((XCRUN_COMMAND_RESULT) AND (NOT (XCODE_VERSION VERSION_LESS 8.0.0))) # Fix Xcode xcrun related issue. # NOTE: This should be fixed by Qt 5.7.1 see here: http://code.qt.io/cgit/qt/qtbase.git/commit/?h=dev&id=77a71c32c9d19b87f79b208929e71282e8d8b5d9 # NOTE: but no one's holding their breath. set(ext_qt_PATCH_COMMAND ${PATCH_COMMAND} -p1 -i ${CMAKE_CURRENT_SOURCE_DIR}/macdeploy-qt.diff COMMAND ${PATCH_COMMAND} -p1 -b -d /qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/mac_standardpaths_qtbug-61159.diff + COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0012-Synthesize-Enter-LeaveEvent-when-QTabletEvent-is-acc.patch #COMMAND ${PATCH_COMMAND} -p1 -b -d /qtbase/mkspecs/features/mac -i ${CMAKE_CURRENT_SOURCE_DIR}/mac-default.patch ) message(STATUS "${EXTPREFIX_qt}:Additional patches injected.") else() # No extra patches will be applied # NOTE: defaults for some untested scenarios like xcrun fails and xcode_version < 8. # NOTE: that is uncharted territory and (hopefully) a very unlikely scenario... - set(ext_qt_PATCH_COMMAND ${PATCH_COMMAND} -p1 -i ${CMAKE_CURRENT_SOURCE_DIR}/macdeploy-qt.diff) + set(ext_qt_PATCH_COMMAND ${PATCH_COMMAND} -p1 -i ${CMAKE_CURRENT_SOURCE_DIR}/macdeploy-qt.diff + COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0012-Synthesize-Enter-LeaveEvent-when-QTabletEvent-is-acc.patch + ) endif() # Qt is big - try and parallelize if at all possible include(ProcessorCount) ProcessorCount(NUM_CORES) if(NOT NUM_CORES EQUAL 0) if (NUM_CORES GREATER 2) # be nice... MATH( EXPR NUM_CORES "${NUM_CORES} - 2" ) endif() set(PARALLEL_MAKE "make;-j${NUM_CORES}") message(STATUS "${EXTPREFIX_qt}:Parallelized make: ${PARALLEL_MAKE}") else() set(PARALLEL_MAKE "make") endif() ExternalProject_Add(ext_qt DOWNLOAD_DIR ${EXTERNALS_DOWNLOAD_DIR} LOG_DOWNLOAD ON LOG_UPDATE ON LOG_CONFIGURE ON LOG_BUILD ON LOG_TEST ON LOG_INSTALL ON BUILD_IN_SOURCE ON URL https://download.qt.io/archive/qt/5.12/5.12.1/single/qt-everywhere-src-5.12.1.tar.xz URL_HASH MD5=6a37466c8c40e87d4a19c3f286ec2542 INSTALL_DIR ${EXTPREFIX_qt} CONFIGURE_COMMAND /configure -skip qt3d -skip qtactiveqt -skip qtcanvas3d -skip qtconnectivity -skip qtdoc -skip qtgraphicaleffects -skip qtlocation -skip qtsensors -skip qtserialport -skip qtwayland -skip qtwebchannel -skip qtwebsockets -skip qtwebview -skip qtxmlpatterns -no-sql-sqlite -skip qtcharts -skip qtdatavis3d -skip qtgamepad -skip qtnetworkauth -skip qtpurchasing -skip qtremoteobjects -skip qtscxml -skip qtserialbus -skip qtspeech -skip qtvirtualkeyboard -nomake examples -nomake tools -no-compile-examples -no-dbus -no-iconv -no-qml-debug -no-libproxy -no-system-proxies -no-icu -no-mtdev -system-zlib -qt-pcre -opensource -confirm-license -prefix ${EXTPREFIX_qt} BUILD_COMMAND ${PARALLEL_MAKE} INSTALL_COMMAND make install UPDATE_COMMAND "" BUILD_IN_SOURCE 1 ) endif()