Introduce 'shell' object for moving and resizing surfaces in the compositor
diff --git a/clients/window.c b/clients/window.c
index a7ed81b..c01ca05 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -52,6 +52,7 @@
struct display {
struct wl_display *display;
struct wl_compositor *compositor;
+ struct wl_shell *shell;
struct wl_output *output;
struct rectangle screen_allocation;
EGLDisplay dpy;
@@ -71,12 +72,11 @@
struct display *display;
struct wl_surface *surface;
const char *title;
- struct rectangle allocation, saved_allocation, surface_allocation;
+ struct rectangle allocation, saved_allocation, pending_allocation;
+ int resize_edges;
int redraw_scheduled;
int minimum_width, minimum_height;
int margin;
- int drag_x, drag_y;
- int state;
int fullscreen;
int decoration;
struct input *grab_device;
@@ -195,16 +195,16 @@
visual = wl_display_get_premultiplied_argb_visual(window->display->display);
wl_surface_attach(window->surface,
name,
- window->surface_allocation.width,
- window->surface_allocation.height,
+ window->allocation.width,
+ window->allocation.height,
stride,
visual);
wl_surface_map(window->surface,
- window->surface_allocation.x - window->margin,
- window->surface_allocation.y - window->margin,
- window->surface_allocation.width,
- window->surface_allocation.height);
+ window->allocation.x,
+ window->allocation.y,
+ window->allocation.width,
+ window->allocation.height);
wl_compositor_commit(window->display->compositor, 0);
}
@@ -229,7 +229,6 @@
window->cairo_surface =
display_create_surface(window->display, &window->allocation);
- window->surface_allocation = window->allocation;
width = window->allocation.width;
height = window->allocation.height;
@@ -274,7 +273,6 @@
{
window->cairo_surface =
display_create_surface(window->display, &window->allocation);
- window->surface_allocation = window->allocation;
}
void
@@ -315,61 +313,11 @@
int32_t x, int32_t y, int32_t sx, int32_t sy)
{
struct input *input = data;
- struct window *window = input->pointer_focus;
input->x = x;
input->y = y;
input->sx = sx;
input->sy = sy;
-
- switch (window->state) {
- case WINDOW_MOVING:
- if (window->fullscreen)
- break;
- if (window->grab_device != input)
- break;
- window->allocation.x = window->drag_x + x;
- window->allocation.y = window->drag_y + y;
- wl_surface_map(window->surface,
- window->allocation.x - window->margin,
- window->allocation.y - window->margin,
- window->allocation.width,
- window->allocation.height);
- wl_compositor_commit(window->display->compositor, 1);
- break;
-
- case WINDOW_RESIZING_TOP:
- case WINDOW_RESIZING_BOTTOM:
- case WINDOW_RESIZING_LEFT:
- case WINDOW_RESIZING_RIGHT:
- case WINDOW_RESIZING_TOP_LEFT:
- case WINDOW_RESIZING_TOP_RIGHT:
- case WINDOW_RESIZING_BOTTOM_LEFT:
- case WINDOW_RESIZING_BOTTOM_RIGHT:
- if (window->fullscreen)
- break;
- if (window->grab_device != input)
- break;
- if (window->state & WINDOW_RESIZING_LEFT) {
- window->allocation.x = x - window->drag_x + window->saved_allocation.x;
- window->allocation.width = window->drag_x - x + window->saved_allocation.width;
- }
- if (window->state & WINDOW_RESIZING_RIGHT)
- window->allocation.width = x - window->drag_x + window->saved_allocation.width;
- if (window->state & WINDOW_RESIZING_TOP) {
- window->allocation.y = y - window->drag_y + window->saved_allocation.y;
- window->allocation.height = window->drag_y - y + window->saved_allocation.height;
- }
- if (window->state & WINDOW_RESIZING_BOTTOM)
- window->allocation.height = y - window->drag_y + window->saved_allocation.height;
-
- if (window->resize_handler)
- (*window->resize_handler)(window,
- window->user_data);
- else if (window->redraw_handler)
- window_schedule_redraw(window);
- break;
- }
}
static void window_handle_button(void *data, struct wl_input_device *input_device,
@@ -400,10 +348,8 @@
if (button == BTN_LEFT && state == 1) {
switch (hlocation | vlocation) {
case WINDOW_MOVING:
- window->drag_x = window->allocation.x - input->x;
- window->drag_y = window->allocation.y - input->y;
- window->state = WINDOW_MOVING;
- window->grab_device = input;
+ wl_shell_move(window->display->shell,
+ window->surface, input_device, time);
break;
case WINDOW_RESIZING_TOP:
case WINDOW_RESIZING_BOTTOM:
@@ -413,19 +359,11 @@
case WINDOW_RESIZING_TOP_RIGHT:
case WINDOW_RESIZING_BOTTOM_LEFT:
case WINDOW_RESIZING_BOTTOM_RIGHT:
- window->drag_x = input->x;
- window->drag_y = input->y;
- window->saved_allocation = window->allocation;
- window->state = hlocation | vlocation;
- window->grab_device = input;
- break;
- default:
- window->state = WINDOW_STABLE;
+ wl_shell_resize(window->display->shell,
+ window->surface, input_device, time,
+ hlocation | vlocation);
break;
}
- } else if (button == BTN_LEFT &&
- state == 0 && window->grab_device == input) {
- window->state = WINDOW_STABLE;
}
}
@@ -519,6 +457,34 @@
window_handle_keyboard_focus,
};
+static void
+handle_configure(void *data, struct wl_shell *shell,
+ uint32_t time, uint32_t edges,
+ struct wl_surface *surface,
+ int32_t x, int32_t y, int32_t width, int32_t height)
+{
+ struct window *window = wl_surface_get_user_data(surface);
+
+ window->resize_edges = edges;
+ window->pending_allocation.x = x;
+ window->pending_allocation.y = y;
+ window->pending_allocation.width = width;
+ window->pending_allocation.height = height;
+
+ if (!(edges & 15))
+ return;
+
+ if (window->resize_handler)
+ (*window->resize_handler)(window,
+ window->user_data);
+ else if (window->redraw_handler)
+ window_schedule_redraw(window);
+}
+
+static const struct wl_shell_listener shell_listener = {
+ handle_configure,
+};
+
void
window_get_child_rectangle(struct window *window,
struct rectangle *rectangle)
@@ -542,12 +508,14 @@
if (!window->fullscreen) {
width = rectangle->width + 20 + window->margin * 2;
height = rectangle->height + 60 + window->margin * 2;
- if (window->state & WINDOW_RESIZING_LEFT)
- window->allocation.x -=
- width - window->allocation.width;
- if (window->state & WINDOW_RESIZING_TOP)
- window->allocation.y -=
- height - window->allocation.height;
+
+ if (window->resize_edges & WINDOW_RESIZING_LEFT)
+ window->allocation.x +=
+ window->allocation.width - width;
+ if (window->resize_edges & WINDOW_RESIZING_TOP)
+ window->allocation.y +=
+ window->allocation.height - height;
+
window->allocation.width = width;
window->allocation.height = height;
}
@@ -582,8 +550,13 @@
{
struct window *window = data;
+ if (window->resize_edges)
+ window->allocation = window->pending_allocation;
+
window->redraw_handler(window, window->user_data);
+
window->redraw_scheduled = 0;
+ window->resize_edges = 0;
return FALSE;
}
@@ -696,7 +669,6 @@
window->allocation.height = height;
window->saved_allocation = window->allocation;
window->margin = 16;
- window->state = WINDOW_STABLE;
window->decoration = 1;
wl_surface_set_user_data(window->surface, window);
@@ -809,6 +781,9 @@
wl_output_add_listener(d->output, &output_listener, d);
} else if (wl_object_implements(object, "input_device", 1)) {
display_add_input(d, object);
+ } else if (wl_object_implements(object, "shell", 1)) {
+ d->shell = (struct wl_shell *) object;
+ wl_shell_add_listener(d->shell, &shell_listener, d);
}
}