commit 1bb790d66fd78a1a310b20ae9f46fdc330ed1626
parent 98a3a362e8daaa92a6f710a63718e81343e652be
Author: Michael Forney <mforney@mforney.org>
Date: Tue, 30 Sep 2014 21:55:49 -0700
Add support for atomic moves and resizes
Diffstat:
6 files changed, 73 insertions(+), 3 deletions(-)
diff --git a/libswc/shell_surface.c b/libswc/shell_surface.c
@@ -51,6 +51,8 @@ static void configure(struct window * window, uint32_t width, uint32_t height)
wl_shell_surface_send_configure(shell_surface->resource,
WL_SHELL_SURFACE_RESIZE_NONE,
width, height);
+ /* wl_shell does not support acknowledging configures. */
+ window->configure.acknowledged = true;
}
static void close(struct window * window)
diff --git a/libswc/view.c b/libswc/view.c
@@ -60,6 +60,7 @@ void view_finalize(struct view * view)
int view_attach(struct view * view, struct wld_buffer * buffer)
{
int ret;
+ struct view_handler * handler;
if ((ret = view->impl->attach(view, buffer)) < 0)
return ret;
@@ -71,6 +72,7 @@ int view_attach(struct view * view, struct wld_buffer * buffer)
wld_buffer_reference(buffer);
view->buffer = buffer;
+ HANDLE(view, handler, attach);
return 0;
}
diff --git a/libswc/view.h b/libswc/view.h
@@ -71,6 +71,8 @@ struct view_handler_impl
{
/* Called when the view has displayed the next frame. */
void (* frame)(struct view_handler * handler, uint32_t time);
+ /* Called when a new buffer is attached to the view. */
+ void (* attach)(struct view_handler * handler);
/* Called after the view's position changes. */
void (* move)(struct view_handler * handler);
/* Called after the view's size changes. */
diff --git a/libswc/window.c b/libswc/window.c
@@ -95,6 +95,18 @@ static void end_interaction(struct window_pointer_interaction * interaction)
wl_list_remove(&interaction->handler.link);
}
+static void flush(struct window * window)
+{
+ if (window->move.pending)
+ {
+ if (window->impl->move)
+ window->impl->move(window, window->move.x, window->move.y);
+
+ view_move(&window->view->base, window->move.x, window->move.y);
+ window->move.pending = false;
+ }
+}
+
EXPORT
void swc_window_set_handler(struct swc_window * base,
const struct swc_window_handler * handler,
@@ -153,6 +165,10 @@ void swc_window_set_stacked(struct swc_window * base)
{
struct window * window = INTERNAL(base);
+ flush(window);
+ window->configure.pending = false;
+ window->configure.width = 0;
+ window->configure.height = 0;
if (window->impl->set_mode)
window->impl->set_mode(window, WINDOW_MODE_STACKED);
window->mode = WINDOW_MODE_STACKED;
@@ -190,11 +206,18 @@ void swc_window_set_position(struct swc_window * base, int32_t x, int32_t y)
struct swc_rectangle * geometry = &window->view->base.geometry;
if (x == geometry->x && y == geometry->y)
+ {
+ window->move.pending = false;
return;
+ }
+
+ window->move.x = x;
+ window->move.y = y;
+ window->move.pending = true;
- if (window->impl->move)
- window->impl->move(window, x, y);
- view_move(&window->view->base, x, y);
+ /* If we don't have a configure pending, perform the move now. */
+ if (!window->configure.pending)
+ flush(window);
}
EXPORT
@@ -202,8 +225,25 @@ void swc_window_set_size(struct swc_window * base,
uint32_t width, uint32_t height)
{
struct window * window = INTERNAL(base);
+ struct swc_rectangle * geometry = &window->view->base.geometry;
+
+ if ((window->configure.pending
+ && width == window->configure.width
+ && height == window->configure.height)
+ || (!window->configure.pending
+ && width == geometry->width && height == geometry->height))
+ {
+ return;
+ }
window->impl->configure(window, width, height);
+
+ if (window->mode == WINDOW_MODE_TILED)
+ {
+ window->configure.width = width;
+ window->configure.height = height;
+ window->configure.pending = true;
+ }
}
EXPORT
@@ -301,6 +341,15 @@ static bool handle_button(struct pointer_handler * handler, uint32_t time,
return true;
}
+static void handle_attach(struct view_handler * handler)
+{
+ struct window * window = wl_container_of(handler, window, view_handler);
+
+ if (window->configure.acknowledged)
+ flush(window);
+ window->configure.pending = false;
+}
+
static void handle_resize(struct view_handler * handler,
uint32_t old_width, uint32_t old_height)
{
@@ -322,6 +371,7 @@ static void handle_resize(struct view_handler * handler,
}
static const struct view_handler_impl view_handler_impl = {
+ .attach = &handle_attach,
.resize = &handle_resize,
};
@@ -343,11 +393,15 @@ bool window_initialize(struct window * window, const struct window_impl * impl,
window->view->window = window;
window->managed = false;
window->mode = WINDOW_MODE_STACKED;
+ window->move.pending = false;
window->move.interaction.active = false;
window->move.interaction.handler = (struct pointer_handler) {
.motion = &move_motion,
.button = &handle_button
};
+ window->configure.pending = false;
+ window->configure.width = 0;
+ window->configure.height = 0;
window->resize.interaction.active = false;
window->resize.interaction.handler = (struct pointer_handler) {
.motion = &resize_motion,
diff --git a/libswc/window.h b/libswc/window.h
@@ -60,6 +60,9 @@ struct window
{
struct window_pointer_interaction interaction;
struct { int32_t x, y; } offset;
+
+ bool pending;
+ int32_t x, y;
} move;
struct
@@ -68,6 +71,12 @@ struct window
struct { int32_t x, y; } offset;
uint32_t edges;
} resize;
+
+ struct
+ {
+ bool pending, acknowledged;
+ uint32_t width, height;
+ } configure;
};
struct window_impl
diff --git a/libswc/xwm.c b/libswc/xwm.c
@@ -175,6 +175,7 @@ static void configure(struct window * window, uint32_t width, uint32_t height)
values[0] = width;
values[1] = height;
+ window->configure.acknowledged = true;
xcb_configure_window(xwm.connection, xwl_window->id, mask, values);
xcb_flush(xwm.connection);
}