commit 3509094243c822fdbca518341b1f219d524d39b6
parent 10a70b62b5ee56192b0ee5edbf79e077b3a3f748
Author: Michael Forney <mforney@mforney.org>
Date: Tue, 25 Feb 2014 14:09:23 -0800
shell_surface: Add basic support for state transitions
Diffstat:
4 files changed, 62 insertions(+), 19 deletions(-)
diff --git a/libswc/compositor.c b/libswc/compositor.c
@@ -518,6 +518,11 @@ void compositor_view_destroy(struct compositor_view * view)
free(view);
}
+struct compositor_view * compositor_view(struct view * view)
+{
+ return view->impl == &view_impl ? (struct compositor_view *) view : NULL;
+}
+
void compositor_view_set_parent(struct compositor_view * view,
struct compositor_view * parent)
{
diff --git a/libswc/compositor.h b/libswc/compositor.h
@@ -71,6 +71,11 @@ struct compositor_view * swc_compositor_create_view
void compositor_view_destroy(struct compositor_view * view);
+/**
+ * Returns view as a compositor_view, or NULL if view is not a compositor_view.
+ */
+struct compositor_view * compositor_view(struct view * view);
+
void compositor_view_set_parent(struct compositor_view * view,
struct compositor_view * parent);
diff --git a/libswc/shell_surface.c b/libswc/shell_surface.c
@@ -24,6 +24,8 @@
#include "shell_surface.h"
#include "compositor.h"
#include "internal.h"
+#include "output.h"
+#include "screen.h"
#include "seat.h"
#include "surface.h"
#include "swc.h"
@@ -39,16 +41,6 @@ struct shell_surface
struct wl_resource * resource;
struct wl_listener surface_destroy_listener;
-
- enum
- {
- SHELL_SURFACE_TYPE_UNSPECIFIED,
- SHELL_SURFACE_TYPE_TOPLEVEL,
- SHELL_SURFACE_TYPE_TRANSIENT,
- SHELL_SURFACE_TYPE_FULLSCREEN,
- SHELL_SURFACE_TYPE_POPUP,
- SHELL_SURFACE_TYPE_MAXIMIZED
- } type;
};
static void pong(struct wl_client * client, struct wl_resource * resource,
@@ -86,11 +78,8 @@ static void set_toplevel(struct wl_client * client,
{
struct shell_surface * shell_surface = wl_resource_get_user_data(resource);
- if (shell_surface->type == SHELL_SURFACE_TYPE_TOPLEVEL)
- return;
-
- shell_surface->type = SHELL_SURFACE_TYPE_TOPLEVEL;
window_set_state(&shell_surface->window, SWC_WINDOW_STATE_NORMAL);
+ window_set_parent(&shell_surface->window, NULL);
}
static void set_transient(struct wl_client * client,
@@ -98,7 +87,20 @@ static void set_transient(struct wl_client * client,
struct wl_resource * parent_resource,
int32_t x, int32_t y, uint32_t flags)
{
- /* XXX: Handle transient */
+ struct shell_surface * shell_surface = wl_resource_get_user_data(resource);
+ struct swc_surface * parent_surface
+ = wl_resource_get_user_data(parent_resource);
+ struct compositor_view * parent_view
+ = compositor_view(parent_surface->view);
+
+ if (!parent_view || !parent_view->window)
+ return;
+
+ window_set_state(&shell_surface->window, SWC_WINDOW_STATE_NORMAL);
+ window_set_parent(&shell_surface->window, parent_view->window);
+ view_move(&shell_surface->window.view->base,
+ parent_view->base.geometry.x + x,
+ parent_view->base.geometry.y + y);
}
static void set_fullscreen(struct wl_client * client,
@@ -106,7 +108,18 @@ static void set_fullscreen(struct wl_client * client,
uint32_t method, uint32_t framerate,
struct wl_resource * output_resource)
{
- /* XXX: Handle fullscreen */
+ struct shell_surface * shell_surface = wl_resource_get_user_data(resource);
+ struct swc_output * output = output_resource
+ ? wl_resource_get_user_data(output_resource) : NULL;
+ struct screen * screen;
+
+ screen = output ? output->screen
+ : CONTAINER_OF(swc.screens.next, typeof(*screen), link);
+
+ /* TODO: Handle fullscreen windows. */
+
+ window_set_state(&shell_surface->window, SWC_WINDOW_STATE_NORMAL);
+ window_set_parent(&shell_surface->window, NULL);
}
static void set_popup(struct wl_client * client, struct wl_resource * resource,
@@ -114,14 +127,32 @@ static void set_popup(struct wl_client * client, struct wl_resource * resource,
struct wl_resource * parent_resource,
int32_t x, int32_t y, uint32_t flags)
{
- /* XXX: Handle popup */
+ struct shell_surface * shell_surface = wl_resource_get_user_data(resource);
+ struct swc_surface * parent_surface
+ = wl_resource_get_user_data(parent_resource);
+ struct compositor_view * parent_view
+ = compositor_view(parent_surface->view);
+
+ if (!parent_view || !parent_view->window)
+ return;
+
+ window_set_state(&shell_surface->window, SWC_WINDOW_STATE_NONE);
+ window_set_parent(&shell_surface->window, parent_view->window);
+ view_move(&shell_surface->window.view->base,
+ parent_view->base.geometry.x + x,
+ parent_view->base.geometry.y + y);
}
static void set_maximized(struct wl_client * client,
struct wl_resource * resource,
struct wl_resource * output_resource)
{
- /* XXX: Handle maximized */
+ struct shell_surface * shell_surface = wl_resource_get_user_data(resource);
+
+ /* TODO: Handle maximized windows. */
+
+ window_set_state(&shell_surface->window, SWC_WINDOW_STATE_NORMAL);
+ window_set_parent(&shell_surface->window, NULL);
}
static void set_title(struct wl_client * client, struct wl_resource * resource,
@@ -201,7 +232,6 @@ struct shell_surface * shell_surface_new(struct wl_client * client, uint32_t id,
goto error1;
window_initialize(&shell_surface->window, &shell_window_impl, surface);
- shell_surface->type = SHELL_SURFACE_TYPE_UNSPECIFIED;
shell_surface->surface_destroy_listener.notify = &handle_surface_destroy;
wl_resource_add_destroy_listener(surface->resource,
&shell_surface->surface_destroy_listener);
diff --git a/libswc/window.c b/libswc/window.c
@@ -280,6 +280,9 @@ void window_set_class(struct window * window, const char * class)
void window_set_state(struct window * window, uint32_t state)
{
+ if (window->base.state == state)
+ return;
+
window->base.state = state;
swc_send_event(&window->base.event_signal, SWC_WINDOW_STATE_CHANGED, NULL);
}