aboutsummaryrefslogtreecommitdiffstats
path: root/sway/desktop
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-08-18 15:10:06 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-08-18 15:10:06 +1000
commitb0a5f3a25f52bc1d48d771cb02820042006d8d9e (patch)
treee7a2e4c60e562589e3b9a54c6ce559a41dcf7534 /sway/desktop
parentSet current size when a floating xwayland view resizes (diff)
downloadsway-b0a5f3a25f52bc1d48d771cb02820042006d8d9e.tar.gz
sway-b0a5f3a25f52bc1d48d771cb02820042006d8d9e.tar.zst
sway-b0a5f3a25f52bc1d48d771cb02820042006d8d9e.zip
Store geometry in the view and handle any floating view resizing
Diffstat (limited to 'sway/desktop')
-rw-r--r--sway/desktop/desktop.c18
-rw-r--r--sway/desktop/output.c9
-rw-r--r--sway/desktop/render.c10
-rw-r--r--sway/desktop/transaction.c72
-rw-r--r--sway/desktop/xdg_shell.c28
-rw-r--r--sway/desktop/xdg_shell_v6.c29
-rw-r--r--sway/desktop/xwayland.c36
7 files changed, 115 insertions, 87 deletions
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
26void 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
33void 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,
140void output_view_for_each_surface(struct sway_output *output, 140void 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
162void output_view_for_each_popup(struct sway_output *output, 159void 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
125static 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
135static uint32_t configure(struct sway_view *view, double lx, double ly, 126static 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) {
242static const struct sway_view_impl view_impl = { 233static 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
124static 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
134static uint32_t configure(struct sway_view *view, double lx, double ly, 125static 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) {
239static const struct sway_view_impl view_impl = { 230static 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
280static 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
280static void handle_commit(struct wl_listener *listener, void *data) { 291static 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);