diff --git a/configure.ac b/configure.ac index efd8fb813..432f74c8b 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ(2.50) m4_define([mutter_major_version], [3]) m4_define([mutter_minor_version], [9]) -m4_define([mutter_micro_version], [90]) +m4_define([mutter_micro_version], [91]) m4_define([mutter_version], [mutter_major_version.mutter_minor_version.mutter_micro_version]) diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c index 2dc75f8d8..0928a2fcb 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -236,7 +236,7 @@ set_cogl_texture (MetaShapedTexture *stex, if (priv->texture) cogl_object_unref (priv->texture); - priv->texture = cogl_tex; + priv->texture = cogl_object_ref (cogl_tex); if (cogl_tex != NULL) { @@ -870,26 +870,7 @@ meta_shaped_texture_attach_wayland_buffer (MetaShapedTexture *stex, g_return_if_fail (priv->wayland.surface->buffer_ref.buffer == buffer); if (buffer) - { - CoglContext *ctx = - clutter_backend_get_cogl_context (clutter_get_default_backend ()); - CoglError *catch_error = NULL; - CoglTexture *texture = - COGL_TEXTURE (cogl_wayland_texture_2d_new_from_buffer (ctx, - buffer->resource, - &catch_error)); - if (!texture) - { - cogl_error_free (catch_error); - } - else - { - buffer->width = cogl_texture_get_width (texture); - buffer->height = cogl_texture_get_height (texture); - } - - set_cogl_texture (stex, texture); - } + set_cogl_texture (stex, buffer->texture); else set_cogl_texture (stex, NULL); diff --git a/src/core/constraints.h b/src/core/constraints.h index 5fa1e4ebc..0bea43d11 100644 --- a/src/core/constraints.h +++ b/src/core/constraints.h @@ -35,7 +35,8 @@ typedef enum META_DO_GRAVITY_ADJUST = 1 << 1, META_IS_USER_ACTION = 1 << 2, META_IS_MOVE_ACTION = 1 << 3, - META_IS_RESIZE_ACTION = 1 << 4 + META_IS_RESIZE_ACTION = 1 << 4, + META_IS_WAYLAND_RESIZE = 1 << 5 } MetaMoveResizeFlags; void meta_window_constrain (MetaWindow *window, diff --git a/src/core/window-private.h b/src/core/window-private.h index 3ca2b0a99..9504bca15 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -127,6 +127,7 @@ struct _MetaWindow Window xtransient_for; Window xgroup_leader; Window xclient_leader; + MetaWindow *transient_for; /* Initial workspace property */ int initial_workspace; @@ -403,6 +404,12 @@ struct _MetaWindow */ MetaRectangle rect; + /* The size we want the window to be (i.e. what we last asked + * the client to configure). + * This is only used for wayland clients. + */ + MetaRectangle expected_rect; + gboolean has_custom_frame_extents; GtkBorder custom_frame_extents; @@ -600,6 +607,11 @@ void meta_window_move_resize_request(MetaWindow *window, int y, int width, int height); +void meta_window_move_resize_wayland (MetaWindow *window, + int width, + int height, + int dx, + int dy); gboolean meta_window_configure_request (MetaWindow *window, XEvent *event); gboolean meta_window_property_notify (MetaWindow *window, @@ -716,4 +728,7 @@ void meta_window_set_gtk_dbus_properties (MetaWindow *window, const char *application_object_path, const char *window_object_path); +void meta_window_set_transient_for (MetaWindow *window, + MetaWindow *parent); + #endif diff --git a/src/core/window-props.c b/src/core/window-props.c index 73452cc27..1ac52391e 100644 --- a/src/core/window-props.c +++ b/src/core/window-props.c @@ -1554,9 +1554,6 @@ reload_transient_for (MetaWindow *window, if (transient_for == window->xtransient_for) return; - if (meta_window_appears_focused (window) && window->xtransient_for != None) - meta_window_propagate_focus_appearance (window, FALSE); - old_transient_for = window->xtransient_for; window->xtransient_for = transient_for; @@ -1569,46 +1566,14 @@ reload_transient_for (MetaWindow *window, else meta_verbose ("Window %s is not transient\n", window->desc); - /* may now be a dialog */ - meta_window_recalc_window_type (window); - - if (!window->constructing) + if (window->transient_parent_is_root_window || window->xtransient_for == None) + meta_window_set_transient_for (window, NULL); + else { - /* If the window attaches, detaches, or changes attached - * parents, we need to destroy the MetaWindow and let a new one - * be created (which happens as a side effect of - * meta_window_unmanage()). The condition below is correct - * because we know window->xtransient_for has changed. - */ - if (window->attached || meta_window_should_attach_to_parent (window)) - { - guint32 timestamp; - - window->xtransient_for = old_transient_for; - timestamp = meta_display_get_current_time_roundtrip (window->display); - meta_window_unmanage (window, timestamp); - return; - } + parent = meta_display_lookup_x_window (window->display, + window->xtransient_for); + meta_window_set_transient_for (window, parent); } - - /* update stacking constraints */ - if (!window->override_redirect) - meta_stack_update_transient (window->screen->stack, window); - - /* possibly change its group. We treat being a window's transient as - * equivalent to making it your group leader, to work around shortcomings - * in programs such as xmms-- see #328211. - */ - if (window->xtransient_for != None && - window->xgroup_leader != None && - window->xtransient_for != window->xgroup_leader) - meta_window_group_leader_changed (window); - - if (!window->constructing && !window->override_redirect) - meta_window_queue (window, META_QUEUE_MOVE_RESIZE); - - if (meta_window_appears_focused (window) && window->xtransient_for != None) - meta_window_propagate_focus_appearance (window, TRUE); } static void diff --git a/src/core/window.c b/src/core/window.c index 199799d24..9505d28b4 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -239,6 +239,9 @@ meta_window_finalize (GObject *object) if (window->opaque_region) cairo_region_destroy (window->opaque_region); + if (window->transient_for) + g_object_unref (window->transient_for); + meta_icon_cache_free (&window->icon_cache); g_free (window->sm_client_id); @@ -1114,11 +1117,6 @@ meta_window_new_shared (MetaDisplay *display, * can use this time as a fallback. */ if (!window->override_redirect && !window->net_wm_user_time_set) { - MetaWindow *parent = NULL; - if (window->xtransient_for) - parent = meta_display_lookup_x_window (window->display, - window->xtransient_for); - /* First, maybe the app was launched with startup notification using an * obsolete version of the spec; use that timestamp if it exists. */ @@ -1127,8 +1125,8 @@ meta_window_new_shared (MetaDisplay *display, * being recorded as a fallback for potential transients */ window->net_wm_user_time = window->initial_timestamp; - else if (parent != NULL) - meta_window_set_user_time(window, parent->net_wm_user_time); + else if (window->transient_for != NULL) + meta_window_set_user_time(window, window->transient_for->net_wm_user_time); else /* NOTE: Do NOT toggle net_wm_user_time_set to true; this is just * being recorded as a fallback for potential transients @@ -1218,21 +1216,16 @@ meta_window_new_shared (MetaDisplay *display, if (!window->override_redirect) { if (window->workspace == NULL && - window->xtransient_for != None) + window->transient_for != NULL) { /* Try putting dialog on parent's workspace */ - MetaWindow *parent; - - parent = meta_display_lookup_x_window (window->display, - window->xtransient_for); - - if (parent && parent->workspace) + if (window->transient_for->workspace) { meta_topic (META_DEBUG_PLACEMENT, "Putting window %s on same workspace as parent %s\n", - window->desc, parent->desc); + window->desc, window->transient_for->desc); - if (parent->on_all_workspaces_requested) + if (window->transient_for->on_all_workspaces_requested) { window->on_all_workspaces_requested = TRUE; window->on_all_workspaces = TRUE; @@ -1240,7 +1233,7 @@ meta_window_new_shared (MetaDisplay *display, /* this will implicitly add to the appropriate MRU lists */ - meta_workspace_add_window (parent->workspace, window); + meta_workspace_add_window (window->transient_for->workspace, window); } } @@ -4456,14 +4449,14 @@ window_activate (MetaWindow *window, /* For non-transient windows, we just set up a pulsing indicator, rather than move windows or workspaces. See http://bugzilla.gnome.org/show_bug.cgi?id=482354 */ - if (window->xtransient_for == None && + if (window->transient_for == NULL && !meta_window_located_on_workspace (window, workspace)) { meta_window_set_demands_attention (window); /* We've marked it as demanding, don't need to do anything else. */ return; } - else if (window->xtransient_for != None) + else if (window->transient_for != NULL) { /* Move transients to current workspace - preference dialogs should appear over the source window. */ @@ -5001,6 +4994,7 @@ meta_window_move_resize_internal (MetaWindow *window, * 2 | A not-resize-only ConfigureRequest/net_moveresize_window request * 3 | meta_window_move * 3 | meta_window_move_resize + * 4 | meta_window_move_resize_wayland * * For each of the cases, root_x_nw and root_y_nw must be treated as follows: * @@ -5011,8 +5005,12 @@ meta_window_move_resize_internal (MetaWindow *window, * coordinates are relative to some corner or side of the outer * window (except for the case of StaticGravity) and we want to * know the location of the upper left corner of the inner window. - * (3) These values are already the desired positon of the NW corner + * (3) These values are already the desired position of the NW corner * of the inner window + * (4) These values are already the desired position of the NW corner + * of the inner window (which is also the outer window, because + * we don't decorate wayland clients), and the client has acknowledged + * the window size change. */ XWindowChanges values; unsigned int mask; @@ -5028,6 +5026,7 @@ meta_window_move_resize_internal (MetaWindow *window, gboolean is_configure_request; gboolean do_gravity_adjust; gboolean is_user_action; + gboolean is_wayland_resize; gboolean did_placement; gboolean configure_frame_first; gboolean use_static_gravity; @@ -5044,9 +5043,12 @@ meta_window_move_resize_internal (MetaWindow *window, is_configure_request = (flags & META_IS_CONFIGURE_REQUEST) != 0; do_gravity_adjust = (flags & META_DO_GRAVITY_ADJUST) != 0; is_user_action = (flags & META_IS_USER_ACTION) != 0; + is_wayland_resize = (flags & META_IS_WAYLAND_RESIZE) != 0; - /* The action has to be a move or a resize or both... */ - g_assert (flags & (META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION)); + /* The action has to be a move, a resize or the wayland client + * acking our choice of size. + */ + g_assert (flags & (META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION | META_IS_WAYLAND_RESIZE)); /* We don't need it in the idle queue anymore. */ meta_window_unqueue (window, META_QUEUE_MOVE_RESIZE); @@ -5104,310 +5106,405 @@ meta_window_move_resize_internal (MetaWindow *window, did_placement = !window->placed && window->calc_placement; - meta_window_constrain (window, - window->frame ? &borders : NULL, - flags, - gravity, - &old_rect, - &new_rect); - - w = new_rect.width; - h = new_rect.height; - root_x_nw = new_rect.x; - root_y_nw = new_rect.y; - - if (w != window->rect.width || - h != window->rect.height) - need_resize_client = TRUE; - - window->rect.width = w; - window->rect.height = h; - - if (window->frame) + if (flags & (META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION)) { - int frame_size_dx, frame_size_dy; - int new_w, new_h; - - new_w = window->rect.width + borders.total.left + borders.total.right; - - if (window->shaded) - new_h = borders.total.top; - else - new_h = window->rect.height + borders.total.top + borders.total.bottom; - - frame_size_dx = new_w - window->frame->rect.width; - frame_size_dy = new_h - window->frame->rect.height; - - need_resize_frame = (frame_size_dx != 0 || frame_size_dy != 0); - - window->frame->rect.width = new_w; - window->frame->rect.height = new_h; - - meta_topic (META_DEBUG_GEOMETRY, - "Calculated frame size %dx%d\n", - window->frame->rect.width, - window->frame->rect.height); + meta_window_constrain (window, + window->frame ? &borders : NULL, + flags, + gravity, + &old_rect, + &new_rect); } - /* For nice effect, when growing the window we want to move/resize - * the frame first, when shrinking the window we want to move/resize - * the client first. If we grow one way and shrink the other, - * see which way we're moving "more" - * - * Mail from Owen subject "Suggestion: Gravity and resizing from the left" - * http://mail.gnome.org/archives/wm-spec-list/1999-November/msg00088.html - * - * An annoying fact you need to know in this code is that StaticGravity - * does nothing if you _only_ resize or _only_ move the frame; - * it must move _and_ resize, otherwise you get NorthWestGravity - * behavior. The move and resize must actually occur, it is not - * enough to set CWX | CWWidth but pass in the current size/pos. - */ - - if (window->frame) + if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) { - int new_x, new_y; - int frame_pos_dx, frame_pos_dy; + g_assert (window->frame == NULL); - /* Compute new frame coords */ - new_x = root_x_nw - borders.total.left; - new_y = root_y_nw - borders.total.top; - - frame_pos_dx = new_x - window->frame->rect.x; - frame_pos_dy = new_y - window->frame->rect.y; - - need_move_frame = (frame_pos_dx != 0 || frame_pos_dy != 0); - - window->frame->rect.x = new_x; - window->frame->rect.y = new_y; - - /* If frame will both move and resize, then StaticGravity - * on the child window will kick in and implicitly move - * the child with respect to the frame. The implicit - * move will keep the child in the same place with - * respect to the root window. If frame only moves - * or only resizes, then the child will just move along - * with the frame. + /* For wayland clients, the size is completely determined by the client, + * and while this allows to avoid some trickery with frames and the resulting + * lagging, we also need to insist a bit when the constraints would apply + * a different size than the client decides. + * + * Note that this is not generally a problem for normal toplevel windows (the + * constraints don't see the size hints, or just change the position), but + * it can be for maximized or fullscreen. + * */ + root_x_nw = new_rect.x; + root_y_nw = new_rect.y; - /* window->rect.x, window->rect.y are relative to frame, - * remember they are the server coords + /* First, save where we would like the client to be. This is used by the next + * attach to determine if the client is really moving/resizing or not. */ + window->expected_rect = new_rect; - new_x = borders.total.left; - new_y = borders.total.top; - - if (need_resize_frame && need_move_frame && - static_gravity_works (window->display)) + if (is_wayland_resize) { - /* static gravity kicks in because frame - * is both moved and resized - */ - /* when we move the frame by frame_pos_dx, frame_pos_dy the - * client will implicitly move relative to frame by the - * inverse delta. - * - * When moving client then frame, we move the client by the - * frame delta, to be canceled out by the implicit move by - * the inverse frame delta, resulting in a client at new_x, - * new_y. - * - * When moving frame then client, we move the client - * by the same delta as the frame, because the client - * was "left behind" by the frame - resulting in a client - * at new_x, new_y. - * - * In both cases we need to move the client window - * in all cases where we had to move the frame window. + /* This is a call to wl_surface_commit(), ignore the new_rect and + * update the real client size to match the buffer size. */ - client_move_x = new_x + frame_pos_dx; - client_move_y = new_y + frame_pos_dy; + window->rect.width = w; + window->rect.height = h; + } - if (need_move_frame) + if (new_rect.width != window->rect.width || + new_rect.height != window->rect.height) + { + /* We need to resize the client. Resizing is in two parts: + * some of the movement happens immediately, and some happens as part + * of the resizing (through dx/dy in wl_surface_attach). + * + * To do so, we need to compute the resize from the point of the view + * of the client, and then adjust the immediate resize to match. + * + * dx/dy are the values we expect from the new attach(), while deltax/ + * deltay reflect the overall movement. + */ + MetaRectangle client_rect; + int dx, dy; + int deltax, deltay; + + meta_rectangle_resize_with_gravity (&old_rect, + &client_rect, + gravity, + new_rect.width, + new_rect.height); + + deltax = new_rect.x - old_rect.x; + deltay = new_rect.y - old_rect.y; + dx = client_rect.x - old_rect.x; + dy = client_rect.y - old_rect.y; + + if ((deltax - dx) != 0 || + (deltay - dy) != 0) need_move_client = TRUE; - use_static_gravity = TRUE; + window->rect.x += (deltax - dx); + window->rect.y += (deltay - dy); + + need_resize_client = TRUE; + meta_wayland_surface_configure_notify (window->surface, + new_rect.width, + new_rect.height, + (dx != 0 ? WL_SHELL_SURFACE_RESIZE_LEFT : 0) | + (dy != 0 ? WL_SHELL_SURFACE_RESIZE_TOP : 0)); } else { - client_move_x = new_x; - client_move_y = new_y; - - if (client_move_x != window->rect.x || - client_move_y != window->rect.y) + /* No resize happening, we can just move the window and live with it. */ + if (window->rect.x != new_rect.x || + window->rect.y != new_rect.y) need_move_client = TRUE; + window->rect.x = new_rect.x; + window->rect.y = new_rect.y; + } + } + else + { + /* Everything else is the old X11 code, including weird gravities, + * the interaction with frames and the synthetic configure notifies. + */ + + root_x_nw = new_rect.x; + root_y_nw = new_rect.y; + w = new_rect.width; + h = new_rect.height; + + if (w != window->rect.width || + h != window->rect.height) + need_resize_client = TRUE; + + window->rect.width = w; + window->rect.height = h; + + if (window->frame) + { + int frame_size_dx, frame_size_dy; + int new_w, new_h; + + new_w = window->rect.width + borders.total.left + borders.total.right; + + if (window->shaded) + new_h = borders.total.top; + else + new_h = window->rect.height + borders.total.top + borders.total.bottom; + + frame_size_dx = new_w - window->frame->rect.width; + frame_size_dy = new_h - window->frame->rect.height; + + need_resize_frame = (frame_size_dx != 0 || frame_size_dy != 0); + + window->frame->rect.width = new_w; + window->frame->rect.height = new_h; + + meta_topic (META_DEBUG_GEOMETRY, + "Calculated frame size %dx%d\n", + window->frame->rect.width, + window->frame->rect.height); + } + + /* For nice effect, when growing the window we want to move/resize + * the frame first, when shrinking the window we want to move/resize + * the client first. If we grow one way and shrink the other, + * see which way we're moving "more" + * + * Mail from Owen subject "Suggestion: Gravity and resizing from the left" + * http://mail.gnome.org/archives/wm-spec-list/1999-November/msg00088.html + * + * An annoying fact you need to know in this code is that StaticGravity + * does nothing if you _only_ resize or _only_ move the frame; + * it must move _and_ resize, otherwise you get NorthWestGravity + * behavior. The move and resize must actually occur, it is not + * enough to set CWX | CWWidth but pass in the current size/pos. + */ + + if (window->frame) + { + int new_x, new_y; + int frame_pos_dx, frame_pos_dy; + + /* Compute new frame coords */ + new_x = root_x_nw - borders.total.left; + new_y = root_y_nw - borders.total.top; + + frame_pos_dx = new_x - window->frame->rect.x; + frame_pos_dy = new_y - window->frame->rect.y; + + need_move_frame = (frame_pos_dx != 0 || frame_pos_dy != 0); + + window->frame->rect.x = new_x; + window->frame->rect.y = new_y; + + /* If frame will both move and resize, then StaticGravity + * on the child window will kick in and implicitly move + * the child with respect to the frame. The implicit + * move will keep the child in the same place with + * respect to the root window. If frame only moves + * or only resizes, then the child will just move along + * with the frame. + */ + + /* window->rect.x, window->rect.y are relative to frame, + * remember they are the server coords + */ + + new_x = borders.total.left; + new_y = borders.total.top; + + if (need_resize_frame && need_move_frame && + static_gravity_works (window->display)) + { + /* static gravity kicks in because frame + * is both moved and resized + */ + /* when we move the frame by frame_pos_dx, frame_pos_dy the + * client will implicitly move relative to frame by the + * inverse delta. + * + * When moving client then frame, we move the client by the + * frame delta, to be canceled out by the implicit move by + * the inverse frame delta, resulting in a client at new_x, + * new_y. + * + * When moving frame then client, we move the client + * by the same delta as the frame, because the client + * was "left behind" by the frame - resulting in a client + * at new_x, new_y. + * + * In both cases we need to move the client window + * in all cases where we had to move the frame window. + */ + + client_move_x = new_x + frame_pos_dx; + client_move_y = new_y + frame_pos_dy; + + if (need_move_frame) + need_move_client = TRUE; + + use_static_gravity = TRUE; + } + else + { + client_move_x = new_x; + client_move_y = new_y; + + if (client_move_x != window->rect.x || + client_move_y != window->rect.y) + need_move_client = TRUE; + + use_static_gravity = FALSE; + } + + /* This is the final target position, but not necessarily what + * we pass to XConfigureWindow, due to StaticGravity implicit + * movement. + */ + window->rect.x = new_x; + window->rect.y = new_y; + } + else + { + if (root_x_nw != window->rect.x || + root_y_nw != window->rect.y) + need_move_client = TRUE; + + window->rect.x = root_x_nw; + window->rect.y = root_y_nw; + + client_move_x = window->rect.x; + client_move_y = window->rect.y; + use_static_gravity = FALSE; } - /* This is the final target position, but not necessarily what - * we pass to XConfigureWindow, due to StaticGravity implicit - * movement. + /* If frame extents have changed, fill in other frame fields and + change frame's extents property. */ + if (window->frame && + (window->frame->child_x != borders.total.left || + window->frame->child_y != borders.total.top || + window->frame->right_width != borders.total.right || + window->frame->bottom_height != borders.total.bottom)) + { + window->frame->child_x = borders.total.left; + window->frame->child_y = borders.total.top; + window->frame->right_width = borders.total.right; + window->frame->bottom_height = borders.total.bottom; + + update_net_frame_extents (window); + } + + /* See ICCCM 4.1.5 for when to send ConfigureNotify */ + + need_configure_notify = FALSE; + + /* If this is a configure request and we change nothing, then we + * must send configure notify. */ - window->rect.x = new_x; - window->rect.y = new_y; - } - else - { - if (root_x_nw != window->rect.x || - root_y_nw != window->rect.y) - need_move_client = TRUE; + if (is_configure_request && + !(need_move_client || need_move_frame || + need_resize_client || need_resize_frame || + window->border_width != 0)) + need_configure_notify = TRUE; - window->rect.x = root_x_nw; - window->rect.y = root_y_nw; + /* We must send configure notify if we move but don't resize, since + * the client window may not get a real event + */ + if ((need_move_client || need_move_frame) && + !(need_resize_client || need_resize_frame)) + need_configure_notify = TRUE; - client_move_x = window->rect.x; - client_move_y = window->rect.y; + /* MapRequest events with a PPosition or UPosition hint with a frame + * are moved by mutter without resizing; send a configure notify + * in such cases. See #322840. (Note that window->constructing is + * only true iff this call is due to a MapRequest, and when + * PPosition/UPosition hints aren't set, mutter seems to send a + * ConfigureNotify anyway due to the above code.) + */ + if (window->constructing && window->frame && + ((window->size_hints.flags & PPosition) || + (window->size_hints.flags & USPosition))) + need_configure_notify = TRUE; - use_static_gravity = FALSE; - } + /* The rest of this function syncs our new size/pos with X as + * efficiently as possible + */ - /* If frame extents have changed, fill in other frame fields and - change frame's extents property. */ - if (window->frame && - (window->frame->child_x != borders.total.left || - window->frame->child_y != borders.total.top || - window->frame->right_width != borders.total.right || - window->frame->bottom_height != borders.total.bottom)) - { - window->frame->child_x = borders.total.left; - window->frame->child_y = borders.total.top; - window->frame->right_width = borders.total.right; - window->frame->bottom_height = borders.total.bottom; + /* Normally, we configure the frame first depending on whether + * we grow the frame more than we shrink. The idea is to avoid + * messing up the window contents by having a temporary situation + * where the frame is smaller than the window. However, if we're + * cooperating with the client to create an atomic frame upate, + * and the window is redirected, then we should always update + * the frame first, since updating the frame will force a new + * backing pixmap to be allocated, and the old backing pixmap + * will be left undisturbed for us to paint to the screen until + * the client finishes redrawing. + */ + if (window->extended_sync_request_counter) + { + configure_frame_first = TRUE; + } + else + { + size_dx = w - window->rect.width; + size_dy = h - window->rect.height; - update_net_frame_extents (window); - } + configure_frame_first = size_dx + size_dy >= 0; + } - /* See ICCCM 4.1.5 for when to send ConfigureNotify */ + if (use_static_gravity) + meta_window_set_gravity (window, StaticGravity); - need_configure_notify = FALSE; + if (configure_frame_first && window->frame) + frame_shape_changed = meta_frame_sync_to_window (window->frame, + gravity, + need_move_frame, need_resize_frame); - /* If this is a configure request and we change nothing, then we - * must send configure notify. - */ - if (is_configure_request && - !(need_move_client || need_move_frame || - need_resize_client || need_resize_frame || - window->border_width != 0)) - need_configure_notify = TRUE; + values.border_width = 0; + values.x = client_move_x; + values.y = client_move_y; + values.width = window->rect.width; + values.height = window->rect.height; - /* We must send configure notify if we move but don't resize, since - * the client window may not get a real event - */ - if ((need_move_client || need_move_frame) && - !(need_resize_client || need_resize_frame)) - need_configure_notify = TRUE; + mask = 0; + if (is_configure_request && window->border_width != 0) + mask |= CWBorderWidth; /* must force to 0 */ + if (need_move_client) + mask |= (CWX | CWY); + if (need_resize_client) + mask |= (CWWidth | CWHeight); - /* MapRequest events with a PPosition or UPosition hint with a frame - * are moved by mutter without resizing; send a configure notify - * in such cases. See #322840. (Note that window->constructing is - * only true iff this call is due to a MapRequest, and when - * PPosition/UPosition hints aren't set, mutter seems to send a - * ConfigureNotify anyway due to the above code.) - */ - if (window->constructing && window->frame && - ((window->size_hints.flags & PPosition) || - (window->size_hints.flags & USPosition))) - need_configure_notify = TRUE; + if (mask != 0) + { + { + int newx, newy; + meta_window_get_position (window, &newx, &newy); + meta_topic (META_DEBUG_GEOMETRY, + "Syncing new client geometry %d,%d %dx%d, border: %s pos: %s size: %s\n", + newx, newy, + window->rect.width, window->rect.height, + mask & CWBorderWidth ? "true" : "false", + need_move_client ? "true" : "false", + need_resize_client ? "true" : "false"); + } - /* The rest of this function syncs our new size/pos with X as - * efficiently as possible - */ - - /* Normally, we configure the frame first depending on whether - * we grow the frame more than we shrink. The idea is to avoid - * messing up the window contents by having a temporary situation - * where the frame is smaller than the window. However, if we're - * cooperating with the client to create an atomic frame upate, - * and the window is redirected, then we should always update - * the frame first, since updating the frame will force a new - * backing pixmap to be allocated, and the old backing pixmap - * will be left undisturbed for us to paint to the screen until - * the client finishes redrawing. - */ - if (window->extended_sync_request_counter) - { - configure_frame_first = TRUE; - } - else - { - size_dx = w - window->rect.width; - size_dy = h - window->rect.height; - - configure_frame_first = size_dx + size_dy >= 0; - } - - if (use_static_gravity) - meta_window_set_gravity (window, StaticGravity); - - if (configure_frame_first && window->frame) - frame_shape_changed = meta_frame_sync_to_window (window->frame, - gravity, - need_move_frame, need_resize_frame); - - values.border_width = 0; - values.x = client_move_x; - values.y = client_move_y; - values.width = window->rect.width; - values.height = window->rect.height; - - mask = 0; - if (is_configure_request && window->border_width != 0) - mask |= CWBorderWidth; /* must force to 0 */ - if (need_move_client) - mask |= (CWX | CWY); - if (need_resize_client) - mask |= (CWWidth | CWHeight); - - if (mask != 0) - { - { - int newx, newy; - meta_window_get_position (window, &newx, &newy); - meta_topic (META_DEBUG_GEOMETRY, - "Syncing new client geometry %d,%d %dx%d, border: %s pos: %s size: %s\n", - newx, newy, - window->rect.width, window->rect.height, - mask & CWBorderWidth ? "true" : "false", - need_move_client ? "true" : "false", - need_resize_client ? "true" : "false"); - } - - meta_error_trap_push (window->display); + meta_error_trap_push (window->display); #ifdef HAVE_XSYNC - if (window == window->display->grab_window && - meta_grab_op_is_resizing (window->display->grab_op) && - !window->disable_sync && - window->sync_request_counter != None && - window->sync_request_alarm != None && - window->sync_request_timeout_id == 0) - { - send_sync_request (window); - } + if (window == window->display->grab_window && + meta_grab_op_is_resizing (window->display->grab_op) && + !window->disable_sync && + window->sync_request_counter != None && + window->sync_request_alarm != None && + window->sync_request_timeout_id == 0) + { + send_sync_request (window); + } #endif - XConfigureWindow (window->display->xdisplay, - window->xwindow, - mask, - &values); + XConfigureWindow (window->display->xdisplay, + window->xwindow, + mask, + &values); - meta_error_trap_pop (window->display); + meta_error_trap_pop (window->display); + } + + if (!configure_frame_first && window->frame) + frame_shape_changed = meta_frame_sync_to_window (window->frame, + gravity, + need_move_frame, need_resize_frame); + + /* Put gravity back to be nice to lesser window managers */ + if (use_static_gravity) + meta_window_set_gravity (window, NorthWestGravity); + + if (need_configure_notify) + send_configure_notify (window); } - if (!configure_frame_first && window->frame) - frame_shape_changed = meta_frame_sync_to_window (window->frame, - gravity, - need_move_frame, need_resize_frame); - - /* Put gravity back to be nice to lesser window managers */ - if (use_static_gravity) - meta_window_set_gravity (window, NorthWestGravity); - - if (need_configure_notify) - send_configure_notify (window); - if (!window->placed && window->force_save_user_rect && !window->fullscreen) force_save_user_window_placement (window); else if (is_user_action) @@ -5415,7 +5512,7 @@ meta_window_move_resize_internal (MetaWindow *window, if (need_move_frame || need_resize_frame || need_move_client || need_resize_client || - did_placement) + did_placement || is_wayland_resize) { int newx, newy; meta_window_get_position (window, &newx, &newy); @@ -5485,6 +5582,37 @@ meta_window_resize (MetaWindow *window, x, y, w, h); } +/* + * meta_window_move_resize_wayland: + * + * Complete a resize operation from a wayland client. + * + */ +void +meta_window_move_resize_wayland (MetaWindow *window, + int width, + int height, + int dx, + int dy) +{ + int x, y; + MetaMoveResizeFlags flags; + + flags = META_IS_WAYLAND_RESIZE; + + meta_window_get_position (window, &x, &y); + x += dx; y += dy; + + if (x != window->expected_rect.x || y != window->expected_rect.y) + flags |= META_IS_MOVE_ACTION; + if (width != window->expected_rect.width || + height != window->expected_rect.height) + flags |= META_IS_RESIZE_ACTION; + + meta_window_move_resize_internal (window, flags, NorthWestGravity, + x, y, width, height); +} + /** * meta_window_move: * @window: a #MetaWindow @@ -5995,7 +6123,7 @@ get_modal_transient (MetaWindow *window) { MetaWindow *transient = tmp->data; - if (transient->xtransient_for == modal_transient->xwindow && + if (transient->transient_for == modal_transient && transient->wm_state_modal) { modal_transient = transient; @@ -8365,7 +8493,7 @@ recalc_window_type (MetaWindow *window) XFree (atom_name); } } - else if (window->xtransient_for != None) + else if (window->transient_for != NULL) { window->type = META_WINDOW_DIALOG; } @@ -8708,8 +8836,7 @@ recalc_window_features (MetaWindow *window) case META_WINDOW_MODAL_DIALOG: /* only skip taskbar if we have a real transient parent (and ignore the application hints) */ - if (window->xtransient_for != None && - window->xtransient_for != window->screen->xroot) + if (window->transient_for != NULL) window->skip_taskbar = TRUE; else window->skip_taskbar = FALSE; @@ -10313,11 +10440,10 @@ meta_window_foreach_ancestor (MetaWindow *window, w = window; do { - if (w->xtransient_for == None || - w->transient_parent_is_root_window) + if (w->transient_for == NULL) break; - w = meta_display_lookup_x_window (w->display, w->xtransient_for); + w = w->transient_for; } while (w && (* func) (w, user_data)); } @@ -11140,7 +11266,9 @@ meta_window_get_transient_for (MetaWindow *window) { g_return_val_if_fail (META_IS_WINDOW (window), NULL); - if (window->xtransient_for) + if (window->transient_for) + return window->transient_for; + else if (window->xtransient_for) return meta_display_lookup_x_window (window->display, window->xtransient_for); else @@ -11545,3 +11673,55 @@ meta_window_set_gtk_dbus_properties (MetaWindow *window, g_object_thaw_notify (G_OBJECT (window)); } + +void +meta_window_set_transient_for (MetaWindow *window, + MetaWindow *parent) +{ + if (meta_window_appears_focused (window) && window->transient_for != None) + meta_window_propagate_focus_appearance (window, FALSE); + + /* may now be a dialog */ + meta_window_recalc_window_type (window); + + if (!window->constructing) + { + /* If the window attaches, detaches, or changes attached + * parents, we need to destroy the MetaWindow and let a new one + * be created (which happens as a side effect of + * meta_window_unmanage()). The condition below is correct + * because we know window->transient_for has changed. + */ + if (window->attached || meta_window_should_attach_to_parent (window)) + { + guint32 timestamp; + + timestamp = meta_display_get_current_time_roundtrip (window->display); + meta_window_unmanage (window, timestamp); + return; + } + } + + /* update stacking constraints */ + if (!window->override_redirect) + meta_stack_update_transient (window->screen->stack, window); + + /* We know this won't create a reference cycle because we check for loops */ + g_clear_object (&window->transient_for); + window->transient_for = parent ? g_object_ref (parent) : NULL; + + /* possibly change its group. We treat being a window's transient as + * equivalent to making it your group leader, to work around shortcomings + * in programs such as xmms-- see #328211. + */ + if (window->xtransient_for != None && + window->xgroup_leader != None && + window->xtransient_for != window->xgroup_leader) + meta_window_group_leader_changed (window); + + if (!window->constructing && !window->override_redirect) + meta_window_queue (window, META_QUEUE_MOVE_RESIZE); + + if (meta_window_appears_focused (window) && window->transient_for != None) + meta_window_propagate_focus_appearance (window, TRUE); +} diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 1ce77f72d..3f82a69a3 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -64,8 +65,9 @@ static void surface_process_damage (MetaWaylandSurface *surface, cairo_region_t *region) { - if (surface->window && - surface->buffer_ref.buffer) + g_assert (surface->window); + + if (surface->buffer_ref.buffer) { MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (surface->window)); @@ -111,7 +113,7 @@ static void meta_wayland_surface_attach (struct wl_client *wayland_client, struct wl_resource *wayland_surface_resource, struct wl_resource *wayland_buffer_resource, - gint32 sx, gint32 sy) + gint32 dx, gint32 dy) { MetaWaylandSurface *surface = wl_resource_get_user_data (wayland_surface_resource); @@ -130,8 +132,8 @@ meta_wayland_surface_attach (struct wl_client *wayland_client, if (surface->pending.buffer) wl_list_remove (&surface->pending.buffer_destroy_listener.link); - surface->pending.sx = sx; - surface->pending.sy = sy; + surface->pending.dx = dx; + surface->pending.dy = dy; surface->pending.buffer = buffer; surface->pending.newly_attached = TRUE; @@ -247,36 +249,86 @@ meta_wayland_surface_commit (struct wl_client *client, if (surface->pending.newly_attached && surface->buffer_ref.buffer != surface->pending.buffer) { + MetaWaylandBuffer *buffer = surface->pending.buffer; + CoglContext *ctx = + clutter_backend_get_cogl_context (clutter_get_default_backend ()); + CoglError *catch_error = NULL; + CoglTexture *texture = + COGL_TEXTURE (cogl_wayland_texture_2d_new_from_buffer (ctx, + buffer->resource, + &catch_error)); + if (!texture) + { + cogl_error_free (catch_error); + meta_warning ("Could not import pending buffer, ignoring commit\n"); + return; + } + else + { + buffer->texture = texture; + buffer->width = cogl_texture_get_width (texture); + buffer->height = cogl_texture_get_height (texture); + } + /* Note: we set this before informing any window-actor since the * window actor will expect to find the new buffer within the * surface. */ meta_wayland_buffer_reference (&surface->buffer_ref, surface->pending.buffer); + } + + if (!surface->buffer_ref.buffer) + { + meta_warning ("Commit without a buffer? Ignoring\n"); + return; + } + + if (surface->initial_state) + { + MetaDisplay *display = meta_get_display (); + int width; + int height; + + width = surface->buffer_ref.buffer->width; + height = surface->buffer_ref.buffer->height; + + /* This will free and clear initial_state */ + surface->window = meta_window_new_for_wayland (display, width, height, surface); + } + + if (surface == compositor->seat->sprite) + meta_wayland_seat_update_sprite (compositor->seat); + else if (surface->window) + { + MetaWindow *window = surface->window; if (surface->pending.buffer) - { - MetaWaylandBuffer *buffer = surface->pending.buffer; + { + MetaWaylandBuffer *buffer = surface->pending.buffer; + MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - if (surface->window) - { - MetaWindow *window = surface->window; - MetaWindowActor *window_actor = - META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - MetaRectangle rect; + meta_window_actor_attach_wayland_buffer (window_actor, buffer); + } - meta_window_get_input_rect (surface->window, &rect); + /* We resize X based surfaces according to X events */ + if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) + { + int new_width; + int new_height; - if (window_actor) - meta_window_actor_attach_wayland_buffer (window_actor, buffer); + new_width = surface->buffer_ref.buffer->width; + new_height = surface->buffer_ref.buffer->height; + if (new_width != window->rect.width || + new_height != window->rect.height || + surface->pending.dx != 0 || + surface->pending.dy != 0) + meta_window_move_resize_wayland (surface->window, new_width, new_height, + surface->pending.dx, surface->pending.dy); + } - /* XXX: we resize X based surfaces according to X events */ - if (surface->xid == 0 && - (buffer->width != rect.width || buffer->height != rect.height)) - meta_window_resize (surface->window, FALSE, buffer->width, buffer->height); - } - else if (surface == compositor->seat->sprite) - meta_wayland_seat_update_sprite (compositor->seat); - } + meta_window_set_opaque_region (surface->window, surface->pending.opaque_region); + meta_window_set_input_region (surface->window, surface->pending.input_region); + surface_process_damage (surface, surface->pending.damage); } if (surface->pending.buffer) @@ -284,20 +336,11 @@ meta_wayland_surface_commit (struct wl_client *client, wl_list_remove (&surface->pending.buffer_destroy_listener.link); surface->pending.buffer = NULL; } - surface->pending.sx = 0; - surface->pending.sy = 0; + surface->pending.dx = 0; + surface->pending.dy = 0; surface->pending.newly_attached = FALSE; - - if (surface->window) - { - meta_window_set_opaque_region (surface->window, surface->pending.opaque_region); - g_clear_pointer (&surface->pending.opaque_region, cairo_region_destroy); - - meta_window_set_input_region (surface->window, surface->pending.input_region); - g_clear_pointer (&surface->pending.input_region, cairo_region_destroy); - } - - surface_process_damage (surface, surface->pending.damage); + g_clear_pointer (&surface->pending.opaque_region, cairo_region_destroy); + g_clear_pointer (&surface->pending.input_region, cairo_region_destroy); empty_region (surface->pending.damage); /* wl_surface.frame */ @@ -632,34 +675,6 @@ shell_surface_resize (struct wl_client *client, g_warning ("TODO: support shell_surface_resize request"); } -static void -ensure_surface_window (MetaWaylandSurface *surface) -{ - MetaDisplay *display = meta_get_display (); - - if (!surface->window) - { - int width, height; - - if (surface->buffer_ref.buffer) - { - MetaWaylandBuffer *buffer = surface->buffer_ref.buffer; - width = buffer->width; - height = buffer->width; - } - else - { - width = 0; - height = 0; - } - - surface->window = - meta_window_new_for_wayland (display, width, height, surface); - - meta_window_calc_showing (surface->window); - } -} - static void shell_surface_set_toplevel (struct wl_client *client, struct wl_resource *resource) @@ -672,9 +687,19 @@ shell_surface_set_toplevel (struct wl_client *client, if (client == compositor->xwayland_client) return; - ensure_surface_window (surface); + if (surface->window) + { + if (surface->window->fullscreen) + meta_window_unmake_fullscreen (surface->window); + if (meta_window_get_maximized (surface->window) != 0) + meta_window_unmaximize (surface->window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL); + } + else + { + ensure_initial_state (surface); - meta_window_unmake_fullscreen (surface->window); + surface->initial_state->initial_type = META_WAYLAND_SURFACE_TOPLEVEL; + } } static void @@ -687,13 +712,22 @@ shell_surface_set_transient (struct wl_client *client, { MetaWaylandSurfaceExtension *shell_surface = wl_resource_get_user_data (resource); MetaWaylandSurface *surface = shell_surface->surface; + MetaWaylandSurface *parent_surface = wl_resource_get_user_data (parent); MetaWaylandCompositor *compositor = surface->compositor; /* NB: Surfaces from xwayland become managed based on X events. */ if (client == compositor->xwayland_client) return; - ensure_surface_window (surface); + if (surface->window) + meta_window_set_transient_for (surface->window, parent_surface->window); + else + { + ensure_initial_state (surface); + + surface->initial_state->initial_type = META_WAYLAND_SURFACE_TOPLEVEL; + surface->initial_state->transient_for = parent; + } } static void @@ -711,9 +745,14 @@ shell_surface_set_fullscreen (struct wl_client *client, if (client == compositor->xwayland_client) return; - ensure_surface_window (surface); + if (surface->window) + meta_window_make_fullscreen (surface->window); + else + { + ensure_initial_state (surface); - meta_window_make_fullscreen (surface->window); + surface->initial_state->initial_type = META_WAYLAND_SURFACE_FULLSCREEN; + } } static void @@ -733,7 +772,22 @@ shell_surface_set_maximized (struct wl_client *client, struct wl_resource *resource, struct wl_resource *output) { - g_warning ("TODO: support shell_surface_set_maximized request"); + MetaWaylandSurfaceExtension *shell_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = shell_surface->surface; + MetaWaylandCompositor *compositor = surface->compositor; + + /* NB: Surfaces from xwayland become managed based on X events. */ + if (client == compositor->xwayland_client) + return; + + if (surface->window) + meta_window_maximize (surface->window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL); + else + { + ensure_initial_state (surface); + + surface->initial_state->initial_type = META_WAYLAND_SURFACE_MAXIMIZED; + } } static void @@ -813,7 +867,7 @@ destroy_surface_extension (struct wl_resource *resource) g_free (extension); } -static void +static MetaWaylandSurfaceExtension * create_surface_extension (struct wl_client *client, struct wl_resource *master_resource, guint32 id, @@ -834,6 +888,8 @@ create_surface_extension (struct wl_client *client, extension->surface_destroy_listener.notify = extension_handle_surface_destroy; wl_resource_add_destroy_listener (surface->resource, &extension->surface_destroy_listener); + + return extension; } static void @@ -844,7 +900,7 @@ get_shell_surface (struct wl_client *client, { MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); - if (surface->has_shell_surface) + if (surface->shell_surface) { wl_resource_post_error (surface_resource, WL_DISPLAY_ERROR_INVALID_OBJECT, @@ -852,10 +908,9 @@ get_shell_surface (struct wl_client *client, return; } - create_surface_extension (client, resource, id, surface, - &wl_shell_surface_interface, - &meta_wayland_shell_surface_interface); - surface->has_shell_surface = TRUE; + surface->shell_surface = create_surface_extension (client, resource, id, surface, + &wl_shell_surface_interface, + &meta_wayland_shell_surface_interface); } static const struct wl_shell_interface meta_wayland_shell_interface = @@ -946,7 +1001,7 @@ get_gtk_surface (struct wl_client *client, { MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); - if (surface->has_gtk_surface) + if (surface->gtk_surface) { wl_resource_post_error (surface_resource, WL_DISPLAY_ERROR_INVALID_OBJECT, @@ -954,10 +1009,9 @@ get_gtk_surface (struct wl_client *client, return; } - create_surface_extension (client, resource, id, surface, - >k_surface_interface, - &meta_wayland_gtk_surface_interface); - surface->has_gtk_surface = TRUE; + surface->gtk_surface = create_surface_extension (client, resource, id, surface, + >k_surface_interface, + &meta_wayland_gtk_surface_interface); } static const struct gtk_shell_interface meta_wayland_gtk_shell_interface = @@ -1003,6 +1057,29 @@ meta_wayland_surface_set_initial_state (MetaWaylandSurface *surface, if (initial == NULL) return; + /* Note that we poke at the bits directly here, because we're + in the middle of meta_window_new_shared() */ + switch (initial->initial_type) + { + case META_WAYLAND_SURFACE_TOPLEVEL: + break; + case META_WAYLAND_SURFACE_FULLSCREEN: + window->fullscreen = TRUE; + break; + case META_WAYLAND_SURFACE_MAXIMIZED: + window->maximized_horizontally = window->maximized_vertically = TRUE; + break; + default: + g_assert_not_reached (); + } + + if (initial->transient_for) + { + MetaWaylandSurface *parent = wl_resource_get_user_data (initial->transient_for); + if (parent) + window->transient_for = g_object_ref (parent->window); + } + if (initial->title) meta_window_set_title (window, initial->title); @@ -1045,3 +1122,14 @@ free_initial_state (MetaWaylandSurfaceInitialState *initial) g_slice_free (MetaWaylandSurfaceInitialState, initial); } + +void +meta_wayland_surface_configure_notify (MetaWaylandSurface *surface, + int new_width, + int new_height, + int edges) +{ + if (surface->shell_surface) + wl_shell_surface_send_configure (surface->shell_surface->resource, + edges, new_width, new_height); +} diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index 5957bceae..dab412488 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -36,6 +36,7 @@ struct _MetaWaylandBuffer struct wl_signal destroy_signal; struct wl_listener destroy_listener; + CoglTexture *texture; int32_t width, height; uint32_t busy_count; }; @@ -52,8 +53,8 @@ typedef struct gboolean newly_attached; MetaWaylandBuffer *buffer; struct wl_listener buffer_destroy_listener; - int32_t sx; - int32_t sy; + int32_t dx; + int32_t dy; /* wl_surface.damage */ cairo_region_t *damage; @@ -65,8 +66,17 @@ typedef struct struct wl_list frame_callback_list; } MetaWaylandDoubleBufferedState; +typedef enum { + META_WAYLAND_SURFACE_TOPLEVEL = 0, + META_WAYLAND_SURFACE_MAXIMIZED, + META_WAYLAND_SURFACE_FULLSCREEN +} MetaWaylandSurfaceType; + typedef struct { + MetaWaylandSurfaceType initial_type; + struct wl_resource *transient_for; + char *title; char *wm_class; @@ -78,17 +88,21 @@ typedef struct char *gtk_window_object_path; } MetaWaylandSurfaceInitialState; +typedef struct +{ + MetaWaylandSurface *surface; + struct wl_resource *resource; + struct wl_listener surface_destroy_listener; +} MetaWaylandSurfaceExtension; + struct _MetaWaylandSurface { struct wl_resource *resource; MetaWaylandCompositor *compositor; - guint32 xid; - int x; - int y; MetaWaylandBufferReference buffer_ref; MetaWindow *window; - gboolean has_shell_surface; - gboolean has_gtk_surface; + MetaWaylandSurfaceExtension *shell_surface; + MetaWaylandSurfaceExtension *gtk_surface; /* All the pending state, that wl_surface.commit will apply. */ MetaWaylandDoubleBufferedState pending; @@ -98,13 +112,6 @@ struct _MetaWaylandSurface MetaWaylandSurfaceInitialState *initial_state; }; -typedef struct -{ - MetaWaylandSurface *surface; - struct wl_resource *resource; - struct wl_listener surface_destroy_listener; -} MetaWaylandSurfaceExtension; - void meta_wayland_init_shell (MetaWaylandCompositor *compositor); MetaWaylandSurface *meta_wayland_surface_create (MetaWaylandCompositor *compositor, @@ -116,4 +123,9 @@ void meta_wayland_surface_free (MetaWaylandSurface *surface) void meta_wayland_surface_set_initial_state (MetaWaylandSurface *surface, MetaWindow *window); +void meta_wayland_surface_configure_notify (MetaWaylandSurface *surface, + int width, + int height, + int edges); + #endif diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index 5259025ba..90030ff55 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -187,6 +187,7 @@ meta_wayland_buffer_reference (MetaWaylandBufferReference *ref, if (ref->buffer->busy_count == 0) { + g_clear_pointer (&ref->buffer->texture, cogl_object_unref); g_assert (wl_resource_get_client (ref->buffer->resource)); wl_resource_queue_event (ref->buffer->resource, WL_BUFFER_RELEASE); } @@ -609,8 +610,8 @@ synthesize_motion_event (MetaWaylandCompositor *compositor, device_event.event_y = wl_fixed_to_double (pointer->y); } - if (surface && surface->xid != None) - device_event.event = surface->xid; + if (surface && surface->window != NULL) + device_event.event = surface->window->xwindow; else device_event.event = device_event.root; diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 49cc51d50..0e67c6d8d 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -45,10 +45,6 @@ xserver_set_window_id (struct wl_client *client, MetaDisplay *display = meta_get_display (); MetaWindow *window; - g_return_if_fail (surface->xid == None); - - surface->xid = xid; - window = meta_display_lookup_x_window (display, xid); if (window) {