diff options
author | Tiago Vignatti <tiago.vignatti@intel.com> | 2012-10-03 15:42:26 +0300 |
---|---|---|
committer | Tiago Vignatti <tiago.vignatti@intel.com> | 2012-10-03 15:42:26 +0300 |
commit | 9e66e570e85693ed5aafd27aacb20c5849d37a9d (patch) | |
tree | 3ff13ebaa0ccb0894070d1108c3cb1eae7d44430 | |
parent | c21f8a42d86ef4ff81c5f0c0158c16950505359e (diff) |
xwayland: Start to move to new subsurface protocolxwm-client-OLD
Still too much "multiple surfaces" rather than "subsurfaces". Working on it
now...
Signed-off-by: Tiago Vignatti <tiago.vignatti@intel.com>
-rw-r--r-- | clients/xwm.c | 6 | ||||
-rw-r--r-- | protocol/xserver.xml | 5 | ||||
-rw-r--r-- | src/compositor.h | 9 | ||||
-rw-r--r-- | src/shell.c | 269 | ||||
-rw-r--r-- | src/xwayland/window-manager.c | 36 |
5 files changed, 204 insertions, 121 deletions
diff --git a/clients/xwm.c b/clients/xwm.c index c5f9f50..c225c4a 100644 --- a/clients/xwm.c +++ b/clients/xwm.c @@ -627,8 +627,8 @@ xwm_create_frame(struct xwm_window *window, struct xwm *xwm) window_get_wl_surface(frame->window)); window_shell_surface_add_listener(frame->window, shsurf); - wl_shell_surface_set_xwayland(shsurf, window->id, -1, -1, - WL_SHELL_SURFACE_XWAYLAND_FRAME); + wl_shell_surface_set_subsurface(shsurf, NULL, 0, 0, + WL_SHELL_SURFACE_SUBSURFACE_TOPLEVEL); frame->widget = frame_create(frame->window, frame); window_set_user_data(frame->window, window); @@ -644,6 +644,8 @@ xwm_create_frame(struct xwm_window *window, struct xwm *xwm) window_schedule_resize(frame->window, width, height); + wm_frame_surface(xwm->wm, window_get_wl_surface(frame->window), + window->id); return frame; } diff --git a/protocol/xserver.xml b/protocol/xserver.xml index 588ad94..f672014 100644 --- a/protocol/xserver.xml +++ b/protocol/xserver.xml @@ -111,6 +111,11 @@ <arg name="id" type="uint"/> </request> + <request name="frame_surface"> + <arg name="surface" type="object" interface="wl_surface"/> + <arg name="xid" type="uint"/> + </request> + <request name="move"> <arg name="id" type="uint"/> </request> diff --git a/src/compositor.h b/src/compositor.h index 25d3a8b..044585a 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -81,10 +81,11 @@ struct weston_shell_interface { struct weston_surface *surface, const struct weston_shell_client *client); - void (*set_toplevel)(struct shell_surface *shsurf); - - void (*set_xwayland)(struct shell_surface *shsurf, int xid, - int x, int y, uint32_t flags); + void (*set_subsurface)(struct shell_surface *shsurf, + struct weston_surface *parent, + int x, int y, uint32_t method); + void (*set_subsurface_parent)(struct shell_surface *shsurf, + struct weston_surface *parent); int (*move)(struct shell_surface *shsurf, struct weston_seat *ws); int (*resize)(struct shell_surface *shsurf, struct weston_seat *ws, uint32_t edges); diff --git a/src/shell.c b/src/shell.c index e3c3730..efe9723 100644 --- a/src/shell.c +++ b/src/shell.c @@ -145,8 +145,7 @@ enum shell_surface_type { SHELL_SURFACE_FULLSCREEN, SHELL_SURFACE_MAXIMIZED, SHELL_SURFACE_POPUP, - - SHELL_SURFACE_XWAYLAND + SHELL_SURFACE_SUBSURFACE }; struct ping_timer { @@ -197,10 +196,10 @@ struct shell_surface { struct { int32_t x, y; - uint32_t flags; - int32_t xid; - struct shell_surface *tie; /* either XWM frame or X client */ - } xwayland; + uint32_t method; + struct weston_surface *parent; + struct weston_surface *child; /* XXX: one only */ + } subsurface; struct ping_timer *ping_timer; @@ -275,6 +274,43 @@ destroy_shell_grab_shsurf(struct wl_listener *listener, void *data) grab->shsurf = NULL; } +static struct shell_surface * +get_subsurface_parent(struct shell_surface *child) +{ + if (child->type != SHELL_SURFACE_SUBSURFACE) + return NULL; + + if (!child->subsurface.parent) + return NULL; + + return get_shell_surface(child->subsurface.parent); +} + +static struct shell_surface * +get_subsurface_child(struct shell_surface *parent) +{ + if (parent->type != SHELL_SURFACE_SUBSURFACE) + return NULL; + + if (!parent->subsurface.child) + return NULL; + + return get_shell_surface(parent->subsurface.child); +} + +/* returns parent or "next" child, depending the subsurface method */ +static struct shell_surface * +get_subsurface_relative(struct shell_surface *shsurf) +{ + if (shsurf->type != SHELL_SURFACE_SUBSURFACE) + return NULL; + + if (shsurf->subsurface.method == WL_SHELL_SURFACE_SUBSURFACE_TOPLEVEL) + return get_subsurface_child(shsurf); + else + return get_shell_surface(shsurf->subsurface.parent); +} + static void shell_grab_start(struct shell_grab *grab, const struct wl_pointer_grab_interface *interface, @@ -304,16 +340,16 @@ shell_grab_end(struct shell_grab *grab) { struct weston_compositor *compositor = grab->shsurf->surface->compositor; - struct shell_surface *shsurf_tmp, *shsurf = grab->shsurf; + struct shell_surface *relative, *shsurf = grab->shsurf; if (shsurf) wl_list_remove(&grab->shsurf_destroy_listener.link); - if (shsurf->type == SHELL_SURFACE_XWAYLAND) { - shsurf_tmp = shsurf->xwayland.tie; - if (shsurf_tmp) + if (shsurf->type == SHELL_SURFACE_SUBSURFACE) { + relative = get_subsurface_relative(shsurf); + if (relative) wl_signal_emit(&compositor->position_signal, - shsurf_tmp->surface); + relative->surface); } wl_signal_emit(&compositor->position_signal, grab->shsurf->surface); @@ -1011,7 +1047,7 @@ move_grab_motion(struct wl_pointer_grab *grab, { struct weston_move_grab *move = (struct weston_move_grab *) grab; struct wl_pointer *pointer = grab->pointer; - struct shell_surface *shsurf_x, *shsurf = move->base.shsurf; + struct shell_surface *relative, *shsurf = move->base.shsurf; struct weston_surface *es; int dx = wl_fixed_to_int(pointer->x + move->dx); int dy = wl_fixed_to_int(pointer->y + move->dy); @@ -1023,17 +1059,19 @@ move_grab_motion(struct wl_pointer_grab *grab, weston_surface_configure(es, dx, dy, es->geometry.width, es->geometry.height); - if (shsurf->type == SHELL_SURFACE_XWAYLAND) { - if (shsurf->xwayland.flags == WL_SHELL_SURFACE_XWAYLAND_FRAME) { + if (shsurf->type == SHELL_SURFACE_SUBSURFACE) { + if (shsurf->subsurface.method == + WL_SHELL_SURFACE_SUBSURFACE_TOPLEVEL) { dx += 32 + 6; dy += 32 + 27; } else { dx -= 32 + 6; dy -= 32 + 27; } - shsurf_x = shsurf->xwayland.tie; - if (shsurf_x) { - es = shsurf_x->surface; + + relative = get_subsurface_relative(shsurf); + if (relative) { + es = relative->surface; weston_surface_configure(es, dx, dy, es->geometry.width, es->geometry.height); } @@ -1118,7 +1156,7 @@ resize_grab_motion(struct wl_pointer_grab *grab, { struct weston_resize_grab *resize = (struct weston_resize_grab *) grab; struct wl_pointer *pointer = grab->pointer; - struct shell_surface *shsurf_x, *shsurf = resize->base.shsurf; + struct shell_surface *relative, *shsurf = resize->base.shsurf; int32_t width, height; wl_fixed_t from_x, from_y; wl_fixed_t to_x, to_y; @@ -1149,10 +1187,10 @@ resize_grab_motion(struct wl_pointer_grab *grab, shsurf->client->send_configure(shsurf->surface, resize->edges, width, height); - if (shsurf->type == SHELL_SURFACE_XWAYLAND) { - shsurf_x = shsurf->xwayland.tie; - if (shsurf_x) - shsurf_x->client->send_configure(shsurf_x->surface, + if (shsurf->type == SHELL_SURFACE_SUBSURFACE) { + relative = get_subsurface_relative(shsurf); + if (relative) + relative->client->send_configure(relative->surface, resize->edges, width, height); } } @@ -1504,7 +1542,7 @@ reset_shell_surface_type(struct shell_surface *surface) case SHELL_SURFACE_TOPLEVEL: case SHELL_SURFACE_TRANSIENT: case SHELL_SURFACE_POPUP: - case SHELL_SURFACE_XWAYLAND: + case SHELL_SURFACE_SUBSURFACE: break; } @@ -1524,8 +1562,8 @@ set_surface_type(struct shell_surface *shsurf) shsurf->next_type = SHELL_SURFACE_NONE; switch (shsurf->type) { - case SHELL_SURFACE_XWAYLAND: case SHELL_SURFACE_TOPLEVEL: + case SHELL_SURFACE_SUBSURFACE: break; case SHELL_SURFACE_TRANSIENT: weston_surface_set_position(surface, @@ -1596,38 +1634,65 @@ shell_surface_set_transient(struct wl_client *client, } static void -set_xwayland(struct shell_surface *shsurf, int xid, int x, int y, - uint32_t flags) +set_subsurface_parent(struct shell_surface *child, + struct weston_surface *parent_surface) { - struct workspace *ws = get_current_workspace(shsurf->shell); - struct weston_surface *es; - struct shell_surface *shsurf_tmp; - - shsurf->xwayland.x = x; - shsurf->xwayland.y = y; - shsurf->xwayland.xid = xid; - shsurf->xwayland.flags = flags; - shsurf->next_type = SHELL_SURFACE_XWAYLAND; - - /* tie Wayland window frame with its X client and vice-versa */ - wl_list_for_each(es, &ws->layer.surface_list, layer_link) { - shsurf_tmp = get_shell_surface(es); - if (shsurf_tmp->xwayland.xid == xid) { - shsurf->xwayland.tie = shsurf_tmp; - shsurf_tmp->xwayland.tie = shsurf; - break; - } + struct shell_surface *parent; + + if (!parent_surface) + return; + + child->subsurface.parent = parent_surface; + parent = get_shell_surface(parent_surface); + parent->subsurface.child = child->surface; + + /*TODO: send a parent_changed event? */ +} + +static void +shell_surface_set_subsurface_parent(struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *parent_resource) +{ + struct shell_surface *parent = resource->data; + struct weston_surface *parent_surface = parent_resource->data; + + set_subsurface_parent(parent, parent_surface); +} + +static void +set_subsurface(struct shell_surface *shsurf, struct weston_surface *parent, + int x, int y, uint32_t method) +{ + shsurf->subsurface.method = method; + shsurf->next_type = SHELL_SURFACE_SUBSURFACE; + + switch (method) { + case WL_SHELL_SURFACE_SUBSURFACE_TOPLEVEL: + set_subsurface_parent(shsurf, NULL); + break; + case WL_SHELL_SURFACE_SUBSURFACE_CHILD: + case WL_SHELL_SURFACE_SUBSURFACE_TRANSIENT: + shsurf->subsurface.x = x; + shsurf->subsurface.y = y; + set_subsurface_parent(shsurf, parent); + break; } } static void -shell_surface_set_xwayland(struct wl_client *client, - struct wl_resource *resource, int xid, - int x, int y, uint32_t flags) +shell_surface_set_subsurface(struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *parent_resource, + int x, int y, uint32_t method) { struct shell_surface *shsurf = resource->data; + struct weston_surface *parent = NULL; + + if (parent_resource) + parent = parent_resource->data; - set_xwayland(shsurf, xid, x, y, flags); + set_subsurface(shsurf, parent, x, y, method); } static struct desktop_shell * @@ -1979,7 +2044,8 @@ static const struct wl_shell_surface_interface shell_surface_implementation = { shell_surface_set_fullscreen, shell_surface_set_popup, shell_surface_set_maximized, - shell_surface_set_xwayland, + shell_surface_set_subsurface, + shell_surface_set_subsurface_parent, shell_surface_set_title, shell_surface_set_class }; @@ -2000,8 +2066,8 @@ destroy_shell_surface(struct shell_surface *shsurf) if (shsurf->fullscreen.black_surface) weston_surface_destroy(shsurf->fullscreen.black_surface); - if (shsurf->type == SHELL_SURFACE_XWAYLAND && shsurf->xwayland.tie) - shsurf->xwayland.tie->xwayland.tie = NULL; + if (shsurf->type == SHELL_SURFACE_SUBSURFACE) + /* XXX */ /* As destroy_resource() use wl_list_for_each_safe(), * we can always remove the listener. @@ -2702,24 +2768,18 @@ activate(struct desktop_shell *shell, struct weston_surface *surface, { struct focus_state *state; struct workspace *ws = get_current_workspace(shell); - struct weston_surface *es = NULL, *xframe = NULL; + struct weston_surface *es = NULL; struct shell_surface *shsurf = get_shell_surface(surface); + struct shell_surface *parent = NULL, *child = NULL; if (!shsurf) return; - if (get_shell_surface_type(surface) == SHELL_SURFACE_XWAYLAND) { - if (shsurf->xwayland.flags == WL_SHELL_SURFACE_XWAYLAND_FRAME) { - if (shsurf->xwayland.tie) { - xframe = shsurf->surface; - es = shsurf->xwayland.tie->surface; - } - } else { - if (shsurf->xwayland.tie) { - es = shsurf->surface; - xframe = shsurf->xwayland.tie->surface; - } - } + if (get_shell_surface_type(surface) == SHELL_SURFACE_SUBSURFACE) { + parent = get_subsurface_parent(shsurf); + child = get_subsurface_child(shsurf); + if (child) + es = child->surface; } if (!es) @@ -2744,8 +2804,11 @@ activate(struct desktop_shell *shell, struct weston_surface *surface, break; default: lower_fullscreen_layer(shell); - if (xframe) - weston_surface_restack(xframe, &ws->layer.surface_list); + + /* restack subsurface whereas toplevel is always on the top */ + if (parent && parent->surface) + weston_surface_restack(parent->surface, + &ws->layer.surface_list); weston_surface_restack(es, &ws->layer.surface_list); break; } @@ -2968,51 +3031,35 @@ weston_surface_set_initial_position (struct weston_surface *surface, } static void -shell_xwayland_set_position(struct shell_surface *shsurf, - struct weston_surface *surface) +shell_subsurface_set_position(struct shell_surface *shsurf, + struct weston_surface *surface) { struct desktop_shell *shell = shsurf->shell; - struct shell_surface *shsurf_tmp; - struct workspace *ws = get_current_workspace(shsurf->shell); - struct weston_surface *es; - - switch (shsurf->xwayland.flags) { - case WL_SHELL_SURFACE_XWAYLAND_FRAME: - /* if toplevel was mapped before the frame, then - * layer.surface_list still didn't get that at set_xwayland - * time and we need to tie both again here */ - wl_list_for_each(es, &ws->layer.surface_list, layer_link) { - shsurf_tmp = get_shell_surface(es); - if (shsurf_tmp->xwayland.xid == shsurf->xwayland.xid) { - shsurf->xwayland.tie = shsurf_tmp; - shsurf_tmp->xwayland.tie = shsurf; - - weston_surface_set_position(shsurf_tmp->surface, - shsurf_tmp->xwayland.x + shsurf->xwayland.x, - shsurf_tmp->xwayland.y + shsurf->xwayland.y); - break; - } - } + struct shell_surface *pshsurf; + switch (shsurf->subsurface.method) { + case WL_SHELL_SURFACE_SUBSURFACE_TOPLEVEL: weston_surface_set_initial_position(surface, shell); - shsurf->xwayland.x = surface->geometry.x; - shsurf->xwayland.y = surface->geometry.y; + shsurf->subsurface.x = surface->geometry.x; + shsurf->subsurface.y = surface->geometry.y; break; - case WL_SHELL_SURFACE_XWAYLAND_TOPLEVEL: - shsurf_tmp = shsurf->xwayland.tie; - if (shsurf_tmp) + case WL_SHELL_SURFACE_SUBSURFACE_CHILD: + pshsurf = get_shell_surface(shsurf->subsurface.parent); + if (pshsurf) weston_surface_set_position(surface, - shsurf_tmp->xwayland.x + shsurf->xwayland.x, - shsurf_tmp->xwayland.y + shsurf->xwayland.y); + pshsurf->subsurface.x + shsurf->subsurface.x, + pshsurf->subsurface.y + shsurf->subsurface.y); else { weston_surface_set_initial_position(surface, shell); - shsurf->xwayland.x = surface->geometry.x; - shsurf->xwayland.y = surface->geometry.y; + shsurf->subsurface.x = surface->geometry.x; + shsurf->subsurface.y = surface->geometry.y; } break; - case WL_SHELL_SURFACE_XWAYLAND_TRANSIENT: - weston_surface_set_position(surface, shsurf->xwayland.x, - shsurf->xwayland.y); + case WL_SHELL_SURFACE_SUBSURFACE_TRANSIENT: + /* TODO: xwayland will have to send the correct geom here, + * i.e. global? */ + weston_surface_set_position(surface, shsurf->subsurface.x, + shsurf->subsurface.y); break; } } @@ -3055,8 +3102,8 @@ map(struct desktop_shell *shell, struct weston_surface *surface, surface->geometry.x + sx, surface->geometry.y + sy); break; - case SHELL_SURFACE_XWAYLAND: - shell_xwayland_set_position(shsurf, surface); + case SHELL_SURFACE_SUBSURFACE: + shell_subsurface_set_position(shsurf, surface); break; default: ; @@ -3085,9 +3132,9 @@ map(struct desktop_shell *shell, struct weston_surface *surface, } switch (surface_type) { - case SHELL_SURFACE_XWAYLAND: - if (shsurf->xwayland.flags == - WL_SHELL_SURFACE_XWAYLAND_TRANSIENT) + case SHELL_SURFACE_SUBSURFACE: + if (shsurf->subsurface.method == + WL_SHELL_SURFACE_SUBSURFACE_TRANSIENT) break; case SHELL_SURFACE_TRANSIENT: if (shsurf->transient.flags == @@ -3467,9 +3514,9 @@ switcher_next(struct switcher *switcher) wl_list_for_each(surface, &ws->layer.surface_list, layer_link) { shsurf = get_shell_surface(surface); switch (get_shell_surface_type(surface)) { - case SHELL_SURFACE_XWAYLAND: - if (shsurf->xwayland.flags != - WL_SHELL_SURFACE_XWAYLAND_TOPLEVEL) + case SHELL_SURFACE_SUBSURFACE: + if (shsurf->subsurface.method != + WL_SHELL_SURFACE_SUBSURFACE_CHILD) break; case SHELL_SURFACE_TOPLEVEL: case SHELL_SURFACE_FULLSCREEN: @@ -3892,8 +3939,8 @@ module_init(struct weston_compositor *ec) ec->ping_handler = ping_handler; ec->shell_interface.shell = shell; ec->shell_interface.create_shell_surface = create_shell_surface; - ec->shell_interface.set_toplevel = set_toplevel; - ec->shell_interface.set_xwayland = set_xwayland; + ec->shell_interface.set_subsurface = set_subsurface; + ec->shell_interface.set_subsurface_parent = set_subsurface_parent; ec->shell_interface.move = surface_move; ec->shell_interface.resize = surface_resize; diff --git a/src/xwayland/window-manager.c b/src/xwayland/window-manager.c index 3461de3..ddc70e3 100644 --- a/src/xwayland/window-manager.c +++ b/src/xwayland/window-manager.c @@ -30,6 +30,7 @@ struct xserver_window { struct wl_surface *surface; + struct weston_surface *frame_surface; struct weston_xserver *wxs; struct wl_listener surface_destroy_listener; struct shell_surface *shsurf; @@ -168,13 +169,15 @@ xserver_get_window_surface(struct wl_client *client, weston_surface, &shell_client); if (!window->flags) - shell_interface->set_xwayland(window->shsurf, window->id, + shell_interface->set_subsurface(window->shsurf, + window->frame_surface, 32 + 6, 32 + 27, - WL_SHELL_SURFACE_XWAYLAND_TOPLEVEL); + WL_SHELL_SURFACE_SUBSURFACE_CHILD); else - shell_interface->set_xwayland(window->shsurf, window->id, + shell_interface->set_subsurface(window->shsurf, + NULL, window->x + 32, window->y + 32, - WL_SHELL_SURFACE_XWAYLAND_TRANSIENT); + WL_SHELL_SURFACE_SUBSURFACE_TRANSIENT); } const struct xserver_interface xserver_implementation = { @@ -207,6 +210,7 @@ wm_get_window(struct wl_client *client, struct wl_resource *resource, w->old_height = -1; w->dx = 0; w->dy = 0; + w->surface = NULL; } else { fprintf(stderr, "found: %d, flags: %d, (%d, %d) x %d %d\n", id, flags, x, y, width, height); @@ -231,6 +235,29 @@ wm_get_map(struct wl_client *client, struct wl_resource *resource, xserver_send_map(wxs->resource, id); } +static void +wm_get_frame_surface(struct wl_client *client, struct wl_resource *resource, + struct wl_resource *surface_resource, uint32_t xid) +{ + struct weston_xserver *wxs = resource->data; + struct weston_shell_interface *shell_interface = + &wxs->compositor->shell_interface; + struct weston_surface *frame_surface = surface_resource->data; + struct xserver_window *window; + struct weston_surface *xclient_surface; + + window = hash_table_lookup(wxs->window_hash, xid); + if (!window) + return; + + window->frame_surface = frame_surface; + + xclient_surface = (struct weston_surface *) window->surface; + if (xclient_surface && weston_surface_is_mapped(xclient_surface)) + shell_interface->set_subsurface_parent(window->shsurf, + frame_surface); +} + static struct weston_seat * weston_wm_pick_seat(struct weston_xserver *wxs) { @@ -273,6 +300,7 @@ wm_get_resize(struct wl_client *client, struct wl_resource *resource, const struct wm_interface wm_implementation = { wm_get_window, wm_get_map, + wm_get_frame_surface, wm_get_move, wm_get_resize }; |