diff options
author | Tiago Vignatti <tiago.vignatti@intel.com> | 2012-09-20 14:38:05 +0300 |
---|---|---|
committer | Tiago Vignatti <tiago.vignatti@intel.com> | 2012-09-25 10:42:06 +0300 |
commit | 16477161c8d0af39bf56541b0c74403a72672c0a (patch) | |
tree | 211e5f3b3dba1f85799472ee83b30272b31b97b6 | |
parent | d8563ac2794404e61e93c64696d74c4dce18cf41 (diff) |
xwayland: Handle configure event for improved resizingxwayland-1.12
We strictly need that for dealing with the "grab on top or left" resize case.
Signed-off-by: Tiago Vignatti <tiago.vignatti@intel.com>
-rw-r--r-- | hw/xfree86/xwayland/xserver.xml | 29 | ||||
-rw-r--r-- | hw/xfree86/xwayland/xwayland-private.h | 4 | ||||
-rw-r--r-- | hw/xfree86/xwayland/xwayland-window.c | 34 | ||||
-rw-r--r-- | hw/xfree86/xwayland/xwayland.c | 31 |
4 files changed, 69 insertions, 29 deletions
diff --git a/hw/xfree86/xwayland/xserver.xml b/hw/xfree86/xwayland/xserver.xml index f59303d93..588ad9418 100644 --- a/hw/xfree86/xwayland/xserver.xml +++ b/hw/xfree86/xwayland/xserver.xml @@ -43,13 +43,22 @@ <arg name="id" type="uint"/> </event> - <event name="position"> - <description summary="suggest global window coordinates"> + <event name="configure"> + <description summary="XXX"> + The configure event asks the client to resize its surface. + The size is a hint, in the sense that the client is free to + ignore it if it doesn't resize, pick a smaller size (to + satisfy aspect ration or resize in steps of NxM pixels). The + client is free to dismiss all but the last configure event it + received. </description> <arg name="id" type="uint"/> <arg name="x" type="int"/> <arg name="y" type="int"/> + <arg name="width" type="int"/> + <arg name="height" type="int"/> + <arg name="edges" type="uint"/> </event> </interface> @@ -111,22 +120,6 @@ <arg name="edges" type="uint"/> </request> - <event name="configure"> - <description summary="suggest resize"> - The configure event asks the client to resize its surface. - The size is a hint, in the sense that the client is free to - ignore it if it doesn't resize, pick a smaller size (to - satisfy aspect ration or resize in steps of NxM pixels). The - client is free to dismiss all but the last configure event it - received. - </description> - - <arg name="id" type="uint"/> - <arg name="edges" type="uint"/> - <arg name="width" type="int"/> - <arg name="height" type="int"/> - </event> - <event name="state"> <arg name="id" type="uint"/> <arg name="activate" type="uint"/> diff --git a/hw/xfree86/xwayland/xwayland-private.h b/hw/xfree86/xwayland/xwayland-private.h index 58720f929..cbb309cf1 100644 --- a/hw/xfree86/xwayland/xwayland-private.h +++ b/hw/xfree86/xwayland/xwayland-private.h @@ -34,6 +34,7 @@ struct xwl_window { DamagePtr damage; struct xorg_list link; struct xorg_list link_damage; + int dx, dy, last_dx, last_dy, old_width, old_height; }; struct xwl_output; @@ -102,7 +103,8 @@ struct xwl_seat { struct xwl_screen *xwl_screen_get(ScreenPtr screen); void -xwl_window_attach(struct xwl_window *xwl_window, PixmapPtr pixmap); +xwl_window_attach(struct xwl_window *xwl_window, PixmapPtr pixmap, + int dx, int dy); void xwayland_screen_preinit_output(struct xwl_screen *xwl_screen, ScrnInfoPtr scrninfo); diff --git a/hw/xfree86/xwayland/xwayland-window.c b/hw/xfree86/xwayland/xwayland-window.c index 892e7dbaa..2c5ad9607 100644 --- a/hw/xfree86/xwayland/xwayland-window.c +++ b/hw/xfree86/xwayland/xwayland-window.c @@ -60,7 +60,8 @@ static const struct wl_callback_listener free_pixmap_listener = { }; void -xwl_window_attach(struct xwl_window *xwl_window, PixmapPtr pixmap) +xwl_window_attach(struct xwl_window *xwl_window, PixmapPtr pixmap, + int dx, int dy) { struct xwl_screen *xwl_screen = xwl_window->xwl_screen; struct wl_callback *callback; @@ -77,7 +78,8 @@ xwl_window_attach(struct xwl_window *xwl_window, PixmapPtr pixmap) return; } - wl_surface_attach(xwl_window->surface, xwl_window->buffer, 0, 0); + wl_surface_attach(xwl_window->surface, xwl_window->buffer, + dx, dy); wl_surface_damage(xwl_window->surface, 0, 0, pixmap->drawable.width, pixmap->drawable.height); @@ -191,7 +193,12 @@ xwl_realize_window(WindowPtr window) ErrorF("wl_display_create_surface failed\n"); return FALSE; } - + xwl_window->last_dx = window->drawable.width; + xwl_window->last_dy = window->drawable.height; + xwl_window->old_width = window->drawable.width; + xwl_window->old_height = window->drawable.height; + xwl_window->dx = 0; + xwl_window->dy = 0; wl_surface_set_user_data(xwl_window->surface, xwl_window); dixSetPrivate(&window->devPrivates, @@ -260,6 +267,7 @@ xwl_set_window_pixmap(WindowPtr window, PixmapPtr pixmap) ScreenPtr screen = window->drawable.pScreen; struct xwl_screen *xwl_screen; struct xwl_window *xwl_window; + int dx = 0, dy = 0; xwl_screen = xwl_screen_get(screen); @@ -270,8 +278,24 @@ xwl_set_window_pixmap(WindowPtr window, PixmapPtr pixmap) xwl_window = dixLookupPrivate(&window->devPrivates, &xwl_window_private_key); - if (xwl_window) - xwl_window_attach(xwl_window, pixmap); + if (!xwl_window) + return; + + if (xwl_window->dx && pixmap->drawable.width != xwl_window->old_width) + dx = xwl_window->old_width - pixmap->drawable.width; + + if (xwl_window->dy && pixmap->drawable.height != xwl_window->old_height) + dy = xwl_window->old_height - pixmap->drawable.height; + + ErrorF("%s: ** %d %d (%d %d)\n", __func__, dx, dy, + xwl_window->dx, xwl_window->dy); + xwl_window_attach(xwl_window, pixmap, dx, dy); + + xwl_window->dx = xwl_window->dx - dx; + xwl_window->dy = xwl_window->dy - dy; + + xwl_window->old_width = pixmap->drawable.width; + xwl_window->old_height = pixmap->drawable.height; } static void diff --git a/hw/xfree86/xwayland/xwayland.c b/hw/xfree86/xwayland/xwayland.c index dfe6da315..ba8dc8d54 100644 --- a/hw/xfree86/xwayland/xwayland.c +++ b/hw/xfree86/xwayland/xwayland.c @@ -81,6 +81,8 @@ xwl_get_map(void *data, struct xserver *xserver, int id) ScreenPtr screen = xwl_screen->screen; WindowPtr pWin; + ErrorF("%s\n", __func__); + xorg_list_for_each_entry_safe(xwl_window, wtmp, &xwl_screen->window_list, link) { pWin = xwl_window->window; @@ -88,24 +90,29 @@ xwl_get_map(void *data, struct xserver *xserver, int id) xserver_set_window_surface(xwl_screen->xserver, xwl_window->surface, pWin->drawable.id); - xwl_window_attach(xwl_window, (*screen->GetWindowPixmap)(pWin)); + xwl_window_attach(xwl_window, (*screen->GetWindowPixmap)(pWin), + 0, 0); return; } } } static void -xwl_get_position(void *data, struct xserver *xserver, uint32_t id, int x, int y) +xwl_handle_configure(void *data, struct xserver *xserver, uint32_t id, + int x, int y, int width, int height, uint32_t edges) { struct xwl_screen *xwl_screen = data; struct xwl_window *xwl_window, *wtmp; WindowPtr pWin; ClientPtr pClient; int err; - XID vlist[2]; + XID vlist[4]; + uint32_t mask = CWX | CWY | CWWidth | CWHeight; vlist[0] = x; vlist[1] = y; + vlist[2] = width; + vlist[3] = height; xorg_list_for_each_entry_safe(xwl_window, wtmp, &xwl_screen->window_list, link) { @@ -120,7 +127,21 @@ xwl_get_position(void *data, struct xserver *xserver, uint32_t id, int x, int y) return; } - ConfigureWindow(pWin, CWX | CWY, vlist, pClient); + /* dx and dy are produced here, wait X server requests to be + * processed (in special XConfigureWindow), and so only then they + * are consumed at xwl_set_window_pixmap() */ + if (edges & WL_SHELL_SURFACE_RESIZE_LEFT) + xwl_window->dx = xwl_window->dx + xwl_window->last_dx - width; + + if (edges & WL_SHELL_SURFACE_RESIZE_TOP) + xwl_window->dy = xwl_window->dy + xwl_window->last_dy - height; + + xwl_window->last_dx = width; + xwl_window->last_dy = height; + + ErrorF("%s: (%d, %d) %dx%d ** (%d %d)\n", __func__, x, y, + width, height, xwl_window->dx, xwl_window->dy); + ConfigureWindow(pWin, mask, vlist, pClient); return; } @@ -130,7 +151,7 @@ xwl_get_position(void *data, struct xserver *xserver, uint32_t id, int x, int y) static const struct xserver_listener xserver_listener = { xwl_get_map, - xwl_get_position + xwl_handle_configure }; static void |