[PATCH v2] shell: moving drag surface refine

juan.j.zhao at linux.intel.com juan.j.zhao at linux.intel.com
Tue Jul 31 01:00:26 PDT 2012


From: Juan Zhao <juan.j.zhao at linux.intel.com>

When applications not directly based on toytoolkit, like simple-egl, efl
applications is grabbed and moved, they may be moved to the place under
the panel. Then they could not be grabbed again.
Don't allow the pointer's bounding box move across the shell's active_regions.

One more open question, I also added current output's check and did not enable
 it, and it works, should we need this?

Signed-off-by: Juan Zhao <juan.j.zhao at linux.intel.com>
---
 src/compositor-drm.c |   5 ++-
 src/compositor.h     |   2 +-
 src/shell.c          | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 106 insertions(+), 4 deletions(-)

diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index cd0395e..723ca13 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -1669,7 +1669,10 @@ update_outputs(struct drm_compositor *ec, struct udev_device *drm_device)
 		}
 	}
 
-	/* FIXME: handle zero outputs, without terminating */	
+	ec->base.shell_interface.reconf_active_regions(
+					ec->base.shell_interface.shell);
+
+	/* FIXME: handle zero outputs, without terminating */
 	if (ec->connector_allocator == 0)
 		wl_display_terminate(ec->base.wl_display);
 }
diff --git a/src/compositor.h b/src/compositor.h
index 22c0174..4ea47bd 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -88,7 +88,7 @@ struct weston_shell_interface {
 	int (*move)(struct shell_surface *shsurf, struct weston_seat *ws);
 	int (*resize)(struct shell_surface *shsurf,
 		      struct weston_seat *ws, uint32_t edges);
-
+	void (*reconf_active_regions)(void *shell);
 };
 
 struct weston_border {
diff --git a/src/shell.c b/src/shell.c
index a9e4d4f..09ebf73 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -124,6 +124,7 @@ struct desktop_shell {
 	uint32_t binding_modifier;
 	enum animation_type win_animation_type;
 	struct weston_surface *debug_repaint_surface;
+	pixman_region32_t active_regions;
 };
 
 enum shell_surface_type {
@@ -221,6 +222,17 @@ get_shell_surface(struct weston_surface *surface);
 static struct desktop_shell *
 shell_surface_get_shell(struct shell_surface *shsurf);
 
+static int
+get_output_panel_height(struct desktop_shell *shell,
+                        struct weston_output *output);
+
+static struct weston_output *
+get_default_output(struct weston_compositor *compositor);
+
+static void
+shell_active_regions_subtract(struct desktop_shell *shell, int32_t x,
+			       int32_t y, int32_t width, int32_t height);
+
 static bool
 shell_surface_is_top_fullscreen(struct shell_surface *shsurf)
 {
@@ -784,13 +796,44 @@ move_grab_motion(struct wl_pointer_grab *grab,
 	struct wl_pointer *pointer = grab->pointer;
 	struct shell_surface *shsurf = move->base.shsurf;
 	struct weston_surface *es;
+	struct desktop_shell *shell = NULL;
 	int dx = wl_fixed_to_int(pointer->x + move->dx);
 	int dy = wl_fixed_to_int(pointer->y + move->dy);
+	int boxsize = 4;
+	int bounding_x = wl_fixed_to_int(pointer->x) - boxsize;
+	int bounding_y = wl_fixed_to_int(pointer->y) - boxsize;
+	pixman_box32_t *e;
+	pixman_region32_t region;
 
 	if (!shsurf)
 		return;
 
 	es = shsurf->surface;
+	shell = shell_surface_get_shell(shsurf);
+
+	bounding_x = bounding_x>0 ? bounding_x:0;
+	bounding_y = bounding_y>0 ? bounding_y:0;
+	pixman_region32_init_rect(&region, bounding_x, bounding_y,
+				   boxsize<<1, boxsize<<1);
+
+	pixman_region32_intersect(&region, &region,
+				  &shell->active_regions);
+	/*FIXME: should be focus on the surface's output only?*/
+	/*
+	struct weston_output * current_output;
+	current_output = shsurf->output ? shsurf->output
+			                : get_default_output(es->compositor);
+	pixman_region32_intersect(&region, &region,
+				  &current_output->region);
+	*/
+	e = pixman_region32_extents(&region);
+	if (e->x2 - e->x1 <= boxsize) {
+		if(e->y2 - e->y1 <= boxsize)
+			return;
+		dx = (int)es->geometry.x;
+	}
+	if (e->y2 - e->y1 <= boxsize)
+		dy = (int)es->geometry.y;
 
 	weston_surface_configure(es, dx, dy,
 				 es->geometry.width, es->geometry.height);
@@ -1909,11 +1952,27 @@ desktop_shell_set_background(struct wl_client *client,
 }
 
 static void
+shell_active_regions_subtract(struct desktop_shell *shell, int32_t x,
+			       int32_t y, int32_t width, int32_t height)
+{
+	pixman_region32_t region;
+	pixman_region32_init_rect(&region, x, y, width, height);
+
+	pixman_region32_subtract(&shell->active_regions,
+				  &shell->active_regions, &region);
+}
+
+static void
 panel_configure(struct weston_surface *es, int32_t sx, int32_t sy)
 {
 	struct desktop_shell *shell = es->private;
 
 	configure_static_surface(es, &shell->panel_layer);
+	shell_active_regions_subtract( shell,
+				      (int32_t)es->geometry.x,
+				      (int32_t)es->geometry.y,
+				       es->geometry.width,
+				       es->geometry.height);
 }
 
 static void
@@ -3216,11 +3275,48 @@ shell_destroy(struct wl_listener *listener, void *data)
 		workspace_destroy(*ws);
 	wl_array_release(&shell->workspaces.array);
 
+	pixman_region32_fini(&shell->active_regions);
+
 	free(shell->screensaver.path);
 	free(shell);
 }
 
 static void
+shell_init_active_regions(struct weston_compositor *ec, struct desktop_shell *shell)
+{
+	struct weston_output *output;
+	pixman_region32_init(&shell->active_regions);
+	wl_list_for_each(output, &ec->output_list, link) {
+		pixman_region32_union(&shell->active_regions, &shell->active_regions,
+				&output->region);
+	}
+
+	return;
+}
+
+static void
+shell_reconf_active_regions(void *dshell)
+{
+	struct desktop_shell *shell = (struct desktop_shell *)dshell;
+	struct weston_surface *surface;
+
+	pixman_region32_fini(&shell->active_regions);
+	shell_init_active_regions(shell->compositor, shell);
+
+	wl_list_for_each(surface, &shell->panel_layer.surface_list, layer_link) {
+		if (!surface->output)
+			continue;
+
+		shell_active_regions_subtract( shell,
+				      (int32_t)surface->geometry.x,
+				      (int32_t)surface->geometry.y,
+				       surface->geometry.width,
+				       surface->geometry.height);
+	}
+
+}
+
+static void
 shell_add_bindings(struct weston_compositor *ec, struct desktop_shell *shell)
 {
 	uint32_t mod;
@@ -3266,9 +3362,9 @@ shell_add_bindings(struct weston_compositor *ec, struct desktop_shell *shell)
 				          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,
+	weston_compositor_add_key_binding(ec, KEY_U, mod,
 					  workspace_up_binding, shell);
-	weston_compositor_add_key_binding(ec, KEY_DOWN, mod,
+	weston_compositor_add_key_binding(ec, KEY_J, mod,
 					  workspace_down_binding, shell);
 
 	/* Add bindings for mod+F[1-6] for workspace 1 to 6. */
@@ -3317,6 +3413,7 @@ shell_init(struct weston_compositor *ec)
 	ec->shell_interface.set_transient = set_transient;
 	ec->shell_interface.move = surface_move;
 	ec->shell_interface.resize = surface_resize;
+	ec->shell_interface.reconf_active_regions = shell_reconf_active_regions;
 
 	wl_list_init(&shell->screensaver.surfaces);
 	wl_list_init(&shell->input_panel.surfaces);
@@ -3372,5 +3469,7 @@ shell_init(struct weston_compositor *ec)
 
 	shell_add_bindings(ec, shell);
 
+	shell_init_active_regions(ec, shell);
+
 	return 0;
 }
-- 
1.7.11



More information about the wayland-devel mailing list