Bug 405494

Summary: Problems with Qt's Windows Ink implementation
Product: krita Reporter: Halla Rempt <halla>
Component: Tablets (tablet issues are only very rarely bugs in Krita!)Assignee: Krita Bugs <krita-bugs-null>
Status: RESOLVED FIXED    
Severity: normal CC: alvin, dimula73, nikola.knezevic.mne
Priority: NOR Keywords: regression
Version: unspecified   
Target Milestone: ---   
Platform: Microsoft Windows   
OS: Microsoft Windows   
URL: https://bugreports.qt.io/browse/QTBUG-74700
Latest Commit: Version Fixed In:
Attachments: tablet log wintab
tablet log windows ink
mobile studio pro, windows ink enabled
mobile studio pro, windows ink disabled, no pressure
Tablet log with Windows Ink enabled in Wacom driver and Qt 5.12.2

Description Halla Rempt 2019-03-15 13:00:53 UTC
Between the krita 4.2.0 preview 2 and the HDR preview, the stylus has stopped working on with a Lenovo Yoga 920 and Windows 10. 

Symptoms: when trying to draw on the canvas, the cursor oscillates quickly between the forbidden cursor and the paint cursor. The active preset oscillates between two presets, maybe the previous and current on? No idea. When trying to paint, only the start of a line is painted, not the rest.

When opening the brush editor, painting works in the scratch pad. On trying to close the brush editor by clicking on the canvas painting on the canvas suddenly works smoothly. After closing the brush editor, clicking anywhere on the canvas opens the brush editor.
Comment 1 Halla Rempt 2019-03-15 13:03:02 UTC
Sysinfo:

OpenGL Info
 
  Vendor:  "Google Inc." 
  Renderer:  "ANGLE (Intel(R) UHD Graphics 620 Direct3D11 vs_5_0 ps_5_0)" 
  Version:  "OpenGL ES 3.0 (ANGLE 2.1.0.57ea533f79a7)" 
  Shading language:  "OpenGL ES GLSL ES 3.00 (ANGLE 2.1.0.57ea533f79a7)" 
  Requested format:  QSurfaceFormat(version 3.0, options QFlags<QSurfaceFormat::FormatOption>(DeprecatedFunctions), depthBufferSize 24, redBufferSize 8, greenBufferSize 8, blueBufferSize 8, alphaBufferSize 8, stencilBufferSize 8, samples -1, swapBehavior QSurfaceFormat::DoubleBuffer, swapInterval 0, colorSpace QSurfaceFormat::DefaultColorSpace, profile  QSurfaceFormat::CompatibilityProfile) 
  Current format:    QSurfaceFormat(version 3.0, options QFlags<QSurfaceFormat::FormatOption>(), depthBufferSize 24, redBufferSize 8, greenBufferSize 8, blueBufferSize 8, alphaBufferSize 8, stencilBufferSize 8, samples 0, swapBehavior QSurfaceFormat::DefaultSwapBehavior, swapInterval 0, colorSpace QSurfaceFormat::DefaultColorSpace, profile  QSurfaceFormat::NoProfile) 
     Version: 3.0
     Supports deprecated functions false 
     is OpenGL ES: true 

QPA OpenGL Detection Info 
  supportsDesktopGL: true 
  supportsAngleD3D11: true 
  isQtPreferAngle: false 
== log ==
 Supported renderers: QFlags(0x2|0x4) 
Surface format preference list: 
* QSurfaceFormat(version 3.0, options QFlags<QSurfaceFormat::FormatOption>(DeprecatedFunctions), depthBufferSize 24, redBufferSize 8, greenBufferSize 8, blueBufferSize 8, alphaBufferSize 8, stencilBufferSize 8, samples -1, swapBehavior QSurfaceFormat::DoubleBuffer, swapInterval 0, colorSpace QSurfaceFormat::DefaultColorSpace, profile  QSurfaceFormat::CompatibilityProfile) 
    QSurfaceFormat::OpenGLES 
* QSurfaceFormat(version 3.0, options QFlags<QSurfaceFormat::FormatOption>(DeprecatedFunctions), depthBufferSize 24, redBufferSize 8, greenBufferSize 8, blueBufferSize 8, alphaBufferSize 8, stencilBufferSize 8, samples -1, swapBehavior QSurfaceFormat::DoubleBuffer, swapInterval 0, colorSpace QSurfaceFormat::DefaultColorSpace, profile  QSurfaceFormat::CompatibilityProfile) 
    QSurfaceFormat::OpenGL 
* QSurfaceFormat(version 3.0, options QFlags<QSurfaceFormat::FormatOption>(DeprecatedFunctions), depthBufferSize 24, redBufferSize 16, greenBufferSize 16, blueBufferSize 16, alphaBufferSize 16, stencilBufferSize 8, samples -1, swapBehavior QSurfaceFormat::DoubleBuffer, swapInterval 0, colorSpace QSurfaceFormat::scRGBColorSpace, profile  QSurfaceFormat::CompatibilityProfile) 
    QSurfaceFormat::OpenGLES 
* QSurfaceFormat(version 3.0, options QFlags<QSurfaceFormat::FormatOption>(DeprecatedFunctions), depthBufferSize 24, redBufferSize 10, greenBufferSize 10, blueBufferSize 10, alphaBufferSize 2, stencilBufferSize 8, samples -1, swapBehavior QSurfaceFormat::DoubleBuffer, swapInterval 0, colorSpace QSurfaceFormat::bt2020PQColorSpace, profile  QSurfaceFormat::CompatibilityProfile) 
    QSurfaceFormat::OpenGLES 
* QSurfaceFormat(version 3.0, options QFlags<QSurfaceFormat::FormatOption>(DeprecatedFunctions), depthBufferSize 24, redBufferSize 16, greenBufferSize 16, blueBufferSize 16, alphaBufferSize 16, stencilBufferSize 8, samples -1, swapBehavior QSurfaceFormat::DoubleBuffer, swapInterval 0, colorSpace QSurfaceFormat::scRGBColorSpace, profile  QSurfaceFormat::CompatibilityProfile) 
    QSurfaceFormat::OpenGL 
* QSurfaceFormat(version 3.0, options QFlags<QSurfaceFormat::FormatOption>(DeprecatedFunctions), depthBufferSize 24, redBufferSize 10, greenBufferSize 10, blueBufferSize 10, alphaBufferSize 2, stencilBufferSize 8, samples -1, swapBehavior QSurfaceFormat::DoubleBuffer, swapInterval 0, colorSpace QSurfaceFormat::bt2020PQColorSpace, profile  QSurfaceFormat::CompatibilityProfile) 
    QSurfaceFormat::OpenGL 
Probing format... QSurfaceFormat::DefaultColorSpace QSurfaceFormat::OpenGLES 
Found format: QSurfaceFormat(version 3.0, options QFlags<QSurfaceFormat::FormatOption>(DeprecatedFunctions), depthBufferSize 24, redBufferSize 8, greenBufferSize 8, blueBufferSize 8, alphaBufferSize 8, stencilBufferSize 8, samples -1, swapBehavior QSurfaceFormat::DoubleBuffer, swapInterval 0, colorSpace QSurfaceFormat::DefaultColorSpace, profile  QSurfaceFormat::CompatibilityProfile) 
    QSurfaceFormat::OpenGLES 
 
== end log == 
================================================================================
SESSION: 15 Mar 2019 13:02:09 +0100. Executing C:\Users\boud\OneDrive\Desktop\krita-x64-4.2.0-HDR\bin\krita.exe

WARNING: This file contains information about your system and the
images you have been working with.

If you have problems with Krita, the Krita developers might ask
you to share this file with them. The information in this file is
not shared automatically with the Krita developers in any way. You
can disable logging to this file in Krita's Configure Krita Dialog.

Please review the contents of this file before sharing this file with
anyone.

Krita

 Version: 4.2.0-pre-alpha
 Languages: en_US
 Hidpi: false

Qt

  Version (compiled): 5.12.1
  Version (loaded): 5.12.1

OS Information

  Build ABI: x86_64-little_endian-llp64
  Build CPU: x86_64
  CPU: x86_64
  Kernel Type: winnt
  Kernel Version: 10.0.17134
  Pretty Productname: Windows 10 (10.0)
  Product Type: windows
  Product Version: 10


Hardware Information

  GPU Acceleration: auto
  Memory: 8033 Mb
  Number of Cores: 8
  Swap Location: C:/Users/boud/AppData/Local/Temp

15 Mar 2019 13:02:18 +0100: Created image "Unnamed", 1600 * 1200 pixels, 300 dpi. Color model: 8-bit integer/channel RGB/Alpha (sRGB-elle-V2-srgbtrc.icc). Layers: 2
Comment 2 Halla Rempt 2019-03-15 13:26:04 UTC
Created attachment 118817 [details]
tablet log wintab
Comment 3 Halla Rempt 2019-03-15 13:26:25 UTC
Created attachment 118818 [details]
tablet log windows ink
Comment 4 Halla Rempt 2019-03-16 13:44:49 UTC
Notes:

* We've now got a build option to disable our own tablet implementations
* When testing a build with this, on the Wacom Mobile Studio I find:

** If windows ink is enabled in the Wacom driver, the selected preset keeps returning to Basic 5, there is a forbidden cursor shown for a short while when approaching the tablet, editing brushes in the brush editor doesn't work intermittently, after opening the brush editor, it tends to popup again when clicking on the canvas. Driver version 6.3.33-3.

** With the Wacom Hybrid Companion, disabling Windows Ink in the wacom driver disables pen input completely. Enabling it enables pen input, without any of the problems reported for the MSP. Driver version 6.3.33-3.
Comment 5 Halla Rempt 2019-03-16 13:51:43 UTC
** WIth the Yoga, the brush editor works find and doesn't popup all the time, there is no forbidden icon shown when approaching the tablet, but the stylus gets reset to the default all the time.
Comment 6 Halla Rempt 2019-03-16 13:54:46 UTC
On the MSP, if Windows ink is disabled in the settings, there is no pressure support.
Comment 7 Halla Rempt 2019-03-16 13:55:26 UTC
Created attachment 118837 [details]
mobile studio pro, windows ink enabled

Some lines drawn, attempt to change the preset
Comment 8 Halla Rempt 2019-03-16 13:56:02 UTC
Created attachment 118838 [details]
mobile studio pro, windows ink disabled, no pressure
Comment 9 Alvin Wong 2019-03-17 07:25:51 UTC
If you would disable the Qt's pointer input messages support, I suggest doing so with Qt 5.12.2 since it contains this commit: https://github.com/qt/qtbase/commit/38504041148f2d1cffea6520ea448dd4171adb0b
Before this commit, Qt also uses pointer input messages for mouse events.

Though I suspect you might be able to just completely disable pointer messages support in Qt by hacking `QWindowsContext::user32dll.supportsPointerApi()` to return `false`, regardless of whether that commit is included or not.
Comment 10 Halla Rempt 2019-03-18 09:32:09 UTC
I'll first update Qt to 5.12.2, do a deps build and nightly build and test that.
Comment 11 Halla Rempt 2019-03-18 09:47:43 UTC
*** Bug 405576 has been marked as a duplicate of this bug. ***
Comment 12 Halla Rempt 2019-03-20 08:02:28 UTC
Okay, with 5.12.2 and our patch to disable wintab disabled, wintab still doesn't work. Windows Ink still is broken: it keeps reverting to the default preset. I'll try to disable both Qt's tablet implementations and revert to ours.
Comment 13 Halla Rempt 2019-03-20 08:09:24 UTC
Created attachment 118923 [details]
Tablet log with Windows Ink enabled in Wacom driver and Qt 5.12.2

After selecting a preset and returning the stylus to the canvas, the preset resets to the default one.
Comment 14 Alvin Wong 2019-03-25 14:06:22 UTC
(In reply to Boudewijn Rempt from comment #13)
> Created attachment 118923 [details]
> Tablet log with Windows Ink enabled in Wacom driver and Qt 5.12.2
> 
> After selecting a preset and returning the stylus to the canvas, the preset
> resets to the default one.

It looks like Qt generated a new stylus ID when the pen left and entered proximity, or perhaps it is using `POINTER_INFO::pointerId` (haven't checked the code). My implementation used `POINTER_INFO::sourceDevice` instead, assuming one pen per digitizer (I don't remember if this is guaranteed). If Krita associates a preset per ID, this would be why.

POINTER_INFO: https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagpointer_info
Comment 15 Halla Rempt 2019-03-25 14:08:35 UTC
Yes, Krita stores a preset per unique id: https://doc.qt.io/qt-5/qtabletevent.html#uniqueId
Comment 16 Halla Rempt 2019-04-02 19:01:12 UTC
Build https://binary-factory.kde.org/job/Krita_Nightly_Windows_Build/511/ properly disabled our own wintab/winink implementation and enables Qt's implementation.

On the Yoga 920 with wacom that only supports windows pointer api, everything works as expected: pressure, eraser barrel button, right-click barrel button.

On the Wacom Mobile Studio Pro, if windows ink is selected in the calibration panel, the eraser end works, the right-click barrel button works, the middle-click barrel button does not work, pressure wors. If the windows ink checkbox is disabled, nothing works (probably as expected, because the Windows Pointer API is present, so qt doesn't fall through to Wintab, because Qt seems to believe that Wintab was obsoleted with Windows 8).
Comment 17 Halla Rempt 2019-04-02 20:15:56 UTC
Note: for some reason the top part of the rocker switch gets redefined to double-click when you switch the wacom driver to windows ink. It can be sett to middle-click, and then panning works again.
Comment 18 Halla Rempt 2019-04-03 06:58:41 UTC
Test with build https://binary-factory.kde.org/job/Krita_Nightly_Windows_Build/512 (no windows ink switch in the settings dialog, so this really is with Qt's tablet code):

* Yoga: everything works as expected.
* MSP: with windows ink enabled, works like on the yoga. Unless with the build I tested yesterday, setting the top barrel button to middle click doesn't do anything. If that works with our winink implementation, that could be another bug in Qt's? With WinInk disabled, nothing works.
Comment 19 Dmitry Kazakov 2019-04-03 15:54:28 UTC
Git commit 13181cd88e1314b43fb48be4ee2147e1e24129a4 by Dmitry Kazakov.
Committed on 03/04/2019 at 15:53.
Pushed by dkazakov into branch 'master'.

Implement a switch for Tablet API in Qt

The patch allows switching of the Tablet API when we use Qt's own
implementation.

The patch is added to our build system, so the fix should appear
in nightlies very soon.

The patch has also been proposed to Qt:
https://codereview.qt-project.org/#/c/258067/

A  +73   -0    3rdparty/ext_qt/0023-Implement-a-switch-for-tablet-API-on-Windows.patch
M  +1    -0    3rdparty/ext_qt/CMakeLists.txt
M  +15   -0    CMakeLists.txt
M  +1    -0    config_use_qt_tablet_windows.h.cmake
M  +14   -0    krita/main.cc
M  +25   -14   libs/ui/dialogs/kis_dlg_preferences.cc
M  +32   -1    libs/ui/kis_config.cc
M  +4    -1    libs/ui/kis_config.h

https://commits.kde.org/krita/13181cd88e1314b43fb48be4ee2147e1e24129a4