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.c105
1 files changed, 99 insertions, 6 deletions
diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c
index 98c16faf..b364663d 100644
--- a/sway/desktop/xdg_shell.c
+++ b/sway/desktop/xdg_shell.c
@@ -1,4 +1,5 @@
1#define _POSIX_C_SOURCE 199309L 1#define _POSIX_C_SOURCE 199309L
2#include <float.h>
2#include <stdbool.h> 3#include <stdbool.h>
3#include <stdlib.h> 4#include <stdlib.h>
4#include <wayland-server.h> 5#include <wayland-server.h>
@@ -95,6 +96,16 @@ static struct sway_xdg_shell_view *xdg_shell_view_from_view(
95 return (struct sway_xdg_shell_view *)view; 96 return (struct sway_xdg_shell_view *)view;
96} 97}
97 98
99static void get_constraints(struct sway_view *view, double *min_width,
100 double *max_width, double *min_height, double *max_height) {
101 struct wlr_xdg_toplevel_state *state =
102 &view->wlr_xdg_surface->toplevel->current;
103 *min_width = state->min_width > 0 ? state->min_width : DBL_MIN;
104 *max_width = state->max_width > 0 ? state->max_width : DBL_MAX;
105 *min_height = state->min_height > 0 ? state->min_height : DBL_MIN;
106 *max_height = state->max_height > 0 ? state->max_height : DBL_MAX;
107}
108
98static const char *get_string_prop(struct sway_view *view, enum sway_view_prop prop) { 109static const char *get_string_prop(struct sway_view *view, enum sway_view_prop prop) {
99 if (xdg_shell_view_from_view(view) == NULL) { 110 if (xdg_shell_view_from_view(view) == NULL) {
100 return NULL; 111 return NULL;
@@ -168,6 +179,14 @@ static void for_each_surface(struct sway_view *view,
168 user_data); 179 user_data);
169} 180}
170 181
182static void for_each_popup(struct sway_view *view,
183 wlr_surface_iterator_func_t iterator, void *user_data) {
184 if (xdg_shell_view_from_view(view) == NULL) {
185 return;
186 }
187 wlr_xdg_surface_for_each_popup(view->wlr_xdg_surface, iterator, user_data);
188}
189
171static void _close(struct sway_view *view) { 190static void _close(struct sway_view *view) {
172 if (xdg_shell_view_from_view(view) == NULL) { 191 if (xdg_shell_view_from_view(view) == NULL) {
173 return; 192 return;
@@ -178,6 +197,18 @@ static void _close(struct sway_view *view) {
178 } 197 }
179} 198}
180 199
200static void close_popups_iterator(struct wlr_surface *surface,
201 int sx, int sy, void *data) {
202 struct wlr_xdg_surface *xdg_surface =
203 wlr_xdg_surface_from_wlr_surface(surface);
204 wlr_xdg_surface_send_close(xdg_surface);
205}
206
207static void close_popups(struct sway_view *view) {
208 wlr_xdg_surface_for_each_popup(view->wlr_xdg_surface,
209 close_popups_iterator, NULL);
210}
211
181static void destroy(struct sway_view *view) { 212static void destroy(struct sway_view *view) {
182 struct sway_xdg_shell_view *xdg_shell_view = 213 struct sway_xdg_shell_view *xdg_shell_view =
183 xdg_shell_view_from_view(view); 214 xdg_shell_view_from_view(view);
@@ -188,6 +219,7 @@ static void destroy(struct sway_view *view) {
188} 219}
189 220
190static const struct sway_view_impl view_impl = { 221static const struct sway_view_impl view_impl = {
222 .get_constraints = get_constraints,
191 .get_string_prop = get_string_prop, 223 .get_string_prop = get_string_prop,
192 .configure = configure, 224 .configure = configure,
193 .set_activated = set_activated, 225 .set_activated = set_activated,
@@ -195,7 +227,9 @@ static const struct sway_view_impl view_impl = {
195 .set_fullscreen = set_fullscreen, 227 .set_fullscreen = set_fullscreen,
196 .wants_floating = wants_floating, 228 .wants_floating = wants_floating,
197 .for_each_surface = for_each_surface, 229 .for_each_surface = for_each_surface,
230 .for_each_popup = for_each_popup,
198 .close = _close, 231 .close = _close,
232 .close_popups = close_popups,
199 .destroy = destroy, 233 .destroy = destroy,
200}; 234};
201 235
@@ -213,10 +247,24 @@ static void handle_commit(struct wl_listener *listener, void *data) {
213 transaction_notify_view_ready(view, xdg_surface->configure_serial); 247 transaction_notify_view_ready(view, xdg_surface->configure_serial);
214 } 248 }
215 249
216 view_update_title(view, false);
217 view_damage_from(view); 250 view_damage_from(view);
218} 251}
219 252
253static void handle_set_title(struct wl_listener *listener, void *data) {
254 struct sway_xdg_shell_view *xdg_shell_view =
255 wl_container_of(listener, xdg_shell_view, set_title);
256 struct sway_view *view = &xdg_shell_view->view;
257 view_update_title(view, false);
258 view_execute_criteria(view);
259}
260
261static void handle_set_app_id(struct wl_listener *listener, void *data) {
262 struct sway_xdg_shell_view *xdg_shell_view =
263 wl_container_of(listener, xdg_shell_view, set_app_id);
264 struct sway_view *view = &xdg_shell_view->view;
265 view_execute_criteria(view);
266}
267
220static void handle_new_popup(struct wl_listener *listener, void *data) { 268static void handle_new_popup(struct wl_listener *listener, void *data) {
221 struct sway_xdg_shell_view *xdg_shell_view = 269 struct sway_xdg_shell_view *xdg_shell_view =
222 wl_container_of(listener, xdg_shell_view, new_popup); 270 wl_container_of(listener, xdg_shell_view, new_popup);
@@ -241,13 +289,41 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data)
241 return; 289 return;
242 } 290 }
243 291
244 view_set_fullscreen(view, e->fullscreen); 292 container_set_fullscreen(view->swayc, e->fullscreen);
245 293
246 struct sway_container *output = container_parent(view->swayc, C_OUTPUT); 294 struct sway_container *output = container_parent(view->swayc, C_OUTPUT);
247 arrange_windows(output); 295 arrange_windows(output);
248 transaction_commit_dirty(); 296 transaction_commit_dirty();
249} 297}
250 298
299static void handle_request_move(struct wl_listener *listener, void *data) {
300 struct sway_xdg_shell_view *xdg_shell_view =
301 wl_container_of(listener, xdg_shell_view, request_move);
302 struct sway_view *view = &xdg_shell_view->view;
303 if (!container_is_floating(view->swayc)) {
304 return;
305 }
306 struct wlr_xdg_toplevel_move_event *e = data;
307 struct sway_seat *seat = e->seat->seat->data;
308 if (e->serial == seat->last_button_serial) {
309 seat_begin_move(seat, view->swayc, seat->last_button);
310 }
311}
312
313static void handle_request_resize(struct wl_listener *listener, void *data) {
314 struct sway_xdg_shell_view *xdg_shell_view =
315 wl_container_of(listener, xdg_shell_view, request_resize);
316 struct sway_view *view = &xdg_shell_view->view;
317 if (!container_is_floating(view->swayc)) {
318 return;
319 }
320 struct wlr_xdg_toplevel_resize_event *e = data;
321 struct sway_seat *seat = e->seat->seat->data;
322 if (e->serial == seat->last_button_serial) {
323 seat_begin_resize(seat, view->swayc, seat->last_button, e->edges);
324 }
325}
326
251static void handle_unmap(struct wl_listener *listener, void *data) { 327static void handle_unmap(struct wl_listener *listener, void *data) {
252 struct sway_xdg_shell_view *xdg_shell_view = 328 struct sway_xdg_shell_view *xdg_shell_view =
253 wl_container_of(listener, xdg_shell_view, unmap); 329 wl_container_of(listener, xdg_shell_view, unmap);
@@ -262,6 +338,10 @@ static void handle_unmap(struct wl_listener *listener, void *data) {
262 wl_list_remove(&xdg_shell_view->commit.link); 338 wl_list_remove(&xdg_shell_view->commit.link);
263 wl_list_remove(&xdg_shell_view->new_popup.link); 339 wl_list_remove(&xdg_shell_view->new_popup.link);
264 wl_list_remove(&xdg_shell_view->request_fullscreen.link); 340 wl_list_remove(&xdg_shell_view->request_fullscreen.link);
341 wl_list_remove(&xdg_shell_view->request_move.link);
342 wl_list_remove(&xdg_shell_view->request_resize.link);
343 wl_list_remove(&xdg_shell_view->set_title.link);
344 wl_list_remove(&xdg_shell_view->set_app_id.link);
265} 345}
266 346
267static void handle_map(struct wl_listener *listener, void *data) { 347static void handle_map(struct wl_listener *listener, void *data) {
@@ -280,7 +360,7 @@ static void handle_map(struct wl_listener *listener, void *data) {
280 view_map(view, view->wlr_xdg_surface->surface); 360 view_map(view, view->wlr_xdg_surface->surface);
281 361
282 if (xdg_surface->toplevel->client_pending.fullscreen) { 362 if (xdg_surface->toplevel->client_pending.fullscreen) {
283 view_set_fullscreen(view, true); 363 container_set_fullscreen(view->swayc, true);
284 struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); 364 struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE);
285 arrange_windows(ws); 365 arrange_windows(ws);
286 } else { 366 } else {
@@ -299,6 +379,22 @@ static void handle_map(struct wl_listener *listener, void *data) {
299 xdg_shell_view->request_fullscreen.notify = handle_request_fullscreen; 379 xdg_shell_view->request_fullscreen.notify = handle_request_fullscreen;
300 wl_signal_add(&xdg_surface->toplevel->events.request_fullscreen, 380 wl_signal_add(&xdg_surface->toplevel->events.request_fullscreen,
301 &xdg_shell_view->request_fullscreen); 381 &xdg_shell_view->request_fullscreen);
382
383 xdg_shell_view->request_move.notify = handle_request_move;
384 wl_signal_add(&xdg_surface->toplevel->events.request_move,
385 &xdg_shell_view->request_move);
386
387 xdg_shell_view->request_resize.notify = handle_request_resize;
388 wl_signal_add(&xdg_surface->toplevel->events.request_resize,
389 &xdg_shell_view->request_resize);
390
391 xdg_shell_view->set_title.notify = handle_set_title;
392 wl_signal_add(&xdg_surface->toplevel->events.set_title,
393 &xdg_shell_view->set_title);
394
395 xdg_shell_view->set_app_id.notify = handle_set_app_id;
396 wl_signal_add(&xdg_surface->toplevel->events.set_app_id,
397 &xdg_shell_view->set_app_id);
302} 398}
303 399
304static void handle_destroy(struct wl_listener *listener, void *data) { 400static void handle_destroy(struct wl_listener *listener, void *data) {
@@ -344,9 +440,6 @@ void handle_xdg_shell_surface(struct wl_listener *listener, void *data) {
344 view_init(&xdg_shell_view->view, SWAY_VIEW_XDG_SHELL, &view_impl); 440 view_init(&xdg_shell_view->view, SWAY_VIEW_XDG_SHELL, &view_impl);
345 xdg_shell_view->view.wlr_xdg_surface = xdg_surface; 441 xdg_shell_view->view.wlr_xdg_surface = xdg_surface;
346 442
347 // TODO:
348 // - Look up pid and open on appropriate workspace
349
350 xdg_shell_view->map.notify = handle_map; 443 xdg_shell_view->map.notify = handle_map;
351 wl_signal_add(&xdg_surface->events.map, &xdg_shell_view->map); 444 wl_signal_add(&xdg_surface->events.map, &xdg_shell_view->map);
352 445