Require mouse release on top of frame button to trigger action
authorPekka Vuorela <pvuorela@iki.fi>
Wed, 26 Sep 2012 12:05:45 +0000 (15:05 +0300)
committerKristian Høgsberg <krh@bitplanet.net>
Wed, 26 Sep 2012 15:22:30 +0000 (11:22 -0400)
As common UI convention, allows action to be avoided by dragging
outside the button after mouse press.

clients/window.c

index c5bccdc..f3b61de 100644 (file)
@@ -1498,6 +1498,7 @@ frame_button_button_handler(struct widget *widget,
 {
        struct frame_button *frame_button = data;
        struct window *window = widget->window;
+       int was_pressed = (frame_button->state == FRAME_BUTTON_ACTIVE);
 
        if (button != BTN_LEFT)
                return;
@@ -1516,6 +1517,9 @@ frame_button_button_handler(struct widget *widget,
                break;
        }
 
+       if (!was_pressed)
+               return;
+
        switch (frame_button->type) {
        case FRAME_BUTTON_CLOSE:
                if (window->close_handler)
@@ -1536,6 +1540,33 @@ frame_button_button_handler(struct widget *widget,
        }
 }
 
+static int
+frame_button_motion_handler(struct widget *widget,
+                            struct input *input, uint32_t time,
+                            float x, float y, void *data)
+{
+       struct frame_button *frame_button = data;
+       enum frame_button_pointer previous_button_state = frame_button->state;
+
+       /* only track state for a pressed button */
+       if (input->grab != widget)
+               return CURSOR_LEFT_PTR;
+
+       if (x > widget->allocation.x &&
+           x < (widget->allocation.x + widget->allocation.width) &&
+           y > widget->allocation.y &&
+           y < (widget->allocation.y + widget->allocation.height)) {
+               frame_button->state = FRAME_BUTTON_ACTIVE;
+       } else {
+               frame_button->state = FRAME_BUTTON_DEFAULT;
+       }
+
+       if (frame_button->state != previous_button_state)
+               widget_schedule_redraw(frame_button->widget);
+
+       return CURSOR_LEFT_PTR;
+}
+
 static void
 frame_button_redraw_handler(struct widget *widget, void *data)
 {
@@ -1612,6 +1643,7 @@ frame_button_create(struct frame *frame, void *data, enum frame_button_action ty
        widget_set_enter_handler(frame_button->widget, frame_button_enter_handler);
        widget_set_leave_handler(frame_button->widget, frame_button_leave_handler);
        widget_set_button_handler(frame_button->widget, frame_button_button_handler);
+       widget_set_motion_handler(frame_button->widget, frame_button_motion_handler);
        return frame_button->widget;
 }