compositor: Add debug key bindings infrastructure
Add the concept of debug key bindings, that are bindings that activate
debug features in the compositor. The bindings are added to a list in
the compositor, but the triggering them is left to the shell.
On the shell side, a global debug key binding is added. When the user
presses mod-shift-space, the shell will invoke the debug bindings based
on the next key press.
This also converts the debug shortcuts for repaint debugging, fan
repaint debugging and the hide overlays shortcut in compositor-drm to
use the new infrastructure.
diff --git a/src/shell.c b/src/shell.c
index d4662ef..ac82653 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -3526,6 +3526,122 @@
weston_compositor_damage_all(compositor);
}
+struct debug_binding_grab {
+ struct wl_keyboard_grab grab;
+ struct weston_seat *seat;
+ uint32_t key[2];
+ int key_released[2];
+};
+
+static void
+debug_binding_key(struct wl_keyboard_grab *grab, uint32_t time,
+ uint32_t key, uint32_t state)
+{
+ struct debug_binding_grab *db = (struct debug_binding_grab *) grab;
+ struct wl_resource *resource;
+ struct wl_display *display;
+ uint32_t serial;
+ int send = 0, terminate = 0;
+ int check_binding = 1;
+ int i;
+
+ if (state == WL_KEYBOARD_KEY_STATE_RELEASED) {
+ /* Do not run bindings on key releases */
+ check_binding = 0;
+
+ for (i = 0; i < 2; i++)
+ if (key == db->key[i])
+ db->key_released[i] = 1;
+
+ if (db->key_released[0] && db->key_released[1]) {
+ /* All key releases been swalled so end the grab */
+ terminate = 1;
+ } else if (key != db->key[0] && key != db->key[1]) {
+ /* Should not swallow release of other keys */
+ send = 1;
+ }
+ } else if (key == db->key[0] && !db->key_released[0]) {
+ /* Do not check bindings for the first press of the binding
+ * key. This allows it to be used as a debug shortcut.
+ * We still need to swallow this event. */
+ check_binding = 0;
+ } else if (db->key[1]) {
+ /* If we already ran a binding don't process another one since
+ * we can't keep track of all the binding keys that were
+ * pressed in order to swallow the release events. */
+ send = 1;
+ check_binding = 0;
+ }
+
+ if (check_binding) {
+ struct weston_compositor *ec = db->seat->compositor;
+
+ if (weston_compositor_run_debug_binding(ec, db->seat, time,
+ key, state)) {
+ /* We ran a binding so swallow the press and keep the
+ * grab to swallow the released too. */
+ send = 0;
+ terminate = 0;
+ db->key[1] = key;
+ } else {
+ /* Terminate the grab since the key pressed is not a
+ * debug binding key. */
+ send = 1;
+ terminate = 1;
+ }
+ }
+
+ if (send) {
+ resource = grab->keyboard->focus_resource;
+
+ if (resource) {
+ display = wl_client_get_display(resource->client);
+ serial = wl_display_next_serial(display);
+ wl_keyboard_send_key(resource, serial, time, key, state);
+ }
+ }
+
+ if (terminate) {
+ wl_keyboard_end_grab(grab->keyboard);
+ free(db);
+ }
+}
+
+static void
+debug_binding_modifiers(struct wl_keyboard_grab *grab, uint32_t serial,
+ uint32_t mods_depressed, uint32_t mods_latched,
+ uint32_t mods_locked, uint32_t group)
+{
+ struct wl_resource *resource;
+
+ resource = grab->keyboard->focus_resource;
+ if (!resource)
+ return;
+
+ wl_keyboard_send_modifiers(resource, serial, mods_depressed,
+ mods_latched, mods_locked, group);
+}
+
+struct wl_keyboard_grab_interface debug_binding_keyboard_grab = {
+ debug_binding_key,
+ debug_binding_modifiers
+};
+
+static void
+debug_binding(struct wl_seat *seat, uint32_t time, uint32_t key, void *data)
+{
+ struct debug_binding_grab *grab;
+
+ grab = calloc(1, sizeof *grab);
+ if (!grab)
+ return;
+
+ grab->seat = (struct weston_seat *) seat;
+ grab->key[0] = key;
+ grab->grab.interface = &debug_binding_keyboard_grab;
+ wl_keyboard_start_grab(seat->keyboard, &grab->grab);
+}
+
static void
force_kill_binding(struct wl_seat *seat, uint32_t time, uint32_t key,
void *data)
@@ -3696,10 +3812,6 @@
ec);
weston_compositor_add_key_binding(ec, KEY_BRIGHTNESSUP, 0,
backlight_binding, ec);
- weston_compositor_add_key_binding(ec, KEY_SPACE, mod | MODIFIER_SHIFT,
- debug_repaint_binding, shell);
- weston_compositor_add_key_binding(ec, KEY_SPACE, mod | MODIFIER_ALT,
- fan_debug_repaint_binding, shell);
weston_compositor_add_key_binding(ec, KEY_K, mod,
force_kill_binding, shell);
weston_compositor_add_key_binding(ec, KEY_UP, mod,
@@ -3723,6 +3835,14 @@
workspace_f_binding,
shell);
}
+
+ /* Debug bindings */
+ weston_compositor_add_key_binding(ec, KEY_SPACE, mod | MODIFIER_SHIFT,
+ debug_binding, shell);
+ weston_compositor_add_debug_binding(ec, KEY_R,
+ debug_repaint_binding, shell);
+ weston_compositor_add_debug_binding(ec, KEY_F,
+ fan_debug_repaint_binding, shell);
}
WL_EXPORT int