[Bf-blender-cvs] [565ea3df607] master: Simplification of Wintab event handling.
Nicholas Rishel
noreply at git.blender.org
Fri Dec 25 01:42:05 CET 2020
Commit: 565ea3df6077a1af5995b9b4defec9b03f3c6c29
Author: Nicholas Rishel
Date: Thu Dec 24 16:25:07 2020 -0800
Branches: master
https://developer.blender.org/rB565ea3df6077a1af5995b9b4defec9b03f3c6c29
Simplification of Wintab event handling.
Previously Wintab packets were added to a local queue to be processed
during Win32 mouse events, in order to correlate Wintab to Win32
mouse buttons. Wintab packets before Win32 mouse down events were
expired on a timer.
This commit drives mouse events during Wintab events when a device is
in range. When a Wintab button is found it is dispatched if an
equivalent event can be popped from the Win32 event queue. If a Win32
mouse button event is not associated with a Wintab event, it falls
through to WM_BUTTON handling. All Wintab packets are handled as they
are received.
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D9908
===================================================================
M intern/ghost/intern/GHOST_SystemWin32.cpp
M intern/ghost/intern/GHOST_SystemWin32.h
M intern/ghost/intern/GHOST_WindowWin32.cpp
M intern/ghost/intern/GHOST_WindowWin32.h
===================================================================
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index 7e800619dda..d1822fe46fd 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -569,13 +569,13 @@ GHOST_TSuccess GHOST_SystemWin32::getButtons(GHOST_Buttons &buttons) const
*/
bool swapped = ::GetSystemMetrics(SM_SWAPBUTTON) == TRUE;
- bool down = HIBYTE(::GetKeyState(VK_LBUTTON)) != 0;
+ bool down = HIBYTE(::GetAsyncKeyState(VK_LBUTTON)) != 0;
buttons.set(swapped ? GHOST_kButtonMaskRight : GHOST_kButtonMaskLeft, down);
- down = HIBYTE(::GetKeyState(VK_MBUTTON)) != 0;
+ down = HIBYTE(::GetAsyncKeyState(VK_MBUTTON)) != 0;
buttons.set(GHOST_kButtonMaskMiddle, down);
- down = HIBYTE(::GetKeyState(VK_RBUTTON)) != 0;
+ down = HIBYTE(::GetAsyncKeyState(VK_RBUTTON)) != 0;
buttons.set(swapped ? GHOST_kButtonMaskLeft : GHOST_kButtonMaskRight, down);
return GHOST_kSuccess;
}
@@ -939,148 +939,106 @@ GHOST_EventButton *GHOST_SystemWin32::processButtonEvent(GHOST_TEventType type,
{
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
- if (type == GHOST_kEventButtonDown) {
- window->updateMouseCapture(MousePressed);
- }
- else if (type == GHOST_kEventButtonUp) {
- window->updateMouseCapture(MouseReleased);
- }
+ GHOST_TabletData td = window->m_tabletInRange ? window->getLastTabletData() :
+ GHOST_TABLET_DATA_NONE;
- /* Check for active Wintab mouse emulation in addition to a tablet in range because a proximity
- * leave event might have fired before the Windows mouse up event, thus there are still tablet
- * events to grab. The described behavior was observed in a Wacom Bamboo CTE-450. */
- if (window->useTabletAPI(GHOST_kTabletWintab) &&
- (window->m_tabletInRange || window->wintabSysButPressed()) &&
- processWintabEvent(type, window, mask, window->getMousePressed())) {
- /* Wintab processing only handles in-contact events. */
- return NULL;
- }
+ /* Ensure button click occurs at its intended position. */
+ DWORD msgPos = ::GetMessagePos();
+ GHOST_TInt32 x_screen = GET_X_LPARAM(msgPos), y_screen = GET_Y_LPARAM(msgPos);
+ system->pushEvent(new GHOST_EventCursor(
+ system->getMilliSeconds(), GHOST_kEventCursorMove, window, x_screen, y_screen, td));
- return new GHOST_EventButton(
- system->getMilliSeconds(), type, window, mask, GHOST_TABLET_DATA_NONE);
+ window->updateMouseCapture(type == GHOST_kEventButtonDown ? MousePressed : MouseReleased);
+ return new GHOST_EventButton(system->getMilliSeconds(), type, window, mask, td);
}
-GHOST_TSuccess GHOST_SystemWin32::processWintabEvent(GHOST_TEventType type,
- GHOST_WindowWin32 *window,
- GHOST_TButtonMask mask,
- bool mousePressed)
+void GHOST_SystemWin32::processWintabEvent(GHOST_WindowWin32 *window)
{
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
- /* Only process Wintab packets if we can correlate them to a Window's mouse button event. When a
- * button event associated to a mouse button by Wintab occurs outside of WM_*BUTTON events,
- * there's no way to tell if other simultaneously pressed non-mouse mapped buttons are associated
- * to a modifier key (shift, alt, ctrl) or a system event (scroll, etc.) and thus it is not
- * possible to determine if a mouse click event should occur. */
- if (!mousePressed && !window->wintabSysButPressed()) {
- return GHOST_kFailure;
- }
-
std::vector<GHOST_WintabInfoWin32> wintabInfo;
if (!window->getWintabInfo(wintabInfo)) {
- return GHOST_kFailure;
- }
-
- auto wtiIter = wintabInfo.begin();
-
- /* We only process events that correlate to a mouse button events, so there may exist Wintab
- * button down events that were instead mapped to e.g. scroll still in the queue. We need to
- * skip those and find the last button down mapped to mouse buttons. */
- if (!window->wintabSysButPressed()) {
- /* Assume there may be no button down event currently in the queue. */
- wtiIter = wintabInfo.end();
-
- for (auto it = wintabInfo.begin(); it != wintabInfo.end(); it++) {
- if (it->type == GHOST_kEventButtonDown) {
- wtiIter = it;
- }
- }
+ return;
}
- bool unhandledButton = type != GHOST_kEventCursorMove;
-
- for (; wtiIter != wintabInfo.end(); wtiIter++) {
- auto info = *wtiIter;
-
+ for (auto info : wintabInfo) {
switch (info.type) {
+ case GHOST_kEventCursorMove: {
+ system->pushEvent(new GHOST_EventCursor(
+ info.time, GHOST_kEventCursorMove, window, info.x, info.y, info.tabletData));
+ break;
+ }
case GHOST_kEventButtonDown: {
- /* While changing windows with a tablet, Window's mouse button events normally occur before
- * tablet proximity events, so a button up event can't be differentiated as occurring from
- * a Wintab tablet or a normal mouse and a Ghost button event will always be generated.
- *
- * If we were called during a button down event create a ghost button down event, otherwise
- * don't duplicate the prior button down as it interrupts drawing immediately after
- * changing a window. */
system->pushEvent(new GHOST_EventCursor(
info.time, GHOST_kEventCursorMove, window, info.x, info.y, info.tabletData));
- if (type == GHOST_kEventButtonDown && mask == info.button) {
+
+ UINT message;
+ switch (info.button) {
+ case GHOST_kButtonMaskLeft:
+ message = WM_LBUTTONDOWN;
+ break;
+ case GHOST_kButtonMaskRight:
+ message = WM_RBUTTONDOWN;
+ break;
+ case GHOST_kButtonMaskMiddle:
+ message = WM_MBUTTONDOWN;
+ break;
+ default:
+ continue;
+ }
+
+ MSG msg;
+ if (PeekMessage(&msg, window->getHWND(), message, message, PM_REMOVE | PM_NOYIELD) &&
+ WM_QUIT != msg.message) {
+ window->updateMouseCapture(MousePressed);
system->pushEvent(
new GHOST_EventButton(info.time, info.type, window, info.button, info.tabletData));
- unhandledButton = false;
}
- window->updateWintabSysBut(MousePressed);
break;
}
- case GHOST_kEventCursorMove:
- system->pushEvent(new GHOST_EventCursor(
- info.time, GHOST_kEventCursorMove, window, info.x, info.y, info.tabletData));
- break;
- case GHOST_kEventButtonUp:
- system->pushEvent(
- new GHOST_EventButton(info.time, info.type, window, info.button, info.tabletData));
- if (type == GHOST_kEventButtonUp && mask == info.button) {
- unhandledButton = false;
+ case GHOST_kEventButtonUp: {
+ UINT message;
+ switch (info.button) {
+ case GHOST_kButtonMaskLeft:
+ message = WM_LBUTTONUP;
+ break;
+ case GHOST_kButtonMaskRight:
+ message = WM_RBUTTONUP;
+ break;
+ case GHOST_kButtonMaskMiddle:
+ message = WM_MBUTTONUP;
+ break;
+ default:
+ continue;
+ }
+
+ MSG msg;
+ if (PeekMessage(&msg, window->getHWND(), message, message, PM_REMOVE | PM_NOYIELD) &&
+ WM_QUIT != msg.message) {
+ window->updateMouseCapture(MouseReleased);
+ system->pushEvent(
+ new GHOST_EventButton(info.time, info.type, window, info.button, info.tabletData));
}
- window->updateWintabSysBut(MouseReleased);
break;
+ }
default:
break;
}
}
-
- /* No Wintab button found correlating to the system button event, handle it too.
- *
- * Wintab button up events may be handled during WM_MOUSEMOVE, before their corresponding
- * WM_*BUTTONUP event has fired, which results in two GHOST Button up events for a single Wintab
- * associated button event. Alternatively this Windows button up event may have been generated
- * from a non-stylus device such as a button on the tablet pad and needs to be handled for some
- * workflows.
- *
- * The ambiguity introduced by Windows and Wintab buttons being asynchronous and having no
- * definitive way to associate each, and that the Wintab API does not provide enough information
- * to differentiate whether the stylus down is or is not modified by another button to a
- * non-mouse mapping, means that we must pessimistically generate mouse up events when we are
- * unsure of an association to prevent the mouse locking into a down state. */
- if (unhandledButton) {
- if (!window->wintabSysButPressed()) {
- GHOST_TInt32 x, y;
- system->getCursorPosition(x, y);
- system->pushEvent(new GHOST_EventCursor(system->getMilliSeconds(),
- GHOST_kEventCursorMove,
- window,
- x,
- y,
- GHOST_TABLET_DATA_NONE));
- }
- system->pushEvent(new GHOST_EventButton(
- system->getMilliSeconds(), type, window, mask, GHOST_TABLET_DATA_NONE));
- }
-
- return GHOST_kSuccess;
}
void GHOST_SystemWin32::processPointerEvent(
UINT type, GHOST_WindowWin32 *window, WPARAM wParam, LPARAM lParam, bool &eventHandled)
{
- std::vector<GHOST_PointerInfoWin32> pointerInfo;
- GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
-
/* Pointer events might fire when changing windows for a device which is set to use Wintab, even
* when when Wintab is left enabled but set to the bottom of Wintab overlap order. */
if (!window->useTabletAPI(GHOST_kTabletNative)) {
return;
}
+ GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
+ std::vector<GHOST_PointerInfoWin32> pointerInfo;
+
if (window->getPointerInfo(pointerInfo, wParam, lParam) != GHOST_kSuccess) {
retu
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list