From ab080e3e6b142ede100b92ed5db423e04f171fd8 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 8 Nov 2013 17:05:07 -0500 Subject: [PATCH] Add support for xdg-shell Replace our existing support for wl_shell with xdg_shell, the new proposal for how Wayland surfaces should work. --- .gitignore | 3 + protocol/Makefile.am | 1 + protocol/xdg-shell.xml | 385 +++++++++++++++++++++++++++ src/Makefile.am | 3 + src/wayland/meta-wayland-pointer.c | 10 +- src/wayland/meta-wayland-surface.c | 387 +++++++++++++--------------- src/wayland/meta-wayland-surface.h | 4 +- src/wayland/meta-wayland-versions.h | 4 +- 8 files changed, 585 insertions(+), 212 deletions(-) create mode 100644 protocol/xdg-shell.xml diff --git a/.gitignore b/.gitignore index 898cd5131..ae4d6b01b 100644 --- a/.gitignore +++ b/.gitignore @@ -81,6 +81,9 @@ src/mutter-plugins.pc src/wayland/gtk-shell-protocol.c src/wayland/gtk-shell-client-protocol.h src/wayland/gtk-shell-server-protocol.h +src/wayland/xdg-shell-protocol.c +src/wayland/xdg-shell-client-protocol.h +src/wayland/xdg-shell-server-protocol.h src/wayland/xserver-protocol.c src/wayland/xserver-client-protocol.h src/wayland/xserver-server-protocol.h diff --git a/protocol/Makefile.am b/protocol/Makefile.am index 0efd1f509..8ce700537 100644 --- a/protocol/Makefile.am +++ b/protocol/Makefile.am @@ -2,5 +2,6 @@ NULL = EXTRA_DIST = \ gtk-shell.xml \ + xdg-shell.xml \ xserver.xml \ $(NULL) diff --git a/protocol/xdg-shell.xml b/protocol/xdg-shell.xml new file mode 100644 index 000000000..fbd4f6da4 --- /dev/null +++ b/protocol/xdg-shell.xml @@ -0,0 +1,385 @@ + + + + + Copyright © 2008-2013 Kristian Høgsberg + Copyright © 2013 Rafael Antognolli + Copyright © 2013 Jasper St. Pierre + Copyright © 2010-2013 Intel Corporation + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that copyright notice and this permission + notice appear in supporting documentation, and that the name of + the copyright holders not be used in advertising or publicity + pertaining to distribution of the software without specific, + written prior permission. The copyright holders make no + representations about the suitability of this software for any + purpose. It is provided "as is" without express or implied + warranty. + + THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + THIS SOFTWARE. + + + + + This interface is implemented by servers that provide + desktop-style user interfaces. + + It allows clients to associate a xdg_surface with + a basic surface. + + + + + Use this enum to check the protocol version, and it will be updated + automatically. + + + + + + + + Use this request in order to enable use of this interface. + + Understand and agree that one is using an unstable interface, + that will likely change in the future, breaking the API. + + + + + + + Create a shell surface for an existing surface. + + Only one shell or popup surface can be associated with a given + surface. + + + + + + + + Create a popup surface for an existing surface. + + Only one shell or popup surface can be associated with a given + surface. + + + + + + + + + + + + + + + + An interface that may be implemented by a wl_surface, for + implementations that provide a desktop-style user interface. + + It provides requests to treat surfaces like windows, allowing to set + properties like maximized, fullscreen, minimized, and to move and resize + them, and associate metadata like title and app id. + + On the server side the object is automatically destroyed when + the related wl_surface is destroyed. On client side, + xdg_surface.destroy() must be called before destroying + the wl_surface object. + + + + + The xdg_surface interface is removed from the wl_surface object + that was turned into a xdg_surface with + xdg_shell.get_xdg_surface request. The xdg_surface properties, + like maximized and fullscreen, are lost. The wl_surface loses + its role as a xdg_surface. The wl_surface is unmapped. + + + + + + Setting a surface as transient of another means that it is child + of another surface. + + Child surfaces are stacked above their parents, and will be + unmapped if the parent is unmapped too. They should not appear + on task bars and alt+tab. + + + + + + + Set a short title for the surface. + + This string may be used to identify the surface in a task bar, + window list, or other user interface elements provided by the + compositor. + + The string must be encoded in UTF-8. + + + + + + + Set an id for the surface. + + The app id identifies the general class of applications to which + the surface belongs. + + It should be the ID that appears in the new desktop entry + specification, the interface name. + + + + + + + A client must respond to a ping event with a pong request or + the client may be deemed unresponsive. + + + + + + + Ping a client to check if it is receiving events and sending + requests. A client is expected to reply with a pong request. + + + + + + + Start a pointer-driven move of the surface. + + This request must be used in response to a button press event. + The server may ignore move requests depending on the state of + the surface (e.g. fullscreen or maximized). + + + + + + + + These values are used to indicate which edge of a surface + is being dragged in a resize operation. The server may + use this information to adapt its behavior, e.g. choose + an appropriate cursor image. + + + + + + + + + + + + + + + Start a pointer-driven resizing of the surface. + + This request must be used in response to a button press event. + The server may ignore resize requests depending on the state of + the surface (e.g. fullscreen or maximized). + + + + + + + + + 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 ratio or resize in steps of NxM pixels). + + The edges parameter provides a hint about how the surface + was resized. The client may use this information to decide + how to adjust its content to the new size (e.g. a scrolling + area might adjust its content position to leave the viewable + content unmoved). Valid edge values are from resize_edge enum. + + The maximized parameter informs if the surface is in a maximized + state. Same for the fullscreen parameter. + + The client is free to dismiss all but the last configure + event it received. + + The width and height arguments specify the size of the window + in surface local coordinates. + + + + + + + + + + + + Set the default output used by this surface when it is first mapped. + + If this value is NULL (default), it's up to the compositor to choose + which display will be used to map this surface. + + When fullscreen or maximized state are set on this surface, and it + wasn't mapped yet, the output set with this method will be used. + Otherwise, the output where the surface is currently mapped will be + used. + + + + + + + Set the surface as fullscreen. + + The compositor must reply to this request with a configure event + with the dimensions for the output on which the surface will be + made fullscreen. + + Once the fullscreen state is set, a "fullscreen_set" event will + be sent to the client. + + Setting one state won't unset another state. Use + xdg_surface.unset_fullscreen for unsetting it. + + + + + + Unset the surface fullscreen state. + + + + + + Set the surface as maximized. + + The compositor must reply to this request with a configure event + with the dimensions for the output on which the surface will be + made maximized. + + Once the maximized state is set, a "maximized_set" event will be + sent to the client. + + Setting one state won't unset another state. Use + xdg_surface.unset_maximized for unsetting it. + + + + + + Unset the surface maximized state. + + + + + + Set the surface minimized state. + + Setting one state won't unset another state. + + + + + + The focused_set event is sent when this surface has been + activated. Window decorations should be updated accordingly. + + + + + + The focused_unset event is sent when this surface has been + deactivated, because another surface has been activated. Window + decorations should be updated accordingly. + + + + + + + An interface that may be implemented by a wl_surface, for + implementations that provide a desktop-style popups/menus. A popup + surface is a transient surface with an added pointer grab. + + An existing implicit grab will be changed to owner-events mode, + and the popup grab will continue after the implicit grab ends + (i.e. releasing the mouse button does not cause the popup to be + unmapped). + + The popup grab continues until the window is destroyed or a mouse + button is pressed in any other clients window. A click in any of + the clients surfaces is reported as normal, however, clicks in + other clients surfaces will be discarded and trigger the callback. + + The x and y arguments specify the locations of the upper left + corner of the surface relative to the upper left corner of the + parent surface, in surface local coordinates. + + xdg_popup surfaces are always transient for another surface. + + + + + The xdg_surface interface is removed from the wl_surface object + that was turned into a xdg_surface with + xdg_shell.get_xdg_surface request. The xdg_surface properties, + like maximized and fullscreen, are lost. The wl_surface loses + its role as a xdg_surface. The wl_surface is unmapped. + + + + + + A client must respond to a ping event with a pong request or + the client may be deemed unresponsive. + + + + + + + Ping a client to check if it is receiving events and sending + requests. A client is expected to reply with a pong request. + + + + + + + The popup_done event is sent out when a popup grab is broken, + that is, when the users clicks a surface that doesn't belong + to the client owning the popup surface. + + + + + + diff --git a/src/Makefile.am b/src/Makefile.am index b2d558421..a8d52bcaf 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -43,6 +43,9 @@ mutter_built_sources = \ wayland/gtk-shell-protocol.c \ wayland/gtk-shell-server-protocol.h \ wayland/gtk-shell-client-protocol.h \ + wayland/xdg-shell-protocol.c \ + wayland/xdg-shell-server-protocol.h \ + wayland/xdg-shell-client-protocol.h \ wayland/xserver-protocol.c \ wayland/xserver-server-protocol.h \ wayland/xserver-client-protocol.h diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 2ec8c75d5..1f6962a5f 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -49,6 +49,7 @@ #include "meta-wayland-pointer.h" #include "meta-wayland-private.h" +#include "xdg-shell-server-protocol.h" #include @@ -532,9 +533,14 @@ meta_wayland_pointer_end_popup_grab (MetaWaylandPointer *pointer) wl_list_for_each_safe (popup, tmp, &popup_grab->all_popups, link) { - MetaWaylandSurfaceExtension *shell_surface = popup->surface->shell_surface; + MetaWaylandSurfaceExtension *shell_surface = popup->surface->xdg_surface; + struct wl_client *client = wl_resource_get_client (shell_surface->resource); + struct wl_display *display = wl_client_get_display (client); + uint32_t serial; - wl_shell_surface_send_popup_done (shell_surface->resource); + serial = wl_display_next_serial (display); + + xdg_popup_send_popup_done (shell_surface->resource, serial); wl_list_remove (&popup->surface_destroy_listener.link); wl_list_remove (&popup->link); g_slice_free (MetaWaylandPopup, popup); diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 5f00ce34a..0a9ebf866 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -39,6 +39,7 @@ #include #include "gtk-shell-server-protocol.h" +#include "xdg-shell-server-protocol.h" #include "meta-wayland-private.h" #include "meta-xwayland-private.h" @@ -492,9 +493,69 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor, } static void -shell_surface_pong (struct wl_client *client, - struct wl_resource *resource, - guint32 serial) +xdg_surface_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + g_warning ("TODO: support xdg_surface.destroy"); +} + +static void +xdg_surface_set_transient_for (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *parent) +{ + MetaWaylandSurfaceExtension *surface_ext = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = surface_ext->surface; + + MetaWaylandSurfaceExtension *parent_ext = wl_resource_get_user_data (parent); + MetaWaylandSurface *parent_surf = parent_ext->surface; + + if (surface->window && parent_surf->window) + meta_window_set_transient_for (surface->window, parent_surf->window); +} + +static void +xdg_surface_set_title (struct wl_client *client, + struct wl_resource *resource, + const char *title) +{ + MetaWaylandSurfaceExtension *extension = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = extension->surface; + + if (surface->window) + meta_window_set_title (surface->window, title); + else + { + ensure_initial_state (surface); + + g_free (surface->initial_state->title); + surface->initial_state->title = g_strdup (title); + } +} + +static void +xdg_surface_set_app_id (struct wl_client *client, + struct wl_resource *resource, + const char *app_id) +{ + MetaWaylandSurfaceExtension *extension = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = extension->surface; + + if (surface->window) + meta_window_set_wm_class (surface->window, app_id, app_id); + else + { + ensure_initial_state (surface); + + g_free (surface->initial_state->app_id); + surface->initial_state->app_id = g_strdup (app_id); + } +} + +static void +xdg_surface_pong (struct wl_client *client, + struct wl_resource *resource, + guint32 serial) { } @@ -568,23 +629,23 @@ static const MetaWaylandPointerGrabInterface move_grab_interface = { }; static void -shell_surface_move (struct wl_client *client, - struct wl_resource *resource, - struct wl_resource *seat_resource, - guint32 serial) +xdg_surface_move (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *seat_resource, + guint32 serial) { MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); - MetaWaylandSurfaceExtension *shell_surface = wl_resource_get_user_data (resource); + MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); MetaWindow *window; MetaWaylandMoveGrab *move_grab; MetaRectangle rect; if (seat->pointer.button_count == 0 || seat->pointer.grab_serial != serial || - seat->pointer.focus != shell_surface->surface) + seat->pointer.focus != xdg_surface->surface) return; - window = shell_surface->surface->window; + window = xdg_surface->surface->window; if (!window) return; @@ -595,15 +656,15 @@ shell_surface_move (struct wl_client *client, move_grab = g_slice_new (MetaWaylandMoveGrab); - meta_window_get_input_rect (shell_surface->surface->window, + meta_window_get_input_rect (xdg_surface->surface->window, &rect); move_grab->generic.interface = &move_grab_interface; move_grab->generic.pointer = &seat->pointer; - move_grab->surface = shell_surface->surface; + move_grab->surface = xdg_surface->surface; move_grab->surface_destroy_listener.notify = move_grab_lose_surface; - wl_resource_add_destroy_listener (shell_surface->surface->resource, + wl_resource_add_destroy_listener (xdg_surface->surface->resource, &move_grab->surface_destroy_listener); move_grab->dx = wl_fixed_from_int (rect.x) - seat->pointer.grab_x; @@ -622,209 +683,97 @@ shell_surface_move (struct wl_client *client, * XXX: For now we just focus the surface directly associated with * the grab. */ - meta_wayland_pointer_set_focus (&seat->pointer, shell_surface->surface); + meta_wayland_pointer_set_focus (&seat->pointer, xdg_surface->surface); } static void -shell_surface_resize (struct wl_client *client, +xdg_surface_resize (struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat, guint32 serial, guint32 edges) { - g_warning ("TODO: support shell_surface_resize request"); + g_warning ("TODO: support xdg_surface.resize"); } static void -shell_surface_set_toplevel (struct wl_client *client, +xdg_surface_set_output (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *output) +{ + g_warning ("TODO: support xdg_surface.set_output"); +} + +static void +xdg_surface_set_fullscreen (struct wl_client *client, struct wl_resource *resource) { - 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) - { - 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); - - surface->initial_state->initial_type = META_WAYLAND_SURFACE_TOPLEVEL; - } -} - -static void -shell_surface_set_transient (struct wl_client *client, - struct wl_resource *resource, - struct wl_resource *parent, - int x, - int y, - guint32 flags) -{ - 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; - - 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 -shell_surface_set_fullscreen (struct wl_client *client, - struct wl_resource *resource, - guint32 method, - guint32 framerate, - struct wl_resource *output) -{ - 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; + MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = xdg_surface->surface; if (surface->window) meta_window_make_fullscreen (surface->window); - else - { - ensure_initial_state (surface); - - surface->initial_state->initial_type = META_WAYLAND_SURFACE_FULLSCREEN; - } } static void -shell_surface_set_popup (struct wl_client *client, - struct wl_resource *resource, - struct wl_resource *seat_resource, - guint32 serial, - struct wl_resource *parent, - gint32 x, - gint32 y, - guint32 flags) +xdg_surface_unset_fullscreen (struct wl_client *client, + struct wl_resource *resource) { - MetaWaylandSurfaceExtension *shell_surface = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = shell_surface->surface; - MetaWaylandCompositor *compositor = surface->compositor; - MetaWaylandSeat *seat = compositor->seat; - - if (serial < seat->pointer.click_serial) - { - /* stale request */ - return; - } + MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = xdg_surface->surface; if (surface->window) - { - meta_warning ("Client set_popup() on an already visible window, this is not supported\n"); - } - else - { - ensure_initial_state (surface); - - surface->initial_state->initial_type = META_WAYLAND_SURFACE_POPUP; - surface->initial_state->transient_for = parent; - surface->initial_state->x = x; - surface->initial_state->y = y; - } - + meta_window_unmake_fullscreen (surface->window); } static void -shell_surface_set_maximized (struct wl_client *client, - struct wl_resource *resource, - struct wl_resource *output) +xdg_surface_set_maximized (struct wl_client *client, + struct wl_resource *resource) { - 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; + MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = xdg_surface->surface; 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 -shell_surface_set_title (struct wl_client *client, - struct wl_resource *resource, - const char *title) +xdg_surface_unset_maximized (struct wl_client *client, + struct wl_resource *resource) { - MetaWaylandSurfaceExtension *extension = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = extension->surface; + MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = xdg_surface->surface; if (surface->window) - meta_window_set_title (surface->window, title); - else - { - ensure_initial_state (surface); - - g_free (surface->initial_state->title); - surface->initial_state->title = g_strdup (title); - } + meta_window_unmaximize (surface->window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL); } static void -shell_surface_set_class (struct wl_client *client, - struct wl_resource *resource, - const char *class_) +xdg_surface_set_minimized (struct wl_client *client, + struct wl_resource *resource) { - MetaWaylandSurfaceExtension *extension = wl_resource_get_user_data (resource); - MetaWaylandSurface *surface = extension->surface; + MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = xdg_surface->surface; if (surface->window) - meta_window_set_wm_class (surface->window, class_, class_); - else - { - ensure_initial_state (surface); - - g_free (surface->initial_state->wm_class); - surface->initial_state->wm_class = g_strdup (class_); - } + meta_window_minimize (surface->window); } -static const struct wl_shell_surface_interface meta_wayland_shell_surface_interface = +static const struct xdg_surface_interface meta_wayland_xdg_surface_interface = { - shell_surface_pong, - shell_surface_move, - shell_surface_resize, - shell_surface_set_toplevel, - shell_surface_set_transient, - shell_surface_set_fullscreen, - shell_surface_set_popup, - shell_surface_set_maximized, - shell_surface_set_title, - shell_surface_set_class + xdg_surface_destroy, + xdg_surface_set_transient_for, + xdg_surface_set_title, + xdg_surface_set_app_id, + xdg_surface_pong, + xdg_surface_move, + xdg_surface_resize, + xdg_surface_set_output, + xdg_surface_set_fullscreen, + xdg_surface_unset_fullscreen, + xdg_surface_set_maximized, + xdg_surface_unset_maximized, + xdg_surface_set_minimized, }; static void @@ -845,9 +794,7 @@ destroy_surface_extension (struct wl_resource *resource) /* In case cleaning up a dead client destroys extension first */ if (extension->surface) - { - wl_list_remove (&extension->surface_destroy_listener.link); - } + wl_list_remove (&extension->surface_destroy_listener.link); g_free (extension); } @@ -879,43 +826,69 @@ create_surface_extension (struct wl_client *client, } static void -get_shell_surface (struct wl_client *client, - struct wl_resource *resource, - guint32 id, - struct wl_resource *surface_resource) +use_unstable_version (struct wl_client *client, + struct wl_resource *resource, + int32_t version) +{ + if (version != META_XDG_SHELL_VERSION) + g_warning ("Bad xdg_shell version: %d", version); +} + +static void +get_xdg_surface (struct wl_client *client, + struct wl_resource *resource, + guint32 id, + struct wl_resource *surface_resource) { MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); - if (surface->shell_surface) + if (surface->xdg_surface) { wl_resource_post_error (surface_resource, WL_DISPLAY_ERROR_INVALID_OBJECT, - "wl_shell::get_shell_surface already requested"); + "xdg_shell::get_xdg_surface already requested"); return; } - surface->shell_surface = create_surface_extension (client, resource, id, - META_WL_SHELL_SURFACE_VERSION, surface, - &wl_shell_surface_interface, - &meta_wayland_shell_surface_interface); + surface->xdg_surface = create_surface_extension (client, resource, id, + META_XDG_SURFACE_VERSION, surface, + &xdg_surface_interface, + &meta_wayland_xdg_surface_interface); } -static const struct wl_shell_interface meta_wayland_shell_interface = +static void +get_xdg_popup (struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *surface, + struct wl_resource *parent, + struct wl_resource *seat, + uint32_t serial, + int32_t x, + int32_t y, + uint32_t flags) { - get_shell_surface + g_warning ("TODO: support xdg_shell.get_xdg_popup"); +} + +static const struct xdg_shell_interface meta_wayland_xdg_shell_interface = +{ + use_unstable_version, + get_xdg_surface, + get_xdg_popup, }; static void -bind_shell (struct wl_client *client, - void *data, - guint32 version, - guint32 id) +bind_xdg_shell (struct wl_client *client, + void *data, + guint32 version, + guint32 id) { struct wl_resource *resource; - resource = wl_resource_create (client, &wl_shell_interface, - MIN (META_WL_SHELL_VERSION, version), id); - wl_resource_set_implementation (resource, &meta_wayland_shell_interface, data, NULL); + resource = wl_resource_create (client, &xdg_shell_interface, + MIN (META_XDG_SHELL_VERSION, version), id); + wl_resource_set_implementation (resource, &meta_wayland_xdg_shell_interface, data, NULL); } static void @@ -993,7 +966,7 @@ get_gtk_surface (struct wl_client *client, { wl_resource_post_error (surface_resource, WL_DISPLAY_ERROR_INVALID_OBJECT, - "wl_shell::get_gtk_surface already requested"); + "gtk_shell::get_gtk_surface already requested"); return; } @@ -1028,10 +1001,10 @@ void meta_wayland_init_shell (MetaWaylandCompositor *compositor) { if (wl_global_create (compositor->wayland_display, - &wl_shell_interface, - META_WL_SHELL_VERSION, - compositor, bind_shell) == NULL) - g_error ("Failed to register a global shell object"); + &xdg_shell_interface, + META_XDG_SHELL_VERSION, + compositor, bind_xdg_shell) == NULL) + g_error ("Failed to register a global xdg-shell object"); if (wl_global_create (compositor->wayland_display, >k_shell_interface, @@ -1072,7 +1045,7 @@ meta_wayland_surface_set_initial_state (MetaWaylandSurface *surface, window->showing_for_first_time = FALSE; window->placed = TRUE; if (!meta_wayland_pointer_start_popup_grab (&seat->pointer, surface)) - wl_shell_surface_send_popup_done (surface->shell_surface->resource); + xdg_popup_send_popup_done (surface->xdg_surface->resource); break; default: g_assert_not_reached (); @@ -1098,8 +1071,8 @@ meta_wayland_surface_set_initial_state (MetaWaylandSurface *surface, if (initial->title) meta_window_set_title (window, initial->title); - if (initial->wm_class) - meta_window_set_wm_class (window, initial->wm_class, initial->wm_class); + if (initial->app_id) + meta_window_set_wm_class (window, initial->app_id, initial->app_id); meta_window_set_gtk_dbus_properties (window, initial->gtk_application_id, @@ -1128,7 +1101,7 @@ static void free_initial_state (MetaWaylandSurfaceInitialState *initial) { g_free (initial->title); - g_free (initial->wm_class); + g_free (initial->app_id); g_free (initial->gtk_application_id); g_free (initial->gtk_unique_bus_name); @@ -1146,7 +1119,9 @@ meta_wayland_surface_configure_notify (MetaWaylandSurface *surface, int new_height, int edges) { - if (surface->shell_surface) - wl_shell_surface_send_configure (surface->shell_surface->resource, - edges, new_width, new_height); + if (surface->xdg_surface) + xdg_surface_send_configure (surface->xdg_surface->resource, + edges, new_width, new_height, + 0, 0 /* XXX: support this */); } + diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index 1a1b3adc5..35348fe28 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -80,7 +80,7 @@ typedef struct int x, y; char *title; - char *wm_class; + char *app_id; char *gtk_application_id; char *gtk_unique_bus_name; @@ -103,7 +103,7 @@ struct _MetaWaylandSurface MetaWaylandCompositor *compositor; MetaWaylandBufferReference buffer_ref; MetaWindow *window; - MetaWaylandSurfaceExtension *shell_surface; + MetaWaylandSurfaceExtension *xdg_surface; MetaWaylandSurfaceExtension *gtk_surface; /* All the pending state, that wl_surface.commit will apply. */ diff --git a/src/wayland/meta-wayland-versions.h b/src/wayland/meta-wayland-versions.h index 1cb569b44..37aa4e3ca 100644 --- a/src/wayland/meta-wayland-versions.h +++ b/src/wayland/meta-wayland-versions.h @@ -37,23 +37,23 @@ /* Global/master objects (version exported by wl_registry and negotiated through bind) */ #define META_WL_COMPOSITOR_VERSION 3 #define META_WL_DATA_DEVICE_MANAGER_VERSION 1 -#define META_WL_SHELL_VERSION 1 #define META_WL_SEAT_VERSION 2 /* 3 not implemented yet */ #define META_WL_OUTPUT_VERSION 2 #define META_XSERVER_VERSION 1 #define META_GTK_SHELL_VERSION 1 +#define META_XDG_SHELL_VERSION 1 /* Slave objects (version inherited from a master object) */ #define META_WL_DATA_OFFER_VERSION 1 /* from wl_data_device */ #define META_WL_DATA_SOURCE_VERSION 1 /* from wl_data_device */ #define META_WL_DATA_DEVICE_VERSION 1 /* from wl_data_device_manager */ -#define META_WL_SHELL_SURFACE_VERSION 1 /* from wl_shell */ #define META_WL_SURFACE_VERSION 3 /* from wl_compositor */ #define META_WL_POINTER_VERSION 2 /* from wl_seat; 3 not implemented yet */ #define META_WL_KEYBOARD_VERSION 2 /* from wl_seat; 3 not implemented yet */ #define META_WL_TOUCH_VERSION 0 /* from wl_seat; wl_touch not supported */ #define META_WL_REGION_VERSION 1 /* from wl_compositor */ #define META_GTK_SURFACE_VERSION 1 /* from gtk_shell */ +#define META_XDG_SURFACE_VERSION 1 /* from xdg_shell */ /* The first version to implement a specific event */ #define META_WL_SEAT_HAS_NAME 2