diff options
author | Drew DeVault <sir@cmpwn.com> | 2018-07-23 20:27:56 -0400 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2018-07-23 20:31:11 -0400 |
commit | f4b882475eee7a81c206c7825616cc4656b2f60b (patch) | |
tree | 38e6ebf81b235424f105dcbcbb194e5e9eac70c0 /sway/desktop/xdg_shell.c | |
parent | Implement pid->workspace tracking (diff) | |
parent | Merge pull request #2342 from RyanDwyer/update-cursor (diff) | |
download | sway-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.c | 115 |
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 | ||
49 | static 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 | |||
48 | static struct sway_xdg_popup *popup_create( | 67 | static 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 | ||
99 | static 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 | |||
77 | static const char *get_string_prop(struct sway_view *view, enum sway_view_prop prop) { | 109 | static 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 | ||
169 | static const struct sway_view_impl view_impl = { | 201 | static 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 | ||
231 | static 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 | |||
239 | static 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 | |||
199 | static void handle_new_popup(struct wl_listener *listener, void *data) { | 246 | static 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 | |||
277 | static 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 | |||
291 | static 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 | ||
229 | static void handle_unmap(struct wl_listener *listener, void *data) { | 305 | static 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 | ||
245 | static void handle_map(struct wl_listener *listener, void *data) { | 325 | static 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 | ||
281 | static void handle_destroy(struct wl_listener *listener, void *data) { | 378 | static 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 | ||