[PATCH weston 08/11] shell: Restack surface when dragged to another output

Jonas Ådahl jadahl at gmail.com
Sat Jan 26 06:33:38 PST 2013


When moving a surface from one output to another using the move grab
binding, restack the surface on the current workspace in the container
associated with the output the surface was moved to.

Signed-off-by: Jonas Ådahl <jadahl at gmail.com>
---
 src/compositor.c |    5 +++++
 src/compositor.h |    1 +
 src/shell.c      |   34 +++++++++++++++++++++++++++++++---
 3 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index 207a216..7aba77d 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -269,6 +269,7 @@ weston_surface_create(struct weston_compositor *compositor)
 
 	wl_list_init(&surface->link);
 	wl_list_init(&surface->layer_link);
+	wl_signal_init(&surface->frame_signal);
 
 	surface->surface.resource.client = NULL;
 
@@ -1122,6 +1123,10 @@ weston_output_repaint(struct weston_output *output, uint32_t msecs)
 		animation->frame_counter++;
 		animation->frame(animation, output, msecs);
 	}
+
+	wl_list_for_each(es, &ec->surface_list, link)
+		if (es->output == output)
+			wl_signal_emit(&es->frame_signal, es);
 }
 
 static int
diff --git a/src/compositor.h b/src/compositor.h
index 57d7442..041f910 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -391,6 +391,7 @@ struct weston_surface {
 	pixman_region32_t input;
 	struct wl_list link;
 	struct wl_list layer_link;
+	struct wl_signal frame_signal;
 	float alpha;
 	struct weston_plane *plane;
 
diff --git a/src/shell.c b/src/shell.c
index be4cf0a..c8ab636 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -224,6 +224,9 @@ struct shell_grab {
 struct weston_move_grab {
 	struct shell_grab base;
 	wl_fixed_t dx, dy;
+
+	struct weston_output *output;
+	struct wl_listener redraw_listener;
 };
 
 struct rotate_grab {
@@ -1150,14 +1153,15 @@ static void
 move_grab_button(struct wl_pointer_grab *grab,
 		 uint32_t time, uint32_t button, uint32_t state_w)
 {
-	struct shell_grab *shell_grab = container_of(grab, struct shell_grab,
-						    grab);
+	struct weston_move_grab *move = (struct weston_move_grab *) grab;
 	struct wl_pointer *pointer = grab->pointer;
 	enum wl_pointer_button_state state = state_w;
 
 	if (pointer->button_count == 0 &&
 	    state == WL_POINTER_BUTTON_STATE_RELEASED) {
-		shell_grab_end(shell_grab);
+		if (move->base.shsurf)
+			wl_list_remove(&move->redraw_listener.link);
+		shell_grab_end(&move->base);
 		free(grab);
 	}
 }
@@ -1168,6 +1172,25 @@ static const struct wl_pointer_grab_interface move_grab_interface = {
 	move_grab_button,
 };
 
+static void
+move_redraw_notify(struct wl_listener *listener, void *data)
+{
+	struct weston_move_grab *move = container_of(listener,
+						     struct weston_move_grab,
+						     redraw_listener);
+	struct shell_surface *shsurf = move->base.shsurf;
+	struct weston_output *output = shsurf->surface->output;
+	struct workspace_container *container;
+	struct workspace *ws;
+
+	if (output != move->output) {
+		move->output = output;
+		container = get_workspace_container(shsurf->shell, output->id);
+		ws = workspace_container_get_current(container);
+		workspace_restack_surface(ws, shsurf);
+	}
+}
+
 static int
 surface_move(struct shell_surface *shsurf, struct weston_seat *ws)
 {
@@ -1183,11 +1206,16 @@ surface_move(struct shell_surface *shsurf, struct weston_seat *ws)
 	if (!move)
 		return -1;
 
+	move->output = shsurf->surface->output;
 	move->dx = wl_fixed_from_double(shsurf->surface->geometry.x) -
 			ws->seat.pointer->grab_x;
 	move->dy = wl_fixed_from_double(shsurf->surface->geometry.y) -
 			ws->seat.pointer->grab_y;
 
+	move->redraw_listener.notify = move_redraw_notify;
+	wl_list_insert(&shsurf->surface->frame_signal.listener_list,
+		       &move->redraw_listener.link);
+
 	shell_grab_start(&move->base, &move_grab_interface, shsurf,
 			 ws->seat.pointer, DESKTOP_SHELL_CURSOR_MOVE);
 
-- 
1.7.10.4



More information about the wayland-devel mailing list