support frame buttons hovering with touchscreen and
cancel button press if a touch was not released over
the button that was pressed
---
 clients/window.c    |   14 ++++++++++++++
 shared/cairo-util.h |    3 +++
 shared/frame.c      |   44 ++++++++++++++++++++++++++++++++++++++------
 3 files changed, 55 insertions(+), 6 deletions(-)

diff --git a/clients/window.c b/clients/window.c
index 325a456..71aeed3 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -2414,6 +2414,19 @@ frame_touch_up_handler(struct widget *widget,
        frame_handle_status(frame, input, time, THEME_LOCATION_CLIENT_AREA);
 }
 
+static void
+frame_touch_motion_handler(struct widget *widget,
+                          struct input *input,
+                          uint32_t time, int32_t id, float x, float y,
+                          void *data)
+{
+       struct window_frame *frame = data;
+
+       frame_touch_motion(frame->frame, input, x, y);
+       if (frame_status(frame->frame) & FRAME_STATUS_REPAINT)
+               widget_schedule_redraw(frame->widget);
+}
+
 struct widget *
 window_frame_create(struct window *window, void *data)
 {
@@ -2441,6 +2454,7 @@ 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_touch_motion_handler(frame->widget, 
frame_touch_motion_handler);
 
        window->frame = frame;
 
diff --git a/shared/cairo-util.h b/shared/cairo-util.h
index 9643023..70f62a6 100644
--- a/shared/cairo-util.h
+++ b/shared/cairo-util.h
@@ -211,6 +211,9 @@ void
 frame_touch_up(struct frame *frame, void *data, int32_t id);
 
 void
+frame_touch_motion(struct frame *frame, void *data, int x, int y);
+
+void
 frame_repaint(struct frame *frame, cairo_t *cr);
 
 #endif
diff --git a/shared/frame.c b/shared/frame.c
index 833117c..d0430a7 100644
--- a/shared/frame.c
+++ b/shared/frame.c
@@ -77,6 +77,7 @@ struct frame_touch {
 
        int x, y;
 
+       struct frame_button *hover_button;
        struct frame_button *button;
 };
 
@@ -789,7 +790,7 @@ frame_touch_down(struct frame *frame, void *data, int32_t 
id, int x, int y)
        struct frame_button *button = frame_find_button(frame, x, y);
        enum theme_location location = THEME_LOCATION_EXTERIOR;
 
-       if (id > 0)
+       if (!touch || (id > 0))
                return location;
 
        location = theme_get_location(frame->theme, x, y,
@@ -797,8 +798,9 @@ frame_touch_down(struct frame *frame, void *data, int32_t 
id, int x, int y)
                                      frame->flags & FRAME_FLAG_MAXIMIZED ?
                                      THEME_FRAME_MAXIMIZED : 0);
 
-       if (touch && button) {
-               touch->button = button;
+       if (button) {
+               touch->hover_button = touch->button = button;
+               frame_button_enter(touch->button);
                frame_button_press(touch->button);
                return location;
        }
@@ -829,16 +831,46 @@ frame_touch_up(struct frame *frame, void *data, int32_t 
id)
 {
        struct frame_touch *touch = frame_touch_get(frame, data);
 
-       if (id > 0)
+       if (!touch || (id > 0))
                return;
 
-       if (touch && touch->button) {
-               frame_button_release(touch->button);
+       if (touch->hover_button)
+               frame_button_leave(touch->hover_button, NULL);
+
+       if (touch->button) {
+               if (touch->button == touch->hover_button)
+                       frame_button_release(touch->button);
+               else
+                       frame_button_cancel(touch->button);
                frame_touch_destroy(touch);
        }
 }
 
 void
+frame_touch_motion(struct frame *frame, void *data, int x, int y)
+{
+       struct frame_touch *touch = frame_touch_get(frame, data);
+       struct frame_button *button = frame_find_button(frame, x, y);
+
+       if (!touch)
+               return;
+
+       touch->x = x;
+       touch->y = y;
+
+       if (touch->hover_button == button)
+               return;
+
+       if (touch->hover_button)
+               frame_button_leave(touch->hover_button, NULL);
+
+       touch->hover_button = button;
+
+       if (touch->hover_button)
+               frame_button_enter(touch->hover_button);
+}
+
+void
 frame_repaint(struct frame *frame, cairo_t *cr)
 {
        struct frame_button *button;
-- 
1.7.9.5

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to