diff --git a/intern/ghost/intern/GHOST_SystemWayland.cc b/intern/ghost/intern/GHOST_SystemWayland.cc index fd7f6c5a515..77480f92072 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cc +++ b/intern/ghost/intern/GHOST_SystemWayland.cc @@ -5451,6 +5451,111 @@ static zwp_text_input_v3_listener text_input_listener = { static CLG_LogRef LOG_WL_SEAT = {"ghost.wl.handle.seat"}; #define LOG (&LOG_WL_SEAT) +static bool gwl_seat_capability_pointer_multitouch_check(const GWL_Seat *seat, const bool fallback) +{ + zwp_pointer_gestures_v1 *pointer_gestures = seat->system->wp_pointer_gestures_get(); + if (pointer_gestures == nullptr) { + return fallback; + } + + bool found = false; +#ifdef ZWP_POINTER_GESTURE_HOLD_V1_INTERFACE + if (seat->wp.pointer_gesture_hold) { + return true; + } + found = true; +#endif +#ifdef ZWP_POINTER_GESTURE_PINCH_V1_INTERFACE + if (seat->wp.pointer_gesture_pinch) { + return true; + } + found = true; +#endif +#ifdef ZWP_POINTER_GESTURE_SWIPE_V1_INTERFACE + if (seat->wp.pointer_gesture_swipe) { + return true; + } + found = true; +#endif + if (found == false) { + return fallback; + } + return false; +} + +static void gwl_seat_capability_pointer_multitouch_enable(GWL_Seat *seat) +{ + zwp_pointer_gestures_v1 *pointer_gestures = seat->system->wp_pointer_gestures_get(); + if (pointer_gestures == nullptr) { + return; + } + + const uint pointer_gestures_version = zwp_pointer_gestures_v1_get_version(pointer_gestures); +#ifdef ZWP_POINTER_GESTURE_HOLD_V1_INTERFACE + if (pointer_gestures_version >= ZWP_POINTER_GESTURES_V1_GET_HOLD_GESTURE_SINCE_VERSION) + { /* Hold gesture. */ + zwp_pointer_gesture_hold_v1 *gesture = zwp_pointer_gestures_v1_get_hold_gesture( + pointer_gestures, seat->wl.pointer); + zwp_pointer_gesture_hold_v1_set_user_data(gesture, seat); + zwp_pointer_gesture_hold_v1_add_listener(gesture, &gesture_hold_listener, seat); + seat->wp.pointer_gesture_hold = gesture; + } +#endif +#ifdef ZWP_POINTER_GESTURE_PINCH_V1_INTERFACE + { /* Pinch gesture. */ + zwp_pointer_gesture_pinch_v1 *gesture = zwp_pointer_gestures_v1_get_pinch_gesture( + pointer_gestures, seat->wl.pointer); + zwp_pointer_gesture_pinch_v1_set_user_data(gesture, seat); + zwp_pointer_gesture_pinch_v1_add_listener(gesture, &gesture_pinch_listener, seat); + seat->wp.pointer_gesture_pinch = gesture; + } +#endif +#ifdef ZWP_POINTER_GESTURE_SWIPE_V1_INTERFACE + { /* Swipe gesture. */ + zwp_pointer_gesture_swipe_v1 *gesture = zwp_pointer_gestures_v1_get_swipe_gesture( + pointer_gestures, seat->wl.pointer); + zwp_pointer_gesture_swipe_v1_set_user_data(gesture, seat); + zwp_pointer_gesture_swipe_v1_add_listener(gesture, &gesture_swipe_listener, seat); + seat->wp.pointer_gesture_swipe = gesture; + } +#endif +} + +static void gwl_seat_capability_pointer_multitouch_disable(GWL_Seat *seat) +{ + const zwp_pointer_gestures_v1 *pointer_gestures = seat->system->wp_pointer_gestures_get(); + if (pointer_gestures == nullptr) { + return; + } +#ifdef ZWP_POINTER_GESTURE_HOLD_V1_INTERFACE + { /* Hold gesture. */ + zwp_pointer_gesture_hold_v1 **gesture_p = &seat->wp.pointer_gesture_hold; + if (*gesture_p) { + zwp_pointer_gesture_hold_v1_destroy(*gesture_p); + *gesture_p = nullptr; + } + } +#endif +#ifdef ZWP_POINTER_GESTURE_PINCH_V1_INTERFACE + { /* Pinch gesture. */ + zwp_pointer_gesture_pinch_v1 **gesture_p = &seat->wp.pointer_gesture_pinch; + if (*gesture_p) { + zwp_pointer_gesture_pinch_v1_destroy(*gesture_p); + *gesture_p = nullptr; + } + } +#endif +#ifdef ZWP_POINTER_GESTURE_SWIPE_V1_INTERFACE + { /* Swipe gesture. */ + zwp_pointer_gesture_swipe_v1 **gesture_p = &seat->wp.pointer_gesture_swipe; + if (*gesture_p) { + zwp_pointer_gesture_swipe_v1_destroy(*gesture_p); + *gesture_p = nullptr; + } + } +#endif +} + static void gwl_seat_capability_pointer_enable(GWL_Seat *seat) { if (seat->wl.pointer) { @@ -5487,38 +5592,7 @@ static void gwl_seat_capability_pointer_enable(GWL_Seat *seat) wl_surface_add_listener(seat->cursor.wl.surface_cursor, &cursor_surface_listener, seat); ghost_wl_surface_tag_cursor_pointer(seat->cursor.wl.surface_cursor); - zwp_pointer_gestures_v1 *pointer_gestures = seat->system->wp_pointer_gestures_get(); - if (pointer_gestures) { - const uint pointer_gestures_version = zwp_pointer_gestures_v1_get_version(pointer_gestures); -#ifdef ZWP_POINTER_GESTURE_HOLD_V1_INTERFACE - if (pointer_gestures_version >= ZWP_POINTER_GESTURES_V1_GET_HOLD_GESTURE_SINCE_VERSION) - { /* Hold gesture. */ - zwp_pointer_gesture_hold_v1 *gesture = zwp_pointer_gestures_v1_get_hold_gesture( - pointer_gestures, seat->wl.pointer); - zwp_pointer_gesture_hold_v1_set_user_data(gesture, seat); - zwp_pointer_gesture_hold_v1_add_listener(gesture, &gesture_hold_listener, seat); - seat->wp.pointer_gesture_hold = gesture; - } -#endif -#ifdef ZWP_POINTER_GESTURE_PINCH_V1_INTERFACE - { /* Pinch gesture. */ - zwp_pointer_gesture_pinch_v1 *gesture = zwp_pointer_gestures_v1_get_pinch_gesture( - pointer_gestures, seat->wl.pointer); - zwp_pointer_gesture_pinch_v1_set_user_data(gesture, seat); - zwp_pointer_gesture_pinch_v1_add_listener(gesture, &gesture_pinch_listener, seat); - seat->wp.pointer_gesture_pinch = gesture; - } -#endif -#ifdef ZWP_POINTER_GESTURE_SWIPE_V1_INTERFACE - { /* Swipe gesture. */ - zwp_pointer_gesture_swipe_v1 *gesture = zwp_pointer_gestures_v1_get_swipe_gesture( - pointer_gestures, seat->wl.pointer); - zwp_pointer_gesture_swipe_v1_set_user_data(gesture, seat); - zwp_pointer_gesture_swipe_v1_add_listener(gesture, &gesture_swipe_listener, seat); - seat->wp.pointer_gesture_swipe = gesture; - } -#endif - } + gwl_seat_capability_pointer_multitouch_enable(seat); } static void gwl_seat_capability_pointer_disable(GWL_Seat *seat) @@ -5527,36 +5601,7 @@ static void gwl_seat_capability_pointer_disable(GWL_Seat *seat) return; } - const zwp_pointer_gestures_v1 *pointer_gestures = seat->system->wp_pointer_gestures_get(); - if (pointer_gestures) { -#ifdef ZWP_POINTER_GESTURE_HOLD_V1_INTERFACE - { /* Hold gesture. */ - zwp_pointer_gesture_hold_v1 **gesture_p = &seat->wp.pointer_gesture_hold; - if (*gesture_p) { - zwp_pointer_gesture_hold_v1_destroy(*gesture_p); - *gesture_p = nullptr; - } - } -#endif -#ifdef ZWP_POINTER_GESTURE_PINCH_V1_INTERFACE - { /* Pinch gesture. */ - zwp_pointer_gesture_pinch_v1 **gesture_p = &seat->wp.pointer_gesture_pinch; - if (*gesture_p) { - zwp_pointer_gesture_pinch_v1_destroy(*gesture_p); - *gesture_p = nullptr; - } - } -#endif -#ifdef ZWP_POINTER_GESTURE_SWIPE_V1_INTERFACE - { /* Swipe gesture. */ - zwp_pointer_gesture_swipe_v1 **gesture_p = &seat->wp.pointer_gesture_swipe; - if (*gesture_p) { - zwp_pointer_gesture_swipe_v1_destroy(*gesture_p); - *gesture_p = nullptr; - } - } -#endif - } + gwl_seat_capability_pointer_multitouch_disable(seat); if (seat->cursor.wl.surface_cursor) { wl_surface_destroy(seat->cursor.wl.surface_cursor); @@ -7971,6 +8016,28 @@ static GWL_SeatStateGrab seat_grab_state_from_mode(const GHOST_TGrabCursorMode m return grab_state; } +void GHOST_SystemWayland::setMultitouchGestures(const bool use) +{ + if (m_multitouchGestures == use) { + return; + } + m_multitouchGestures = use; + + /* Ensure this listeners aren't removed while events are generated. */ + std::lock_guard lock_server_guard{*server_mutex}; + for (GWL_Seat *seat : display_->seats) { + if (use == gwl_seat_capability_pointer_multitouch_check(seat, use)) { + continue; + } + if (use) { + gwl_seat_capability_pointer_multitouch_enable(seat); + } + else { + gwl_seat_capability_pointer_multitouch_disable(seat); + } + } +} + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/intern/ghost/intern/GHOST_SystemWayland.hh b/intern/ghost/intern/GHOST_SystemWayland.hh index b31774ec6bb..17b3944801f 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.hh +++ b/intern/ghost/intern/GHOST_SystemWayland.hh @@ -194,6 +194,8 @@ class GHOST_SystemWayland : public GHOST_System { GHOST_TCapabilityFlag getCapabilities() const override; + void setMultitouchGestures(const bool use) override; + /* WAYLAND utility functions (share window/system logic). */ GHOST_TSuccess cursor_shape_set(GHOST_TStandardCursor shape); diff --git a/scripts/startup/bl_ui/space_userpref.py b/scripts/startup/bl_ui/space_userpref.py index 80a6cb27441..dfa42725cc6 100644 --- a/scripts/startup/bl_ui/space_userpref.py +++ b/scripts/startup/bl_ui/space_userpref.py @@ -1737,7 +1737,15 @@ class USERPREF_PT_input_touchpad(InputPanel, CenterAlignMixIn, Panel): @classmethod def poll(cls, context): import sys - return sys.platform[:3] == "win" or sys.platform == "darwin" + if sys.platform[:3] == "win" or sys.platform == "darwin": + return True + + # WAYLAND supports multi-touch, X11 and SDL don't. + from _bpy import _ghost_backend + if _ghost_backend() == 'WAYLAND': + return True + + return False def draw_centered(self, context, layout): prefs = context.preferences