aboutsummaryrefslogtreecommitdiffstats
path: root/sway/desktop/xdg_shell.c
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2018-07-23 20:27:56 -0400
committerLibravatar Drew DeVault <sir@cmpwn.com>2018-07-23 20:31:11 -0400
commitf4b882475eee7a81c206c7825616cc4656b2f60b (patch)
tree38e6ebf81b235424f105dcbcbb194e5e9eac70c0 /sway/desktop/xdg_shell.c
parentImplement pid->workspace tracking (diff)
parentMerge pull request #2342 from RyanDwyer/update-cursor (diff)
downloadsway-f4b882475eee7a81c206c7825616cc4656b2f60b.tar.gz
sway-f4b882475eee7a81c206c7825616cc4656b2f60b.tar.zst
sway-f4b882475eee7a81c206c7825616cc4656b2f60b.zip
Merge branch 'master' into pid-workspaces
Diffstat (limited to 'sway/desktop/xdg_shell.c')
-rw-r--r--sway/desktop/xdg_shell.c115
1 files changed, 106 insertions, 9 deletions
diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c
index 47604c31..f3e4fef8 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>
@@ -45,6 +46,24 @@ static void popup_handle_destroy(struct wl_listener *listener, void *data) {
45 view_child_destroy(&popup->child); 46 view_child_destroy(&popup->child);
46} 47}
47 48
49static void popup_unconstrain(struct sway_xdg_popup *popup) {
50 struct sway_view *view = popup->child.view;
51 struct wlr_xdg_popup *wlr_popup = popup->wlr_xdg_surface->popup;
52
53 struct sway_container *output = container_parent(view->swayc, C_OUTPUT);
54
55 // the output box expressed in the coordinate system of the toplevel parent
56 // of the popup
57 struct wlr_box output_toplevel_sx_box = {
58 .x = output->x - view->x,
59 .y = output->y - view->y,
60 .width = output->width,
61 .height = output->height,
62 };
63
64 wlr_xdg_popup_unconstrain_from_box(wlr_popup, &output_toplevel_sx_box);
65}
66
48static struct sway_xdg_popup *popup_create( 67static struct sway_xdg_popup *popup_create(
49 struct wlr_xdg_popup *wlr_popup, struct sway_view *view) { 68 struct wlr_xdg_popup *wlr_popup, struct sway_view *view) {
50 struct wlr_xdg_surface *xdg_surface = wlr_popup->base; 69 struct wlr_xdg_surface *xdg_surface = wlr_popup->base;
@@ -55,12 +74,15 @@ static struct sway_xdg_popup *popup_create(
55 return NULL; 74 return NULL;
56 } 75 }
57 view_child_init(&popup->child, &popup_impl, view, xdg_surface->surface); 76 view_child_init(&popup->child, &popup_impl, view, xdg_surface->surface);
77 popup->wlr_xdg_surface = xdg_surface;
58 78
59 wl_signal_add(&xdg_surface->events.new_popup, &popup->new_popup); 79 wl_signal_add(&xdg_surface->events.new_popup, &popup->new_popup);
60 popup->new_popup.notify = popup_handle_new_popup; 80 popup->new_popup.notify = popup_handle_new_popup;
61 wl_signal_add(&xdg_surface->events.destroy, &popup->destroy); 81 wl_signal_add(&xdg_surface->events.destroy, &popup->destroy);
62 popup->destroy.notify = popup_handle_destroy; 82 popup->destroy.notify = popup_handle_destroy;
63 83
84 popup_unconstrain(popup);
85
64 return popup; 86 return popup;
65} 87}
66 88
@@ -74,6 +96,16 @@ static struct sway_xdg_shell_view *xdg_shell_view_from_view(
74 return (struct sway_xdg_shell_view *)view; 96 return (struct sway_xdg_shell_view *)view;
75} 97}
76 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
77static 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) {
78 if (xdg_shell_view_from_view(view) == NULL) { 110 if (xdg_shell_view_from_view(view) == NULL) {
79 return NULL; 111 return NULL;
@@ -167,6 +199,7 @@ static void destroy(struct sway_view *view) {
167} 199}
168 200
169static const struct sway_view_impl view_impl = { 201static const struct sway_view_impl view_impl = {
202 .get_constraints = get_constraints,
170 .get_string_prop = get_string_prop, 203 .get_string_prop = get_string_prop,
171 .configure = configure, 204 .configure = configure,
172 .set_activated = set_activated, 205 .set_activated = set_activated,
@@ -192,10 +225,24 @@ static void handle_commit(struct wl_listener *listener, void *data) {
192 transaction_notify_view_ready(view, xdg_surface->configure_serial); 225 transaction_notify_view_ready(view, xdg_surface->configure_serial);
193 } 226 }
194 227
195 view_update_title(view, false);
196 view_damage_from(view); 228 view_damage_from(view);
197} 229}
198 230
231static void handle_set_title(struct wl_listener *listener, void *data) {
232 struct sway_xdg_shell_view *xdg_shell_view =
233 wl_container_of(listener, xdg_shell_view, set_title);
234 struct sway_view *view = &xdg_shell_view->view;
235 view_update_title(view, false);
236 view_execute_criteria(view);
237}
238
239static void handle_set_app_id(struct wl_listener *listener, void *data) {
240 struct sway_xdg_shell_view *xdg_shell_view =
241 wl_container_of(listener, xdg_shell_view, set_app_id);
242 struct sway_view *view = &xdg_shell_view->view;
243 view_execute_criteria(view);
244}
245
199static void handle_new_popup(struct wl_listener *listener, void *data) { 246static void handle_new_popup(struct wl_listener *listener, void *data) {
200 struct sway_xdg_shell_view *xdg_shell_view = 247 struct sway_xdg_shell_view *xdg_shell_view =
201 wl_container_of(listener, xdg_shell_view, new_popup); 248 wl_container_of(listener, xdg_shell_view, new_popup);
@@ -222,8 +269,37 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data)
222 269
223 view_set_fullscreen(view, e->fullscreen); 270 view_set_fullscreen(view, e->fullscreen);
224 271
225 struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); 272 struct sway_container *output = container_parent(view->swayc, C_OUTPUT);
226 arrange_and_commit(ws); 273 arrange_windows(output);
274 transaction_commit_dirty();
275}
276
277static void handle_request_move(struct wl_listener *listener, void *data) {
278 struct sway_xdg_shell_view *xdg_shell_view =
279 wl_container_of(listener, xdg_shell_view, request_move);
280 struct sway_view *view = &xdg_shell_view->view;
281 if (!container_is_floating(view->swayc)) {
282 return;
283 }
284 struct wlr_xdg_toplevel_move_event *e = data;
285 struct sway_seat *seat = e->seat->seat->data;
286 if (e->serial == seat->last_button_serial) {
287 seat_begin_move(seat, view->swayc, seat->last_button);
288 }
289}
290
291static void handle_request_resize(struct wl_listener *listener, void *data) {
292 struct sway_xdg_shell_view *xdg_shell_view =
293 wl_container_of(listener, xdg_shell_view, request_resize);
294 struct sway_view *view = &xdg_shell_view->view;
295 if (!container_is_floating(view->swayc)) {
296 return;
297 }
298 struct wlr_xdg_toplevel_resize_event *e = data;
299 struct sway_seat *seat = e->seat->seat->data;
300 if (e->serial == seat->last_button_serial) {
301 seat_begin_resize(seat, view->swayc, seat->last_button, e->edges);
302 }
227} 303}
228 304
229static void handle_unmap(struct wl_listener *listener, void *data) { 305static void handle_unmap(struct wl_listener *listener, void *data) {
@@ -240,6 +316,10 @@ static void handle_unmap(struct wl_listener *listener, void *data) {
240 wl_list_remove(&xdg_shell_view->commit.link); 316 wl_list_remove(&xdg_shell_view->commit.link);
241 wl_list_remove(&xdg_shell_view->new_popup.link); 317 wl_list_remove(&xdg_shell_view->new_popup.link);
242 wl_list_remove(&xdg_shell_view->request_fullscreen.link); 318 wl_list_remove(&xdg_shell_view->request_fullscreen.link);
319 wl_list_remove(&xdg_shell_view->request_move.link);
320 wl_list_remove(&xdg_shell_view->request_resize.link);
321 wl_list_remove(&xdg_shell_view->set_title.link);
322 wl_list_remove(&xdg_shell_view->set_app_id.link);
243} 323}
244 324
245static void handle_map(struct wl_listener *listener, void *data) { 325static void handle_map(struct wl_listener *listener, void *data) {
@@ -251,8 +331,8 @@ static void handle_map(struct wl_listener *listener, void *data) {
251 view->natural_width = view->wlr_xdg_surface->geometry.width; 331 view->natural_width = view->wlr_xdg_surface->geometry.width;
252 view->natural_height = view->wlr_xdg_surface->geometry.height; 332 view->natural_height = view->wlr_xdg_surface->geometry.height;
253 if (!view->natural_width && !view->natural_height) { 333 if (!view->natural_width && !view->natural_height) {
254 view->natural_width = view->wlr_xdg_surface->surface->current->width; 334 view->natural_width = view->wlr_xdg_surface->surface->current.width;
255 view->natural_height = view->wlr_xdg_surface->surface->current->height; 335 view->natural_height = view->wlr_xdg_surface->surface->current.height;
256 } 336 }
257 337
258 view_map(view, view->wlr_xdg_surface->surface); 338 view_map(view, view->wlr_xdg_surface->surface);
@@ -260,10 +340,11 @@ static void handle_map(struct wl_listener *listener, void *data) {
260 if (xdg_surface->toplevel->client_pending.fullscreen) { 340 if (xdg_surface->toplevel->client_pending.fullscreen) {
261 view_set_fullscreen(view, true); 341 view_set_fullscreen(view, true);
262 struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); 342 struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE);
263 arrange_and_commit(ws); 343 arrange_windows(ws);
264 } else { 344 } else {
265 arrange_and_commit(view->swayc->parent); 345 arrange_windows(view->swayc->parent);
266 } 346 }
347 transaction_commit_dirty();
267 348
268 xdg_shell_view->commit.notify = handle_commit; 349 xdg_shell_view->commit.notify = handle_commit;
269 wl_signal_add(&xdg_surface->surface->events.commit, 350 wl_signal_add(&xdg_surface->surface->events.commit,
@@ -276,6 +357,22 @@ static void handle_map(struct wl_listener *listener, void *data) {
276 xdg_shell_view->request_fullscreen.notify = handle_request_fullscreen; 357 xdg_shell_view->request_fullscreen.notify = handle_request_fullscreen;
277 wl_signal_add(&xdg_surface->toplevel->events.request_fullscreen, 358 wl_signal_add(&xdg_surface->toplevel->events.request_fullscreen,
278 &xdg_shell_view->request_fullscreen); 359 &xdg_shell_view->request_fullscreen);
360
361 xdg_shell_view->request_move.notify = handle_request_move;
362 wl_signal_add(&xdg_surface->toplevel->events.request_move,
363 &xdg_shell_view->request_move);
364
365 xdg_shell_view->request_resize.notify = handle_request_resize;
366 wl_signal_add(&xdg_surface->toplevel->events.request_resize,
367 &xdg_shell_view->request_resize);
368
369 xdg_shell_view->set_title.notify = handle_set_title;
370 wl_signal_add(&xdg_surface->toplevel->events.set_title,
371 &xdg_shell_view->set_title);
372
373 xdg_shell_view->set_app_id.notify = handle_set_app_id;
374 wl_signal_add(&xdg_surface->toplevel->events.set_app_id,
375 &xdg_shell_view->set_app_id);
279} 376}
280 377
281static void handle_destroy(struct wl_listener *listener, void *data) { 378static void handle_destroy(struct wl_listener *listener, void *data) {
@@ -304,11 +401,11 @@ void handle_xdg_shell_surface(struct wl_listener *listener, void *data) {
304 struct wlr_xdg_surface *xdg_surface = data; 401 struct wlr_xdg_surface *xdg_surface = data;
305 402
306 if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) { 403 if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) {
307 wlr_log(L_DEBUG, "New xdg_shell popup"); 404 wlr_log(WLR_DEBUG, "New xdg_shell popup");
308 return; 405 return;
309 } 406 }
310 407
311 wlr_log(L_DEBUG, "New xdg_shell toplevel title='%s' app_id='%s'", 408 wlr_log(WLR_DEBUG, "New xdg_shell toplevel title='%s' app_id='%s'",
312 xdg_surface->toplevel->title, xdg_surface->toplevel->app_id); 409 xdg_surface->toplevel->title, xdg_surface->toplevel->app_id);
313 wlr_xdg_surface_ping(xdg_surface); 410 wlr_xdg_surface_ping(xdg_surface);
314 411