diff options
Diffstat (limited to 'sway/desktop/xdg_shell.c')
-rw-r--r-- | sway/desktop/xdg_shell.c | 75 |
1 files changed, 45 insertions, 30 deletions
diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index 6ac0f9c7..da3a1cdd 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include "sway/input/input-manager.h" | 8 | #include "sway/input/input-manager.h" |
9 | #include "sway/input/seat.h" | 9 | #include "sway/input/seat.h" |
10 | #include "sway/server.h" | 10 | #include "sway/server.h" |
11 | #include "sway/tree/arrange.h" | ||
11 | #include "sway/tree/container.h" | 12 | #include "sway/tree/container.h" |
12 | #include "sway/tree/layout.h" | 13 | #include "sway/tree/layout.h" |
13 | #include "sway/tree/view.h" | 14 | #include "sway/tree/view.h" |
@@ -87,18 +88,14 @@ static const char *get_string_prop(struct sway_view *view, enum sway_view_prop p | |||
87 | } | 88 | } |
88 | } | 89 | } |
89 | 90 | ||
90 | static void configure(struct sway_view *view, double lx, double ly, int width, | 91 | static uint32_t configure(struct sway_view *view, double lx, double ly, |
91 | int height) { | 92 | int width, int height) { |
92 | struct sway_xdg_shell_view *xdg_shell_view = | 93 | struct sway_xdg_shell_view *xdg_shell_view = |
93 | xdg_shell_view_from_view(view); | 94 | xdg_shell_view_from_view(view); |
94 | if (xdg_shell_view == NULL) { | 95 | if (xdg_shell_view == NULL) { |
95 | return; | 96 | return 0; |
96 | } | 97 | } |
97 | 98 | return wlr_xdg_toplevel_set_size(view->wlr_xdg_surface, width, height); | |
98 | xdg_shell_view->pending_width = width; | ||
99 | xdg_shell_view->pending_height = height; | ||
100 | wlr_xdg_toplevel_set_size(view->wlr_xdg_surface, width, height); | ||
101 | view_update_position(view, lx, ly); | ||
102 | } | 99 | } |
103 | 100 | ||
104 | static void set_activated(struct sway_view *view, bool activated) { | 101 | static void set_activated(struct sway_view *view, bool activated) { |
@@ -166,10 +163,6 @@ static void destroy(struct sway_view *view) { | |||
166 | if (xdg_shell_view == NULL) { | 163 | if (xdg_shell_view == NULL) { |
167 | return; | 164 | return; |
168 | } | 165 | } |
169 | wl_list_remove(&xdg_shell_view->destroy.link); | ||
170 | wl_list_remove(&xdg_shell_view->map.link); | ||
171 | wl_list_remove(&xdg_shell_view->unmap.link); | ||
172 | wl_list_remove(&xdg_shell_view->request_fullscreen.link); | ||
173 | free(xdg_shell_view); | 166 | free(xdg_shell_view); |
174 | } | 167 | } |
175 | 168 | ||
@@ -189,18 +182,16 @@ static void handle_commit(struct wl_listener *listener, void *data) { | |||
189 | struct sway_xdg_shell_view *xdg_shell_view = | 182 | struct sway_xdg_shell_view *xdg_shell_view = |
190 | wl_container_of(listener, xdg_shell_view, commit); | 183 | wl_container_of(listener, xdg_shell_view, commit); |
191 | struct sway_view *view = &xdg_shell_view->view; | 184 | struct sway_view *view = &xdg_shell_view->view; |
192 | if (view->swayc && container_is_floating(view->swayc)) { | 185 | struct wlr_xdg_surface *xdg_surface = view->wlr_xdg_surface; |
193 | int width = view->wlr_xdg_surface->geometry.width; | 186 | |
194 | int height = view->wlr_xdg_surface->geometry.height; | 187 | if (!view->swayc) { |
195 | if (!width && !height) { | 188 | return; |
196 | width = view->wlr_xdg_surface->surface->current->width; | 189 | } |
197 | height = view->wlr_xdg_surface->surface->current->height; | 190 | |
198 | } | 191 | if (view->swayc->instructions->length) { |
199 | view_update_size(view, width, height); | 192 | transaction_notify_view_ready(view, xdg_surface->configure_serial); |
200 | } else { | ||
201 | view_update_size(view, xdg_shell_view->pending_width, | ||
202 | xdg_shell_view->pending_height); | ||
203 | } | 193 | } |
194 | |||
204 | view_update_title(view, false); | 195 | view_update_title(view, false); |
205 | view_damage_from(view); | 196 | view_damage_from(view); |
206 | } | 197 | } |
@@ -215,8 +206,13 @@ static void handle_new_popup(struct wl_listener *listener, void *data) { | |||
215 | static void handle_unmap(struct wl_listener *listener, void *data) { | 206 | static void handle_unmap(struct wl_listener *listener, void *data) { |
216 | struct sway_xdg_shell_view *xdg_shell_view = | 207 | struct sway_xdg_shell_view *xdg_shell_view = |
217 | wl_container_of(listener, xdg_shell_view, unmap); | 208 | wl_container_of(listener, xdg_shell_view, unmap); |
209 | struct sway_view *view = &xdg_shell_view->view; | ||
218 | 210 | ||
219 | view_unmap(&xdg_shell_view->view); | 211 | if (!sway_assert(view->surface, "Cannot unmap unmapped view")) { |
212 | return; | ||
213 | } | ||
214 | |||
215 | view_unmap(view); | ||
220 | 216 | ||
221 | wl_list_remove(&xdg_shell_view->commit.link); | 217 | wl_list_remove(&xdg_shell_view->commit.link); |
222 | wl_list_remove(&xdg_shell_view->new_popup.link); | 218 | wl_list_remove(&xdg_shell_view->new_popup.link); |
@@ -234,8 +230,17 @@ static void handle_map(struct wl_listener *listener, void *data) { | |||
234 | view->natural_width = view->wlr_xdg_surface->surface->current->width; | 230 | view->natural_width = view->wlr_xdg_surface->surface->current->width; |
235 | view->natural_height = view->wlr_xdg_surface->surface->current->height; | 231 | view->natural_height = view->wlr_xdg_surface->surface->current->height; |
236 | } | 232 | } |
233 | |||
237 | view_map(view, view->wlr_xdg_surface->surface); | 234 | view_map(view, view->wlr_xdg_surface->surface); |
238 | 235 | ||
236 | if (xdg_surface->toplevel->client_pending.fullscreen) { | ||
237 | view_set_fullscreen(view, true); | ||
238 | struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); | ||
239 | arrange_and_commit(ws); | ||
240 | } else { | ||
241 | arrange_and_commit(view->swayc->parent); | ||
242 | } | ||
243 | |||
239 | xdg_shell_view->commit.notify = handle_commit; | 244 | xdg_shell_view->commit.notify = handle_commit; |
240 | wl_signal_add(&xdg_surface->surface->events.commit, | 245 | wl_signal_add(&xdg_surface->surface->events.commit, |
241 | &xdg_shell_view->commit); | 246 | &xdg_shell_view->commit); |
@@ -243,16 +248,22 @@ static void handle_map(struct wl_listener *listener, void *data) { | |||
243 | xdg_shell_view->new_popup.notify = handle_new_popup; | 248 | xdg_shell_view->new_popup.notify = handle_new_popup; |
244 | wl_signal_add(&xdg_surface->events.new_popup, | 249 | wl_signal_add(&xdg_surface->events.new_popup, |
245 | &xdg_shell_view->new_popup); | 250 | &xdg_shell_view->new_popup); |
246 | |||
247 | if (xdg_surface->toplevel->client_pending.fullscreen) { | ||
248 | view_set_fullscreen(view, true); | ||
249 | } | ||
250 | } | 251 | } |
251 | 252 | ||
252 | static void handle_destroy(struct wl_listener *listener, void *data) { | 253 | static void handle_destroy(struct wl_listener *listener, void *data) { |
253 | struct sway_xdg_shell_view *xdg_shell_view = | 254 | struct sway_xdg_shell_view *xdg_shell_view = |
254 | wl_container_of(listener, xdg_shell_view, destroy); | 255 | wl_container_of(listener, xdg_shell_view, destroy); |
255 | view_destroy(&xdg_shell_view->view); | 256 | struct sway_view *view = &xdg_shell_view->view; |
257 | if (!sway_assert(view->swayc == NULL || view->swayc->destroying, | ||
258 | "Tried to destroy a mapped view")) { | ||
259 | return; | ||
260 | } | ||
261 | wl_list_remove(&xdg_shell_view->destroy.link); | ||
262 | wl_list_remove(&xdg_shell_view->map.link); | ||
263 | wl_list_remove(&xdg_shell_view->unmap.link); | ||
264 | wl_list_remove(&xdg_shell_view->request_fullscreen.link); | ||
265 | view->wlr_xdg_surface = NULL; | ||
266 | view_destroy(view); | ||
256 | } | 267 | } |
257 | 268 | ||
258 | static void handle_request_fullscreen(struct wl_listener *listener, void *data) { | 269 | static void handle_request_fullscreen(struct wl_listener *listener, void *data) { |
@@ -261,6 +272,7 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data) | |||
261 | struct wlr_xdg_toplevel_set_fullscreen_event *e = data; | 272 | struct wlr_xdg_toplevel_set_fullscreen_event *e = data; |
262 | struct wlr_xdg_surface *xdg_surface = | 273 | struct wlr_xdg_surface *xdg_surface = |
263 | xdg_shell_view->view.wlr_xdg_surface; | 274 | xdg_shell_view->view.wlr_xdg_surface; |
275 | struct sway_view *view = &xdg_shell_view->view; | ||
264 | 276 | ||
265 | if (!sway_assert(xdg_surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL, | 277 | if (!sway_assert(xdg_surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL, |
266 | "xdg_shell requested fullscreen of surface with role %i", | 278 | "xdg_shell requested fullscreen of surface with role %i", |
@@ -271,7 +283,10 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data) | |||
271 | return; | 283 | return; |
272 | } | 284 | } |
273 | 285 | ||
274 | view_set_fullscreen(&xdg_shell_view->view, e->fullscreen); | 286 | view_set_fullscreen(view, e->fullscreen); |
287 | |||
288 | struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); | ||
289 | arrange_and_commit(ws); | ||
275 | } | 290 | } |
276 | 291 | ||
277 | void handle_xdg_shell_surface(struct wl_listener *listener, void *data) { | 292 | void handle_xdg_shell_surface(struct wl_listener *listener, void *data) { |