UI: add preference to disable touchpad multitouch gestures

Available on Windows and macOS, where such gestures are supported.
For Windows, disabling this option restores touchpad behavior to
match Blender 3.2.

Ref T97925

Differential Revision: https://developer.blender.org/D16005
This commit is contained in:
Brecht Van Lommel 2022-09-26 22:56:14 +02:00 committed by Brecht Van Lommel
parent 57ea827bfb
commit 84ddb8b3cc
Notes: blender-bot 2024-02-16 13:39:02 +01:00
Referenced by issue #100749, Blender LTS: Maintenance Task 3.3
Referenced by issue #97925, No option to restore previous trackpad behavior on Windows since multitouch support
Referenced by issue #118233, No option to disable or reverse direction of multi-touch gesture on Linux
14 changed files with 77 additions and 13 deletions

View File

@ -740,6 +740,13 @@ extern unsigned int GHOST_GetContextDefaultOpenGLFramebuffer(GHOST_ContextHandle
*/
extern unsigned int GHOST_GetDefaultOpenGLFramebuffer(GHOST_WindowHandle windowhandle);
/**
* Use multitouch gestures if supported.
* \param systemhandle: The handle to the system.
* \param use: Enable or disable.
*/
extern void GHOST_SetMultitouchGestures(GHOST_SystemHandle systemhandle, const bool use);
/**
* Set which tablet API to use. Only affects Windows, other platforms have a single API.
* \param systemhandle: The handle to the system.

View File

@ -420,6 +420,12 @@ class GHOST_ISystem {
*/
virtual GHOST_TSuccess getButtonState(GHOST_TButton mask, bool &isDown) const = 0;
/**
* Enable multitouch gestures if supported.
* \param use: Enable or disable.
*/
virtual void setMultitouchGestures(const bool use) = 0;
/**
* Set which tablet API to use. Only affects Windows, other platforms have a single API.
* \param api: Enum indicating which API to use.

View File

@ -743,6 +743,12 @@ GHOST_TSuccess GHOST_InvalidateWindow(GHOST_WindowHandle windowhandle)
return window->invalidate();
}
void GHOST_SetMultitouchGestures(GHOST_SystemHandle systemhandle, const bool use)
{
GHOST_ISystem *system = GHOST_ISystem::getSystem();
return system->setMultitouchGestures(use);
}
void GHOST_SetTabletAPI(GHOST_SystemHandle systemhandle, GHOST_TTabletAPI api)
{
GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;

View File

@ -30,6 +30,7 @@ GHOST_System::GHOST_System()
#ifdef WITH_INPUT_NDOF
m_ndofManager(0),
#endif
m_multitouchGestures(true),
m_tabletAPI(GHOST_kTabletAutomatic),
m_is_debug_enabled(false)
{
@ -305,6 +306,11 @@ GHOST_TSuccess GHOST_System::getButtonState(GHOST_TButton mask, bool &isDown) co
return success;
}
void GHOST_System::setMultitouchGestures(const bool use)
{
m_multitouchGestures = use;
}
void GHOST_System::setTabletAPI(GHOST_TTabletAPI api)
{
m_tabletAPI = api;

View File

@ -239,6 +239,12 @@ class GHOST_System : public GHOST_ISystem {
*/
GHOST_TSuccess getButtonState(GHOST_TButton mask, bool &isDown) const;
/**
* Enable multitouch gestures if supported.
* \param use: Enable or disable.
*/
void setMultitouchGestures(const bool use);
/**
* Set which tablet API to use. Only affects Windows, other platforms have a single API.
* \param api: Enum indicating which API to use.
@ -402,6 +408,9 @@ class GHOST_System : public GHOST_ISystem {
/** Settings of the display before the display went full-screen. */
GHOST_DisplaySetting m_preFullScreenSetting;
/* Use multitouch gestures? */
bool m_multitouchGestures;
/** Which tablet API to use. */
GHOST_TTabletAPI m_tabletAPI;

View File

@ -1681,7 +1681,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
/* we assume phases are only set for gestures from trackpad or magic
* mouse events. note that using tablet at the same time may not work
* since this is a static variable */
if (phase == NSEventPhaseBegan)
if (phase == NSEventPhaseBegan && m_multitouchGestures)
m_multiTouchScroll = true;
else if (phase == NSEventPhaseEnded)
m_multiTouchScroll = false;

View File

@ -2093,7 +2093,9 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, uint msg, WPARAM wParam,
/* The DM_POINTERHITTEST message is sent to a window, when pointer input is first
* detected, in order to determine the most probable input target for Direct
* Manipulation. */
window->onPointerHitTest(wParam);
if (system->m_multitouchGestures) {
window->onPointerHitTest(wParam);
}
break;
}
}

View File

@ -1534,6 +1534,23 @@ class USERPREF_PT_input_mouse(InputPanel, CenterAlignMixIn, Panel):
flow.prop(inputs, "move_threshold")
class USERPREF_PT_input_touchpad(InputPanel, CenterAlignMixIn, Panel):
bl_label = "Touchpad"
bl_options = {'DEFAULT_CLOSED'}
@classmethod
def poll(cls, context):
import sys
return sys.platform[:3] == "win" or sys.platform == "darwin"
def draw_centered(self, context, layout):
prefs = context.preferences
inputs = prefs.inputs
col = layout.column()
col.prop(inputs, "use_multitouch_gestures")
class USERPREF_PT_input_tablet(InputPanel, CenterAlignMixIn, Panel):
bl_label = "Tablet"
@ -2411,6 +2428,7 @@ classes = (
USERPREF_PT_input_keyboard,
USERPREF_PT_input_mouse,
USERPREF_PT_input_tablet,
USERPREF_PT_input_touchpad,
USERPREF_PT_input_ndof,
USERPREF_PT_navigation_orbit,
USERPREF_PT_navigation_zoom,

View File

@ -535,7 +535,7 @@ void blo_do_versions_userdef(UserDef *userdef)
}
if (!USER_VERSION_ATLEAST(280, 44)) {
userdef->uiflag &= ~(USER_UIFLAG_UNUSED_0 | USER_UIFLAG_UNUSED_1);
userdef->uiflag &= ~(USER_NO_MULTITOUCH_GESTURES | USER_UIFLAG_UNUSED_1);
userdef->uiflag2 &= ~(USER_UIFLAG2_UNUSED_0);
userdef->gp_settings &= ~(GP_PAINT_UNUSED_0);
}

View File

@ -1075,7 +1075,7 @@ typedef enum eWalkNavigation_Flag {
/** #UserDef.uiflag */
typedef enum eUserpref_UI_Flag {
USER_UIFLAG_UNUSED_0 = (1 << 0), /* cleared */
USER_NO_MULTITOUCH_GESTURES = (1 << 0),
USER_UIFLAG_UNUSED_1 = (1 << 1), /* cleared */
USER_WHEELZOOMDIR = (1 << 2),
USER_FILTERFILEEXTS = (1 << 3),

View File

@ -403,11 +403,11 @@ static void rna_userdef_anim_update(Main *UNUSED(bmain),
USERDEF_TAG_DIRTY;
}
static void rna_userdef_tablet_api_update(Main *UNUSED(bmain),
Scene *UNUSED(scene),
PointerRNA *UNUSED(ptr))
static void rna_userdef_input_devices(Main *UNUSED(bmain),
Scene *UNUSED(scene),
PointerRNA *UNUSED(ptr))
{
WM_init_tablet_api();
WM_init_input_devices();
USERDEF_TAG_DIRTY;
}
@ -5738,6 +5738,14 @@ static void rna_def_userdef_input(BlenderRNA *brna)
RNA_def_property_enum_items(prop, view_zoom_axes);
RNA_def_property_ui_text(prop, "Zoom Axis", "Axis of mouse movement to zoom in or out on");
prop = RNA_def_property(srna, "use_multitouch_gestures", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "uiflag", USER_NO_MULTITOUCH_GESTURES);
RNA_def_property_ui_text(
prop,
"Multitouch Gestures",
"Use multitouch gestures for navigation with touchpad, instead of scroll wheel emulation");
RNA_def_property_update(prop, 0, "rna_userdef_input_devices");
prop = RNA_def_property(srna, "invert_mouse_zoom", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_ZOOM_INVERT);
RNA_def_property_ui_text(
@ -5873,7 +5881,7 @@ static void rna_def_userdef_input(BlenderRNA *brna)
"Tablet API",
"Select the tablet API to use for pressure sensitivity (may require "
"restarting Blender for changes to take effect)");
RNA_def_property_update(prop, 0, "rna_userdef_tablet_api_update");
RNA_def_property_update(prop, 0, "rna_userdef_input_devices");
# ifdef WITH_INPUT_NDOF
/* 3D mouse settings */

View File

@ -94,7 +94,7 @@ void WM_init_state_maximized_set(void);
void WM_init_state_start_with_console_set(bool value);
void WM_init_window_focus_set(bool do_it);
void WM_init_native_pixels(bool do_it);
void WM_init_tablet_api(void);
void WM_init_input_devices(void);
/**
* Initialize Blender and load the startup file & preferences

View File

@ -462,8 +462,8 @@ static void wm_init_userdef(Main *bmain)
/* Update the temporary directory from the preferences or fallback to the system default. */
BKE_tempdir_init(U.tempdir);
/* Update tablet API preference. */
WM_init_tablet_api();
/* Update input device preference. */
WM_init_input_devices();
BLO_sanitize_experimental_features_userpref_blend(&U);
}

View File

@ -2006,12 +2006,14 @@ void WM_init_native_pixels(bool do_it)
/** \name Cursor API
* \{ */
void WM_init_tablet_api(void)
void WM_init_input_devices(void)
{
if (UNLIKELY(!g_system)) {
return;
}
GHOST_SetMultitouchGestures(g_system, (U.uiflag & USER_NO_MULTITOUCH_GESTURES) == 0);
switch (U.tablet_api) {
case USER_TABLET_NATIVE:
GHOST_SetTabletAPI(g_system, GHOST_kTabletWinPointer);