diff options
author | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-08-18 15:10:06 +1000 |
---|---|---|
committer | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-08-18 15:10:06 +1000 |
commit | b0a5f3a25f52bc1d48d771cb02820042006d8d9e (patch) | |
tree | e7a2e4c60e562589e3b9a54c6ce559a41dcf7534 | |
parent | Set current size when a floating xwayland view resizes (diff) | |
download | sway-b0a5f3a25f52bc1d48d771cb02820042006d8d9e.tar.gz sway-b0a5f3a25f52bc1d48d771cb02820042006d8d9e.tar.zst sway-b0a5f3a25f52bc1d48d771cb02820042006d8d9e.zip |
Store geometry in the view and handle any floating view resizing
-rw-r--r-- | include/sway/desktop.h | 5 | ||||
-rw-r--r-- | include/sway/tree/view.h | 14 | ||||
-rw-r--r-- | sway/desktop/desktop.c | 18 | ||||
-rw-r--r-- | sway/desktop/output.c | 9 | ||||
-rw-r--r-- | sway/desktop/render.c | 10 | ||||
-rw-r--r-- | sway/desktop/transaction.c | 72 | ||||
-rw-r--r-- | sway/desktop/xdg_shell.c | 28 | ||||
-rw-r--r-- | sway/desktop/xdg_shell_v6.c | 29 | ||||
-rw-r--r-- | sway/desktop/xwayland.c | 36 | ||||
-rw-r--r-- | sway/tree/container.c | 9 | ||||
-rw-r--r-- | sway/tree/view.c | 26 |
11 files changed, 144 insertions, 112 deletions
diff --git a/include/sway/desktop.h b/include/sway/desktop.h index 348fb187..c969a76b 100644 --- a/include/sway/desktop.h +++ b/include/sway/desktop.h | |||
@@ -1,8 +1,13 @@ | |||
1 | #include <wlr/types/wlr_surface.h> | 1 | #include <wlr/types/wlr_surface.h> |
2 | 2 | ||
3 | struct sway_container; | 3 | struct sway_container; |
4 | struct sway_view; | ||
4 | 5 | ||
5 | void desktop_damage_surface(struct wlr_surface *surface, double lx, double ly, | 6 | void desktop_damage_surface(struct wlr_surface *surface, double lx, double ly, |
6 | bool whole); | 7 | bool whole); |
7 | 8 | ||
8 | void desktop_damage_whole_container(struct sway_container *con); | 9 | void desktop_damage_whole_container(struct sway_container *con); |
10 | |||
11 | void desktop_damage_box(struct wlr_box *box); | ||
12 | |||
13 | void desktop_damage_view(struct sway_view *view); | ||
diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index 0e7f166c..2747e7c4 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h | |||
@@ -38,7 +38,6 @@ struct sway_view_impl { | |||
38 | const char *(*get_string_prop)(struct sway_view *view, | 38 | const char *(*get_string_prop)(struct sway_view *view, |
39 | enum sway_view_prop prop); | 39 | enum sway_view_prop prop); |
40 | uint32_t (*get_int_prop)(struct sway_view *view, enum sway_view_prop prop); | 40 | uint32_t (*get_int_prop)(struct sway_view *view, enum sway_view_prop prop); |
41 | void (*get_geometry)(struct sway_view *view, struct wlr_box *box); | ||
42 | uint32_t (*configure)(struct sway_view *view, double lx, double ly, | 41 | uint32_t (*configure)(struct sway_view *view, double lx, double ly, |
43 | int width, int height); | 42 | int width, int height); |
44 | void (*set_activated)(struct sway_view *view, bool activated); | 43 | void (*set_activated)(struct sway_view *view, bool activated); |
@@ -88,7 +87,14 @@ struct sway_view { | |||
88 | 87 | ||
89 | struct wlr_buffer *saved_buffer; | 88 | struct wlr_buffer *saved_buffer; |
90 | int saved_buffer_width, saved_buffer_height; | 89 | int saved_buffer_width, saved_buffer_height; |
91 | struct wlr_box saved_geometry; // The "old" geometry during a transaction | 90 | |
91 | // The geometry for whatever the client is committing, regardless of | ||
92 | // transaction state. Updated on every commit. | ||
93 | struct wlr_box geometry; | ||
94 | |||
95 | // The "old" geometry during a transaction. Used to damage the old location | ||
96 | // when a transaction is applied. | ||
97 | struct wlr_box saved_geometry; | ||
92 | 98 | ||
93 | bool destroying; | 99 | bool destroying; |
94 | 100 | ||
@@ -243,8 +249,6 @@ const char *view_get_shell(struct sway_view *view); | |||
243 | void view_get_constraints(struct sway_view *view, double *min_width, | 249 | void view_get_constraints(struct sway_view *view, double *min_width, |
244 | double *max_width, double *min_height, double *max_height); | 250 | double *max_width, double *min_height, double *max_height); |
245 | 251 | ||
246 | void view_get_geometry(struct sway_view *view, struct wlr_box *box); | ||
247 | |||
248 | uint32_t view_configure(struct sway_view *view, double lx, double ly, int width, | 252 | uint32_t view_configure(struct sway_view *view, double lx, double ly, int width, |
249 | int height); | 253 | int height); |
250 | 254 | ||
@@ -289,6 +293,8 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface); | |||
289 | 293 | ||
290 | void view_unmap(struct sway_view *view); | 294 | void view_unmap(struct sway_view *view); |
291 | 295 | ||
296 | void view_update_size(struct sway_view *view, int width, int height); | ||
297 | |||
292 | void view_child_init(struct sway_view_child *child, | 298 | void view_child_init(struct sway_view_child *child, |
293 | const struct sway_view_child_impl *impl, struct sway_view *view, | 299 | const struct sway_view_child_impl *impl, struct sway_view *view, |
294 | struct wlr_surface *surface); | 300 | struct wlr_surface *surface); |
diff --git a/sway/desktop/desktop.c b/sway/desktop/desktop.c index 6575519d..72650397 100644 --- a/sway/desktop/desktop.c +++ b/sway/desktop/desktop.c | |||
@@ -22,3 +22,21 @@ void desktop_damage_whole_container(struct sway_container *con) { | |||
22 | } | 22 | } |
23 | } | 23 | } |
24 | } | 24 | } |
25 | |||
26 | void desktop_damage_box(struct wlr_box *box) { | ||
27 | for (int i = 0; i < root_container.children->length; ++i) { | ||
28 | struct sway_container *cont = root_container.children->items[i]; | ||
29 | output_damage_box(cont->sway_output, box); | ||
30 | } | ||
31 | } | ||
32 | |||
33 | void desktop_damage_view(struct sway_view *view) { | ||
34 | desktop_damage_whole_container(view->swayc); | ||
35 | struct wlr_box box = { | ||
36 | .x = view->swayc->current.view_x - view->geometry.x, | ||
37 | .y = view->swayc->current.view_y - view->geometry.y, | ||
38 | .width = view->surface->current.width, | ||
39 | .height = view->surface->current.height, | ||
40 | }; | ||
41 | desktop_damage_box(&box); | ||
42 | } | ||
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index cb0b4a07..b4564fac 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c | |||
@@ -140,23 +140,20 @@ void output_surface_for_each_surface(struct sway_output *output, | |||
140 | void output_view_for_each_surface(struct sway_output *output, | 140 | void output_view_for_each_surface(struct sway_output *output, |
141 | struct sway_view *view, sway_surface_iterator_func_t iterator, | 141 | struct sway_view *view, sway_surface_iterator_func_t iterator, |
142 | void *user_data) { | 142 | void *user_data) { |
143 | struct wlr_box geometry; | ||
144 | view_get_geometry(view, &geometry); | ||
145 | struct surface_iterator_data data = { | 143 | struct surface_iterator_data data = { |
146 | .user_iterator = iterator, | 144 | .user_iterator = iterator, |
147 | .user_data = user_data, | 145 | .user_data = user_data, |
148 | .output = output, | 146 | .output = output, |
149 | .ox = view->swayc->current.view_x - output->swayc->current.swayc_x | 147 | .ox = view->swayc->current.view_x - output->swayc->current.swayc_x |
150 | - geometry.x, | 148 | - view->geometry.x, |
151 | .oy = view->swayc->current.view_y - output->swayc->current.swayc_y | 149 | .oy = view->swayc->current.view_y - output->swayc->current.swayc_y |
152 | - geometry.y, | 150 | - view->geometry.y, |
153 | .width = view->swayc->current.view_width, | 151 | .width = view->swayc->current.view_width, |
154 | .height = view->swayc->current.view_height, | 152 | .height = view->swayc->current.view_height, |
155 | .rotation = 0, // TODO | 153 | .rotation = 0, // TODO |
156 | }; | 154 | }; |
157 | 155 | ||
158 | view_for_each_surface(view, | 156 | view_for_each_surface(view, output_for_each_surface_iterator, &data); |
159 | output_for_each_surface_iterator, &data); | ||
160 | } | 157 | } |
161 | 158 | ||
162 | void output_view_for_each_popup(struct sway_output *output, | 159 | void output_view_for_each_popup(struct sway_output *output, |
diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 28c5a3ed..a4b624b8 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c | |||
@@ -192,12 +192,12 @@ static void render_view_toplevels(struct sway_view *view, | |||
192 | .damage = damage, | 192 | .damage = damage, |
193 | .alpha = alpha, | 193 | .alpha = alpha, |
194 | }; | 194 | }; |
195 | struct wlr_box geometry; | ||
196 | view_get_geometry(view, &geometry); | ||
197 | // Render all toplevels without descending into popups | 195 | // Render all toplevels without descending into popups |
198 | output_surface_for_each_surface(output, view->surface, | 196 | double ox = |
199 | view->swayc->current.view_x - output->wlr_output->lx - geometry.x, | 197 | view->swayc->current.view_x - output->wlr_output->lx - view->geometry.x; |
200 | view->swayc->current.view_y - output->wlr_output->ly - geometry.y, | 198 | double oy = |
199 | view->swayc->current.view_y - output->wlr_output->ly - view->geometry.y; | ||
200 | output_surface_for_each_surface(output, view->surface, ox, oy, | ||
201 | render_surface_iterator, &data); | 201 | render_surface_iterator, &data); |
202 | } | 202 | } |
203 | 203 | ||
diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index 7383c455..c300558a 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <time.h> | 6 | #include <time.h> |
7 | #include <wlr/types/wlr_buffer.h> | 7 | #include <wlr/types/wlr_buffer.h> |
8 | #include "sway/debug.h" | 8 | #include "sway/debug.h" |
9 | #include "sway/desktop.h" | ||
9 | #include "sway/desktop/idle_inhibit_v1.h" | 10 | #include "sway/desktop/idle_inhibit_v1.h" |
10 | #include "sway/desktop/transaction.h" | 11 | #include "sway/desktop/transaction.h" |
11 | #include "sway/output.h" | 12 | #include "sway/output.h" |
@@ -169,51 +170,17 @@ static void transaction_apply(struct sway_transaction *transaction) { | |||
169 | transaction->instructions->items[i]; | 170 | transaction->instructions->items[i]; |
170 | struct sway_container *container = instruction->container; | 171 | struct sway_container *container = instruction->container; |
171 | 172 | ||
172 | // Damage the old and new locations | 173 | // Damage the old location |
173 | struct wlr_box old_con_box = { | 174 | desktop_damage_whole_container(container); |
174 | .x = container->current.swayc_x, | 175 | if (container->type == C_VIEW && container->sway_view->saved_buffer) { |
175 | .y = container->current.swayc_y, | ||
176 | .width = container->current.swayc_width, | ||
177 | .height = container->current.swayc_height, | ||
178 | }; | ||
179 | struct wlr_box new_con_box = { | ||
180 | .x = instruction->state.swayc_x, | ||
181 | .y = instruction->state.swayc_y, | ||
182 | .width = instruction->state.swayc_width, | ||
183 | .height = instruction->state.swayc_height, | ||
184 | }; | ||
185 | // Handle geometry, which may overflow the bounds of the container | ||
186 | struct wlr_box old_surface_box = {0,0,0,0}; | ||
187 | struct wlr_box new_surface_box = {0,0,0,0}; | ||
188 | if (container->type == C_VIEW) { | ||
189 | struct sway_view *view = container->sway_view; | 176 | struct sway_view *view = container->sway_view; |
190 | if (container->sway_view->saved_buffer) { | 177 | struct wlr_box box = { |
191 | old_surface_box.x = | 178 | .x = container->current.view_x - view->saved_geometry.x, |
192 | container->current.view_x - view->saved_geometry.x; | 179 | .y = container->current.view_y - view->saved_geometry.y, |
193 | old_surface_box.y = | 180 | .width = view->saved_buffer_width, |
194 | container->current.view_y - view->saved_geometry.y; | 181 | .height = view->saved_buffer_height, |
195 | old_surface_box.width = view->saved_buffer_width; | 182 | }; |
196 | old_surface_box.height = view->saved_buffer_height; | 183 | desktop_damage_box(&box); |
197 | } | ||
198 | struct wlr_surface *surface = container->sway_view->surface; | ||
199 | if (surface) { | ||
200 | struct wlr_box geometry; | ||
201 | view_get_geometry(view, &geometry); | ||
202 | new_surface_box.x = instruction->state.view_x - geometry.x; | ||
203 | new_surface_box.y = instruction->state.view_y - geometry.y; | ||
204 | new_surface_box.width = surface->current.width; | ||
205 | new_surface_box.height = surface->current.height; | ||
206 | } | ||
207 | } | ||
208 | for (int j = 0; j < root_container.current.children->length; ++j) { | ||
209 | struct sway_container *output = | ||
210 | root_container.current.children->items[j]; | ||
211 | if (output->sway_output) { | ||
212 | output_damage_box(output->sway_output, &old_con_box); | ||
213 | output_damage_box(output->sway_output, &new_con_box); | ||
214 | output_damage_box(output->sway_output, &old_surface_box); | ||
215 | output_damage_box(output->sway_output, &new_surface_box); | ||
216 | } | ||
217 | } | 184 | } |
218 | 185 | ||
219 | // There are separate children lists for each instruction state, the | 186 | // There are separate children lists for each instruction state, the |
@@ -230,6 +197,20 @@ static void transaction_apply(struct sway_transaction *transaction) { | |||
230 | view_remove_saved_buffer(container->sway_view); | 197 | view_remove_saved_buffer(container->sway_view); |
231 | } | 198 | } |
232 | 199 | ||
200 | // Damage the new location | ||
201 | desktop_damage_whole_container(container); | ||
202 | if (container->type == C_VIEW && container->sway_view->surface) { | ||
203 | struct sway_view *view = container->sway_view; | ||
204 | struct wlr_surface *surface = view->surface; | ||
205 | struct wlr_box box = { | ||
206 | .x = container->current.view_x - view->geometry.x, | ||
207 | .y = container->current.view_y - view->geometry.y, | ||
208 | .width = surface->current.width, | ||
209 | .height = surface->current.height, | ||
210 | }; | ||
211 | desktop_damage_box(&box); | ||
212 | } | ||
213 | |||
233 | container->instruction = NULL; | 214 | container->instruction = NULL; |
234 | } | 215 | } |
235 | } | 216 | } |
@@ -323,7 +304,8 @@ static void transaction_commit(struct sway_transaction *transaction) { | |||
323 | } | 304 | } |
324 | if (con->type == C_VIEW) { | 305 | if (con->type == C_VIEW) { |
325 | view_save_buffer(con->sway_view); | 306 | view_save_buffer(con->sway_view); |
326 | view_get_geometry(con->sway_view, &con->sway_view->saved_geometry); | 307 | memcpy(&con->sway_view->saved_geometry, &con->sway_view->geometry, |
308 | sizeof(struct wlr_box)); | ||
327 | } | 309 | } |
328 | con->instruction = instruction; | 310 | con->instruction = instruction; |
329 | } | 311 | } |
diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index 2b260357..aae129bd 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <wlr/util/edges.h> | 7 | #include <wlr/util/edges.h> |
8 | #include "log.h" | 8 | #include "log.h" |
9 | #include "sway/decoration.h" | 9 | #include "sway/decoration.h" |
10 | #include "sway/desktop.h" | ||
10 | #include "sway/input/input-manager.h" | 11 | #include "sway/input/input-manager.h" |
11 | #include "sway/input/seat.h" | 12 | #include "sway/input/seat.h" |
12 | #include "sway/server.h" | 13 | #include "sway/server.h" |
@@ -122,16 +123,6 @@ static const char *get_string_prop(struct sway_view *view, | |||
122 | } | 123 | } |
123 | } | 124 | } |
124 | 125 | ||
125 | static void get_geometry(struct sway_view *view, struct wlr_box *box) { | ||
126 | struct sway_xdg_shell_view *xdg_shell_view = | ||
127 | xdg_shell_view_from_view(view); | ||
128 | if (xdg_shell_view == NULL) { | ||
129 | return; | ||
130 | } | ||
131 | struct wlr_xdg_surface *surface = view->wlr_xdg_surface; | ||
132 | wlr_xdg_surface_get_geometry(surface, box); | ||
133 | } | ||
134 | |||
135 | static uint32_t configure(struct sway_view *view, double lx, double ly, | 126 | static uint32_t configure(struct sway_view *view, double lx, double ly, |
136 | int width, int height) { | 127 | int width, int height) { |
137 | struct sway_xdg_shell_view *xdg_shell_view = | 128 | struct sway_xdg_shell_view *xdg_shell_view = |
@@ -242,7 +233,6 @@ static void destroy(struct sway_view *view) { | |||
242 | static const struct sway_view_impl view_impl = { | 233 | static const struct sway_view_impl view_impl = { |
243 | .get_constraints = get_constraints, | 234 | .get_constraints = get_constraints, |
244 | .get_string_prop = get_string_prop, | 235 | .get_string_prop = get_string_prop, |
245 | .get_geometry = get_geometry, | ||
246 | .configure = configure, | 236 | .configure = configure, |
247 | .set_activated = set_activated, | 237 | .set_activated = set_activated, |
248 | .set_tiled = set_tiled, | 238 | .set_tiled = set_tiled, |
@@ -267,8 +257,24 @@ static void handle_commit(struct wl_listener *listener, void *data) { | |||
267 | } | 257 | } |
268 | 258 | ||
269 | if (view->swayc->instruction) { | 259 | if (view->swayc->instruction) { |
260 | wlr_xdg_surface_get_geometry(xdg_surface, &view->geometry); | ||
270 | transaction_notify_view_ready_by_serial(view, | 261 | transaction_notify_view_ready_by_serial(view, |
271 | xdg_surface->configure_serial); | 262 | xdg_surface->configure_serial); |
263 | } else { | ||
264 | struct wlr_box new_geo; | ||
265 | wlr_xdg_surface_get_geometry(xdg_surface, &new_geo); | ||
266 | |||
267 | if ((new_geo.width != view->width || new_geo.height != view->height) && | ||
268 | container_is_floating(view->swayc)) { | ||
269 | // A floating view has unexpectedly sent a new size | ||
270 | desktop_damage_view(view); | ||
271 | view_update_size(view, new_geo.width, new_geo.height); | ||
272 | memcpy(&view->geometry, &new_geo, sizeof(struct wlr_box)); | ||
273 | desktop_damage_view(view); | ||
274 | transaction_commit_dirty(); | ||
275 | } else { | ||
276 | memcpy(&view->geometry, &new_geo, sizeof(struct wlr_box)); | ||
277 | } | ||
272 | } | 278 | } |
273 | 279 | ||
274 | view_damage_from(view); | 280 | view_damage_from(view); |
diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index bbc7456c..277c53a3 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <wlr/types/wlr_xdg_shell_v6.h> | 6 | #include <wlr/types/wlr_xdg_shell_v6.h> |
7 | #include "log.h" | 7 | #include "log.h" |
8 | #include "sway/decoration.h" | 8 | #include "sway/decoration.h" |
9 | #include "sway/desktop.h" | ||
9 | #include "sway/input/input-manager.h" | 10 | #include "sway/input/input-manager.h" |
10 | #include "sway/input/seat.h" | 11 | #include "sway/input/seat.h" |
11 | #include "sway/server.h" | 12 | #include "sway/server.h" |
@@ -121,16 +122,6 @@ static const char *get_string_prop(struct sway_view *view, | |||
121 | } | 122 | } |
122 | } | 123 | } |
123 | 124 | ||
124 | static void get_geometry(struct sway_view *view, struct wlr_box *box) { | ||
125 | struct sway_xdg_shell_v6_view *xdg_shell_v6_view = | ||
126 | xdg_shell_v6_view_from_view(view); | ||
127 | if (xdg_shell_v6_view == NULL) { | ||
128 | return; | ||
129 | } | ||
130 | struct wlr_xdg_surface_v6 *surface = view->wlr_xdg_surface_v6; | ||
131 | wlr_xdg_surface_v6_get_geometry(surface, box); | ||
132 | } | ||
133 | |||
134 | static uint32_t configure(struct sway_view *view, double lx, double ly, | 125 | static uint32_t configure(struct sway_view *view, double lx, double ly, |
135 | int width, int height) { | 126 | int width, int height) { |
136 | struct sway_xdg_shell_v6_view *xdg_shell_v6_view = | 127 | struct sway_xdg_shell_v6_view *xdg_shell_v6_view = |
@@ -239,7 +230,6 @@ static void destroy(struct sway_view *view) { | |||
239 | static const struct sway_view_impl view_impl = { | 230 | static const struct sway_view_impl view_impl = { |
240 | .get_constraints = get_constraints, | 231 | .get_constraints = get_constraints, |
241 | .get_string_prop = get_string_prop, | 232 | .get_string_prop = get_string_prop, |
242 | .get_geometry = get_geometry, | ||
243 | .configure = configure, | 233 | .configure = configure, |
244 | .set_activated = set_activated, | 234 | .set_activated = set_activated, |
245 | .set_tiled = set_tiled, | 235 | .set_tiled = set_tiled, |
@@ -262,9 +252,26 @@ static void handle_commit(struct wl_listener *listener, void *data) { | |||
262 | if (!view->swayc) { | 252 | if (!view->swayc) { |
263 | return; | 253 | return; |
264 | } | 254 | } |
255 | |||
265 | if (view->swayc->instruction) { | 256 | if (view->swayc->instruction) { |
257 | wlr_xdg_surface_v6_get_geometry(xdg_surface_v6, &view->geometry); | ||
266 | transaction_notify_view_ready_by_serial(view, | 258 | transaction_notify_view_ready_by_serial(view, |
267 | xdg_surface_v6->configure_serial); | 259 | xdg_surface_v6->configure_serial); |
260 | } else { | ||
261 | struct wlr_box new_geo; | ||
262 | wlr_xdg_surface_v6_get_geometry(xdg_surface_v6, &new_geo); | ||
263 | |||
264 | if ((new_geo.width != view->width || new_geo.height != view->height) && | ||
265 | container_is_floating(view->swayc)) { | ||
266 | // A floating view has unexpectedly sent a new size | ||
267 | desktop_damage_view(view); | ||
268 | view_update_size(view, new_geo.width, new_geo.height); | ||
269 | memcpy(&view->geometry, &new_geo, sizeof(struct wlr_box)); | ||
270 | desktop_damage_view(view); | ||
271 | transaction_commit_dirty(); | ||
272 | } else { | ||
273 | memcpy(&view->geometry, &new_geo, sizeof(struct wlr_box)); | ||
274 | } | ||
268 | } | 275 | } |
269 | 276 | ||
270 | view_damage_from(view); | 277 | view_damage_from(view); |
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index e0c44b39..ce7235e4 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c | |||
@@ -277,6 +277,17 @@ static const struct sway_view_impl view_impl = { | |||
277 | .destroy = destroy, | 277 | .destroy = destroy, |
278 | }; | 278 | }; |
279 | 279 | ||
280 | static void get_geometry(struct sway_view *view, struct wlr_box *box) { | ||
281 | box->x = box->y = 0; | ||
282 | if (view->surface) { | ||
283 | box->width = view->surface->current.width; | ||
284 | box->height = view->surface->current.height; | ||
285 | } else { | ||
286 | box->width = 0; | ||
287 | box->height = 0; | ||
288 | } | ||
289 | } | ||
290 | |||
280 | static void handle_commit(struct wl_listener *listener, void *data) { | 291 | static void handle_commit(struct wl_listener *listener, void *data) { |
281 | struct sway_xwayland_view *xwayland_view = | 292 | struct sway_xwayland_view *xwayland_view = |
282 | wl_container_of(listener, xwayland_view, commit); | 293 | wl_container_of(listener, xwayland_view, commit); |
@@ -285,18 +296,25 @@ static void handle_commit(struct wl_listener *listener, void *data) { | |||
285 | struct wlr_surface_state *state = &xsurface->surface->current; | 296 | struct wlr_surface_state *state = &xsurface->surface->current; |
286 | 297 | ||
287 | if (view->swayc->instruction) { | 298 | if (view->swayc->instruction) { |
299 | get_geometry(view, &view->geometry); | ||
288 | transaction_notify_view_ready_by_size(view, | 300 | transaction_notify_view_ready_by_size(view, |
289 | state->width, state->height); | 301 | state->width, state->height); |
290 | } else if ((state->width != view->width || state->height != view->height) && | 302 | } else { |
303 | struct wlr_box new_geo; | ||
304 | get_geometry(view, &new_geo); | ||
305 | |||
306 | if ((new_geo.width != view->width || new_geo.height != view->height) && | ||
291 | container_is_floating(view->swayc)) { | 307 | container_is_floating(view->swayc)) { |
292 | // eg. The Firefox "Save As" dialog when downloading a file | 308 | // A floating view has unexpectedly sent a new size |
293 | // It maps at a small size then changes afterwards. | 309 | // eg. The Firefox "Save As" dialog when downloading a file |
294 | view->width = state->width; | 310 | desktop_damage_view(view); |
295 | view->height = state->height; | 311 | view_update_size(view, new_geo.width, new_geo.height); |
296 | view->swayc->current.view_width = state->width; | 312 | memcpy(&view->geometry, &new_geo, sizeof(struct wlr_box)); |
297 | view->swayc->current.view_height = state->height; | 313 | desktop_damage_view(view); |
298 | container_set_geometry_from_floating_view(view->swayc); | 314 | transaction_commit_dirty(); |
299 | transaction_commit_dirty(); | 315 | } else { |
316 | memcpy(&view->geometry, &new_geo, sizeof(struct wlr_box)); | ||
317 | } | ||
300 | } | 318 | } |
301 | 319 | ||
302 | view_damage_from(view); | 320 | view_damage_from(view); |
diff --git a/sway/tree/container.c b/sway/tree/container.c index b3368a2e..b3f3a344 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c | |||
@@ -522,13 +522,8 @@ static void surface_at_view(struct sway_container *swayc, double lx, double ly, | |||
522 | return; | 522 | return; |
523 | } | 523 | } |
524 | struct sway_view *sview = swayc->sway_view; | 524 | struct sway_view *sview = swayc->sway_view; |
525 | double view_sx = lx - sview->x; | 525 | double view_sx = lx - sview->x + sview->geometry.x; |
526 | double view_sy = ly - sview->y; | 526 | double view_sy = ly - sview->y + sview->geometry.y; |
527 | |||
528 | struct wlr_box geometry; | ||
529 | view_get_geometry(sview, &geometry); | ||
530 | view_sx += geometry.x; | ||
531 | view_sy += geometry.y; | ||
532 | 527 | ||
533 | double _sx, _sy; | 528 | double _sx, _sy; |
534 | struct wlr_surface *_surface = NULL; | 529 | struct wlr_surface *_surface = NULL; |
diff --git a/sway/tree/view.c b/sway/tree/view.c index fba0b52d..fbe4bc58 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c | |||
@@ -162,20 +162,6 @@ void view_get_constraints(struct sway_view *view, double *min_width, | |||
162 | } | 162 | } |
163 | } | 163 | } |
164 | 164 | ||
165 | void view_get_geometry(struct sway_view *view, struct wlr_box *box) { | ||
166 | if (view->surface == NULL) { | ||
167 | box->x = box->y = box->width = box->height = 0; | ||
168 | return; | ||
169 | } | ||
170 | if (view->impl->get_geometry) { | ||
171 | view->impl->get_geometry(view, box); | ||
172 | return; | ||
173 | } | ||
174 | box->x = box->y = 0; | ||
175 | box->width = view->surface->current.width; | ||
176 | box->height = view->surface->current.height; | ||
177 | } | ||
178 | |||
179 | uint32_t view_configure(struct sway_view *view, double lx, double ly, int width, | 165 | uint32_t view_configure(struct sway_view *view, double lx, double ly, int width, |
180 | int height) { | 166 | int height) { |
181 | if (view->impl->configure) { | 167 | if (view->impl->configure) { |
@@ -629,6 +615,18 @@ void view_unmap(struct sway_view *view) { | |||
629 | view->surface = NULL; | 615 | view->surface = NULL; |
630 | } | 616 | } |
631 | 617 | ||
618 | void view_update_size(struct sway_view *view, int width, int height) { | ||
619 | if (!sway_assert(container_is_floating(view->swayc), | ||
620 | "Expected a floating container")) { | ||
621 | return; | ||
622 | } | ||
623 | view->width = width; | ||
624 | view->height = height; | ||
625 | view->swayc->current.view_width = width; | ||
626 | view->swayc->current.view_height = height; | ||
627 | container_set_geometry_from_floating_view(view->swayc); | ||
628 | } | ||
629 | |||
632 | static void view_subsurface_create(struct sway_view *view, | 630 | static void view_subsurface_create(struct sway_view *view, |
633 | struct wlr_subsurface *subsurface) { | 631 | struct wlr_subsurface *subsurface) { |
634 | struct sway_view_child *child = calloc(1, sizeof(struct sway_view_child)); | 632 | struct sway_view_child *child = calloc(1, sizeof(struct sway_view_child)); |