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 };