summaryrefslogtreecommitdiffstats
path: root/sway/desktop/xdg_shell.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/desktop/xdg_shell.c')
-rw-r--r--sway/desktop/xdg_shell.c75
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
90static void configure(struct sway_view *view, double lx, double ly, int width, 91static 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
104static void set_activated(struct sway_view *view, bool activated) { 101static 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) {
215static void handle_unmap(struct wl_listener *listener, void *data) { 206static 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
252static void handle_destroy(struct wl_listener *listener, void *data) { 253static 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
258static void handle_request_fullscreen(struct wl_listener *listener, void *data) { 269static 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
277void handle_xdg_shell_surface(struct wl_listener *listener, void *data) { 292void handle_xdg_shell_surface(struct wl_listener *listener, void *data) {