[PATCH weston 08/16] client: Add support for tablet cursor motion to window frames in libtoytoolkit

Bastian Farkas bfarkas at de.adit-jv.com
Wed Oct 25 11:14:49 UTC 2017


From: Lyude Paul <thatslyude at gmail.com>

When it comes to a window frame, a tablet tool and cursor act almost
identical; they click things, drag things, etc. The tool type and extra
axes don't serve any use in the context of a window frame, so tablet
pointers share the frame_pointer structures used for the mouse pointer.

Co-authored-by: Peter Hutterer <peter.hutterer at who-t.net>
Signed-off-by: Lyude Paul <thatslyude at gmail.com>
Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
Reviewed-by: Jonas Ã…dahl <jadahl at gmail.com>
Signed-off-by: Bastian Farkas <bfarkas at de.adit-jv.com>
---
 clients/window.c    | 23 ++++++++++++++++++++++-
 shared/cairo-util.h |  4 ++++
 shared/frame.c      | 38 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/clients/window.c b/clients/window.c
index bb370d4..ac4004b 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -2648,6 +2648,24 @@ frame_touch_up_handler(struct widget *widget,
 	frame_handle_status(frame, input, time, THEME_LOCATION_CLIENT_AREA);
 }
 
+static int
+frame_tablet_tool_motion_handler(struct widget *widget,
+				 struct tablet_tool *tool,
+				 float x, float y,
+				 void *data)
+{
+	struct window_frame *frame = data;
+	enum theme_location location;
+
+	location = frame_tablet_tool_motion(frame->frame, tool, x, y);
+	if (frame_status(frame->frame) & FRAME_STATUS_REPAINT)
+		widget_schedule_redraw(frame->widget);
+
+	frame_get_pointer_image_for_location(data, location);
+
+	return CURSOR_LEFT_PTR;
+}
+
 struct widget *
 window_frame_create(struct window *window, void *data)
 {
@@ -2675,7 +2693,10 @@ window_frame_create(struct window *window, void *data)
 	widget_set_button_handler(frame->widget, frame_button_handler);
 	widget_set_touch_down_handler(frame->widget, frame_touch_down_handler);
 	widget_set_touch_up_handler(frame->widget, frame_touch_up_handler);
-
+	widget_set_tablet_tool_axis_handlers(frame->widget,
+					     frame_tablet_tool_motion_handler,
+					     NULL, NULL, NULL,
+					     NULL, NULL, NULL);
 	window->frame = frame;
 
 	return frame->child;
diff --git a/shared/cairo-util.h b/shared/cairo-util.h
index 84cf005..0df3d12 100644
--- a/shared/cairo-util.h
+++ b/shared/cairo-util.h
@@ -223,6 +223,10 @@ frame_double_touch_down(struct frame *frame, void *data, int32_t id,
 void
 frame_double_touch_up(struct frame *frame, void *data, int32_t id);
 
+/* May set FRAME_STATUS_REPAINT */
+enum theme_location
+frame_tablet_tool_motion(struct frame *frame, void *pointer, int x, int y);
+
 void
 frame_repaint(struct frame *frame, cairo_t *cr);
 
diff --git a/shared/frame.c b/shared/frame.c
index eb0cd77..992a78f 100644
--- a/shared/frame.c
+++ b/shared/frame.c
@@ -922,6 +922,44 @@ frame_double_touch_up(struct frame *frame, void *data, int32_t id)
 	}
 }
 
+enum theme_location
+frame_tablet_tool_motion(struct frame *frame, void *data, int x, int y)
+{
+	struct frame_pointer *tool_pointer = frame_pointer_get(frame, data);
+	struct frame_button *button,
+			    *prev_button = tool_pointer->hover_button;
+	enum theme_location location;
+
+	location = theme_get_location(frame->theme, tool_pointer->x,
+				      tool_pointer->y, frame->width,
+				      frame->height,
+				      frame->flags & FRAME_FLAG_MAXIMIZED ?
+				      THEME_FRAME_MAXIMIZED : 0);
+
+	if (!tool_pointer)
+		return location;
+
+	tool_pointer->x = x;
+	tool_pointer->y = y;
+
+	button = frame_find_button(frame, x, y);
+
+	if (prev_button) {
+		if (prev_button == button)
+			/* The button hasn't changed so we're done here */
+			return location;
+		else
+			frame_button_leave(prev_button, tool_pointer);
+	}
+
+	if (button)
+		frame_button_enter(button);
+
+	tool_pointer->hover_button = button;
+
+	return location;
+}
+
 void
 frame_repaint(struct frame *frame, cairo_t *cr)
 {
-- 
2.7.4



More information about the wayland-devel mailing list