diff options
-rw-r--r-- | sway/handlers.c | 89 |
1 files changed, 73 insertions, 16 deletions
diff --git a/sway/handlers.c b/sway/handlers.c index cd685118..d74d6252 100644 --- a/sway/handlers.c +++ b/sway/handlers.c | |||
@@ -263,6 +263,78 @@ static void ws_cleanup() { | |||
263 | } | 263 | } |
264 | } | 264 | } |
265 | 265 | ||
266 | static void positioner_place_window(wlc_handle handle) { | ||
267 | const struct wlc_geometry *anchor = wlc_view_positioner_get_anchor_rect(handle); | ||
268 | const struct wlc_size *sr = wlc_view_positioner_get_size(handle); | ||
269 | // a positioner is required to have a non-null anchor and a non-negative size | ||
270 | if (!anchor || !sr || | ||
271 | sr->w <= 0 || sr->h <= 0 || | ||
272 | anchor->size.w <= 0 || anchor->size.h <= 0) { | ||
273 | return; | ||
274 | } | ||
275 | const struct wlc_point offset = *wlc_view_positioner_get_offset(handle); | ||
276 | enum wlc_positioner_anchor_bit anchors = wlc_view_positioner_get_anchor(handle); | ||
277 | enum wlc_positioner_gravity_bit gravity = wlc_view_positioner_get_gravity(handle); | ||
278 | struct wlc_geometry geo = { | ||
279 | .origin = offset, | ||
280 | .size = *sr | ||
281 | }; | ||
282 | |||
283 | if (anchors & WLC_BIT_ANCHOR_TOP) { | ||
284 | geo.origin.y += anchor->origin.y; | ||
285 | } else if (anchors & WLC_BIT_ANCHOR_BOTTOM) { | ||
286 | geo.origin.y += anchor->origin.y + anchor->size.h; | ||
287 | } else { | ||
288 | geo.origin.y += anchor->origin.y + anchor->size.h / 2; | ||
289 | } | ||
290 | if (anchors & WLC_BIT_ANCHOR_LEFT) { | ||
291 | geo.origin.x += anchor->origin.x; | ||
292 | } else if (anchors & WLC_BIT_ANCHOR_RIGHT) { | ||
293 | geo.origin.x += anchor->origin.x + anchor->size.w; | ||
294 | } else { | ||
295 | geo.origin.x += anchor->origin.x + anchor->size.w / 2; | ||
296 | } | ||
297 | |||
298 | if (gravity & WLC_BIT_GRAVITY_TOP) { | ||
299 | geo.origin.y -= geo.size.h; | ||
300 | } else if (gravity & WLC_BIT_GRAVITY_BOTTOM) { | ||
301 | /* default */ | ||
302 | } else { | ||
303 | geo.origin.y -= geo.size.h / 2; | ||
304 | } | ||
305 | if (gravity & WLC_BIT_GRAVITY_LEFT) { | ||
306 | geo.origin.x -= geo.size.w; | ||
307 | } else if (gravity & WLC_BIT_GRAVITY_RIGHT) { | ||
308 | /* default */ | ||
309 | } else { | ||
310 | geo.origin.x -= geo.size.w / 2; | ||
311 | } | ||
312 | |||
313 | sway_log(L_DEBUG, "xdg-positioner: placing window %" PRIuPTR " " | ||
314 | "sized (%u,%u) offset by (%d,%d), " | ||
315 | "anchor rectangle sized (%u,%u) at (%d,%d), " | ||
316 | "anchor edges: %s %s, gravity: %s %s", | ||
317 | handle, | ||
318 | sr->w, sr->h, offset.x, offset.y, | ||
319 | anchor->size.w, anchor->size.h, anchor->origin.x, anchor->origin.y, | ||
320 | anchors & WLC_BIT_ANCHOR_TOP ? "top" : | ||
321 | (anchors & WLC_BIT_ANCHOR_BOTTOM ? "bottom" : "middle"), | ||
322 | anchors & WLC_BIT_ANCHOR_LEFT ? "left" : | ||
323 | (anchors & WLC_BIT_ANCHOR_RIGHT ? "right" : "center"), | ||
324 | gravity & WLC_BIT_GRAVITY_TOP ? "top" : | ||
325 | (gravity & WLC_BIT_GRAVITY_BOTTOM ? "bottom" : "middle"), | ||
326 | gravity & WLC_BIT_GRAVITY_LEFT ? "left" : | ||
327 | (gravity & WLC_BIT_GRAVITY_RIGHT ? "right" : "center")); | ||
328 | |||
329 | wlc_handle parent = wlc_view_get_parent(handle); | ||
330 | if (parent) { | ||
331 | const struct wlc_geometry *pg = wlc_view_get_geometry(parent); | ||
332 | geo.origin.x += pg->origin.x; | ||
333 | geo.origin.y += pg->origin.y; | ||
334 | } | ||
335 | wlc_view_set_geometry(handle, 0, &geo); | ||
336 | } | ||
337 | |||
266 | static bool handle_view_created(wlc_handle handle) { | 338 | static bool handle_view_created(wlc_handle handle) { |
267 | // if view is child of another view, the use that as focused container | 339 | // if view is child of another view, the use that as focused container |
268 | wlc_handle parent = wlc_view_get_parent(handle); | 340 | wlc_handle parent = wlc_view_get_parent(handle); |
@@ -332,22 +404,7 @@ static bool handle_view_created(wlc_handle handle) { | |||
332 | } | 404 | } |
333 | } | 405 | } |
334 | 406 | ||
335 | const struct wlc_geometry *anchor = wlc_view_positioner_get_anchor_rect(handle); | 407 | positioner_place_window(handle); |
336 | if (anchor) { | ||
337 | struct wlc_geometry geo = *wlc_view_get_geometry(handle); | ||
338 | struct wlc_size sr = *wlc_view_positioner_get_size(handle); | ||
339 | if (sr.w <= 0 || sr.h <= 0) | ||
340 | sr = geo.size; | ||
341 | geo.origin = anchor->origin; | ||
342 | geo.size = sr; | ||
343 | wlc_handle parent = wlc_view_get_parent(handle); | ||
344 | if (parent) { | ||
345 | const struct wlc_geometry *pg = wlc_view_get_geometry(parent); | ||
346 | geo.origin.x += pg->origin.x; | ||
347 | geo.origin.y += pg->origin.y; | ||
348 | } | ||
349 | wlc_view_set_geometry(handle, 0, &geo); | ||
350 | } | ||
351 | 408 | ||
352 | sway_log(L_DEBUG, "handle:%" PRIuPTR " type:%x state:%x parent:%" PRIuPTR " " | 409 | sway_log(L_DEBUG, "handle:%" PRIuPTR " type:%x state:%x parent:%" PRIuPTR " " |
353 | "mask:%d (x:%d y:%d w:%d h:%d) title:%s " | 410 | "mask:%d (x:%d y:%d w:%d h:%d) title:%s " |