[PATCH weston 4/5] shell: keyboard focus with sub-surfaces

Pekka Paalanen ppaalanen at gmail.com
Fri Dec 21 04:04:03 PST 2012


The shell needs to redirect some actions to the parent surface, when
they originally target a sub-surface. This patch implements the
following:
- When the activation binding (left button click) targets a sub-surface,
  activate the parent surface instead. This also means, that a keyboard
  focus should never be on a sub-surface, but pointer (and touch) foci
  can.
- Move, resize, and rotate bindings always target the parent surface.
- Opacity (full-surface alpha) binding targets the parent surface. This
  is broken, because it should change the opacity of the whole compound
  window, which is difficult to implement in the renderer.

workspace_manager_move_surface(): is it expected and legal for this to
be called for sub-surfaces?

take_surface_to_workspace_by_seat(): I guess this really doesn't need
the weston_surface_get_parent call, since keyboard focus is supposed to
never be on a sub-surface.

move_surface_to_workspace(): like above, should be ok, as keyboard focus
is not a sub-surface.
---
 src/compositor.c |   13 +++++++++++++
 src/compositor.h |    3 +++
 src/shell.c      |    9 +++++++++
 3 files changed, 25 insertions(+), 0 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index 270b196..f00d5a3 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -1643,6 +1643,19 @@ subsurface_configure(struct weston_surface *surface, int32_t dx, int32_t dy)
 	}
 }
 
+WL_EXPORT struct weston_surface *
+weston_surface_get_parent(struct weston_surface *surface)
+{
+	struct weston_subsurface *sub;
+
+	while (surface && surface->configure == subsurface_configure) {
+		sub = surface->private;
+		surface = sub->parent;
+	}
+
+	return surface;
+}
+
 static void
 subsurface_set_position(struct wl_client *client,
 			struct wl_resource *resource, int32_t x, int32_t y)
diff --git a/src/compositor.h b/src/compositor.h
index c6c4775..0054382 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -727,6 +727,9 @@ weston_surface_move_to_plane(struct weston_surface *surface,
 void
 weston_surface_unmap(struct weston_surface *surface);
 
+struct weston_surface *
+weston_surface_get_parent(struct weston_surface *surface);
+
 void
 weston_buffer_post_release(struct wl_buffer *buffer);
 
diff --git a/src/shell.c b/src/shell.c
index fe9c55e..cf2edca 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -865,6 +865,7 @@ move_surface_to_workspace(struct desktop_shell *shell,
 	wl_list_insert(&to->layer.surface_list, &surface->layer_link);
 
 	drop_focus_state(shell, from, surface);
+	/* XXX: what about foci on sub-surfaces? */
 	wl_list_for_each(seat, &shell->compositor->seat_list, link)
 		if (seat->has_keyboard &&
 		    seat->keyboard.focus == &surface->surface)
@@ -886,6 +887,7 @@ take_surface_to_workspace_by_seat(struct desktop_shell *shell,
 	struct workspace *to;
 	struct focus_state *state;
 
+	surface = weston_surface_get_parent(surface);
 	if (surface == NULL ||
 	    index == shell->workspaces.current)
 		return;
@@ -944,6 +946,7 @@ workspace_manager_move_surface(struct wl_client *client,
 	struct weston_surface *surface =
 		(struct weston_surface *) surface_resource;
 
+	/* XXX: for a sub-surface, move the parent surface or fail? */
 	move_surface_to_workspace(shell, surface, workspace);
 }
 
@@ -2341,6 +2344,7 @@ move_binding(struct wl_seat *seat, uint32_t time, uint32_t button, void *data)
 		(struct weston_surface *) seat->pointer->focus;
 	struct shell_surface *shsurf;
 
+	surface = weston_surface_get_parent(surface);
 	if (surface == NULL)
 		return;
 
@@ -2360,6 +2364,7 @@ resize_binding(struct wl_seat *seat, uint32_t time, uint32_t button, void *data)
 	int32_t x, y;
 	struct shell_surface *shsurf;
 
+	surface = weston_surface_get_parent(surface);
 	if (surface == NULL)
 		return;
 
@@ -2398,6 +2403,8 @@ surface_opacity_binding(struct wl_seat *seat, uint32_t time, uint32_t axis,
 	struct weston_surface *surface =
 		(struct weston_surface *) seat->pointer->focus;
 
+	/* XXX: broken for windows containing sub-surfaces */
+	surface = weston_surface_get_parent(surface);
 	if (surface == NULL)
 		return;
 
@@ -2588,6 +2595,7 @@ rotate_binding(struct wl_seat *seat, uint32_t time, uint32_t button,
 	float dx, dy;
 	float r;
 
+	base_surface = weston_surface_get_parent(base_surface);
 	if (base_surface == NULL)
 		return;
 
@@ -2703,6 +2711,7 @@ click_to_activate_binding(struct wl_seat *seat, uint32_t time, uint32_t button,
 	struct weston_surface *upper;
 
 	focus = (struct weston_surface *) seat->pointer->focus;
+	focus = weston_surface_get_parent(focus);
 	if (!focus)
 		return;
 
-- 
1.7.8.6



More information about the wayland-devel mailing list