summaryrefslogtreecommitdiff
path: root/src/wayland
diff options
context:
space:
mode:
authorJasper St. Pierre <jstpierre@mecheye.net>2014-04-23 16:01:07 -0400
committerJasper St. Pierre <jstpierre@mecheye.net>2014-05-05 14:15:03 -0400
commitfd5c14550a0e75912beeff9d203dbcaef90f0368 (patch)
tree9ffc655126a2988121ec2ca37fbef41e45eb54d3 /src/wayland
parenta5cca5296cd4a3caed214e6203cd313caad3d89a (diff)
downloadmutter-fd5c14550a0e75912beeff9d203dbcaef90f0368.tar.gz
Update to latest xdg-shell protocol
Diffstat (limited to 'src/wayland')
-rw-r--r--src/wayland/meta-wayland-surface.c214
-rw-r--r--src/wayland/meta-wayland-surface.h9
-rw-r--r--src/wayland/protocol/xdg-shell.xml149
3 files changed, 160 insertions, 212 deletions
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index cd35e6431..b5402c74e 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -584,12 +584,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);
}
@@ -857,52 +887,48 @@ 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)
+xdg_surface_ack_configure (struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t serial)
{
- g_warning ("TODO: support xdg_surface.set_output");
+ /* Do nothing for now. In the future, we'd imagine that
+ * we'd ignore attaches when we have a state pending that
+ * we haven't had the client ACK'd, to prevent a race
+ * condition when we have an in-flight attach when the
+ * client gets the new state. */
}
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)
+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);
+}
- surface->state_changed_serial = serial;
+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);
+}
- 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_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_ack_change_state (struct wl_client *client,
- struct wl_resource *resource,
- uint32_t state_type,
- uint32_t value,
- uint32_t serial)
+xdg_surface_unset_fullscreen (struct wl_client *client,
+ struct wl_resource *resource)
{
- /* Do nothing for now. In the future, we'd imagine that
- * we'd ignore attaches when we have a state pending that
- * we haven't had the client ACK'd, to prevent a race
- * condition when we have an in-flight attach when the
- * client gets the new state. */
+ MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
+ meta_window_unmake_fullscreen (surface->window);
}
static void
@@ -910,7 +936,6 @@ 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);
}
@@ -922,9 +947,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,
};
@@ -1727,86 +1754,61 @@ meta_wayland_shell_init (MetaWaylandCompositor *compositor)
g_error ("Failed to register a global wl-subcompositor object");
}
-void
-meta_wayland_surface_configure_notify (MetaWaylandSurface *surface,
- int new_width,
- int new_height)
-{
- /* new_width and new_height comes from window->rect,
- * which is based on the buffer size, not the surface
- * size. The configure event requires surface size. */
- new_width /= surface->scale;
- new_height /= surface->scale;
-
- if (surface->xdg_surface.resource)
- xdg_surface_send_configure (surface->xdg_surface.resource,
- new_width, new_height);
- 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)
+fill_states (struct wl_array *states, MetaWindow *window)
{
- if (surface->xdg_surface.resource)
- {
- uint32_t serial;
+ uint32_t *s;
- 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);
+ 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_send_maximized (MetaWaylandSurface *surface)
-{
- send_change_state (surface, XDG_SURFACE_STATE_MAXIMIZED, TRUE);
-}
-
-void
-meta_wayland_surface_send_unmaximized (MetaWaylandSurface *surface)
+meta_wayland_surface_configure_notify (MetaWaylandSurface *surface,
+ int new_width,
+ int new_height)
{
- send_change_state (surface, XDG_SURFACE_STATE_MAXIMIZED, FALSE);
-}
+ if (surface->xdg_surface.resource)
+ {
+ 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;
-void
-meta_wayland_surface_send_fullscreened (MetaWaylandSurface *surface)
-{
- send_change_state (surface, XDG_SURFACE_STATE_FULLSCREEN, TRUE);
-}
+ wl_array_init (&states);
+ fill_states (&states, surface->window);
-void
-meta_wayland_surface_send_unfullscreened (MetaWaylandSurface *surface)
-{
- send_change_state (surface, XDG_SURFACE_STATE_FULLSCREEN, FALSE);
-}
+ /* new_width and new_height comes from window->rect, which is based on
+ * the buffer size, not the surface size. The configure event requires
+ * surface size. */
+ new_width /= surface->scale;
+ new_height /= surface->scale;
-void
-meta_wayland_surface_activated (MetaWaylandSurface *surface)
-{
- if (surface->xdg_surface.resource)
- xdg_surface_send_activated (surface->xdg_surface.resource);
-}
+ xdg_surface_send_configure (surface->xdg_surface.resource, new_width, new_height, &states, serial);
-void
-meta_wayland_surface_deactivated (MetaWaylandSurface *surface)
-{
- if (surface->xdg_surface.resource)
- xdg_surface_send_deactivated (surface->xdg_surface.resource);
+ 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);
}
void
diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h
index 91a0b1057..c808e6dc6 100644
--- a/src/wayland/meta-wayland-surface.h
+++ b/src/wayland/meta-wayland-surface.h
@@ -109,8 +109,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;
};
@@ -128,13 +126,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 @@
<arg name="edges" type="uint" summary="which edge or corner is being dragged"/>
</request>
- <event name="configure">
- <description summary="suggest resize">
- 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.
- </description>
-
- <arg name="width" type="int"/>
- <arg name="height" type="int"/>
- </event>
-
- <request name="set_output">
- <description summary="set the default output used by this surface">
- 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.
- </description>
- <arg name="output" type="object" interface="wl_output" allow-null="true"/>
- </request>
-
<enum name="state">
<description summary="types of state on the surface">
The different state values used on the surface. This is designed for
@@ -297,89 +263,78 @@
0x1000 - 0x1FFF: GNOME
</description>
<entry name="maximized" value="1" summary="the surface is maximized">
- 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.
</entry>
<entry name="fullscreen" value="2" summary="the surface is fullscreen">
- 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.
+ </entry>
+ <entry name="resizing" value="3">
+ 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.
+ </entry>
+ <entry name="activated" value="4">
+ 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.
</entry>
</enum>
- <request name="request_change_state">
- <description summary="client requests to change a surface's state">
- 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.
+ <event name="configure">
+ <description summary="suggest a surface chnage">
+ 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.
- </description>
- <arg name="state_type" type="uint" summary="the state to set"/>
- <arg name="value" type="uint" summary="the value to change the state to"/>
- <arg name="serial" type="uint" summary="an event serial">
- This serial is so the client can know which change_state event corresponds
- to which request_change_state request it sent out.
- </arg>
- </request>
+ 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.
- <event name="change_state">
- <description summary="compositor wants to change a surface's state">
- 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.
</description>
- <arg name="state_type" type="uint" summary="the state to set"/>
- <arg name="value" type="uint" summary="the value to change the state to"/>
- <arg name="serial" type="uint" summary="a serial for the compositor's own tracking"/>
+ <arg name="width" type="int"/>
+ <arg name="height" type="int"/>
+ <arg name="states" type="array"/>
+ <arg name="serial" type="uint"/>
</event>
- <request name="ack_change_state">
- <description summary="ack a change_state event">
- When a change_state event is received, a client should then ack it
- using the ack_change_state request to ensure that the compositor
+ <request name="ack_configure">
+ <description summary="ack a configure event">
+ 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.
</description>
- <arg name="state_type" type="uint" summary="the state to set"/>
- <arg name="value" type="uint" summary="the value to change the state to"/>
- <arg name="serial" type="uint" summary="a serial to pass to change_state"/>
+ <arg name="serial" type="uint" summary="a serial to configure for"/>
</request>
- <request name="set_minimized">
- <description summary="minimize the surface">
- Minimize the surface.
- </description>
- </request>
+ <request name="set_maximized" />
+ <request name="unset_maximized" />
- <event name="activated">
- <description summary="surface was activated">
- 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.
- </description>
- </event>
+ <request name="set_fullscreen">
+ <description summary="set the window as fullscreen on a monitor">
+ Make the surface fullscreen.
- <event name="deactivated">
- <description summary="surface was deactivated">
- 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.
+ 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.
</description>
- </event>
+ <arg name="output" type="object" interface="wl_output" allow-null="true"/>
+ </request>
+ <request name="unset_fullscreen" />
+
+ <request name="set_minimized" />
<event name="close">
<description summary="surface wants to be closed">