Propagate most axis events to clients
This commit is contained in:
		
							parent
							
								
									f375246657
								
							
						
					
					
						commit
						391eef6ea9
					
				|  | @ -270,7 +270,8 @@ void handle_tablet_tool_proximity(struct libinput_event *event, | ||||||
| 
 | 
 | ||||||
| 	// If the tool is not unique, libinput will not find it again after the
 | 	// If the tool is not unique, libinput will not find it again after the
 | ||||||
| 	// proximity out, so we should destroy it
 | 	// proximity out, so we should destroy it
 | ||||||
| 	if (!tool->unique) { | 	if (!tool->unique && | ||||||
|  | 			libinput_event_tablet_tool_get_proximity_state(tevent) == LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT) { | ||||||
| 		// The tool isn't unique, it can't be on multiple tablets
 | 		// The tool isn't unique, it can't be on multiple tablets
 | ||||||
| 		assert(tool->pad_refs == 1); | 		assert(tool->pad_refs == 1); | ||||||
| 		struct wlr_libinput_tablet *tablet = | 		struct wlr_libinput_tablet *tablet = | ||||||
|  |  | ||||||
|  | @ -111,6 +111,19 @@ struct roots_tablet_pad { | ||||||
| 	struct wl_listener tablet_destroy; | 	struct wl_listener tablet_destroy; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | struct roots_tablet_tool_tool { | ||||||
|  | 	struct wl_list link; | ||||||
|  | 	struct wl_list tool_link; | ||||||
|  | 	struct wlr_tablet_v2_tablet_tool *tablet_v2_tool; | ||||||
|  | 
 | ||||||
|  | 	struct roots_seat *seat; | ||||||
|  | 
 | ||||||
|  | 	struct wl_listener tool_destroy; | ||||||
|  | 
 | ||||||
|  | 	struct roots_tablet_tool *current_tablet; | ||||||
|  | 	struct wl_listener tablet_destroy; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| struct roots_seat *roots_seat_create(struct roots_input *input, char *name); | struct roots_seat *roots_seat_create(struct roots_input *input, char *name); | ||||||
| 
 | 
 | ||||||
| void roots_seat_destroy(struct roots_seat *seat); | void roots_seat_destroy(struct roots_seat *seat); | ||||||
|  |  | ||||||
|  | @ -7,6 +7,7 @@ | ||||||
| 
 | 
 | ||||||
| #include "tablet-unstable-v2-protocol.h" | #include "tablet-unstable-v2-protocol.h" | ||||||
| 
 | 
 | ||||||
|  | struct wlr_tablet_client_v2; | ||||||
| struct wlr_tablet_tool_client_v2; | struct wlr_tablet_tool_client_v2; | ||||||
| struct wlr_tablet_pad_client_v2; | struct wlr_tablet_pad_client_v2; | ||||||
| 
 | 
 | ||||||
|  | @ -27,6 +28,8 @@ struct wlr_tablet_v2_tablet { | ||||||
| 	struct wl_list clients; // wlr_tablet_client_v2::tablet_link
 | 	struct wl_list clients; // wlr_tablet_client_v2::tablet_link
 | ||||||
| 
 | 
 | ||||||
| 	struct wl_listener tool_destroy; | 	struct wl_listener tool_destroy; | ||||||
|  | 
 | ||||||
|  | 	struct wlr_tablet_client_v2 *current_client; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct wlr_tablet_v2_tablet_tool { | struct wlr_tablet_v2_tablet_tool { | ||||||
|  | @ -37,6 +40,9 @@ struct wlr_tablet_v2_tablet_tool { | ||||||
| 	struct wl_listener tool_destroy; | 	struct wl_listener tool_destroy; | ||||||
| 
 | 
 | ||||||
| 	struct wlr_tablet_tool_client_v2 *current_client; | 	struct wlr_tablet_tool_client_v2 *current_client; | ||||||
|  | 	struct wlr_surface *focused_surface; | ||||||
|  | 	struct wl_listener surface_destroy; | ||||||
|  | 	struct wl_listener client_destroy; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct wlr_tablet_v2_tablet_pad { | struct wlr_tablet_v2_tablet_pad { | ||||||
|  | @ -79,6 +85,12 @@ uint32_t wlr_send_tablet_v2_tablet_tool_proximity_in( | ||||||
| void wlr_send_tablet_v2_tablet_tool_motion( | void wlr_send_tablet_v2_tablet_tool_motion( | ||||||
| 		struct wlr_tablet_v2_tablet_tool *tool, double x, double y); | 		struct wlr_tablet_v2_tablet_tool *tool, double x, double y); | ||||||
| 
 | 
 | ||||||
|  | void wlr_send_tablet_v2_tablet_tool_distance( | ||||||
|  | 	struct wlr_tablet_v2_tablet_tool *tool, uint32_t distance); | ||||||
|  | 
 | ||||||
|  | void wlr_send_tablet_v2_tablet_tool_wheel( | ||||||
|  | 	struct wlr_tablet_v2_tablet_tool *tool, double delta, int32_t clicks); | ||||||
|  | 
 | ||||||
| void wlr_send_tablet_v2_tablet_tool_proximity_out( | void wlr_send_tablet_v2_tablet_tool_proximity_out( | ||||||
| 	struct wlr_tablet_v2_tablet_tool *tool); | 	struct wlr_tablet_v2_tablet_tool *tool); | ||||||
| 
 | 
 | ||||||
|  | @ -101,4 +113,7 @@ uint32_t wlr_send_tablet_v2_tablet_pad_leave(struct wlr_tablet_v2_tablet_pad *pa | ||||||
| 
 | 
 | ||||||
| uint32_t wlr_send_tablet_v2_tablet_pad_mode(struct wlr_tablet_v2_tablet_pad *pad, | uint32_t wlr_send_tablet_v2_tablet_pad_mode(struct wlr_tablet_v2_tablet_pad *pad, | ||||||
| 		size_t group, uint32_t mode, uint32_t time); | 		size_t group, uint32_t mode, uint32_t time); | ||||||
|  | 
 | ||||||
|  | bool wlr_surface_accepts_tablet_v2(struct wlr_tablet_v2_tablet *tablet, | ||||||
|  | 		struct wlr_surface *surface); | ||||||
| #endif /* WLR_TYPES_WLR_TABLET_V2_H */ | #endif /* WLR_TYPES_WLR_TABLET_V2_H */ | ||||||
|  |  | ||||||
|  | @ -101,13 +101,75 @@ static void handle_touch_motion(struct wl_listener *listener, void *data) { | ||||||
| 	roots_cursor_handle_touch_motion(cursor, event); | 	roots_cursor_handle_touch_motion(cursor, event); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void handle_tablet_tool_position(struct roots_cursor *cursor, | ||||||
|  | 		struct roots_tablet_tool *tool, | ||||||
|  | 		struct wlr_tablet_tool_tool *tool_tool, | ||||||
|  | 		bool change_x, bool change_y, double x, double y, | ||||||
|  | 		uint32_t time) { | ||||||
|  | 	if (!change_x && !change_y) { | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	wlr_cursor_warp_absolute(cursor->cursor, tool->device, | ||||||
|  | 		change_x ? x : -1 , change_y ? y : -1); | ||||||
|  | 
 | ||||||
|  | 	double sx, sy; | ||||||
|  | 	struct roots_view *view = NULL; | ||||||
|  | 	struct roots_seat *seat = cursor->seat; | ||||||
|  | 	struct roots_desktop *desktop = seat->input->server->desktop; | ||||||
|  | 	struct wlr_surface *surface = desktop_surface_at(desktop, | ||||||
|  | 			cursor->cursor->x, cursor->cursor->y, &sx, &sy, &view); | ||||||
|  | 	struct roots_tablet_tool_tool *roots_tool = tool_tool->data; | ||||||
|  | 	 | ||||||
|  | 	if (!surface) { | ||||||
|  | 		wlr_send_tablet_v2_tablet_tool_proximity_out(roots_tool->tablet_v2_tool); | ||||||
|  | 		/* XXX: TODO: Fallback pointer semantics */ | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	if (!wlr_surface_accepts_tablet_v2(tool->tablet_v2, surface)) { | ||||||
|  | 		wlr_send_tablet_v2_tablet_tool_proximity_out(roots_tool->tablet_v2_tool); | ||||||
|  | 		/* XXX: TODO: Fallback pointer semantics */ | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	wlr_send_tablet_v2_tablet_tool_proximity_in(roots_tool->tablet_v2_tool, | ||||||
|  | 		tool->tablet_v2, surface); | ||||||
|  | 
 | ||||||
|  | 	wlr_send_tablet_v2_tablet_tool_motion(roots_tool->tablet_v2_tool, sx, sy); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static void handle_tool_axis(struct wl_listener *listener, void *data) { | static void handle_tool_axis(struct wl_listener *listener, void *data) { | ||||||
|  | 	wlr_log(L_DEBUG, "Tool Axis"); | ||||||
| 	struct roots_cursor *cursor = | 	struct roots_cursor *cursor = | ||||||
| 		wl_container_of(listener, cursor, tool_axis); | 		wl_container_of(listener, cursor, tool_axis); | ||||||
| 	struct roots_desktop *desktop = cursor->seat->input->server->desktop; | 	struct roots_desktop *desktop = cursor->seat->input->server->desktop; | ||||||
| 	wlr_idle_notify_activity(desktop->idle, cursor->seat->seat); | 	wlr_idle_notify_activity(desktop->idle, cursor->seat->seat); | ||||||
| 	struct wlr_event_tablet_tool_axis *event = data; | 	struct wlr_event_tablet_tool_axis *event = data; | ||||||
| 	roots_cursor_handle_tool_axis(cursor, event); | 	struct roots_tablet_tool_tool *roots_tool = event->tool->data; | ||||||
|  | 
 | ||||||
|  | 	if (!roots_tool) { | ||||||
|  | 		wlr_log(L_DEBUG, "Tool Axis, before proximity"); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/**
 | ||||||
|  | 	 * We need to handle them ourselves, not pass it into the cursor | ||||||
|  | 	 * without any consideration | ||||||
|  | 	 */ | ||||||
|  | 	handle_tablet_tool_position(cursor, event->device->data, event->tool, | ||||||
|  | 		event->updated_axes & WLR_TABLET_TOOL_AXIS_X, | ||||||
|  | 		event->updated_axes & WLR_TABLET_TOOL_AXIS_Y, | ||||||
|  | 		event->x, event->y, event->time_msec); | ||||||
|  | 
 | ||||||
|  | 	if (event->updated_axes & WLR_TABLET_TOOL_AXIS_DISTANCE) { | ||||||
|  | 		wlr_send_tablet_v2_tablet_tool_distance(roots_tool->tablet_v2_tool, event->distance); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (event->updated_axes & WLR_TABLET_TOOL_AXIS_WHEEL) { | ||||||
|  | 		wlr_send_tablet_v2_tablet_tool_wheel(roots_tool->tablet_v2_tool, event->wheel_delta, 0); | ||||||
|  | 	} | ||||||
|  | 	//roots_cursor_handle_tool_axis(cursor, event);
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void handle_tool_tip(struct wl_listener *listener, void *data) { | static void handle_tool_tip(struct wl_listener *listener, void *data) { | ||||||
|  | @ -119,7 +181,22 @@ static void handle_tool_tip(struct wl_listener *listener, void *data) { | ||||||
| 	roots_cursor_handle_tool_tip(cursor, event); | 	roots_cursor_handle_tool_tip(cursor, event); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void handle_tablet_tool_tool_destroy(struct wl_listener *listener, void *data) { | ||||||
|  | 	wlr_log(L_DEBUG, "Tool destroy"); | ||||||
|  | 	struct roots_tablet_tool_tool *tool = | ||||||
|  | 		wl_container_of(listener, tool, tool_destroy); | ||||||
|  | 	 | ||||||
|  | 	wl_list_remove(&tool->link); | ||||||
|  | 	wl_list_remove(&tool->tool_link); | ||||||
|  | 
 | ||||||
|  | 	wl_list_remove(&tool->tool_destroy.link); | ||||||
|  | 	wl_list_remove(&tool->tablet_destroy.link); | ||||||
|  | 
 | ||||||
|  | 	free(tool); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static void handle_tool_proximity(struct wl_listener *listener, void *data) { | static void handle_tool_proximity(struct wl_listener *listener, void *data) { | ||||||
|  | 	wlr_log(L_DEBUG, "Tool Proximity"); | ||||||
| 	struct roots_cursor *cursor = | 	struct roots_cursor *cursor = | ||||||
| 		wl_container_of(listener, cursor, tool_proximity); | 		wl_container_of(listener, cursor, tool_proximity); | ||||||
| 	struct roots_desktop *desktop = cursor->seat->input->server->desktop; | 	struct roots_desktop *desktop = cursor->seat->input->server->desktop; | ||||||
|  | @ -128,8 +205,18 @@ static void handle_tool_proximity(struct wl_listener *listener, void *data) { | ||||||
| 
 | 
 | ||||||
| 	struct wlr_tablet_tool_tool *tool = event->tool; | 	struct wlr_tablet_tool_tool *tool = event->tool; | ||||||
| 	if (!tool->data) { | 	if (!tool->data) { | ||||||
| 		tool->data = wlr_make_tablet_tool(desktop->tablet_v2, cursor->seat->seat, tool); | 		struct roots_tablet_tool_tool *roots_tool = | ||||||
|  | 			calloc(1, sizeof(struct roots_tablet_tool_tool)); | ||||||
|  | 		roots_tool->seat = cursor->seat; | ||||||
|  | 		tool->data = roots_tool; | ||||||
|  | 		roots_tool->tablet_v2_tool = | ||||||
|  | 			wlr_make_tablet_tool(desktop->tablet_v2, cursor->seat->seat, tool); | ||||||
|  | 		roots_tool->tool_destroy.notify = handle_tablet_tool_tool_destroy; | ||||||
|  | 		wl_signal_add(&tool->events.destroy, &roots_tool->tool_destroy); | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	handle_tablet_tool_position(cursor, event->device->data, event->tool, | ||||||
|  | 		true, true, event->x, event->y, event->time_msec); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void handle_request_set_cursor(struct wl_listener *listener, | static void handle_request_set_cursor(struct wl_listener *listener, | ||||||
|  |  | ||||||
|  | @ -950,8 +950,11 @@ static void send_tool_frame(void *data) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void queue_tool_frame(struct wlr_tablet_tool_client_v2 *tool) { | static void queue_tool_frame(struct wlr_tablet_tool_client_v2 *tool) { | ||||||
|  | 	struct wl_display *display = wl_client_get_display(tool->client); | ||||||
|  | 	struct wl_event_loop *loop = wl_display_get_event_loop(display); | ||||||
| 	if (!tool->frame_source) { | 	if (!tool->frame_source) { | ||||||
| 		tool->frame_source = wl_event_loop_add_idle(NULL, send_tool_frame, tool); | 		tool->frame_source = | ||||||
|  | 			wl_event_loop_add_idle(loop, send_tool_frame, tool); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -961,6 +964,10 @@ uint32_t wlr_send_tablet_v2_tablet_tool_proximity_in( | ||||||
| 		struct wlr_surface *surface) { | 		struct wlr_surface *surface) { | ||||||
| 	struct wl_client *client = wl_resource_get_client(surface->resource); | 	struct wl_client *client = wl_resource_get_client(surface->resource); | ||||||
| 
 | 
 | ||||||
|  | 	if (tool->focused_surface == surface) { | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	struct wlr_tablet_client_v2 *tablet_tmp; | 	struct wlr_tablet_client_v2 *tablet_tmp; | ||||||
| 	struct wlr_tablet_client_v2 *tablet_client = NULL; | 	struct wlr_tablet_client_v2 *tablet_client = NULL; | ||||||
| 	wl_list_for_each(tablet_tmp, &tablet->clients, tablet_link) { | 	wl_list_for_each(tablet_tmp, &tablet->clients, tablet_link) { | ||||||
|  | @ -1004,6 +1011,7 @@ uint32_t wlr_send_tablet_v2_tablet_tool_proximity_in( | ||||||
| 		tablet_client->resource, surface->resource); | 		tablet_client->resource, surface->resource); | ||||||
| 	queue_tool_frame(tool_client); | 	queue_tool_frame(tool_client); | ||||||
| 
 | 
 | ||||||
|  | 	tool->focused_surface = surface; | ||||||
| 	return serial; | 	return serial; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -1028,9 +1036,31 @@ void wlr_send_tablet_v2_tablet_tool_proximity_out( | ||||||
| 			wl_event_source_remove(tool->current_client->frame_source); | 			wl_event_source_remove(tool->current_client->frame_source); | ||||||
| 			send_tool_frame(tool->current_client); | 			send_tool_frame(tool->current_client); | ||||||
| 		} | 		} | ||||||
|  | 		tool->current_client = NULL; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void wlr_send_tablet_v2_tablet_tool_distance( | ||||||
|  | 	struct wlr_tablet_v2_tablet_tool *tool, uint32_t distance) { | ||||||
|  | 	if (tool->current_client) { | ||||||
|  | 		zwp_tablet_tool_v2_send_distance(tool->current_client->resource, | ||||||
|  | 			distance); | ||||||
|  | 
 | ||||||
|  | 		queue_tool_frame(tool->current_client); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void wlr_send_tablet_v2_tablet_tool_wheel( | ||||||
|  | 	struct wlr_tablet_v2_tablet_tool *tool, double delta, int32_t clicks) { | ||||||
|  | 	if (tool->current_client) { | ||||||
|  | 		zwp_tablet_tool_v2_send_wheel(tool->current_client->resource, | ||||||
|  | 			clicks, delta); | ||||||
|  | 
 | ||||||
|  | 		queue_tool_frame(tool->current_client); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| uint32_t wlr_send_tablet_v2_tablet_pad_enter( | uint32_t wlr_send_tablet_v2_tablet_pad_enter( | ||||||
| 		struct wlr_tablet_v2_tablet_pad *pad, | 		struct wlr_tablet_v2_tablet_pad *pad, | ||||||
|  | @ -1183,3 +1213,22 @@ uint32_t wlr_send_tablet_v2_tablet_pad_mode(struct wlr_tablet_v2_tablet_pad *pad | ||||||
| 		pad->current_client->groups[group], time, serial, mode); | 		pad->current_client->groups[group], time, serial, mode); | ||||||
| 	return serial; | 	return serial; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | bool wlr_surface_accepts_tablet_v2(struct wlr_tablet_v2_tablet *tablet, | ||||||
|  | 		struct wlr_surface *surface) { | ||||||
|  | 	struct wl_client *client = wl_resource_get_client(surface->resource); | ||||||
|  | 
 | ||||||
|  | 	if (tablet->current_client && | ||||||
|  | 			tablet->current_client->client == client) { | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	struct wlr_tablet_client_v2 *tablet_tmp; | ||||||
|  | 	wl_list_for_each(tablet_tmp, &tablet->clients, tablet_link) { | ||||||
|  | 		if (tablet_tmp->client == client) { | ||||||
|  | 			return true; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return false; | ||||||
|  | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue