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_v6.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_v6.c')
-rw-r--r-- | sway/desktop/xdg_shell_v6.c | 115 |
1 files changed, 106 insertions, 9 deletions
diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index b28c4b9c..46fd4769 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.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> |
@@ -44,6 +45,24 @@ static void popup_handle_destroy(struct wl_listener *listener, void *data) { | |||
44 | view_child_destroy(&popup->child); | 45 | view_child_destroy(&popup->child); |
45 | } | 46 | } |
46 | 47 | ||
48 | static void popup_unconstrain(struct sway_xdg_popup_v6 *popup) { | ||
49 | struct sway_view *view = popup->child.view; | ||
50 | struct wlr_xdg_popup_v6 *wlr_popup = popup->wlr_xdg_surface_v6->popup; | ||
51 | |||
52 | struct sway_container *output = container_parent(view->swayc, C_OUTPUT); | ||
53 | |||
54 | // the output box expressed in the coordinate system of the toplevel parent | ||
55 | // of the popup | ||
56 | struct wlr_box output_toplevel_sx_box = { | ||
57 | .x = output->x - view->x, | ||
58 | .y = output->y - view->y, | ||
59 | .width = output->width, | ||
60 | .height = output->height, | ||
61 | }; | ||
62 | |||
63 | wlr_xdg_popup_v6_unconstrain_from_box(wlr_popup, &output_toplevel_sx_box); | ||
64 | } | ||
65 | |||
47 | static struct sway_xdg_popup_v6 *popup_create( | 66 | static struct sway_xdg_popup_v6 *popup_create( |
48 | struct wlr_xdg_popup_v6 *wlr_popup, struct sway_view *view) { | 67 | struct wlr_xdg_popup_v6 *wlr_popup, struct sway_view *view) { |
49 | struct wlr_xdg_surface_v6 *xdg_surface = wlr_popup->base; | 68 | struct wlr_xdg_surface_v6 *xdg_surface = wlr_popup->base; |
@@ -54,12 +73,15 @@ static struct sway_xdg_popup_v6 *popup_create( | |||
54 | return NULL; | 73 | return NULL; |
55 | } | 74 | } |
56 | view_child_init(&popup->child, &popup_impl, view, xdg_surface->surface); | 75 | view_child_init(&popup->child, &popup_impl, view, xdg_surface->surface); |
76 | popup->wlr_xdg_surface_v6 = xdg_surface; | ||
57 | 77 | ||
58 | wl_signal_add(&xdg_surface->events.new_popup, &popup->new_popup); | 78 | wl_signal_add(&xdg_surface->events.new_popup, &popup->new_popup); |
59 | popup->new_popup.notify = popup_handle_new_popup; | 79 | popup->new_popup.notify = popup_handle_new_popup; |
60 | wl_signal_add(&xdg_surface->events.destroy, &popup->destroy); | 80 | wl_signal_add(&xdg_surface->events.destroy, &popup->destroy); |
61 | popup->destroy.notify = popup_handle_destroy; | 81 | popup->destroy.notify = popup_handle_destroy; |
62 | 82 | ||
83 | popup_unconstrain(popup); | ||
84 | |||
63 | return popup; | 85 | return popup; |
64 | } | 86 | } |
65 | 87 | ||
@@ -73,6 +95,16 @@ static struct sway_xdg_shell_v6_view *xdg_shell_v6_view_from_view( | |||
73 | return (struct sway_xdg_shell_v6_view *)view; | 95 | return (struct sway_xdg_shell_v6_view *)view; |
74 | } | 96 | } |
75 | 97 | ||
98 | static void get_constraints(struct sway_view *view, double *min_width, | ||
99 | double *max_width, double *min_height, double *max_height) { | ||
100 | struct wlr_xdg_toplevel_v6_state *state = | ||
101 | &view->wlr_xdg_surface_v6->toplevel->current; | ||
102 | *min_width = state->min_width > 0 ? state->min_width : DBL_MIN; | ||
103 | *max_width = state->max_width > 0 ? state->max_width : DBL_MAX; | ||
104 | *min_height = state->min_height > 0 ? state->min_height : DBL_MIN; | ||
105 | *max_height = state->max_height > 0 ? state->max_height : DBL_MAX; | ||
106 | } | ||
107 | |||
76 | static const char *get_string_prop(struct sway_view *view, enum sway_view_prop prop) { | 108 | static const char *get_string_prop(struct sway_view *view, enum sway_view_prop prop) { |
77 | if (xdg_shell_v6_view_from_view(view) == NULL) { | 109 | if (xdg_shell_v6_view_from_view(view) == NULL) { |
78 | return NULL; | 110 | return NULL; |
@@ -163,6 +195,7 @@ static void destroy(struct sway_view *view) { | |||
163 | } | 195 | } |
164 | 196 | ||
165 | static const struct sway_view_impl view_impl = { | 197 | static const struct sway_view_impl view_impl = { |
198 | .get_constraints = get_constraints, | ||
166 | .get_string_prop = get_string_prop, | 199 | .get_string_prop = get_string_prop, |
167 | .configure = configure, | 200 | .configure = configure, |
168 | .set_activated = set_activated, | 201 | .set_activated = set_activated, |
@@ -187,10 +220,24 @@ static void handle_commit(struct wl_listener *listener, void *data) { | |||
187 | transaction_notify_view_ready(view, xdg_surface_v6->configure_serial); | 220 | transaction_notify_view_ready(view, xdg_surface_v6->configure_serial); |
188 | } | 221 | } |
189 | 222 | ||
190 | view_update_title(view, false); | ||
191 | view_damage_from(view); | 223 | view_damage_from(view); |
192 | } | 224 | } |
193 | 225 | ||
226 | static void handle_set_title(struct wl_listener *listener, void *data) { | ||
227 | struct sway_xdg_shell_v6_view *xdg_shell_v6_view = | ||
228 | wl_container_of(listener, xdg_shell_v6_view, set_title); | ||
229 | struct sway_view *view = &xdg_shell_v6_view->view; | ||
230 | view_update_title(view, false); | ||
231 | view_execute_criteria(view); | ||
232 | } | ||
233 | |||
234 | static void handle_set_app_id(struct wl_listener *listener, void *data) { | ||
235 | struct sway_xdg_shell_v6_view *xdg_shell_v6_view = | ||
236 | wl_container_of(listener, xdg_shell_v6_view, set_app_id); | ||
237 | struct sway_view *view = &xdg_shell_v6_view->view; | ||
238 | view_execute_criteria(view); | ||
239 | } | ||
240 | |||
194 | static void handle_new_popup(struct wl_listener *listener, void *data) { | 241 | static void handle_new_popup(struct wl_listener *listener, void *data) { |
195 | struct sway_xdg_shell_v6_view *xdg_shell_v6_view = | 242 | struct sway_xdg_shell_v6_view *xdg_shell_v6_view = |
196 | wl_container_of(listener, xdg_shell_v6_view, new_popup); | 243 | wl_container_of(listener, xdg_shell_v6_view, new_popup); |
@@ -217,8 +264,37 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data) | |||
217 | 264 | ||
218 | view_set_fullscreen(view, e->fullscreen); | 265 | view_set_fullscreen(view, e->fullscreen); |
219 | 266 | ||
220 | struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); | 267 | struct sway_container *output = container_parent(view->swayc, C_OUTPUT); |
221 | arrange_and_commit(ws); | 268 | arrange_windows(output); |
269 | transaction_commit_dirty(); | ||
270 | } | ||
271 | |||
272 | static void handle_request_move(struct wl_listener *listener, void *data) { | ||
273 | struct sway_xdg_shell_v6_view *xdg_shell_v6_view = | ||
274 | wl_container_of(listener, xdg_shell_v6_view, request_move); | ||
275 | struct sway_view *view = &xdg_shell_v6_view->view; | ||
276 | if (!container_is_floating(view->swayc)) { | ||
277 | return; | ||
278 | } | ||
279 | struct wlr_xdg_toplevel_v6_move_event *e = data; | ||
280 | struct sway_seat *seat = e->seat->seat->data; | ||
281 | if (e->serial == seat->last_button_serial) { | ||
282 | seat_begin_move(seat, view->swayc, seat->last_button); | ||
283 | } | ||
284 | } | ||
285 | |||
286 | static void handle_request_resize(struct wl_listener *listener, void *data) { | ||
287 | struct sway_xdg_shell_v6_view *xdg_shell_v6_view = | ||
288 | wl_container_of(listener, xdg_shell_v6_view, request_resize); | ||
289 | struct sway_view *view = &xdg_shell_v6_view->view; | ||
290 | if (!container_is_floating(view->swayc)) { | ||
291 | return; | ||
292 | } | ||
293 | struct wlr_xdg_toplevel_v6_resize_event *e = data; | ||
294 | struct sway_seat *seat = e->seat->seat->data; | ||
295 | if (e->serial == seat->last_button_serial) { | ||
296 | seat_begin_resize(seat, view->swayc, seat->last_button, e->edges); | ||
297 | } | ||
222 | } | 298 | } |
223 | 299 | ||
224 | static void handle_unmap(struct wl_listener *listener, void *data) { | 300 | static void handle_unmap(struct wl_listener *listener, void *data) { |
@@ -235,6 +311,10 @@ static void handle_unmap(struct wl_listener *listener, void *data) { | |||
235 | wl_list_remove(&xdg_shell_v6_view->commit.link); | 311 | wl_list_remove(&xdg_shell_v6_view->commit.link); |
236 | wl_list_remove(&xdg_shell_v6_view->new_popup.link); | 312 | wl_list_remove(&xdg_shell_v6_view->new_popup.link); |
237 | wl_list_remove(&xdg_shell_v6_view->request_fullscreen.link); | 313 | wl_list_remove(&xdg_shell_v6_view->request_fullscreen.link); |
314 | wl_list_remove(&xdg_shell_v6_view->request_move.link); | ||
315 | wl_list_remove(&xdg_shell_v6_view->request_resize.link); | ||
316 | wl_list_remove(&xdg_shell_v6_view->set_title.link); | ||
317 | wl_list_remove(&xdg_shell_v6_view->set_app_id.link); | ||
238 | } | 318 | } |
239 | 319 | ||
240 | static void handle_map(struct wl_listener *listener, void *data) { | 320 | static void handle_map(struct wl_listener *listener, void *data) { |
@@ -246,8 +326,8 @@ static void handle_map(struct wl_listener *listener, void *data) { | |||
246 | view->natural_width = view->wlr_xdg_surface_v6->geometry.width; | 326 | view->natural_width = view->wlr_xdg_surface_v6->geometry.width; |
247 | view->natural_height = view->wlr_xdg_surface_v6->geometry.height; | 327 | view->natural_height = view->wlr_xdg_surface_v6->geometry.height; |
248 | if (!view->natural_width && !view->natural_height) { | 328 | if (!view->natural_width && !view->natural_height) { |
249 | view->natural_width = view->wlr_xdg_surface_v6->surface->current->width; | 329 | view->natural_width = view->wlr_xdg_surface_v6->surface->current.width; |
250 | view->natural_height = view->wlr_xdg_surface_v6->surface->current->height; | 330 | view->natural_height = view->wlr_xdg_surface_v6->surface->current.height; |
251 | } | 331 | } |
252 | 332 | ||
253 | view_map(view, view->wlr_xdg_surface_v6->surface); | 333 | view_map(view, view->wlr_xdg_surface_v6->surface); |
@@ -255,10 +335,11 @@ static void handle_map(struct wl_listener *listener, void *data) { | |||
255 | if (xdg_surface->toplevel->client_pending.fullscreen) { | 335 | if (xdg_surface->toplevel->client_pending.fullscreen) { |
256 | view_set_fullscreen(view, true); | 336 | view_set_fullscreen(view, true); |
257 | struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); | 337 | struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); |
258 | arrange_and_commit(ws); | 338 | arrange_windows(ws); |
259 | } else { | 339 | } else { |
260 | arrange_and_commit(view->swayc->parent); | 340 | arrange_windows(view->swayc->parent); |
261 | } | 341 | } |
342 | transaction_commit_dirty(); | ||
262 | 343 | ||
263 | xdg_shell_v6_view->commit.notify = handle_commit; | 344 | xdg_shell_v6_view->commit.notify = handle_commit; |
264 | wl_signal_add(&xdg_surface->surface->events.commit, | 345 | wl_signal_add(&xdg_surface->surface->events.commit, |
@@ -271,6 +352,22 @@ static void handle_map(struct wl_listener *listener, void *data) { | |||
271 | xdg_shell_v6_view->request_fullscreen.notify = handle_request_fullscreen; | 352 | xdg_shell_v6_view->request_fullscreen.notify = handle_request_fullscreen; |
272 | wl_signal_add(&xdg_surface->toplevel->events.request_fullscreen, | 353 | wl_signal_add(&xdg_surface->toplevel->events.request_fullscreen, |
273 | &xdg_shell_v6_view->request_fullscreen); | 354 | &xdg_shell_v6_view->request_fullscreen); |
355 | |||
356 | xdg_shell_v6_view->request_move.notify = handle_request_move; | ||
357 | wl_signal_add(&xdg_surface->toplevel->events.request_move, | ||
358 | &xdg_shell_v6_view->request_move); | ||
359 | |||
360 | xdg_shell_v6_view->request_resize.notify = handle_request_resize; | ||
361 | wl_signal_add(&xdg_surface->toplevel->events.request_resize, | ||
362 | &xdg_shell_v6_view->request_resize); | ||
363 | |||
364 | xdg_shell_v6_view->set_title.notify = handle_set_title; | ||
365 | wl_signal_add(&xdg_surface->toplevel->events.set_title, | ||
366 | &xdg_shell_v6_view->set_title); | ||
367 | |||
368 | xdg_shell_v6_view->set_app_id.notify = handle_set_app_id; | ||
369 | wl_signal_add(&xdg_surface->toplevel->events.set_app_id, | ||
370 | &xdg_shell_v6_view->set_app_id); | ||
274 | } | 371 | } |
275 | 372 | ||
276 | static void handle_destroy(struct wl_listener *listener, void *data) { | 373 | static void handle_destroy(struct wl_listener *listener, void *data) { |
@@ -295,11 +392,11 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { | |||
295 | struct wlr_xdg_surface_v6 *xdg_surface = data; | 392 | struct wlr_xdg_surface_v6 *xdg_surface = data; |
296 | 393 | ||
297 | if (xdg_surface->role == WLR_XDG_SURFACE_V6_ROLE_POPUP) { | 394 | if (xdg_surface->role == WLR_XDG_SURFACE_V6_ROLE_POPUP) { |
298 | wlr_log(L_DEBUG, "New xdg_shell_v6 popup"); | 395 | wlr_log(WLR_DEBUG, "New xdg_shell_v6 popup"); |
299 | return; | 396 | return; |
300 | } | 397 | } |
301 | 398 | ||
302 | wlr_log(L_DEBUG, "New xdg_shell_v6 toplevel title='%s' app_id='%s'", | 399 | wlr_log(WLR_DEBUG, "New xdg_shell_v6 toplevel title='%s' app_id='%s'", |
303 | xdg_surface->toplevel->title, xdg_surface->toplevel->app_id); | 400 | xdg_surface->toplevel->title, xdg_surface->toplevel->app_id); |
304 | wlr_xdg_surface_v6_ping(xdg_surface); | 401 | wlr_xdg_surface_v6_ping(xdg_surface); |
305 | 402 | ||