From eed03d38b022ef018aed8ceb07ea78ce19db0774 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 11 Apr 2014 22:46:26 -0700 Subject: [PATCH] Update to latest xdg-shell protocol --- src/core/window.c | 20 --- src/wayland/meta-wayland-surface.c | 220 +++++++++++++++-------------- src/wayland/meta-wayland-surface.h | 9 -- src/wayland/protocol/xdg-shell.xml | 149 +++++++------------ 4 files changed, 163 insertions(+), 235 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index 9e329671d..aebdc40a5 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -2968,9 +2968,6 @@ meta_window_maximize_internal (MetaWindow *window, meta_window_recalc_features (window); set_net_wm_state (window); - if (window->surface && window->maximized_horizontally && window->maximized_vertically) - meta_wayland_surface_send_maximized (window->surface); - g_object_freeze_notify (G_OBJECT (window)); g_object_notify (G_OBJECT (window), "maximized-horizontally"); g_object_notify (G_OBJECT (window), "maximized-vertically"); @@ -3422,9 +3419,6 @@ meta_window_unmaximize_internal (MetaWindow *window, set_net_wm_state (window); } - if (window->surface && !window->maximized_horizontally && !window->maximized_vertically) - meta_wayland_surface_send_unmaximized (window->surface); - g_object_freeze_notify (G_OBJECT (window)); g_object_notify (G_OBJECT (window), "maximized-horizontally"); g_object_notify (G_OBJECT (window), "maximized-vertically"); @@ -3531,9 +3525,6 @@ meta_window_make_fullscreen_internal (MetaWindow *window) /* For the auto-minimize feature, if we fail to get focus */ meta_screen_queue_check_fullscreen (window->screen); - if (window->surface) - meta_wayland_surface_send_fullscreened (window->surface); - g_object_notify (G_OBJECT (window), "fullscreen"); } } @@ -3590,9 +3581,6 @@ meta_window_unmake_fullscreen (MetaWindow *window) meta_window_update_layer (window); - if (window->surface) - meta_wayland_surface_send_unfullscreened (window->surface); - g_object_notify (G_OBJECT (window), "fullscreen"); } } @@ -5566,14 +5554,6 @@ meta_window_appears_focused_changed (MetaWindow *window) if (window->frame) meta_frame_queue_draw (window->frame); - - if (window->surface) - { - if (meta_window_appears_focused (window)) - meta_wayland_surface_activated (window->surface); - else - meta_wayland_surface_deactivated (window->surface); - } } /** diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index e4d3cb8c0..77000b274 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -519,12 +519,42 @@ sync_reactive (MetaWaylandSurface *surface) surface_should_be_reactive (surface)); } +static void +surface_state_changed (MetaWaylandSurface *surface) +{ + if (surface->window) + meta_wayland_surface_configure_notify (surface, + surface->window->rect.width, + surface->window->rect.height); +} + +static void +window_appears_focused_changed (MetaWindow *window, + GParamSpec *pspec, + gpointer user_data) +{ + MetaWaylandSurface *surface = user_data; + + surface_state_changed (surface); +} + void meta_wayland_surface_set_window (MetaWaylandSurface *surface, MetaWindow *window) { + if (surface->window) + { + g_signal_handlers_disconnect_by_func (surface->window, window_appears_focused_changed, surface); + } + surface->window = window; + if (surface->window) + { + g_signal_connect (surface->window, "notify::appears-focused", + G_CALLBACK (window_appears_focused_changed), surface); + } + sync_reactive (surface); } @@ -791,46 +821,9 @@ xdg_surface_resize (struct wl_client *client, } static void -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_request_change_state (struct wl_client *client, - struct wl_resource *resource, - uint32_t state_type, - uint32_t value, - uint32_t serial) -{ - MetaWaylandSurface *surface = wl_resource_get_user_data (resource); - - surface->state_changed_serial = serial; - - switch (state_type) - { - case XDG_SURFACE_STATE_MAXIMIZED: - if (value) - meta_window_maximize (surface->window, META_MAXIMIZE_BOTH); - else - meta_window_unmaximize (surface->window, META_MAXIMIZE_BOTH); - break; - case XDG_SURFACE_STATE_FULLSCREEN: - if (value) - meta_window_make_fullscreen (surface->window); - else - meta_window_unmake_fullscreen (surface->window); - } -} - -static void -xdg_surface_ack_change_state (struct wl_client *client, - struct wl_resource *resource, - uint32_t state_type, - uint32_t value, - uint32_t serial) +xdg_surface_ack_configure (struct wl_client *client, + struct wl_resource *resource, + uint32_t serial) { /* Do nothing for now. In the future, we'd imagine that * we'd ignore attaches when we have a state pending that @@ -839,12 +832,44 @@ xdg_surface_ack_change_state (struct wl_client *client, * client gets the new state. */ } +static void +xdg_surface_set_maximized (struct wl_client *client, + struct wl_resource *resource) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); + meta_window_maximize (surface->window, META_MAXIMIZE_BOTH); +} + +static void +xdg_surface_unset_maximized (struct wl_client *client, + struct wl_resource *resource) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); + meta_window_unmaximize (surface->window, META_MAXIMIZE_BOTH); +} + +static void +xdg_surface_set_fullscreen (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *output_resource) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); + meta_window_make_fullscreen (surface->window); +} + +static void +xdg_surface_unset_fullscreen (struct wl_client *client, + struct wl_resource *resource) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); + meta_window_unmake_fullscreen (surface->window); +} + static void xdg_surface_set_minimized (struct wl_client *client, struct wl_resource *resource) { MetaWaylandSurface *surface = wl_resource_get_user_data (resource); - meta_window_minimize (surface->window); } @@ -856,9 +881,11 @@ static const struct xdg_surface_interface meta_wayland_xdg_surface_interface = { xdg_surface_set_app_id, xdg_surface_move, xdg_surface_resize, - xdg_surface_set_output, - xdg_surface_request_change_state, - xdg_surface_ack_change_state, + xdg_surface_ack_configure, + xdg_surface_set_maximized, + xdg_surface_unset_maximized, + xdg_surface_set_fullscreen, + xdg_surface_unset_fullscreen, xdg_surface_set_minimized, }; @@ -1661,82 +1688,57 @@ meta_wayland_shell_init (MetaWaylandCompositor *compositor) g_error ("Failed to register a global wl-subcompositor object"); } +static void +fill_states (struct wl_array *states, MetaWindow *window) +{ + uint32_t *s; + + if (META_WINDOW_MAXIMIZED (window)) + { + s = wl_array_add (states, sizeof *s); + *s = XDG_SURFACE_STATE_MAXIMIZED; + } + if (meta_window_is_fullscreen (window)) + { + s = wl_array_add (states, sizeof *s); + *s = XDG_SURFACE_STATE_FULLSCREEN; + } + if (meta_grab_op_is_resizing (window->display->grab_op)) + { + s = wl_array_add (states, sizeof *s); + *s = XDG_SURFACE_STATE_RESIZING; + } + if (meta_window_appears_focused (window)) + { + s = wl_array_add (states, sizeof *s); + *s = XDG_SURFACE_STATE_ACTIVATED; + } +} + void meta_wayland_surface_configure_notify (MetaWaylandSurface *surface, int new_width, int new_height) { if (surface->xdg_surface.resource) - xdg_surface_send_configure (surface->xdg_surface.resource, - new_width, new_height); + { + struct wl_client *client = wl_resource_get_client (surface->xdg_surface.resource); + struct wl_display *display = wl_client_get_display (client); + uint32_t serial = wl_display_next_serial (display); + struct wl_array states; + + wl_array_init (&states); + fill_states (&states, surface->window); + + xdg_surface_send_configure (surface->xdg_surface.resource, new_width, new_height, &states, serial); + + wl_array_release (&states); + } else if (surface->wl_shell_surface.resource) wl_shell_surface_send_configure (surface->wl_shell_surface.resource, 0, new_width, new_height); } -static void -send_change_state (MetaWaylandSurface *surface, - uint32_t state_type, - uint32_t value) -{ - if (surface->xdg_surface.resource) - { - uint32_t serial; - - if (surface->state_changed_serial != 0) - { - serial = surface->state_changed_serial; - surface->state_changed_serial = 0; - } - else - { - struct wl_client *client = wl_resource_get_client (surface->xdg_surface.resource); - struct wl_display *display = wl_client_get_display (client); - serial = wl_display_next_serial (display); - } - - xdg_surface_send_change_state (surface->xdg_surface.resource, state_type, value, serial); - } -} - -void -meta_wayland_surface_send_maximized (MetaWaylandSurface *surface) -{ - send_change_state (surface, XDG_SURFACE_STATE_MAXIMIZED, TRUE); -} - -void -meta_wayland_surface_send_unmaximized (MetaWaylandSurface *surface) -{ - send_change_state (surface, XDG_SURFACE_STATE_MAXIMIZED, FALSE); -} - -void -meta_wayland_surface_send_fullscreened (MetaWaylandSurface *surface) -{ - send_change_state (surface, XDG_SURFACE_STATE_FULLSCREEN, TRUE); -} - -void -meta_wayland_surface_send_unfullscreened (MetaWaylandSurface *surface) -{ - send_change_state (surface, XDG_SURFACE_STATE_FULLSCREEN, FALSE); -} - -void -meta_wayland_surface_activated (MetaWaylandSurface *surface) -{ - if (surface->xdg_surface.resource) - xdg_surface_send_activated (surface->xdg_surface.resource); -} - -void -meta_wayland_surface_deactivated (MetaWaylandSurface *surface) -{ - if (surface->xdg_surface.resource) - xdg_surface_send_deactivated (surface->xdg_surface.resource); -} - void meta_wayland_surface_ping (MetaWaylandSurface *surface, guint32 serial) diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index fc744e81e..62d631e61 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -106,8 +106,6 @@ struct _MetaWaylandSurface GSList *pending_placement_ops; } sub; - uint32_t state_changed_serial; - /* All the pending state that wl_surface.commit will apply. */ MetaWaylandPendingState pending; }; @@ -125,13 +123,6 @@ void meta_wayland_surface_set_window (MetaWaylandSurface *surface void meta_wayland_surface_configure_notify (MetaWaylandSurface *surface, int width, int height); -void meta_wayland_surface_send_maximized (MetaWaylandSurface *surface); -void meta_wayland_surface_send_unmaximized (MetaWaylandSurface *surface); -void meta_wayland_surface_send_fullscreened (MetaWaylandSurface *surface); -void meta_wayland_surface_send_unfullscreened (MetaWaylandSurface *surface); - -void meta_wayland_surface_activated (MetaWaylandSurface *surface); -void meta_wayland_surface_deactivated (MetaWaylandSurface *surface); void meta_wayland_surface_ping (MetaWaylandSurface *surface, guint32 serial); diff --git a/src/wayland/protocol/xdg-shell.xml b/src/wayland/protocol/xdg-shell.xml index 788269347..3c186102b 100644 --- a/src/wayland/protocol/xdg-shell.xml +++ b/src/wayland/protocol/xdg-shell.xml @@ -241,40 +241,6 @@ - - - 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 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. - - - - The different state values used on the surface. This is designed for @@ -297,89 +263,78 @@ 0x1000 - 0x1FFF: GNOME - A non-zero value indicates the surface is maximized. Otherwise, - the surface is unmaximized. + The surface is maximized. The window geometry specified in the configure + event must be obeyed by the client. - A non-zero value indicates the surface is fullscreen. Otherwise, - the surface is not fullscreen. + The surface is fullscreen. The window geometry specified in the configure + event must be obeyed by the client. + + + The surface is being resized. The window geometry specified in the + configure event is a maximum; the client cannot resize beyond it. + Clients that have aspect ratio or cell sizing configuration can use + a smaller size, however. + + + Client window decorations should be painted as if the window is + active. Do not assume this means that the window actually has + keyboard or pointer focus. - - - This asks the compositor to change the state. If the compositor wants - to change the state, it will send a change_state event with the same - state_type, value, and serial, and the event flow continues as if it - it was initiated by the compositor. + + + The configure event asks the client to resize its surface. - If the compositor does not want to change the state, it will send a - change_state to the client with the old value of the state. - - - - - This serial is so the client can know which change_state event corresponds - to which request_change_state request it sent out. - - + The width and height arguments specify a hint to the window + about how its surface should be resized in surface local + coordinates. The states listed in the event specify how the + width/height arguments should be interpreted. - - - This event tells the client to change a surface's state. The client - should respond with an ack_change_state request to the compositor to - guarantee that the compositor knows that the client has seen it. + A client should arrange a new surface, and then send a + ack_configure request with the serial sent in this configure + event before attaching a new surface. + + If the client receives multiple configure events before it + can respond to one, it is free to discard all but the last + event it received. - - - + + + + - - - When a change_state event is received, a client should then ack it - using the ack_change_state request to ensure that the compositor + + + When a configure event is received, a client should then ack it + using the ack_configure request to ensure that the compositor knows the client has seen the event. By this point, the state is confirmed, and the next attach should - contain the buffer drawn for the new state value. - - The values here need to be the same as the values in the cooresponding - change_state event. + contain the buffer drawn for the configure event you are acking. - - - + - - - Minimize the surface. + + + + + + Make the surface fullscreen. + + You can specify an output that you would prefer to be fullscreen. + If this value is NULL, it's up to the compositor to choose which + display will be used to map this surface. + + - - - The activated_set event is sent when this surface has been - activated, which means that the surface has user attention. - Window decorations should be updated accordingly. You should - not use this event for anything but the style of decorations - you display, use wl_keyboard.enter and wl_keyboard.leave for - determining keyboard focus. - - - - - - The deactivate event is sent when this surface has been - deactivated, which means that the surface lost user attention. - Window decorations should be updated accordingly. You should - not use this event for anything but the style of decorations - you display, use wl_keyboard.enter and wl_keyboard.leave for - determining keyboard focus. - - +