diff options
Diffstat (limited to 'sway/tree/view.c')
-rw-r--r-- | sway/tree/view.c | 188 |
1 files changed, 130 insertions, 58 deletions
diff --git a/sway/tree/view.c b/sway/tree/view.c index b7d1a41b..09c804e4 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c | |||
@@ -1,3 +1,4 @@ | |||
1 | #include <stdlib.h> | ||
1 | #include <wayland-server.h> | 2 | #include <wayland-server.h> |
2 | #include <wlr/types/wlr_output_layout.h> | 3 | #include <wlr/types/wlr_output_layout.h> |
3 | #include "log.h" | 4 | #include "log.h" |
@@ -6,82 +7,117 @@ | |||
6 | #include "sway/tree/layout.h" | 7 | #include "sway/tree/layout.h" |
7 | #include "sway/tree/view.h" | 8 | #include "sway/tree/view.h" |
8 | 9 | ||
10 | struct sway_view *view_create(enum sway_view_type type, | ||
11 | const struct sway_view_impl *impl) { | ||
12 | struct sway_view *view = calloc(1, sizeof(struct sway_view)); | ||
13 | if (view == NULL) { | ||
14 | return NULL; | ||
15 | } | ||
16 | view->type = type; | ||
17 | view->impl = impl; | ||
18 | return view; | ||
19 | } | ||
20 | |||
21 | void view_destroy(struct sway_view *view) { | ||
22 | if (view == NULL) { | ||
23 | return; | ||
24 | } | ||
25 | |||
26 | if (view->surface != NULL) { | ||
27 | view_unmap(view); | ||
28 | } | ||
29 | |||
30 | container_view_destroy(view->swayc); | ||
31 | free(view); | ||
32 | } | ||
33 | |||
9 | const char *view_get_title(struct sway_view *view) { | 34 | const char *view_get_title(struct sway_view *view) { |
10 | if (view->iface.get_prop) { | 35 | if (view->impl->get_prop) { |
11 | return view->iface.get_prop(view, VIEW_PROP_TITLE); | 36 | return view->impl->get_prop(view, VIEW_PROP_TITLE); |
12 | } | 37 | } |
13 | return NULL; | 38 | return NULL; |
14 | } | 39 | } |
15 | 40 | ||
16 | const char *view_get_app_id(struct sway_view *view) { | 41 | const char *view_get_app_id(struct sway_view *view) { |
17 | if (view->iface.get_prop) { | 42 | if (view->impl->get_prop) { |
18 | return view->iface.get_prop(view, VIEW_PROP_APP_ID); | 43 | return view->impl->get_prop(view, VIEW_PROP_APP_ID); |
19 | } | 44 | } |
20 | return NULL; | 45 | return NULL; |
21 | } | 46 | } |
22 | 47 | ||
23 | const char *view_get_class(struct sway_view *view) { | 48 | const char *view_get_class(struct sway_view *view) { |
24 | if (view->iface.get_prop) { | 49 | if (view->impl->get_prop) { |
25 | return view->iface.get_prop(view, VIEW_PROP_CLASS); | 50 | return view->impl->get_prop(view, VIEW_PROP_CLASS); |
26 | } | 51 | } |
27 | return NULL; | 52 | return NULL; |
28 | } | 53 | } |
29 | 54 | ||
30 | const char *view_get_instance(struct sway_view *view) { | 55 | const char *view_get_instance(struct sway_view *view) { |
31 | if (view->iface.get_prop) { | 56 | if (view->impl->get_prop) { |
32 | return view->iface.get_prop(view, VIEW_PROP_INSTANCE); | 57 | return view->impl->get_prop(view, VIEW_PROP_INSTANCE); |
33 | } | 58 | } |
34 | return NULL; | 59 | return NULL; |
35 | } | 60 | } |
36 | 61 | ||
37 | void view_set_size(struct sway_view *view, int width, int height) { | 62 | void view_configure(struct sway_view *view, double ox, double oy, int width, |
38 | if (view->iface.set_size) { | 63 | int height) { |
39 | struct wlr_box box = { | 64 | if (view->impl->configure) { |
40 | .x = view->swayc->x, | 65 | view->impl->configure(view, ox, oy, width, height); |
41 | .y = view->swayc->y, | ||
42 | .width = view->width, | ||
43 | .height = view->height, | ||
44 | }; | ||
45 | view->iface.set_size(view, width, height); | ||
46 | view_update_outputs(view, &box); | ||
47 | } | 66 | } |
48 | } | 67 | } |
49 | 68 | ||
50 | // TODO make view coordinates in layout coordinates | 69 | void view_set_activated(struct sway_view *view, bool activated) { |
51 | void view_set_position(struct sway_view *view, double ox, double oy) { | 70 | if (view->impl->set_activated) { |
52 | if (view->iface.set_position) { | 71 | view->impl->set_activated(view, activated); |
53 | struct wlr_box box = { | ||
54 | .x = view->swayc->x, | ||
55 | .y = view->swayc->y, | ||
56 | .width = view->width, | ||
57 | .height = view->height, | ||
58 | }; | ||
59 | view->iface.set_position(view, ox, oy); | ||
60 | view_update_outputs(view, &box); | ||
61 | } | 72 | } |
62 | } | 73 | } |
63 | 74 | ||
64 | void view_set_activated(struct sway_view *view, bool activated) { | 75 | void view_close(struct sway_view *view) { |
65 | if (view->iface.set_activated) { | 76 | if (view->impl->close) { |
66 | view->iface.set_activated(view, activated); | 77 | view->impl->close(view); |
67 | } | 78 | } |
68 | } | 79 | } |
69 | 80 | ||
70 | void view_close(struct sway_view *view) { | 81 | struct sway_container *container_view_destroy(struct sway_container *view) { |
71 | if (view->iface.close) { | 82 | if (!view) { |
72 | view->iface.close(view); | 83 | return NULL; |
73 | } | 84 | } |
85 | wlr_log(L_DEBUG, "Destroying view '%s'", view->name); | ||
86 | struct sway_container *parent = container_destroy(view); | ||
87 | arrange_windows(parent, -1, -1); | ||
88 | return parent; | ||
89 | } | ||
90 | |||
91 | void view_damage_whole(struct sway_view *view) { | ||
92 | for (int i = 0; i < root_container.children->length; ++i) { | ||
93 | struct sway_container *cont = root_container.children->items[i]; | ||
94 | if (cont->type == C_OUTPUT) { | ||
95 | output_damage_whole_view(cont->sway_output, view); | ||
96 | } | ||
97 | } | ||
98 | } | ||
99 | |||
100 | void view_damage_from(struct sway_view *view) { | ||
101 | // TODO | ||
102 | view_damage_whole(view); | ||
103 | } | ||
104 | |||
105 | static void view_get_layout_box(struct sway_view *view, struct wlr_box *box) { | ||
106 | struct sway_container *output = container_parent(view->swayc, C_OUTPUT); | ||
107 | |||
108 | box->x = output->x + view->swayc->x; | ||
109 | box->y = output->y + view->swayc->y; | ||
110 | box->width = view->width; | ||
111 | box->height = view->height; | ||
74 | } | 112 | } |
75 | 113 | ||
76 | void view_update_outputs(struct sway_view *view, const struct wlr_box *before) { | 114 | static void view_update_outputs(struct sway_view *view, |
115 | const struct wlr_box *before) { | ||
116 | struct wlr_box box; | ||
117 | view_get_layout_box(view, &box); | ||
118 | |||
77 | struct wlr_output_layout *output_layout = | 119 | struct wlr_output_layout *output_layout = |
78 | root_container.sway_root->output_layout; | 120 | root_container.sway_root->output_layout; |
79 | struct wlr_box box = { | ||
80 | .x = view->swayc->x, | ||
81 | .y = view->swayc->y, | ||
82 | .width = view->width, | ||
83 | .height = view->height, | ||
84 | }; | ||
85 | struct wlr_output_layout_output *layout_output; | 121 | struct wlr_output_layout_output *layout_output; |
86 | wl_list_for_each(layout_output, &output_layout->outputs, link) { | 122 | wl_list_for_each(layout_output, &output_layout->outputs, link) { |
87 | bool intersected = before != NULL && wlr_output_layout_intersects( | 123 | bool intersected = before != NULL && wlr_output_layout_intersects( |
@@ -97,27 +133,63 @@ void view_update_outputs(struct sway_view *view, const struct wlr_box *before) { | |||
97 | } | 133 | } |
98 | } | 134 | } |
99 | 135 | ||
100 | struct sway_container *container_view_destroy(struct sway_container *view) { | 136 | void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) { |
101 | if (!view) { | 137 | if (!sway_assert(view->surface == NULL, "cannot map mapped view")) { |
102 | return NULL; | 138 | return; |
103 | } | 139 | } |
104 | wlr_log(L_DEBUG, "Destroying view '%s'", view->name); | 140 | |
105 | struct sway_container *parent = container_destroy(view); | 141 | struct sway_seat *seat = input_manager_current_seat(input_manager); |
106 | arrange_windows(parent, -1, -1); | 142 | struct sway_container *focus = seat_get_focus_inactive(seat, |
107 | return parent; | 143 | &root_container); |
144 | struct sway_container *cont = container_view_create(focus, view); | ||
145 | |||
146 | view->surface = wlr_surface; | ||
147 | view->swayc = cont; | ||
148 | |||
149 | arrange_windows(cont->parent, -1, -1); | ||
150 | input_manager_set_focus(input_manager, cont); | ||
151 | |||
152 | view_damage_whole(view); | ||
153 | view_update_outputs(view, NULL); | ||
108 | } | 154 | } |
109 | 155 | ||
110 | void view_damage_whole(struct sway_view *view) { | 156 | void view_unmap(struct sway_view *view) { |
111 | struct sway_container *cont = NULL; | 157 | if (!sway_assert(view->surface != NULL, "cannot unmap unmapped view")) { |
112 | for (int i = 0; i < root_container.children->length; ++i) { | 158 | return; |
113 | cont = root_container.children->items[i]; | ||
114 | if (cont->type == C_OUTPUT) { | ||
115 | output_damage_whole_view(cont->sway_output, view); | ||
116 | } | ||
117 | } | 159 | } |
160 | |||
161 | view_damage_whole(view); | ||
162 | |||
163 | container_view_destroy(view->swayc); | ||
164 | |||
165 | view->swayc = NULL; | ||
166 | view->surface = NULL; | ||
118 | } | 167 | } |
119 | 168 | ||
120 | void view_damage_from(struct sway_view *view) { | 169 | void view_update_position(struct sway_view *view, double ox, double oy) { |
121 | // TODO | 170 | if (view->swayc->x == ox && view->swayc->y == oy) { |
171 | return; | ||
172 | } | ||
173 | |||
174 | struct wlr_box box; | ||
175 | view_get_layout_box(view, &box); | ||
176 | view_damage_whole(view); | ||
177 | view->swayc->x = ox; | ||
178 | view->swayc->y = oy; | ||
179 | view_update_outputs(view, &box); | ||
180 | view_damage_whole(view); | ||
181 | } | ||
182 | |||
183 | void view_update_size(struct sway_view *view, int width, int height) { | ||
184 | if (view->width == width && view->height == height) { | ||
185 | return; | ||
186 | } | ||
187 | |||
188 | struct wlr_box box; | ||
189 | view_get_layout_box(view, &box); | ||
190 | view_damage_whole(view); | ||
191 | view->width = width; | ||
192 | view->height = height; | ||
193 | view_update_outputs(view, &box); | ||
122 | view_damage_whole(view); | 194 | view_damage_whole(view); |
123 | } | 195 | } |