On Fri, Jul 27, 2012 at 02:58:50AM -0700, juan.j.z...@linux.intel.com wrote: > From: Juan Zhao <juan.j.z...@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 desktop's viewport.
This is good, but it doesn't work for multiple monitors. I think we need a different strategy for supporting multiple outputs. The outputs are rectangles laid out in the global coordinate system (output->x/y and output->current->width/height). Here's what I think should work: we add a new shell->active_region to weston_compositor, and pixman_region32_union all the outputs into that union and then subtract all the panel rectangles. It won't change very often so we can just keep that in desktop_shell and update it on monitor hotplug or resolution changes. To see if we can move a surface, we intersect the bounding box for the surface with shell->active_region and look at the boxes in the intersection. If all boxes are below a minimum width we cancel the horizontal movement (set dx = es->geometry.x). If all boxes are below a certain height we cancel the vertical movement. It's a slightly different heuristics than the bounding box you implemented below, but I think it works better. The bounding box approach will restrict motion event though there may be plenty of surface left on the screen to grab later. The region intersect approach just makes sure there's always a minimum amount of surface on the screen. Kristian > Signed-off-by: Juan Zhao <juan.j.z...@linux.intel.com> > --- > src/shell.c | 34 ++++++++++++++++++++++++++++++++++ > 1 file changed, 34 insertions(+) > > diff --git a/src/shell.c b/src/shell.c > index a9e4d4f..b85f3f6 100644 > --- a/src/shell.c > +++ b/src/shell.c > @@ -221,6 +221,13 @@ 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 bool > shell_surface_is_top_fullscreen(struct shell_surface *shsurf) > { > @@ -784,13 +791,40 @@ 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 bounding_x, bounding_y, view_x, view_y, view_w, view_h, > panel_height; > + int ncx = 0, ncy = 0; > + int boxsize = 10; > > if (!shsurf) > return; > > es = shsurf->surface; > + shsurf->output = shsurf->output ? shsurf->output > + : get_default_output(es->compositor); > + shell = shell_surface_get_shell(shsurf); > + panel_height = get_output_panel_height(shell, shsurf->output); > + > + weston_surface_from_global(es, wl_fixed_to_int(pointer->x), > + wl_fixed_to_int(pointer->y), > + &ncx, &ncy); > + ncx -= boxsize>>1; > + ncy -= boxsize>>1; > + > + bounding_x = dx + (ncx>0?ncx:0); > + bounding_y = dy + (ncy>0?ncy:0); > + > + view_x = 0; > + view_y = panel_height; > + view_w = shsurf->output->current->width; > + view_h = shsurf->output->current->height - panel_height; > + > + if ( !(bounding_x >= view_x && bounding_y >= view_y && > + bounding_x + boxsize <= view_x + view_w && > + bounding_y + boxsize <= view_y + view_h) ) > + return; > > weston_surface_configure(es, dx, dy, > es->geometry.width, es->geometry.height); > -- > 1.7.11 > _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel