diff --git a/src/bindings.c b/src/bindings.c index 03c92387..7cbded92 100644 --- a/src/bindings.c +++ b/src/bindings.c @@ -210,9 +210,20 @@ binding_modifiers(struct weston_keyboard_grab *grab, uint32_t serial, } } +static void +binding_cancel(struct weston_keyboard_grab *grab) +{ + struct binding_keyboard_grab *binding_grab = + container_of(grab, struct binding_keyboard_grab, grab); + + weston_keyboard_end_grab(grab->keyboard); + free(binding_grab); +} + static const struct weston_keyboard_grab_interface binding_grab = { binding_key, binding_modifiers, + binding_cancel, }; static void diff --git a/src/compositor.h b/src/compositor.h index 1b94764b..297d227e 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -240,6 +240,7 @@ struct weston_pointer_grab_interface { void (*motion)(struct weston_pointer_grab *grab, uint32_t time); void (*button)(struct weston_pointer_grab *grab, uint32_t time, uint32_t button, uint32_t state); + void (*cancel)(struct weston_pointer_grab *grab); }; struct weston_pointer_grab { @@ -254,6 +255,7 @@ struct weston_keyboard_grab_interface { void (*modifiers)(struct weston_keyboard_grab *grab, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group); + void (*cancel)(struct weston_keyboard_grab *grab); }; struct weston_keyboard_grab { @@ -276,6 +278,7 @@ struct weston_touch_grab_interface { int touch_id, wl_fixed_t sx, wl_fixed_t sy); + void (*cancel)(struct weston_touch_grab *grab); }; struct weston_touch_grab { diff --git a/src/data-device.c b/src/data-device.c index 3e22b513..888e6065 100644 --- a/src/data-device.c +++ b/src/data-device.c @@ -344,10 +344,23 @@ drag_grab_button(struct weston_pointer_grab *grab, } } +static void +drag_grab_cancel(struct weston_pointer_grab *grab) +{ + struct weston_drag *drag = + container_of(grab, struct weston_drag, grab); + + if (drag->data_source) + wl_list_remove(&drag->data_source_listener.link); + + data_device_end_drag_grab(drag); +} + static const struct weston_pointer_grab_interface drag_grab_interface = { drag_grab_focus, drag_grab_motion, drag_grab_button, + drag_grab_cancel, }; static void diff --git a/src/input.c b/src/input.c index ffb7b35e..e265efd3 100644 --- a/src/input.c +++ b/src/input.c @@ -162,11 +162,17 @@ default_grab_button(struct weston_pointer_grab *grab, } } +static void +default_grab_pointer_cancel(struct weston_pointer_grab *grab) +{ +} + static const struct weston_pointer_grab_interface default_pointer_grab_interface = { default_grab_focus, default_grab_motion, - default_grab_button + default_grab_button, + default_grab_pointer_cancel, }; static void @@ -225,10 +231,16 @@ default_grab_touch_motion(struct weston_touch_grab *grab, uint32_t time, } } +static void +default_grab_touch_cancel(struct weston_touch_grab *grab) +{ +} + static const struct weston_touch_grab_interface default_touch_grab_interface = { default_grab_touch_down, default_grab_touch_up, - default_grab_touch_motion + default_grab_touch_motion, + default_grab_touch_cancel, }; static void @@ -329,10 +341,16 @@ default_grab_modifiers(struct weston_keyboard_grab *grab, uint32_t serial, } } +static void +default_grab_keyboard_cancel(struct weston_keyboard_grab *grab) +{ +} + static const struct weston_keyboard_grab_interface default_keyboard_grab_interface = { default_grab_key, default_grab_modifiers, + default_grab_keyboard_cancel, }; static void @@ -601,6 +619,12 @@ weston_keyboard_end_grab(struct weston_keyboard *keyboard) keyboard->grab = &keyboard->default_grab; } +static void +weston_keyboard_cancel_grab(struct weston_keyboard *keyboard) +{ + keyboard->grab->interface->cancel(keyboard->grab); +} + WL_EXPORT void weston_pointer_start_grab(struct weston_pointer *pointer, struct weston_pointer_grab *grab) @@ -617,6 +641,12 @@ weston_pointer_end_grab(struct weston_pointer *pointer) pointer->grab->interface->focus(pointer->grab); } +static void +weston_pointer_cancel_grab(struct weston_pointer *pointer) +{ + pointer->grab->interface->cancel(pointer->grab); +} + WL_EXPORT void weston_touch_start_grab(struct weston_touch *touch, struct weston_touch_grab *grab) { @@ -630,6 +660,12 @@ weston_touch_end_grab(struct weston_touch *touch) touch->grab = &touch->default_grab; } +static void +weston_touch_cancel_grab(struct weston_touch *touch) +{ + touch->grab->interface->cancel(touch->grab); +} + WL_EXPORT void weston_pointer_clamp(struct weston_pointer *pointer, wl_fixed_t *fx, wl_fixed_t *fy) { @@ -1139,10 +1175,7 @@ notify_keyboard_focus_out(struct weston_seat *seat) } weston_keyboard_set_focus(keyboard, NULL); - /* FIXME: We really need keyboard grab cancel here to - * let the grab shut down properly. As it is we leak - * the grab data. */ - weston_keyboard_end_grab(keyboard); + weston_keyboard_cancel_grab(keyboard); } WL_EXPORT void @@ -1798,6 +1831,7 @@ weston_seat_release_keyboard(struct weston_seat *seat) seat->keyboard_device_count--; if (seat->keyboard_device_count == 0) { weston_keyboard_set_focus(seat->keyboard, NULL); + weston_keyboard_cancel_grab(seat->keyboard); seat_send_updated_caps(seat); } } @@ -1835,6 +1869,7 @@ weston_seat_release_pointer(struct weston_seat *seat) weston_pointer_set_focus(pointer, NULL, wl_fixed_from_int(0), wl_fixed_from_int(0)); + weston_pointer_cancel_grab(pointer); if (pointer->sprite) pointer_unmap_sprite(pointer); @@ -1872,6 +1907,7 @@ weston_seat_release_touch(struct weston_seat *seat) seat->touch_device_count--; if (seat->touch_device_count == 0) { weston_touch_set_focus(seat, NULL); + weston_touch_cancel_grab(seat->touch); seat_send_updated_caps(seat); } } diff --git a/src/shell.c b/src/shell.c index badfd0c1..6596e95d 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1162,10 +1162,22 @@ touch_move_grab_motion(struct weston_touch_grab *grab, uint32_t time, weston_compositor_schedule_repaint(es->compositor); } +static void +touch_move_grab_cancel(struct weston_touch_grab *grab) +{ + struct weston_touch_move_grab *move = + (struct weston_touch_move_grab *) container_of( + grab, struct shell_touch_grab, grab); + + shell_touch_grab_end(&move->base); + free(move); +} + static const struct weston_touch_grab_interface touch_move_grab_interface = { touch_move_grab_down, touch_move_grab_up, touch_move_grab_motion, + touch_move_grab_cancel, }; static int @@ -1236,10 +1248,21 @@ move_grab_button(struct weston_pointer_grab *grab, } } +static void +move_grab_cancel(struct weston_pointer_grab *grab) +{ + struct shell_grab *shell_grab = + container_of(grab, struct shell_grab, grab); + + shell_grab_end(shell_grab); + free(grab); +} + static const struct weston_pointer_grab_interface move_grab_interface = { noop_grab_focus, move_grab_motion, move_grab_button, + move_grab_cancel, }; static int @@ -1366,10 +1389,20 @@ resize_grab_button(struct weston_pointer_grab *grab, } } +static void +resize_grab_cancel(struct weston_pointer_grab *grab) +{ + struct weston_resize_grab *resize = (struct weston_resize_grab *) grab; + + shell_grab_end(&resize->base); + free(grab); +} + static const struct weston_pointer_grab_interface resize_grab_interface = { noop_grab_focus, resize_grab_motion, resize_grab_button, + resize_grab_cancel, }; /* @@ -1498,10 +1531,20 @@ busy_cursor_grab_button(struct weston_pointer_grab *base, } } +static void +busy_cursor_grab_cancel(struct weston_pointer_grab *base) +{ + struct shell_grab *grab = (struct shell_grab *) base; + + shell_grab_end(grab); + free(grab); +} + static const struct weston_pointer_grab_interface busy_cursor_grab_interface = { busy_cursor_grab_focus, busy_cursor_grab_motion, busy_cursor_grab_button, + busy_cursor_grab_cancel, }; static void @@ -2267,10 +2310,17 @@ popup_grab_button(struct weston_pointer_grab *grab, shseat->popup_grab.initial_up = 1; } +static void +popup_grab_cancel(struct weston_pointer_grab *grab) +{ + popup_grab_end(grab->pointer); +} + static const struct weston_pointer_grab_interface popup_grab_interface = { popup_grab_focus, popup_grab_motion, popup_grab_button, + popup_grab_cancel, }; static void @@ -3114,10 +3164,21 @@ rotate_grab_button(struct weston_pointer_grab *grab, } } +static void +rotate_grab_cancel(struct weston_pointer_grab *grab) +{ + struct rotate_grab *rotate = + container_of(grab, struct rotate_grab, base.grab); + + shell_grab_end(&rotate->base); + free(rotate); +} + static const struct weston_pointer_grab_interface rotate_grab_interface = { noop_grab_focus, rotate_grab_motion, rotate_grab_button, + rotate_grab_cancel, }; static void @@ -4349,9 +4410,18 @@ switcher_modifier(struct weston_keyboard_grab *grab, uint32_t serial, switcher_destroy(switcher); } +static void +switcher_cancel(struct weston_keyboard_grab *grab) +{ + struct switcher *switcher = container_of(grab, struct switcher, grab); + + switcher_destroy(switcher); +} + static const struct weston_keyboard_grab_interface switcher_grab = { switcher_key, switcher_modifier, + switcher_cancel, }; static void @@ -4505,9 +4575,19 @@ debug_binding_modifiers(struct weston_keyboard_grab *grab, uint32_t serial, } } +static void +debug_binding_cancel(struct weston_keyboard_grab *grab) +{ + struct debug_binding_grab *db = (struct debug_binding_grab *) grab; + + weston_keyboard_end_grab(grab->keyboard); + free(db); +} + struct weston_keyboard_grab_interface debug_binding_keyboard_grab = { debug_binding_key, - debug_binding_modifiers + debug_binding_modifiers, + debug_binding_cancel, }; static void diff --git a/src/text-backend.c b/src/text-backend.c index 37dfb756..107ccd63 100644 --- a/src/text-backend.c +++ b/src/text-backend.c @@ -570,9 +570,16 @@ input_method_context_grab_modifier(struct weston_keyboard_grab *grab, uint32_t s mods_locked, group); } +static void +input_method_context_grab_cancel(struct weston_keyboard_grab *grab) +{ + weston_keyboard_end_grab(grab->keyboard); +} + static const struct weston_keyboard_grab_interface input_method_context_grab = { input_method_context_grab_key, input_method_context_grab_modifier, + input_method_context_grab_cancel, }; static void