Skip to content

Commit 42ae47a

Browse files
WaylandBackend: wire up wl_touch implementation
The Wayland backend had wl_touch declared but never hooked up, so touch input was silently dropped when running nested. Tested with variations of `gamescope -e -- steam -steamdeck -steamos3 -steampal -gamepadui` on KDE Wayland, Gnome, and Cosmic. Closes: #1606
1 parent e1efc14 commit 42ae47a

1 file changed

Lines changed: 106 additions & 0 deletions

File tree

src/Backends/WaylandBackend.cpp

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,7 @@ namespace gamescope
556556
uint32_t m_uAxisSource = WL_POINTER_AXIS_SOURCE_WHEEL;
557557

558558
wl_surface *m_pCurrentCursorSurface = nullptr;
559+
wl_surface *m_pCurrentTouchSurface = nullptr;
559560

560561
std::optional<wl_fixed_t> m_ofPendingCursorX;
561562
std::optional<wl_fixed_t> m_ofPendingCursorY;
@@ -592,6 +593,15 @@ namespace gamescope
592593

593594
void Wayland_RelativePointer_RelativeMotion( zwp_relative_pointer_v1 *pRelativePointer, uint32_t uTimeHi, uint32_t uTimeLo, wl_fixed_t fDx, wl_fixed_t fDy, wl_fixed_t fDxUnaccel, wl_fixed_t fDyUnaccel );
594595
static const zwp_relative_pointer_v1_listener s_RelativePointerListener;
596+
597+
void Wayland_Touch_Down( wl_touch *pTouch, uint32_t uSerial, uint32_t uTime, wl_surface *pSurface, int32_t nId, wl_fixed_t fX, wl_fixed_t fY );
598+
void Wayland_Touch_Up( wl_touch *pTouch, uint32_t uSerial, uint32_t uTime, int32_t nId );
599+
void Wayland_Touch_Motion( wl_touch *pTouch, uint32_t uTime, int32_t nId, wl_fixed_t fX, wl_fixed_t fY );
600+
void Wayland_Touch_Frame( wl_touch *pTouch );
601+
void Wayland_Touch_Cancel( wl_touch *pTouch );
602+
void Wayland_Touch_Shape( wl_touch *pTouch, int32_t nId, wl_fixed_t fMajor, wl_fixed_t fMinor );
603+
void Wayland_Touch_Orientation( wl_touch *pTouch, int32_t nId, wl_fixed_t fOrientation );
604+
static const wl_touch_listener s_TouchListener;
595605
};
596606
const wl_registry_listener CWaylandInputThread::s_RegistryListener =
597607
{
@@ -629,6 +639,16 @@ namespace gamescope
629639
{
630640
.relative_motion = WAYLAND_USERDATA_TO_THIS( CWaylandInputThread, Wayland_RelativePointer_RelativeMotion ),
631641
};
642+
const wl_touch_listener CWaylandInputThread::s_TouchListener =
643+
{
644+
.down = WAYLAND_USERDATA_TO_THIS( CWaylandInputThread, Wayland_Touch_Down ),
645+
.up = WAYLAND_USERDATA_TO_THIS( CWaylandInputThread, Wayland_Touch_Up ),
646+
.motion = WAYLAND_USERDATA_TO_THIS( CWaylandInputThread, Wayland_Touch_Motion ),
647+
.frame = WAYLAND_USERDATA_TO_THIS( CWaylandInputThread, Wayland_Touch_Frame ),
648+
.cancel = WAYLAND_USERDATA_TO_THIS( CWaylandInputThread, Wayland_Touch_Cancel ),
649+
.shape = WAYLAND_USERDATA_TO_THIS( CWaylandInputThread, Wayland_Touch_Shape ),
650+
.orientation = WAYLAND_USERDATA_TO_THIS( CWaylandInputThread, Wayland_Touch_Orientation ),
651+
};
632652

633653
class CWaylandBackend : public CBaseBackend
634654
{
@@ -3024,6 +3044,20 @@ namespace gamescope
30243044
wl_keyboard_add_listener( m_pKeyboard, &s_KeyboardListener, this );
30253045
}
30263046
}
3047+
3048+
if ( !!( uCapabilities & WL_SEAT_CAPABILITY_TOUCH ) != !!m_pTouch )
3049+
{
3050+
if ( m_pTouch )
3051+
{
3052+
wl_touch_release( m_pTouch );
3053+
m_pTouch = nullptr;
3054+
}
3055+
else
3056+
{
3057+
m_pTouch = wl_seat_get_touch( m_pSeat );
3058+
wl_touch_add_listener( m_pTouch, &s_TouchListener, this );
3059+
}
3060+
}
30273061
}
30283062

30293063
void CWaylandInputThread::Wayland_Seat_Name( wl_seat *pSeat, const char *pName )
@@ -3250,6 +3284,78 @@ namespace gamescope
32503284
wlserver_unlock();
32513285
}
32523286

3287+
// Touch
3288+
3289+
void CWaylandInputThread::Wayland_Touch_Down( wl_touch *pTouch, uint32_t uSerial, uint32_t uTime, wl_surface *pSurface, int32_t nId, wl_fixed_t fX, wl_fixed_t fY )
3290+
{
3291+
if ( !IsGamescopeToplevel( pSurface ) )
3292+
return;
3293+
3294+
m_pCurrentTouchSurface = pSurface;
3295+
3296+
CWaylandPlane *pPlane = (CWaylandPlane *)wl_surface_get_user_data( m_pCurrentTouchSurface );
3297+
if ( !pPlane )
3298+
return;
3299+
3300+
auto oState = pPlane->GetCurrentState();
3301+
if ( !oState )
3302+
return;
3303+
3304+
uint32_t uScale = oState->uFractionalScale;
3305+
double flX = ( wl_fixed_to_double( fX ) * uScale / 120.0 + oState->nDestX ) / g_nOutputWidth;
3306+
double flY = ( wl_fixed_to_double( fY ) * uScale / 120.0 + oState->nDestY ) / g_nOutputHeight;
3307+
3308+
wlserver_lock();
3309+
wlserver_touchdown( flX, flY, nId, ++m_uFakeTimestamp );
3310+
wlserver_unlock();
3311+
}
3312+
void CWaylandInputThread::Wayland_Touch_Up( wl_touch *pTouch, uint32_t uSerial, uint32_t uTime, int32_t nId )
3313+
{
3314+
wlserver_lock();
3315+
wlserver_touchup( nId, ++m_uFakeTimestamp );
3316+
wlserver_unlock();
3317+
}
3318+
void CWaylandInputThread::Wayland_Touch_Motion( wl_touch *pTouch, uint32_t uTime, int32_t nId, wl_fixed_t fX, wl_fixed_t fY )
3319+
{
3320+
if ( !m_pCurrentTouchSurface )
3321+
return;
3322+
3323+
CWaylandPlane *pPlane = (CWaylandPlane *)wl_surface_get_user_data( m_pCurrentTouchSurface );
3324+
if ( !pPlane )
3325+
return;
3326+
3327+
auto oState = pPlane->GetCurrentState();
3328+
if ( !oState )
3329+
return;
3330+
3331+
uint32_t uScale = oState->uFractionalScale;
3332+
double flX = ( wl_fixed_to_double( fX ) * uScale / 120.0 + oState->nDestX ) / g_nOutputWidth;
3333+
double flY = ( wl_fixed_to_double( fY ) * uScale / 120.0 + oState->nDestY ) / g_nOutputHeight;
3334+
3335+
wlserver_lock();
3336+
wlserver_touchmotion( flX, flY, nId, ++m_uFakeTimestamp );
3337+
wlserver_unlock();
3338+
}
3339+
void CWaylandInputThread::Wayland_Touch_Frame( wl_touch *pTouch )
3340+
{
3341+
}
3342+
void CWaylandInputThread::Wayland_Touch_Cancel( wl_touch *pTouch )
3343+
{
3344+
wlserver_lock();
3345+
std::set<uint32_t> touchIds = wlserver.touch_down_ids;
3346+
for ( uint32_t nId : touchIds )
3347+
wlserver_touchup( nId, ++m_uFakeTimestamp );
3348+
wlserver_unlock();
3349+
3350+
m_pCurrentTouchSurface = nullptr;
3351+
}
3352+
void CWaylandInputThread::Wayland_Touch_Shape( wl_touch *pTouch, int32_t nId, wl_fixed_t fMajor, wl_fixed_t fMinor )
3353+
{
3354+
}
3355+
void CWaylandInputThread::Wayland_Touch_Orientation( wl_touch *pTouch, int32_t nId, wl_fixed_t fOrientation )
3356+
{
3357+
}
3358+
32533359
/////////////////////////
32543360
// Backend Instantiator
32553361
/////////////////////////

0 commit comments

Comments
 (0)