swc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/swc
Log | Files | Refs | README | LICENSE

commit 5f0e5d591c85c13948b9b469ee7441fe0a79db25
parent 57bad52d1604a3cbdb8d0e1f64b1fde97c858a20
Author: Michael Forney <mforney@mforney.org>
Date:   Sat, 16 Aug 2014 16:43:54 -0700

window: Implement interactive resizing

Diffstat:
Mlibswc/panel.c | 3++-
Mlibswc/view.c | 5++++-
Mlibswc/view.h | 3++-
Mlibswc/window.c | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Mlibswc/window.h | 2++
5 files changed, 65 insertions(+), 5 deletions(-)

diff --git a/libswc/panel.c b/libswc/panel.c @@ -152,7 +152,8 @@ static const struct swc_panel_interface panel_implementation = { .set_strut = &set_strut }; -static void handle_resize(struct view_handler * handler) +static void handle_resize(struct view_handler * handler, + uint32_t old_width, uint32_t old_height) { struct panel * panel = wl_container_of(handler, panel, view_handler); diff --git a/libswc/view.c b/libswc/view.c @@ -106,9 +106,12 @@ bool view_set_size(struct view * view, uint32_t width, uint32_t height) if (view->geometry.width == width && view->geometry.height == height) return false; + uint32_t old_width = view->geometry.width, + old_height = view->geometry.height; + view->geometry.width = width; view->geometry.height = height; - HANDLE(view, handler, resize); + HANDLE(view, handler, resize, old_width, old_height); return true; } diff --git a/libswc/view.h b/libswc/view.h @@ -74,7 +74,8 @@ struct view_handler_impl /* Called after the view's position changes. */ void (* move)(struct view_handler * handler); /* Called after the view's size changes. */ - void (* resize)(struct view_handler * handler); + void (* resize)(struct view_handler * handler, + uint32_t old_width, uint32_t old_height); /* Called when the set of screens the view is visible on changes. */ void (* screens)(struct view_handler * handler, uint32_t left, uint32_t entered); diff --git a/libswc/window.c b/libswc/window.c @@ -263,7 +263,22 @@ static bool move_motion(struct pointer_handler * handler, uint32_t time, static bool resize_motion(struct pointer_handler * handler, uint32_t time, wl_fixed_t fx, wl_fixed_t fy) { - /* TODO: Implement interactive resizing */ + struct window * window + = wl_container_of(handler, window, resize.interaction.handler); + const struct swc_rectangle * geometry = &window->view->base.geometry; + uint32_t width = geometry->width, height = geometry->height; + + if (window->resize.edges & SWC_WINDOW_EDGE_LEFT) + width -= wl_fixed_to_int(fx) + window->resize.offset.x - geometry->x; + else if (window->resize.edges & SWC_WINDOW_EDGE_RIGHT) + width = wl_fixed_to_int(fx) + window->resize.offset.x - geometry->x; + + if (window->resize.edges & SWC_WINDOW_EDGE_TOP) + height -= wl_fixed_to_int(fy) + window->resize.offset.y - geometry->y; + else if (window->resize.edges & SWC_WINDOW_EDGE_BOTTOM) + height = wl_fixed_to_int(fy) + window->resize.offset.y - geometry->y; + + window->impl->configure(window, width, height); return true; } @@ -286,6 +301,30 @@ static bool handle_button(struct pointer_handler * handler, uint32_t time, return true; } +static void handle_resize(struct view_handler * handler, + uint32_t old_width, uint32_t old_height) +{ + struct window * window = wl_container_of(handler, window, view_handler); + + if (window->resize.interaction.active + && window->resize.edges & (SWC_WINDOW_EDGE_TOP | SWC_WINDOW_EDGE_LEFT)) + { + const struct swc_rectangle * geometry = &window->view->base.geometry; + int32_t x = geometry->x, y = geometry->y; + + if (window->resize.edges & SWC_WINDOW_EDGE_LEFT) + x += old_width - geometry->width; + if (window->resize.edges & SWC_WINDOW_EDGE_TOP) + y += old_height - geometry->height; + + view_move(&window->view->base, x, y); + } +} + +static const struct view_handler_impl view_handler_impl = { + .resize = &handle_resize, +}; + bool window_initialize(struct window * window, const struct window_impl * impl, struct swc_surface * surface) { @@ -300,6 +339,7 @@ bool window_initialize(struct window * window, const struct window_impl * impl, window->impl = impl; window->handler = &null_handler; + window->view_handler.impl = &view_handler_impl; window->view->window = window; window->managed = false; window->mode = WINDOW_MODE_STACKED; @@ -314,6 +354,8 @@ bool window_initialize(struct window * window, const struct window_impl * impl, .button = &handle_button }; + wl_list_insert(&window->view->base.handlers, &window->view_handler.link); + return true; } @@ -401,13 +443,24 @@ void window_begin_resize(struct window * window, uint32_t edges, return; } + struct swc_rectangle * geometry = &window->view->base.geometry; + int32_t px = wl_fixed_to_int(swc.seat->pointer->x), + py = wl_fixed_to_int(swc.seat->pointer->y); + begin_interaction(&window->resize.interaction, button); if (!edges) { - /* TODO: Calculate edges to use */ + edges |= (px < geometry->x + geometry->width / 2) + ? SWC_WINDOW_EDGE_LEFT : SWC_WINDOW_EDGE_RIGHT; + edges |= (py < geometry->y + geometry->height / 2) + ? SWC_WINDOW_EDGE_TOP : SWC_WINDOW_EDGE_BOTTOM; } + window->resize.offset.x = geometry->x - px + + ((edges & SWC_WINDOW_EDGE_RIGHT) ? geometry->width : 0); + window->resize.offset.y = geometry->y - py + + ((edges & SWC_WINDOW_EDGE_BOTTOM) ? geometry->height : 0); window->resize.edges = edges; } diff --git a/libswc/window.h b/libswc/window.h @@ -52,6 +52,7 @@ struct window void * handler_data; struct compositor_view * view; + struct view_handler view_handler; bool managed; enum window_mode mode; @@ -64,6 +65,7 @@ struct window struct { struct window_pointer_interaction interaction; + struct { int32_t x, y; } offset; uint32_t edges; } resize; };