[PATCH] Implement move surface key bindings.

Scott Moreau oreaus at gmail.com
Thu Feb 2 10:46:17 PST 2012


Super+F7 to initiate, arrow keys to move, Enter to accept and Esc to terminate. We need a way to move the cursor to an abitrary position such as a warp_pointer function, instead of just moving the pointer image. We also need a uniform way to set a pointer image outside of toytoolkit.
---
 src/compositor.c |    4 +-
 src/shell.c      |  151 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 152 insertions(+), 3 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index ab184ac..ab92bd6 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -1411,9 +1411,7 @@ notify_key(struct wl_input_device *device,
 		*k = key;
 	}
 
-	if (device->keyboard_focus_resource)
-		wl_resource_post_event(device->keyboard_focus_resource,
-				       WL_INPUT_DEVICE_KEY, time, key, state);
+	device->grab->interface->key(device->grab, time, key, state);
 }
 
 WL_EXPORT void
diff --git a/src/shell.c b/src/shell.c
index 168443b..c7e277e 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -114,6 +114,7 @@ struct weston_move_grab {
 	struct wl_grab grab;
 	struct weston_surface *surface;
 	int32_t dx, dy;
+	int32_t origin_x, origin_y;
 };
 
 struct rotate_grab {
@@ -183,10 +184,73 @@ move_grab_button(struct wl_grab *grab,
 	}
 }
 
+static void
+move_grab_key(struct wl_grab *grab,
+		 uint32_t time, int32_t key, int32_t state)
+{
+	if (state == 0)
+		return;
+
+	struct wl_input_device *device = grab->input_device;
+	struct weston_move_grab *move = (struct weston_move_grab *) grab;
+	struct weston_surface *es = move->surface;
+	int32_t x_offset = 0;
+	int32_t y_offset = 0;
+	int increment = 20;
+
+	switch (key) {
+		case KEY_UP:
+			y_offset -= increment;
+			break;
+		case KEY_LEFT:
+			x_offset -= increment;
+			break;
+		case KEY_RIGHT:
+			x_offset += increment;
+			break;
+		case KEY_DOWN:
+			y_offset += increment;
+			break;
+		case KEY_ENTER:
+			wl_input_device_end_grab(device, time);
+			free(grab);
+			return;		
+		case KEY_ESC:
+			weston_surface_configure(es,
+						 move->origin_x,
+						 move->origin_y,
+						 es->geometry.width, es->geometry.height);
+			/* FIXME: Actually warp pointer instead
+			 * of just moving the cursor image */
+			notify_motion(device, time,
+							abs(move->dx) + es->geometry.x,
+							abs(move->dy) + es->geometry.y);
+			wl_input_device_end_grab(device, time);
+			free(grab);
+			return;
+		default:
+			return;
+	}
+
+	if (x_offset || y_offset) {
+		weston_surface_configure(es,
+					 x_offset + es->geometry.x,
+					 y_offset + es->geometry.y,
+					 es->geometry.width, es->geometry.height);
+		/* FIXME: Actually warp pointer instead
+		 * of just moving the cursor image.
+		 * Also, need a way to set cursor image. */
+		notify_motion(device, time,
+						abs(move->dx) + es->geometry.x,
+						abs(move->dy) + es->geometry.y);
+	}
+}
+
 static const struct wl_grab_interface move_grab_interface = {
 	noop_grab_focus,
 	move_grab_motion,
 	move_grab_button,
+	move_grab_key,
 };
 
 static int
@@ -212,6 +276,37 @@ weston_surface_move(struct weston_surface *es,
 	return 0;
 }
 
+static int
+weston_surface_keyboard_move(struct weston_surface *es,
+		    struct weston_input_device *wd, uint32_t time)
+{
+	struct weston_move_grab *move;
+
+	move = malloc(sizeof *move);
+	if (!move)
+		return -1;
+
+	move->grab.interface = &move_grab_interface;
+	move->dx = es->geometry.x - ((es->geometry.width / 2) + es->geometry.x);
+	move->dy = es->geometry.y - ((es->geometry.height / 2) + es->geometry.y);
+	move->origin_x = es->geometry.x;
+	move->origin_y = es->geometry.y;
+	move->surface = es;
+
+	/* FIXME: Actually warp pointer instead
+	 * of just moving the cursor image */
+	notify_motion(&wd->input_device, time,
+					abs(move->dx) + es->geometry.x,
+					abs(move->dy) + es->geometry.y);
+
+	wl_input_device_start_grab(&wd->input_device, &move->grab, time);
+
+	wl_input_device_set_keyboard_focus(&wd->input_device,
+					  &es->surface, time);
+
+	return 0;
+}
+
 static void
 shell_surface_move(struct wl_client *client, struct wl_resource *resource,
 		   struct wl_resource *input_resource, uint32_t time)
@@ -276,10 +371,17 @@ resize_grab_button(struct wl_grab *grab,
 	}
 }
 
+static void
+resize_grab_key(struct wl_grab *grab,
+		   uint32_t time, int32_t key, int32_t state)
+{
+}
+
 static const struct wl_grab_interface resize_grab_interface = {
 	noop_grab_focus,
 	resize_grab_motion,
 	resize_grab_button,
+	resize_grab_key,
 };
 
 static int
@@ -502,10 +604,17 @@ popup_grab_button(struct wl_grab *grab,
 		shsurf->popup.initial_up = 1;
 }
 
+static void
+popup_grab_key(struct wl_grab *grab,
+		   uint32_t time, int32_t key, int32_t state)
+{
+}
+
 static const struct wl_grab_interface popup_grab_interface = {
 	popup_grab_focus,
 	popup_grab_motion,
 	popup_grab_button,
+	popup_grab_key,
 };
 
 static void
@@ -917,6 +1026,39 @@ move_binding(struct wl_input_device *device, uint32_t time,
 }
 
 static void
+move_binding_key(struct wl_input_device *device, uint32_t time,
+	     uint32_t key, uint32_t button, uint32_t state, void *data)
+{
+	if (!device->keyboard_focus_resource)
+		return;
+
+	struct weston_surface *surface =
+		(struct weston_surface *) device->keyboard_focus;
+	struct shell_surface *shsurf;
+
+	if (surface == NULL)
+		return;
+
+	shsurf = get_shell_surface(surface);
+	if (!shsurf)
+		return;
+
+	switch (shsurf->type) {
+		case SHELL_SURFACE_NONE:
+		case SHELL_SURFACE_PANEL:
+		case SHELL_SURFACE_BACKGROUND:
+		case SHELL_SURFACE_LOCK:
+		case SHELL_SURFACE_SCREENSAVER:
+			return;
+		default:
+			break;
+	}
+
+	weston_surface_keyboard_move(surface,
+					(struct weston_input_device *) device, time);
+}
+
+static void
 resize_binding(struct wl_input_device *device, uint32_t time,
 	       uint32_t key, uint32_t button, uint32_t state, void *data)
 {
@@ -1040,10 +1182,17 @@ rotate_grab_button(struct wl_grab *grab,
 	}
 }
 
+static void
+rotate_grab_key(struct wl_grab *grab,
+		   uint32_t time, int32_t key, int32_t state)
+{
+}
+
 static const struct wl_grab_interface rotate_grab_interface = {
 	noop_grab_focus,
 	rotate_grab_motion,
 	rotate_grab_button,
+	rotate_grab_key,
 };
 
 static void
@@ -1638,6 +1787,8 @@ shell_init(struct weston_compositor *ec)
 
 	weston_compositor_add_binding(ec, 0, BTN_LEFT, MODIFIER_SUPER,
 				    move_binding, shell);
+	weston_compositor_add_binding(ec, KEY_F7, 0, MODIFIER_SUPER,
+				    move_binding_key, shell);
 	weston_compositor_add_binding(ec, 0, BTN_MIDDLE, MODIFIER_SUPER,
 				    resize_binding, shell);
 	weston_compositor_add_binding(ec, KEY_BACKSPACE, 0,
-- 
1.7.4.1



More information about the wayland-devel mailing list