@ -2,12 +2,20 @@
# include <float.h>
# include <wlr/types/wlr_cursor.h>
# include <wlr/types/wlr_tablet_v2.h>
# include <wlr/types/wlr_touch.h>
# include "sway/input/cursor.h"
# include "sway/input/seat.h"
# include "sway/tree/view.h"
# include "sway/desktop/transaction.h"
# include "log.h"
struct seatop_touch_point_event {
double ref_lx , ref_ly ; // touch's x/y at start of op
double ref_con_lx , ref_con_ly ; // container's x/y at start of op
int32_t touch_id ;
struct wl_list link ;
} ;
struct seatop_down_event {
struct sway_container * con ;
struct sway_seat * seat ;
@ -15,8 +23,87 @@ struct seatop_down_event {
struct wlr_surface * surface ;
double ref_lx , ref_ly ; // cursor's x/y at start of op
double ref_con_lx , ref_con_ly ; // container's x/y at start of op
struct wl_list point_events ; // seatop_touch_point_event::link
} ;
static void handle_touch_motion ( struct sway_seat * seat ,
struct wlr_touch_motion_event * event , double lx , double ly ) {
struct seatop_down_event * e = seat - > seatop_data ;
struct seatop_touch_point_event * point_event ;
bool found = false ;
wl_list_for_each ( point_event , & e - > point_events , link ) {
if ( point_event - > touch_id = = event - > touch_id ) {
found = true ;
break ;
}
}
if ( ! found ) {
return ; // Probably not a point_event from this seatop_down
}
double moved_x = lx - point_event - > ref_lx ;
double moved_y = ly - point_event - > ref_ly ;
double sx = point_event - > ref_con_lx + moved_x ;
double sy = point_event - > ref_con_ly + moved_y ;
wlr_seat_touch_notify_motion ( seat - > wlr_seat , event - > time_msec ,
event - > touch_id , sx , sy ) ;
}
static void handle_touch_up ( struct sway_seat * seat ,
struct wlr_touch_up_event * event ) {
struct seatop_down_event * e = seat - > seatop_data ;
struct seatop_touch_point_event * point_event , * tmp ;
wl_list_for_each_safe ( point_event , tmp , & e - > point_events , link ) {
if ( point_event - > touch_id = = event - > touch_id ) {
wl_list_remove ( & point_event - > link ) ;
free ( point_event ) ;
break ;
}
}
if ( wl_list_empty ( & e - > point_events ) ) {
seatop_begin_default ( seat ) ;
}
wlr_seat_touch_notify_up ( seat - > wlr_seat , event - > time_msec , event - > touch_id ) ;
}
static void handle_touch_down ( struct sway_seat * seat ,
struct wlr_touch_down_event * event , double lx , double ly ) {
struct seatop_down_event * e = seat - > seatop_data ;
double sx , sy ;
struct wlr_surface * surface = NULL ;
struct sway_node * focused_node = node_at_coords ( seat , seat - > touch_x ,
seat - > touch_y , & surface , & sx , & sy ) ;
if ( ! surface | | surface ! = e - > surface ) { // Must start from the initial surface
return ;
}
struct seatop_touch_point_event * point_event =
calloc ( 1 , sizeof ( struct seatop_touch_point_event ) ) ;
if ( ! sway_assert ( point_event , " Unable to allocate point_event " ) ) {
return ;
}
point_event - > touch_id = event - > touch_id ;
point_event - > ref_lx = lx ;
point_event - > ref_ly = ly ;
point_event - > ref_con_lx = sx ;
point_event - > ref_con_ly = sy ;
wl_list_insert ( & e - > point_events , & point_event - > link ) ;
wlr_seat_touch_notify_down ( seat - > wlr_seat , surface , event - > time_msec ,
event - > touch_id , sx , sy ) ;
if ( focused_node ) {
seat_set_focus ( seat , focused_node ) ;
}
}
static void handle_pointer_axis ( struct sway_seat * seat ,
struct wlr_pointer_axis_event * event ) {
struct sway_input_device * input_device =
@ -99,14 +186,17 @@ static const struct sway_seatop_impl seatop_impl = {
. pointer_axis = handle_pointer_axis ,
. tablet_tool_tip = handle_tablet_tool_tip ,
. tablet_tool_motion = handle_tablet_tool_motion ,
. touch_motion = handle_touch_motion ,
. touch_up = handle_touch_up ,
. touch_down = handle_touch_down ,
. unref = handle_unref ,
. end = handle_end ,
. allow_set_cursor = true ,
} ;
void seatop_begin_down ( struct sway_seat * seat , struct sway_container * con ,
uint32_t time_msec , double sx , double sy ) {
seatop_begin_down_on_surface ( seat , con - > view - > surface , time_msec, sx, sy ) ;
double sx , double sy ) {
seatop_begin_down_on_surface ( seat , con - > view - > surface , sx, sy ) ;
struct seatop_down_event * e = seat - > seatop_data ;
e - > con = con ;
@ -114,13 +204,20 @@ void seatop_begin_down(struct sway_seat *seat, struct sway_container *con,
transaction_commit_dirty ( ) ;
}
void seatop_begin_touch_down ( struct sway_seat * seat ,
struct wlr_surface * surface , struct wlr_touch_down_event * event ,
double sx , double sy , double lx , double ly ) {
seatop_begin_down_on_surface ( seat , surface , sx , sy ) ;
handle_touch_down ( seat , event , lx , ly ) ;
}
void seatop_begin_down_on_surface ( struct sway_seat * seat ,
struct wlr_surface * surface , uint32_t time_msec , double sx , double sy ) {
struct wlr_surface * surface , double sx , double sy ) {
seatop_end ( seat ) ;
struct seatop_down_event * e =
calloc ( 1 , sizeof ( struct seatop_down_event ) ) ;
if ( ! e ) {
if ( ! sway_assert ( e , " Unable to allocate e " ) ) {
return ;
}
e - > con = NULL ;
@ -132,6 +229,7 @@ void seatop_begin_down_on_surface(struct sway_seat *seat,
e - > ref_ly = seat - > cursor - > cursor - > y ;
e - > ref_con_lx = sx ;
e - > ref_con_ly = sy ;
wl_list_init ( & e - > point_events ) ;
seat - > seatop_impl = & seatop_impl ;
seat - > seatop_data = e ;