summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTiago Vignatti <tiago.vignatti@intel.com>2012-10-03 15:42:26 +0300
committerTiago Vignatti <tiago.vignatti@intel.com>2012-10-03 15:42:26 +0300
commit9e66e570e85693ed5aafd27aacb20c5849d37a9d (patch)
tree3ff13ebaa0ccb0894070d1108c3cb1eae7d44430
parentc21f8a42d86ef4ff81c5f0c0158c16950505359e (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.c6
-rw-r--r--protocol/xserver.xml5
-rw-r--r--src/compositor.h9
-rw-r--r--src/shell.c269
-rw-r--r--src/xwayland/window-manager.c36
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
};