commit 5f0e5d5

Michael Forney  ·  2014-08-16 23:43:54 +0000 UTC
parent 57bad52
window: Implement interactive resizing
5 files changed,  +65, -5
+2, -1
 1@@ -152,7 +152,8 @@ static const struct swc_panel_interface panel_implementation = {
 2     .set_strut = &set_strut
 3 };
 4 
 5-static void handle_resize(struct view_handler * handler)
 6+static void handle_resize(struct view_handler * handler,
 7+                          uint32_t old_width, uint32_t old_height)
 8 {
 9     struct panel * panel = wl_container_of(handler, panel, view_handler);
10 
+4, -1
 1@@ -106,9 +106,12 @@ bool view_set_size(struct view * view, uint32_t width, uint32_t height)
 2     if (view->geometry.width == width && view->geometry.height == height)
 3         return false;
 4 
 5+    uint32_t old_width = view->geometry.width,
 6+             old_height = view->geometry.height;
 7+
 8     view->geometry.width = width;
 9     view->geometry.height = height;
10-    HANDLE(view, handler, resize);
11+    HANDLE(view, handler, resize, old_width, old_height);
12 
13     return true;
14 }
+2, -1
 1@@ -74,7 +74,8 @@ struct view_handler_impl
 2     /* Called after the view's position changes. */
 3     void (* move)(struct view_handler * handler);
 4     /* Called after the view's size changes. */
 5-    void (* resize)(struct view_handler * handler);
 6+    void (* resize)(struct view_handler * handler,
 7+                    uint32_t old_width, uint32_t old_height);
 8     /* Called when the set of screens the view is visible on changes. */
 9     void (* screens)(struct view_handler * handler,
10                      uint32_t left, uint32_t entered);
+55, -2
 1@@ -263,7 +263,22 @@ static bool move_motion(struct pointer_handler * handler, uint32_t time,
 2 static bool resize_motion(struct pointer_handler * handler, uint32_t time,
 3                           wl_fixed_t fx, wl_fixed_t fy)
 4 {
 5-    /* TODO: Implement interactive resizing */
 6+    struct window * window
 7+        = wl_container_of(handler, window, resize.interaction.handler);
 8+    const struct swc_rectangle * geometry = &window->view->base.geometry;
 9+    uint32_t width = geometry->width, height = geometry->height;
10+
11+    if (window->resize.edges & SWC_WINDOW_EDGE_LEFT)
12+        width -= wl_fixed_to_int(fx) + window->resize.offset.x - geometry->x;
13+    else if (window->resize.edges & SWC_WINDOW_EDGE_RIGHT)
14+        width = wl_fixed_to_int(fx) + window->resize.offset.x - geometry->x;
15+
16+    if (window->resize.edges & SWC_WINDOW_EDGE_TOP)
17+        height -= wl_fixed_to_int(fy) + window->resize.offset.y - geometry->y;
18+    else if (window->resize.edges & SWC_WINDOW_EDGE_BOTTOM)
19+        height = wl_fixed_to_int(fy) + window->resize.offset.y - geometry->y;
20+
21+    window->impl->configure(window, width, height);
22 
23     return true;
24 }
25@@ -286,6 +301,30 @@ static bool handle_button(struct pointer_handler * handler, uint32_t time,
26     return true;
27 }
28 
29+static void handle_resize(struct view_handler * handler,
30+                          uint32_t old_width, uint32_t old_height)
31+{
32+    struct window * window = wl_container_of(handler, window, view_handler);
33+
34+    if (window->resize.interaction.active
35+        && window->resize.edges & (SWC_WINDOW_EDGE_TOP | SWC_WINDOW_EDGE_LEFT))
36+    {
37+        const struct swc_rectangle * geometry = &window->view->base.geometry;
38+        int32_t x = geometry->x, y = geometry->y;
39+
40+        if (window->resize.edges & SWC_WINDOW_EDGE_LEFT)
41+            x += old_width - geometry->width;
42+        if (window->resize.edges & SWC_WINDOW_EDGE_TOP)
43+            y += old_height - geometry->height;
44+
45+        view_move(&window->view->base, x, y);
46+    }
47+}
48+
49+static const struct view_handler_impl view_handler_impl = {
50+    .resize = &handle_resize,
51+};
52+
53 bool window_initialize(struct window * window, const struct window_impl * impl,
54                        struct swc_surface * surface)
55 {
56@@ -300,6 +339,7 @@ bool window_initialize(struct window * window, const struct window_impl * impl,
57 
58     window->impl = impl;
59     window->handler = &null_handler;
60+    window->view_handler.impl = &view_handler_impl;
61     window->view->window = window;
62     window->managed = false;
63     window->mode = WINDOW_MODE_STACKED;
64@@ -314,6 +354,8 @@ bool window_initialize(struct window * window, const struct window_impl * impl,
65         .button = &handle_button
66     };
67 
68+    wl_list_insert(&window->view->base.handlers, &window->view_handler.link);
69+
70     return true;
71 }
72 
73@@ -401,13 +443,24 @@ void window_begin_resize(struct window * window, uint32_t edges,
74         return;
75     }
76 
77+    struct swc_rectangle * geometry = &window->view->base.geometry;
78+    int32_t px = wl_fixed_to_int(swc.seat->pointer->x),
79+            py = wl_fixed_to_int(swc.seat->pointer->y);
80+
81     begin_interaction(&window->resize.interaction, button);
82 
83     if (!edges)
84     {
85-        /* TODO: Calculate edges to use */
86+        edges |= (px < geometry->x + geometry->width / 2)
87+            ? SWC_WINDOW_EDGE_LEFT : SWC_WINDOW_EDGE_RIGHT;
88+        edges |= (py < geometry->y + geometry->height / 2)
89+            ? SWC_WINDOW_EDGE_TOP : SWC_WINDOW_EDGE_BOTTOM;
90     }
91 
92+    window->resize.offset.x = geometry->x - px
93+        + ((edges & SWC_WINDOW_EDGE_RIGHT) ? geometry->width : 0);
94+    window->resize.offset.y = geometry->y - py
95+        + ((edges & SWC_WINDOW_EDGE_BOTTOM) ? geometry->height : 0);
96     window->resize.edges = edges;
97 }
98 
+2, -0
 1@@ -52,6 +52,7 @@ struct window
 2     void * handler_data;
 3 
 4     struct compositor_view * view;
 5+    struct view_handler view_handler;
 6     bool managed;
 7     enum window_mode mode;
 8 
 9@@ -64,6 +65,7 @@ struct window
10     struct
11     {
12         struct window_pointer_interaction interaction;
13+        struct { int32_t x, y; } offset;
14         uint32_t edges;
15     } resize;
16 };