Add cancel function to grab interfaces
A grab can potentially allocate memory and would normally end the grab
itself, freeing the allocated memory in the process. However at in some
situations the compositor may want to abort a grab. The grab owner still
needs to free some memory and abort the grab properly. To do this a new
function 'cancel' is introduced in all the grab interfaces instructing
the grabs owner to abort the grab.
This patch also hooks up grab cancelling to seat device releasing and
when the compositor looses focus, which would potentially leak memory
before.
Signed-off-by: Jonas Ådahl <jadahl@gmail.com>
diff --git a/src/shell.c b/src/shell.c
index badfd0c..6596e95 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -1162,10 +1162,22 @@
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 @@
}
}
+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 @@
}
}
+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 @@
}
}
+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 @@
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 @@
}
}
+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_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 @@
}
}
+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