From 8836b167bf0ff152de951f7fdabb1deae85f6e93 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 13 Mar 2018 19:21:08 -0400 Subject: [PATCH 01/22] store xdg-positioner properties on the popup --- include/wlr/types/wlr_xdg_shell_v6.h | 60 ++++++++++++++++++++++++++++ types/wlr_xdg_shell_v6.c | 6 +++ 2 files changed, 66 insertions(+) diff --git a/include/wlr/types/wlr_xdg_shell_v6.h b/include/wlr/types/wlr_xdg_shell_v6.h index 7dc746ce..42eb332a 100644 --- a/include/wlr/types/wlr_xdg_shell_v6.h +++ b/include/wlr/types/wlr_xdg_shell_v6.h @@ -32,6 +32,62 @@ struct wlr_xdg_client_v6 { struct wl_event_source *ping_timer; }; +enum wlr_positioner_v6_anchor { + /** + * the center of the anchor rectangle + */ + WLR_POSITIONER_V6_ANCHOR_NONE = 0, + /** + * the top edge of the anchor rectangle + */ + WLR_POSITIONER_V6_ANCHOR_TOP = 1, + /** + * the bottom edge of the anchor rectangle + */ + WLR_POSITIONER_V6_ANCHOR_BOTTOM = 2, + /** + * the left edge of the anchor rectangle + */ + WLR_POSITIONER_V6_ANCHOR_LEFT = 4, + /** + * the right edge of the anchor rectangle + */ + WLR_POSITIONER_V6_ANCHOR_RIGHT = 8, +}; + +enum wlr_positioner_v6_gravity { + /** + * center over the anchor edge + */ + WLR_POSITIONER_V6_GRAVITY_NONE = 0, + /** + * position above the anchor edge + */ + WLR_POSITIONER_V6_GRAVITY_TOP = 1, + /** + * position below the anchor edge + */ + WLR_POSITIONER_V6_GRAVITY_BOTTOM = 2, + /** + * position to the left of the anchor edge + */ + WLR_POSITIONER_V6_GRAVITY_LEFT = 4, + /** + * position to the right of the anchor edge + */ + WLR_POSITIONER_V6_GRAVITY_RIGHT = 8, +}; + +enum wlr_positioner_v6_constraint_adjustment { + WLR_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_NONE = 0, + WLR_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_SLIDE_X = 1, + WLR_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_SLIDE_Y = 2, + WLR_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_FLIP_X = 4, + WLR_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_FLIP_Y = 8, + WLR_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_RESIZE_X = 16, + WLR_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_RESIZE_Y = 32, +}; + struct wlr_xdg_popup_v6 { struct wlr_xdg_surface_v6 *base; struct wl_list link; @@ -42,6 +98,10 @@ struct wlr_xdg_popup_v6 { struct wlr_seat *seat; struct wlr_box geometry; + enum wlr_positioner_v6_anchor anchor; + enum wlr_positioner_v6_gravity gravity; + enum wlr_positioner_v6_constraint_adjustment constraint_adjustment; + struct wl_list grab_link; // wlr_xdg_popup_grab_v6::popups }; diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index e07d78a1..c75e5857 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -537,6 +537,12 @@ static void xdg_surface_get_popup(struct wl_client *client, surface->popup_state->parent = parent; surface->popup_state->geometry = xdg_positioner_get_geometry(positioner, surface, parent); + + // positioner properties + surface->popup_state->anchor = (uint32_t)positioner->anchor; + surface->popup_state->gravity = (uint32_t)positioner->gravity; + surface->popup_state->constraint_adjustment = (uint32_t)positioner->constraint_adjustment; + wl_list_insert(&parent->popups, &surface->popup_state->link); wl_resource_set_implementation(surface->popup_state->resource, From 4da18f7fc361bcde631249268320c9f1e4ef7c7c Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Mon, 26 Mar 2018 12:46:04 -0400 Subject: [PATCH 02/22] xdg-positioner attrs --- include/wlr/types/wlr_xdg_shell_v6.h | 28 ++++++++++++-- types/wlr_xdg_shell_v6.c | 55 ++++++++++++---------------- 2 files changed, 48 insertions(+), 35 deletions(-) diff --git a/include/wlr/types/wlr_xdg_shell_v6.h b/include/wlr/types/wlr_xdg_shell_v6.h index 75570127..47d78664 100644 --- a/include/wlr/types/wlr_xdg_shell_v6.h +++ b/include/wlr/types/wlr_xdg_shell_v6.h @@ -88,6 +88,21 @@ enum wlr_positioner_v6_constraint_adjustment { WLR_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_RESIZE_Y = 32, }; +struct wlr_xdg_positioner_v6_attributes { + struct wlr_box anchor_rect; + enum wlr_positioner_v6_anchor anchor; + enum wlr_positioner_v6_gravity gravity; + enum wlr_positioner_v6_constraint_adjustment constraint_adjustment; + + struct { + int32_t width, height; + } size; + + struct { + int32_t x, y; + } offset; +}; + struct wlr_xdg_popup_v6 { struct wlr_xdg_surface_v6 *base; struct wl_list link; @@ -98,9 +113,16 @@ struct wlr_xdg_popup_v6 { struct wlr_seat *seat; struct wlr_box geometry; - enum wlr_positioner_v6_anchor anchor; - enum wlr_positioner_v6_gravity gravity; - enum wlr_positioner_v6_constraint_adjustment constraint_adjustment; + struct wlr_xdg_positioner_v6_attributes positioner; + struct wlr_box anchor_rect; + + struct { + int32_t width, height; + } size; + + struct { + int32_t x, y; + } offset; struct wl_list grab_link; // wlr_xdg_popup_grab_v6::popups }; diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index 0e9419b4..6fddfdbc 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -18,22 +18,9 @@ static const char *wlr_desktop_xdg_popup_role = "xdg_popup_v6"; struct wlr_xdg_positioner_v6 { struct wl_resource *resource; - - struct wlr_box anchor_rect; - enum zxdg_positioner_v6_anchor anchor; - enum zxdg_positioner_v6_gravity gravity; - enum zxdg_positioner_v6_constraint_adjustment constraint_adjustment; - - struct { - int32_t width, height; - } size; - - struct { - int32_t x, y; - } offset; + struct wlr_xdg_positioner_v6_attributes *attrs; }; - static void resource_handle_destroy(struct wl_client *client, struct wl_resource *resource) { wl_resource_destroy(resource); @@ -279,6 +266,7 @@ static struct wlr_xdg_positioner_v6 *xdg_positioner_from_resource( static void xdg_positioner_destroy(struct wl_resource *resource) { struct wlr_xdg_positioner_v6 *positioner = xdg_positioner_from_resource(resource); + free(positioner->attrs); free(positioner); } @@ -294,8 +282,8 @@ static void xdg_positioner_handle_set_size(struct wl_client *client, return; } - positioner->size.width = width; - positioner->size.height = height; + positioner->attrs->size.width = width; + positioner->attrs->size.height = height; } static void xdg_positioner_handle_set_anchor_rect(struct wl_client *client, @@ -311,10 +299,10 @@ static void xdg_positioner_handle_set_anchor_rect(struct wl_client *client, return; } - positioner->anchor_rect.x = x; - positioner->anchor_rect.y = y; - positioner->anchor_rect.width = width; - positioner->anchor_rect.height = height; + positioner->attrs->anchor_rect.x = x; + positioner->attrs->anchor_rect.y = y; + positioner->attrs->anchor_rect.width = width; + positioner->attrs->anchor_rect.height = height; } static void xdg_positioner_handle_set_anchor(struct wl_client *client, @@ -332,7 +320,7 @@ static void xdg_positioner_handle_set_anchor(struct wl_client *client, return; } - positioner->anchor = anchor; + positioner->attrs->anchor = anchor; } static void xdg_positioner_handle_set_gravity(struct wl_client *client, @@ -350,7 +338,7 @@ static void xdg_positioner_handle_set_gravity(struct wl_client *client, return; } - positioner->gravity = gravity; + positioner->attrs->gravity = gravity; } static void xdg_positioner_handle_set_constraint_adjustment( @@ -359,7 +347,7 @@ static void xdg_positioner_handle_set_constraint_adjustment( struct wlr_xdg_positioner_v6 *positioner = xdg_positioner_from_resource(resource); - positioner->constraint_adjustment = constraint_adjustment; + positioner->attrs->constraint_adjustment = constraint_adjustment; } static void xdg_positioner_handle_set_offset(struct wl_client *client, @@ -367,8 +355,8 @@ static void xdg_positioner_handle_set_offset(struct wl_client *client, struct wlr_xdg_positioner_v6 *positioner = xdg_positioner_from_resource(resource); - positioner->offset.x = x; - positioner->offset.y = y; + positioner->attrs->offset.x = x; + positioner->attrs->offset.y = y; } static const struct zxdg_positioner_v6_interface @@ -392,6 +380,10 @@ static void xdg_shell_handle_create_positioner(struct wl_client *wl_client, return; } + // TODO: allocate the positioner attrs? + positioner->attrs = + calloc(1, sizeof(struct wlr_xdg_positioner_v6_attributes)); + positioner->resource = wl_resource_create(wl_client, &zxdg_positioner_v6_interface, wl_resource_get_version(resource), @@ -408,7 +400,7 @@ static void xdg_shell_handle_create_positioner(struct wl_client *wl_client, } static struct wlr_box xdg_positioner_get_geometry( - struct wlr_xdg_positioner_v6 *positioner, + struct wlr_xdg_positioner_v6_attributes *positioner, struct wlr_xdg_surface_v6 *surface, struct wlr_xdg_surface_v6 *parent) { struct wlr_box geometry = { .x = positioner->offset.x, @@ -453,7 +445,7 @@ static struct wlr_box xdg_positioner_get_geometry( } if (positioner->constraint_adjustment == - ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_NONE) { + WLR_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_NONE) { return geometry; } @@ -567,7 +559,7 @@ static void xdg_surface_handle_get_popup(struct wl_client *client, struct wlr_xdg_positioner_v6 *positioner = xdg_positioner_from_resource(positioner_resource); - if (positioner->size.width == 0 || positioner->anchor_rect.width == 0) { + if (positioner->attrs->size.width == 0 || positioner->attrs->anchor_rect.width == 0) { wl_resource_post_error(resource, ZXDG_SHELL_V6_ERROR_INVALID_POSITIONER, "positioner object is not complete"); @@ -598,12 +590,11 @@ static void xdg_surface_handle_get_popup(struct wl_client *client, surface->popup->base = surface; surface->popup->parent = parent; surface->popup->geometry = - xdg_positioner_get_geometry(positioner, surface, parent); + xdg_positioner_get_geometry(positioner->attrs, surface, parent); // positioner properties - surface->popup->anchor = (uint32_t)positioner->anchor; - surface->popup->gravity = (uint32_t)positioner->gravity; - surface->popup->constraint_adjustment = (uint32_t)positioner->constraint_adjustment; + memcpy(&surface->popup->positioner, &positioner->attrs, + sizeof(struct wlr_xdg_positioner_v6_attributes)); wl_list_insert(&parent->popups, &surface->popup->link); From bbd0e23fa79ec39c872c09e49d09a9ccbda68bcd Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Mon, 26 Mar 2018 23:48:32 -0400 Subject: [PATCH 03/22] xdg-positioner constraint detection --- include/wlr/types/wlr_xdg_shell_v6.h | 18 ++-- rootston/xdg_shell_v6.c | 49 ++++++++++ types/wlr_output_layout.c | 8 +- types/wlr_xdg_shell_v6.c | 137 ++++++++++++++++++++++++++- 4 files changed, 198 insertions(+), 14 deletions(-) diff --git a/include/wlr/types/wlr_xdg_shell_v6.h b/include/wlr/types/wlr_xdg_shell_v6.h index 47d78664..e192d36a 100644 --- a/include/wlr/types/wlr_xdg_shell_v6.h +++ b/include/wlr/types/wlr_xdg_shell_v6.h @@ -114,15 +114,6 @@ struct wlr_xdg_popup_v6 { struct wlr_box geometry; struct wlr_xdg_positioner_v6_attributes positioner; - struct wlr_box anchor_rect; - - struct { - int32_t width, height; - } size; - - struct { - int32_t x, y; - } offset; struct wl_list grab_link; // wlr_xdg_popup_grab_v6::popups }; @@ -305,4 +296,13 @@ struct wlr_xdg_surface_v6 *wlr_xdg_surface_v6_popup_at( struct wlr_xdg_surface_v6 *surface, double sx, double sy, double *popup_sx, double *popup_sy); +/** + * Get the anchor point for this popup in the root parent's coordinate system. + */ +void wlr_xdg_popup_v6_get_anchor_point(struct wlr_xdg_popup_v6 *popup, + int *root_sx, int *root_sy); + +void wlr_positioner_v6_invert( + struct wlr_xdg_positioner_v6_attributes *positioner); + #endif diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 13d25331..36ecc897 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -45,6 +45,55 @@ static struct roots_xdg_popup_v6 *popup_create(struct roots_view *view, if (popup == NULL) { return NULL; } + + struct wlr_xdg_surface_v6 *parent = wlr_popup->parent; + double popup_lx = wlr_popup->geometry.x; + double popup_ly = wlr_popup->geometry.y; + while (parent->role != WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL) { + popup_lx += parent->popup->geometry.x; + popup_ly += parent->popup->geometry.y; + parent = parent->popup->parent; + } + + popup_lx += view->x + parent->geometry.x; + popup_ly += view->y + parent->geometry.y; + int popup_width = wlr_popup->geometry.width; + int popup_height = wlr_popup->geometry.height; + + int anchor_x, anchor_y; + wlr_xdg_popup_v6_get_anchor_point(wlr_popup, &anchor_x, &anchor_y); + anchor_x += popup_lx; + anchor_y += popup_ly; + + struct wlr_output_layout *layout = view->desktop->layout; + + // get the output that contains (or closest to) the anchor point + struct wlr_output *output = + wlr_output_layout_output_at(layout, anchor_x, anchor_y); + if (output == NULL) { + // TODO find the closest output to the anchor + assert(false); + } + + // does the output completely contain the popup? + struct wlr_box *output_box = wlr_output_layout_get_box(layout, output); + bool output_contains_popup_x = popup_lx >= output_box->x && + popup_lx + popup_width <= output_box->x + output_box->width; + bool output_contains_popup_y = popup_ly >= output_box->y && + popup_ly + popup_height <= output_box->y + output_box->height; + + if (!output_contains_popup_x) { + // TODO flip_x + // TODO slide_x + // TODO resize_x + } + + if (!output_contains_popup_y) { + // TODO flip_y + // TODO slide_y + // TODO resize_y + } + popup->wlr_popup = wlr_popup; popup->view_child.destroy = popup_destroy; view_child_init(&popup->view_child, view, wlr_popup->base->surface); diff --git a/types/wlr_output_layout.c b/types/wlr_output_layout.c index 2462bdd2..8d328c17 100644 --- a/types/wlr_output_layout.c +++ b/types/wlr_output_layout.c @@ -339,8 +339,12 @@ void wlr_output_layout_closest_point(struct wlr_output_layout *layout, } } - *dest_x = min_x; - *dest_y = min_y; + if (dest_x) { + *dest_x = min_x; + } + if (dest_y) { + *dest_y = min_y; + } } struct wlr_box *wlr_output_layout_get_box( diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index 6fddfdbc..fc3a38d4 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -454,7 +454,6 @@ static struct wlr_box xdg_positioner_get_geometry( return geometry; } - static const struct zxdg_popup_v6_interface zxdg_popup_v6_implementation; static struct wlr_xdg_surface_v6 *xdg_surface_from_xdg_popup_resource( @@ -593,7 +592,7 @@ static void xdg_surface_handle_get_popup(struct wl_client *client, xdg_positioner_get_geometry(positioner->attrs, surface, parent); // positioner properties - memcpy(&surface->popup->positioner, &positioner->attrs, + memcpy(&surface->popup->positioner, positioner->attrs, sizeof(struct wlr_xdg_positioner_v6_attributes)); wl_list_insert(&parent->popups, &surface->popup->link); @@ -605,7 +604,6 @@ static void xdg_surface_handle_get_popup(struct wl_client *client, wlr_signal_emit_safe(&parent->events.new_popup, surface->popup); } - static const struct zxdg_toplevel_v6_interface zxdg_toplevel_v6_implementation; static struct wlr_xdg_surface_v6 *xdg_surface_from_xdg_toplevel_resource( @@ -1591,3 +1589,136 @@ struct wlr_xdg_surface_v6 *wlr_xdg_surface_v6_popup_at( return NULL; } + +void wlr_xdg_popup_v6_get_anchor_point(struct wlr_xdg_popup_v6 *popup, + int *root_sx, int *root_sy) { + struct wlr_box rect = popup->positioner.anchor_rect; + enum wlr_positioner_v6_anchor anchor = popup->positioner.anchor; + int sx = 0, sy = 0; + + if (anchor == WLR_POSITIONER_V6_ANCHOR_NONE) { + sx = (rect.x + rect.width) / 2; + sy = (rect.y + rect.height) / 2; + } else if (anchor == WLR_POSITIONER_V6_ANCHOR_TOP) { + sx = (rect.x + rect.width) / 2; + sy = rect.y; + } else if (anchor == WLR_POSITIONER_V6_ANCHOR_BOTTOM) { + sx = (rect.x + rect.width) / 2; + sy = rect.y + rect.height; + } else if (anchor == WLR_POSITIONER_V6_ANCHOR_LEFT) { + sx = rect.x; + sy = (rect.y + rect.height) / 2; + } else if (anchor == WLR_POSITIONER_V6_ANCHOR_RIGHT) { + sx = rect.x + rect.width; + sy = (rect.y + rect.height) / 2; + } else if (anchor == (WLR_POSITIONER_V6_ANCHOR_TOP | + WLR_POSITIONER_V6_ANCHOR_LEFT)) { + sx = rect.x; + sy = rect.y; + } else if (anchor == (WLR_POSITIONER_V6_ANCHOR_TOP | + WLR_POSITIONER_V6_ANCHOR_RIGHT)) { + sx = rect.x + rect.width; + sy = rect.y; + } else if (anchor == (WLR_POSITIONER_V6_ANCHOR_BOTTOM | + WLR_POSITIONER_V6_ANCHOR_LEFT)) { + sx = rect.x; + sy = rect.y + rect.height; + } else if (anchor == (WLR_POSITIONER_V6_ANCHOR_BOTTOM | + WLR_POSITIONER_V6_ANCHOR_RIGHT)) { + sx = rect.x + rect.width; + sy = rect.y + rect.height; + } + + *root_sx = sx; + *root_sy = sy; + + /* + // XXX: THIS IS WILL WORK WITH XDG SHELL STABLE + switch (popup->positioner.anchor) { + case WLR_POSITIONER_ANCHOR_NONE: + sx = (rect.x + rect.width) / 2; + sy = (rect.y + rect.height) / 2; + break; + case WLR_POSITIONER_ANCHOR_TOP: + sx = (rect.x + rect.width) / 2; + sy = rect.y; + break; + case WLR_POSITIONER_ANCHOR_BOTTOM: + sx = (rect.x + rect.width) / 2; + sy = rect.y + rect.height; + break; + case WLR_POSITIONER_ANCHOR_LEFT: + sx = rect.x; + sy = (rect.y + rect.height) / 2; + break; + case WLR_POSITIONER_ANCHOR_RIGHT: + sx = rect.x + rect.width; + sy = (rect.y + rect.height) / 2; + break; + case WLR_POSITIONER_ANCHOR_TOP_LEFT: + sx = rect.x; + sy = rect.y; + break; + case WLR_POSITIONER_ANCHOR_BOTTOM_LEFT: + sx = rect.x; + sy = rect.y + rect.height; + break; + case WLR_POSITIONER_ANCHOR_TOP_RIGHT: + sx = rect.x + rect.width; + sy = rect.y; + break; + case WLR_POSITIONER_ANCHOR_BOTTOM_RIGHT: + sx = rect.x + rect.width; + sy = rect.y + rect.height; + break; + } + */ +} + +void wlr_positioner_v6_invert( + struct wlr_xdg_positioner_v6_attributes *positioner) { + enum wlr_positioner_v6_anchor anchor = positioner->anchor; + + if (anchor == WLR_POSITIONER_V6_ANCHOR_NONE) { + // already inverted + } else if (anchor == WLR_POSITIONER_V6_ANCHOR_TOP) { + positioner->anchor = WLR_POSITIONER_V6_ANCHOR_BOTTOM; + } else if (anchor == WLR_POSITIONER_V6_ANCHOR_BOTTOM) { + positioner->anchor = WLR_POSITIONER_V6_ANCHOR_TOP; + } else if (anchor == WLR_POSITIONER_V6_ANCHOR_LEFT) { + positioner->anchor = WLR_POSITIONER_V6_ANCHOR_RIGHT; + } else if (anchor == WLR_POSITIONER_V6_ANCHOR_RIGHT) { + positioner->anchor = WLR_POSITIONER_V6_ANCHOR_LEFT; + } else if (anchor == (WLR_POSITIONER_V6_ANCHOR_TOP | + WLR_POSITIONER_V6_ANCHOR_LEFT)) { + positioner->anchor = WLR_POSITIONER_V6_ANCHOR_BOTTOM | WLR_POSITIONER_V6_ANCHOR_RIGHT; + } else if (anchor == (WLR_POSITIONER_V6_ANCHOR_TOP | + WLR_POSITIONER_V6_ANCHOR_RIGHT)) { + positioner->anchor = WLR_POSITIONER_V6_ANCHOR_BOTTOM | WLR_POSITIONER_V6_ANCHOR_LEFT; + } else if (anchor == (WLR_POSITIONER_V6_ANCHOR_BOTTOM | + WLR_POSITIONER_V6_ANCHOR_LEFT)) { + positioner->anchor = WLR_POSITIONER_V6_ANCHOR_TOP | WLR_POSITIONER_V6_ANCHOR_RIGHT; + } else if (anchor == (WLR_POSITIONER_V6_ANCHOR_BOTTOM | + WLR_POSITIONER_V6_ANCHOR_RIGHT)) { + positioner->anchor = WLR_POSITIONER_V6_ANCHOR_TOP | WLR_POSITIONER_V6_ANCHOR_LEFT; + } + + enum wlr_positioner_v6_gravity gravity = positioner->gravity; + switch (gravity) { + case WLR_POSITIONER_V6_GRAVITY_NONE: + // already inverted + break; + case WLR_POSITIONER_V6_GRAVITY_TOP: + positioner->gravity = WLR_POSITIONER_V6_GRAVITY_BOTTOM; + break; + case WLR_POSITIONER_V6_GRAVITY_BOTTOM: + positioner->gravity = WLR_POSITIONER_V6_GRAVITY_TOP; + break; + case WLR_POSITIONER_V6_GRAVITY_LEFT: + positioner->gravity = WLR_POSITIONER_V6_GRAVITY_RIGHT; + break; + case WLR_POSITIONER_V6_GRAVITY_RIGHT: + positioner->gravity = WLR_POSITIONER_V6_GRAVITY_LEFT; + break; + } +} From 8371e2f41dbcb8d3ae42a4fb386577d97301ac5a Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 27 Mar 2018 14:49:31 -0400 Subject: [PATCH 04/22] implement flip_x --- include/wlr/types/wlr_xdg_shell_v6.h | 8 +- rootston/xdg_shell_v6.c | 123 ++++++++++++++++----------- types/wlr_xdg_shell_v6.c | 81 ++++++++---------- 3 files changed, 115 insertions(+), 97 deletions(-) diff --git a/include/wlr/types/wlr_xdg_shell_v6.h b/include/wlr/types/wlr_xdg_shell_v6.h index e192d36a..e085c493 100644 --- a/include/wlr/types/wlr_xdg_shell_v6.h +++ b/include/wlr/types/wlr_xdg_shell_v6.h @@ -296,13 +296,19 @@ struct wlr_xdg_surface_v6 *wlr_xdg_surface_v6_popup_at( struct wlr_xdg_surface_v6 *surface, double sx, double sy, double *popup_sx, double *popup_sy); +struct wlr_box wlr_xdg_positioner_v6_get_geometry( + struct wlr_xdg_positioner_v6_attributes *positioner); + /** * Get the anchor point for this popup in the root parent's coordinate system. */ void wlr_xdg_popup_v6_get_anchor_point(struct wlr_xdg_popup_v6 *popup, int *root_sx, int *root_sy); -void wlr_positioner_v6_invert( +void wlr_positioner_v6_invert_x( + struct wlr_xdg_positioner_v6_attributes *positioner); + +void wlr_positioner_v6_invert_y( struct wlr_xdg_positioner_v6_attributes *positioner); #endif diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 36ecc897..0a698e50 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -38,6 +38,77 @@ static void popup_handle_new_popup(struct wl_listener *listener, void *data) { popup_create(popup->view_child.view, wlr_popup); } +static void popup_get_coords(struct wlr_xdg_popup_v6 *popup, + double *sx, double *sy) { + struct wlr_xdg_surface_v6 *parent = popup->parent; + double popup_sx = popup->geometry.x; + double popup_sy = popup->geometry.y; + while (parent->role != WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL) { + popup_sx += parent->popup->geometry.x; + popup_sy += parent->popup->geometry.y; + parent = parent->popup->parent; + } + + *sx = popup_sx + parent->geometry.x; + *sy = popup_sy + parent->geometry.y; +} + +static void popup_is_constrained(struct roots_xdg_popup_v6 *popup, + bool *x_constrained, bool *y_constrained) { + struct roots_view *view = popup->view_child.view; + struct wlr_output_layout *layout = view->desktop->layout; + struct wlr_xdg_popup_v6 *wlr_popup = popup->wlr_popup; + int popup_width = wlr_popup->geometry.width; + int popup_height = wlr_popup->geometry.height; + + int anchor_lx, anchor_ly; + wlr_xdg_popup_v6_get_anchor_point(wlr_popup, &anchor_lx, &anchor_ly); + + double popup_lx, popup_ly; + popup_get_coords(wlr_popup, &popup_lx, &popup_ly); + popup_lx += view->x; + popup_ly += view->y; + + anchor_lx += popup_lx; + anchor_ly += popup_ly; + + double dest_x = 0, dest_y = 0; + wlr_output_layout_closest_point(layout, NULL, anchor_lx, anchor_ly, + &dest_x, &dest_y); + + struct wlr_output *output = + wlr_output_layout_output_at(layout, dest_x, dest_y); + // XXX: handle empty output layout + assert(output); + + struct wlr_box *output_box = wlr_output_layout_get_box(layout, output); + *x_constrained = popup_lx <= output_box->x || + popup_lx + popup_width >= output_box->x + output_box->width; + *y_constrained = popup_ly <= output_box->y || + popup_ly + popup_height >= output_box->y + output_box->height; +} + +static void popup_unconstrain_flip(struct roots_xdg_popup_v6 *popup) { + bool x_constrained, y_constrained; + popup_is_constrained(popup, &x_constrained, &y_constrained); + + if (x_constrained) { + wlr_positioner_v6_invert_x(&popup->wlr_popup->positioner); + } + if (y_constrained) { + wlr_positioner_v6_invert_y(&popup->wlr_popup->positioner); + } + + popup->wlr_popup->geometry = + wlr_xdg_positioner_v6_get_geometry(&popup->wlr_popup->positioner); +} + +static void popup_unconstrain(struct roots_xdg_popup_v6 *popup) { + popup_unconstrain_flip(popup); + // TODO popup_unconstrain_slide(popup); + // TODO popup_unconstrain_resize(popup); +} + static struct roots_xdg_popup_v6 *popup_create(struct roots_view *view, struct wlr_xdg_popup_v6 *wlr_popup) { struct roots_xdg_popup_v6 *popup = @@ -45,55 +116,6 @@ static struct roots_xdg_popup_v6 *popup_create(struct roots_view *view, if (popup == NULL) { return NULL; } - - struct wlr_xdg_surface_v6 *parent = wlr_popup->parent; - double popup_lx = wlr_popup->geometry.x; - double popup_ly = wlr_popup->geometry.y; - while (parent->role != WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL) { - popup_lx += parent->popup->geometry.x; - popup_ly += parent->popup->geometry.y; - parent = parent->popup->parent; - } - - popup_lx += view->x + parent->geometry.x; - popup_ly += view->y + parent->geometry.y; - int popup_width = wlr_popup->geometry.width; - int popup_height = wlr_popup->geometry.height; - - int anchor_x, anchor_y; - wlr_xdg_popup_v6_get_anchor_point(wlr_popup, &anchor_x, &anchor_y); - anchor_x += popup_lx; - anchor_y += popup_ly; - - struct wlr_output_layout *layout = view->desktop->layout; - - // get the output that contains (or closest to) the anchor point - struct wlr_output *output = - wlr_output_layout_output_at(layout, anchor_x, anchor_y); - if (output == NULL) { - // TODO find the closest output to the anchor - assert(false); - } - - // does the output completely contain the popup? - struct wlr_box *output_box = wlr_output_layout_get_box(layout, output); - bool output_contains_popup_x = popup_lx >= output_box->x && - popup_lx + popup_width <= output_box->x + output_box->width; - bool output_contains_popup_y = popup_ly >= output_box->y && - popup_ly + popup_height <= output_box->y + output_box->height; - - if (!output_contains_popup_x) { - // TODO flip_x - // TODO slide_x - // TODO resize_x - } - - if (!output_contains_popup_y) { - // TODO flip_y - // TODO slide_y - // TODO resize_y - } - popup->wlr_popup = wlr_popup; popup->view_child.destroy = popup_destroy; view_child_init(&popup->view_child, view, wlr_popup->base->surface); @@ -101,6 +123,9 @@ static struct roots_xdg_popup_v6 *popup_create(struct roots_view *view, wl_signal_add(&wlr_popup->base->events.destroy, &popup->destroy); popup->new_popup.notify = popup_handle_new_popup; wl_signal_add(&wlr_popup->base->events.new_popup, &popup->new_popup); + + popup_unconstrain(popup); + return popup; } diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index fc3a38d4..76340a3c 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -399,9 +399,7 @@ static void xdg_shell_handle_create_positioner(struct wl_client *wl_client, positioner, xdg_positioner_destroy); } -static struct wlr_box xdg_positioner_get_geometry( - struct wlr_xdg_positioner_v6_attributes *positioner, - struct wlr_xdg_surface_v6 *surface, struct wlr_xdg_surface_v6 *parent) { +struct wlr_box wlr_xdg_positioner_v6_get_geometry(struct wlr_xdg_positioner_v6_attributes *positioner) { struct wlr_box geometry = { .x = positioner->offset.x, .y = positioner->offset.y, @@ -589,7 +587,7 @@ static void xdg_surface_handle_get_popup(struct wl_client *client, surface->popup->base = surface; surface->popup->parent = parent; surface->popup->geometry = - xdg_positioner_get_geometry(positioner->attrs, surface, parent); + wlr_xdg_positioner_v6_get_geometry(positioner->attrs); // positioner properties memcpy(&surface->popup->positioner, positioner->attrs, @@ -1675,50 +1673,39 @@ void wlr_xdg_popup_v6_get_anchor_point(struct wlr_xdg_popup_v6 *popup, */ } -void wlr_positioner_v6_invert( - struct wlr_xdg_positioner_v6_attributes *positioner) { - enum wlr_positioner_v6_anchor anchor = positioner->anchor; - - if (anchor == WLR_POSITIONER_V6_ANCHOR_NONE) { - // already inverted - } else if (anchor == WLR_POSITIONER_V6_ANCHOR_TOP) { - positioner->anchor = WLR_POSITIONER_V6_ANCHOR_BOTTOM; - } else if (anchor == WLR_POSITIONER_V6_ANCHOR_BOTTOM) { - positioner->anchor = WLR_POSITIONER_V6_ANCHOR_TOP; - } else if (anchor == WLR_POSITIONER_V6_ANCHOR_LEFT) { - positioner->anchor = WLR_POSITIONER_V6_ANCHOR_RIGHT; - } else if (anchor == WLR_POSITIONER_V6_ANCHOR_RIGHT) { - positioner->anchor = WLR_POSITIONER_V6_ANCHOR_LEFT; - } else if (anchor == (WLR_POSITIONER_V6_ANCHOR_TOP | - WLR_POSITIONER_V6_ANCHOR_LEFT)) { - positioner->anchor = WLR_POSITIONER_V6_ANCHOR_BOTTOM | WLR_POSITIONER_V6_ANCHOR_RIGHT; - } else if (anchor == (WLR_POSITIONER_V6_ANCHOR_TOP | - WLR_POSITIONER_V6_ANCHOR_RIGHT)) { - positioner->anchor = WLR_POSITIONER_V6_ANCHOR_BOTTOM | WLR_POSITIONER_V6_ANCHOR_LEFT; - } else if (anchor == (WLR_POSITIONER_V6_ANCHOR_BOTTOM | - WLR_POSITIONER_V6_ANCHOR_LEFT)) { - positioner->anchor = WLR_POSITIONER_V6_ANCHOR_TOP | WLR_POSITIONER_V6_ANCHOR_RIGHT; - } else if (anchor == (WLR_POSITIONER_V6_ANCHOR_BOTTOM | - WLR_POSITIONER_V6_ANCHOR_RIGHT)) { - positioner->anchor = WLR_POSITIONER_V6_ANCHOR_TOP | WLR_POSITIONER_V6_ANCHOR_LEFT; +void wlr_positioner_v6_invert_x(struct wlr_xdg_positioner_v6_attributes *positioner) { + if (positioner->anchor & WLR_POSITIONER_V6_ANCHOR_LEFT) { + positioner->anchor &= ~WLR_POSITIONER_V6_ANCHOR_LEFT; + positioner->anchor |= WLR_POSITIONER_V6_ANCHOR_RIGHT; + } else if (positioner->anchor & WLR_POSITIONER_V6_ANCHOR_RIGHT) { + positioner->anchor &= ~WLR_POSITIONER_V6_ANCHOR_RIGHT; + positioner->anchor |= WLR_POSITIONER_V6_ANCHOR_LEFT; } - enum wlr_positioner_v6_gravity gravity = positioner->gravity; - switch (gravity) { - case WLR_POSITIONER_V6_GRAVITY_NONE: - // already inverted - break; - case WLR_POSITIONER_V6_GRAVITY_TOP: - positioner->gravity = WLR_POSITIONER_V6_GRAVITY_BOTTOM; - break; - case WLR_POSITIONER_V6_GRAVITY_BOTTOM: - positioner->gravity = WLR_POSITIONER_V6_GRAVITY_TOP; - break; - case WLR_POSITIONER_V6_GRAVITY_LEFT: - positioner->gravity = WLR_POSITIONER_V6_GRAVITY_RIGHT; - break; - case WLR_POSITIONER_V6_GRAVITY_RIGHT: - positioner->gravity = WLR_POSITIONER_V6_GRAVITY_LEFT; - break; + if (positioner->gravity & WLR_POSITIONER_V6_GRAVITY_RIGHT) { + positioner->gravity &= ~WLR_POSITIONER_V6_GRAVITY_RIGHT; + positioner->gravity |= WLR_POSITIONER_V6_GRAVITY_LEFT; + } else if (positioner->gravity & WLR_POSITIONER_V6_GRAVITY_LEFT) { + positioner->gravity &= ~WLR_POSITIONER_V6_GRAVITY_LEFT; + positioner->gravity |= WLR_POSITIONER_V6_GRAVITY_RIGHT; + } +} + +void wlr_positioner_v6_invert_y( + struct wlr_xdg_positioner_v6_attributes *positioner) { + if (positioner->anchor & WLR_POSITIONER_V6_ANCHOR_TOP) { + positioner->anchor &= ~WLR_POSITIONER_V6_ANCHOR_TOP; + positioner->anchor |= WLR_POSITIONER_V6_ANCHOR_BOTTOM; + } else if (positioner->anchor & WLR_POSITIONER_V6_ANCHOR_BOTTOM) { + positioner->anchor &= ~WLR_POSITIONER_V6_ANCHOR_BOTTOM; + positioner->anchor |= WLR_POSITIONER_V6_ANCHOR_TOP; + } + + if (positioner->gravity & WLR_POSITIONER_V6_GRAVITY_TOP) { + positioner->gravity &= ~WLR_POSITIONER_V6_GRAVITY_TOP; + positioner->gravity |= WLR_POSITIONER_V6_GRAVITY_BOTTOM; + } else if (positioner->gravity & WLR_POSITIONER_V6_GRAVITY_BOTTOM) { + positioner->gravity &= ~WLR_POSITIONER_V6_GRAVITY_BOTTOM; + positioner->gravity |= WLR_POSITIONER_V6_GRAVITY_TOP; } } From 9ff84db06d44aed7188cb574a6e877d93a12e8df Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 27 Mar 2018 15:13:35 -0400 Subject: [PATCH 05/22] unconstrain stubs --- rootston/xdg_shell_v6.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 0a698e50..60e2b541 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -103,10 +103,34 @@ static void popup_unconstrain_flip(struct roots_xdg_popup_v6 *popup) { wlr_xdg_positioner_v6_get_geometry(&popup->wlr_popup->positioner); } +static void popup_unconstrain_slide(struct roots_xdg_popup_v6 *popup) { + bool x_constrained, y_constrained; + popup_is_constrained(popup, &x_constrained, &y_constrained); + + if (x_constrained) { + // TODO slide_x + } + if (y_constrained) { + // TODO slide_y + } +} + +static void popup_unconstrain_resize(struct roots_xdg_popup_v6 *popup) { + bool x_constrained, y_constrained; + popup_is_constrained(popup, &x_constrained, &y_constrained); + + if (x_constrained) { + // TODO resize_x + } + if (y_constrained) { + // TODO resize_y + } +} + static void popup_unconstrain(struct roots_xdg_popup_v6 *popup) { popup_unconstrain_flip(popup); - // TODO popup_unconstrain_slide(popup); - // TODO popup_unconstrain_resize(popup); + popup_unconstrain_slide(popup); + popup_unconstrain_resize(popup); } static struct roots_xdg_popup_v6 *popup_create(struct roots_view *view, From edb643fc6c55b47dd766b4e516b16108719d1ecd Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 27 Mar 2018 17:16:08 -0400 Subject: [PATCH 06/22] basic xdg-positioner --- rootston/xdg_shell_v6.c | 101 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 93 insertions(+), 8 deletions(-) diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 60e2b541..f5cb2cd7 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -92,6 +92,26 @@ static void popup_unconstrain_flip(struct roots_xdg_popup_v6 *popup) { bool x_constrained, y_constrained; popup_is_constrained(popup, &x_constrained, &y_constrained); + if (!x_constrained && !y_constrained) { + return; + } + + if (x_constrained) { + wlr_positioner_v6_invert_x(&popup->wlr_popup->positioner); + } + if (y_constrained) { + wlr_positioner_v6_invert_y(&popup->wlr_popup->positioner); + } + + popup->wlr_popup->geometry = + wlr_xdg_positioner_v6_get_geometry(&popup->wlr_popup->positioner); + + popup_is_constrained(popup, &x_constrained, &y_constrained); + + if (!x_constrained && !y_constrained) { + return; + } + if (x_constrained) { wlr_positioner_v6_invert_x(&popup->wlr_popup->positioner); } @@ -104,26 +124,91 @@ static void popup_unconstrain_flip(struct roots_xdg_popup_v6 *popup) { } static void popup_unconstrain_slide(struct roots_xdg_popup_v6 *popup) { - bool x_constrained, y_constrained; - popup_is_constrained(popup, &x_constrained, &y_constrained); + struct roots_view *view = popup->view_child.view; + struct wlr_output_layout *layout = view->desktop->layout; + struct wlr_xdg_popup_v6 *wlr_popup = popup->wlr_popup; + int popup_width = wlr_popup->geometry.width; + int popup_height = wlr_popup->geometry.height; + + int anchor_lx, anchor_ly; + wlr_xdg_popup_v6_get_anchor_point(wlr_popup, &anchor_lx, &anchor_ly); + + double popup_lx, popup_ly; + popup_get_coords(wlr_popup, &popup_lx, &popup_ly); + popup_lx += view->x; + popup_ly += view->y; + + anchor_lx += popup_lx; + anchor_ly += popup_ly; + + double dest_x = 0, dest_y = 0; + wlr_output_layout_closest_point(layout, NULL, anchor_lx, anchor_ly, + &dest_x, &dest_y); + + struct wlr_output *output = + wlr_output_layout_output_at(layout, dest_x, dest_y); + // XXX: handle empty output layout + assert(output); + + struct wlr_box *output_box = wlr_output_layout_get_box(layout, output); + + bool x_constrained = popup_lx <= output_box->x || + popup_lx + popup_width >= output_box->x + output_box->width; + bool y_constrained = popup_ly <= output_box->y || + popup_ly + popup_height >= output_box->y + output_box->height; + + double popup_ox = popup_lx - output_box->x, + popup_oy = popup_ly - output_box->y; if (x_constrained) { - // TODO slide_x + wlr_popup->geometry.x -= popup_width - (output_box->width - popup_ox); } if (y_constrained) { - // TODO slide_y + wlr_popup->geometry.y -= popup_height - (output_box->height - popup_oy); } } static void popup_unconstrain_resize(struct roots_xdg_popup_v6 *popup) { - bool x_constrained, y_constrained; - popup_is_constrained(popup, &x_constrained, &y_constrained); + struct roots_view *view = popup->view_child.view; + struct wlr_output_layout *layout = view->desktop->layout; + struct wlr_xdg_popup_v6 *wlr_popup = popup->wlr_popup; + int popup_width = wlr_popup->geometry.width; + int popup_height = wlr_popup->geometry.height; + + int anchor_lx, anchor_ly; + wlr_xdg_popup_v6_get_anchor_point(wlr_popup, &anchor_lx, &anchor_ly); + + double popup_lx, popup_ly; + popup_get_coords(wlr_popup, &popup_lx, &popup_ly); + popup_lx += view->x; + popup_ly += view->y; + + anchor_lx += popup_lx; + anchor_ly += popup_ly; + + double dest_x = 0, dest_y = 0; + wlr_output_layout_closest_point(layout, NULL, anchor_lx, anchor_ly, + &dest_x, &dest_y); + + struct wlr_output *output = + wlr_output_layout_output_at(layout, dest_x, dest_y); + // XXX: handle empty output layout + assert(output); + + struct wlr_box *output_box = wlr_output_layout_get_box(layout, output); + + bool x_constrained = popup_lx <= output_box->x || + popup_lx + popup_width >= output_box->x + output_box->width; + bool y_constrained = popup_ly <= output_box->y || + popup_ly + popup_height >= output_box->y + output_box->height; + + double popup_ox = popup_lx - output_box->x, popup_oy = popup_ly - output_box->y; if (x_constrained) { - // TODO resize_x + wlr_popup->geometry.width = output_box->x + output_box->width - popup_ox; } if (y_constrained) { - // TODO resize_y + wlr_popup->geometry.height = output_box->y + output_box->height - popup_oy; } } From 738f5e33440eac4f1619c639784b9815f451285a Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 28 Mar 2018 11:42:01 -0400 Subject: [PATCH 07/22] cleanup xdg-positioner rootston code --- rootston/xdg_shell_v6.c | 161 ++++++++++++++++------------------------ 1 file changed, 65 insertions(+), 96 deletions(-) diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index e3c70e96..5fa016a0 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -65,8 +65,8 @@ static void popup_get_coords(struct wlr_xdg_popup_v6 *popup, *sy = popup_sy + parent->geometry.y; } -static void popup_is_constrained(struct roots_xdg_popup_v6 *popup, - bool *x_constrained, bool *y_constrained) { +static void popup_constraint_offset(struct roots_xdg_popup_v6 *popup, + int *offset_x, int *offset_y) { struct roots_view *view = popup->view_child.view; struct wlr_output_layout *layout = view->desktop->layout; struct wlr_xdg_popup_v6 *wlr_popup = popup->wlr_popup; @@ -94,134 +94,103 @@ static void popup_is_constrained(struct roots_xdg_popup_v6 *popup, assert(output); struct wlr_box *output_box = wlr_output_layout_get_box(layout, output); - *x_constrained = popup_lx <= output_box->x || + bool x_constrained = popup_lx <= output_box->x || popup_lx + popup_width >= output_box->x + output_box->width; - *y_constrained = popup_ly <= output_box->y || + bool y_constrained = popup_ly <= output_box->y || popup_ly + popup_height >= output_box->y + output_box->height; -} -static void popup_unconstrain_flip(struct roots_xdg_popup_v6 *popup) { - bool x_constrained, y_constrained; - popup_is_constrained(popup, &x_constrained, &y_constrained); + *offset_x = *offset_y = 0; - if (!x_constrained && !y_constrained) { - return; - } + double popup_ox = popup_lx - output_box->x; + double popup_oy = popup_ly - output_box->y; if (x_constrained) { + *offset_x = popup_width - (output_box->width - popup_ox); + } + + if (y_constrained) { + *offset_y = popup_height - (output_box->height - popup_oy); + } +} + +static bool popup_unconstrain_flip(struct roots_xdg_popup_v6 *popup) { + int offset_x, offset_y; + popup_constraint_offset(popup, &offset_y, &offset_y); + + if (!offset_x && !offset_y) { + return true; + } + + if (offset_x) { wlr_positioner_v6_invert_x(&popup->wlr_popup->positioner); } - if (y_constrained) { + if (offset_y) { wlr_positioner_v6_invert_y(&popup->wlr_popup->positioner); } popup->wlr_popup->geometry = wlr_xdg_positioner_v6_get_geometry(&popup->wlr_popup->positioner); - popup_is_constrained(popup, &x_constrained, &y_constrained); + popup_constraint_offset(popup, &offset_x, &offset_y); - if (!x_constrained && !y_constrained) { - return; + if (!offset_x && !offset_y) { + // no longer constrained + return true; } - if (x_constrained) { + // revert the positioner back if it didn't fix it and go to the next part + if (offset_x) { wlr_positioner_v6_invert_x(&popup->wlr_popup->positioner); } - if (y_constrained) { + if (offset_y) { wlr_positioner_v6_invert_y(&popup->wlr_popup->positioner); } popup->wlr_popup->geometry = wlr_xdg_positioner_v6_get_geometry(&popup->wlr_popup->positioner); + + return false; } -static void popup_unconstrain_slide(struct roots_xdg_popup_v6 *popup) { - struct roots_view *view = popup->view_child.view; - struct wlr_output_layout *layout = view->desktop->layout; - struct wlr_xdg_popup_v6 *wlr_popup = popup->wlr_popup; - int popup_width = wlr_popup->geometry.width; - int popup_height = wlr_popup->geometry.height; +static bool popup_unconstrain_slide(struct roots_xdg_popup_v6 *popup) { + int offset_x, offset_y; + popup_constraint_offset(popup, &offset_x, &offset_y); - int anchor_lx, anchor_ly; - wlr_xdg_popup_v6_get_anchor_point(wlr_popup, &anchor_lx, &anchor_ly); - - double popup_lx, popup_ly; - popup_get_coords(wlr_popup, &popup_lx, &popup_ly); - popup_lx += view->x; - popup_ly += view->y; - - anchor_lx += popup_lx; - anchor_ly += popup_ly; - - double dest_x = 0, dest_y = 0; - wlr_output_layout_closest_point(layout, NULL, anchor_lx, anchor_ly, - &dest_x, &dest_y); - - struct wlr_output *output = - wlr_output_layout_output_at(layout, dest_x, dest_y); - // XXX: handle empty output layout - assert(output); - - struct wlr_box *output_box = wlr_output_layout_get_box(layout, output); - - bool x_constrained = popup_lx <= output_box->x || - popup_lx + popup_width >= output_box->x + output_box->width; - bool y_constrained = popup_ly <= output_box->y || - popup_ly + popup_height >= output_box->y + output_box->height; - - double popup_ox = popup_lx - output_box->x, - popup_oy = popup_ly - output_box->y; - - if (x_constrained) { - wlr_popup->geometry.x -= popup_width - (output_box->width - popup_ox); + if (!offset_x && !offset_y) { + return true; } - if (y_constrained) { - wlr_popup->geometry.y -= popup_height - (output_box->height - popup_oy); + + if (offset_x) { + popup->wlr_popup->geometry.x -= offset_x; } + if (offset_y) { + popup->wlr_popup->geometry.y -= abs(offset_y); + } + + popup_constraint_offset(popup, &offset_y, &offset_y); + + return !offset_x && !offset_y; } -static void popup_unconstrain_resize(struct roots_xdg_popup_v6 *popup) { - struct roots_view *view = popup->view_child.view; - struct wlr_output_layout *layout = view->desktop->layout; - struct wlr_xdg_popup_v6 *wlr_popup = popup->wlr_popup; - int popup_width = wlr_popup->geometry.width; - int popup_height = wlr_popup->geometry.height; +static bool popup_unconstrain_resize(struct roots_xdg_popup_v6 *popup) { + int offset_x, offset_y; + popup_constraint_offset(popup, &offset_x, &offset_y); - int anchor_lx, anchor_ly; - wlr_xdg_popup_v6_get_anchor_point(wlr_popup, &anchor_lx, &anchor_ly); - - double popup_lx, popup_ly; - popup_get_coords(wlr_popup, &popup_lx, &popup_ly); - popup_lx += view->x; - popup_ly += view->y; - - anchor_lx += popup_lx; - anchor_ly += popup_ly; - - double dest_x = 0, dest_y = 0; - wlr_output_layout_closest_point(layout, NULL, anchor_lx, anchor_ly, - &dest_x, &dest_y); - - struct wlr_output *output = - wlr_output_layout_output_at(layout, dest_x, dest_y); - // XXX: handle empty output layout - assert(output); - - struct wlr_box *output_box = wlr_output_layout_get_box(layout, output); - - bool x_constrained = popup_lx <= output_box->x || - popup_lx + popup_width >= output_box->x + output_box->width; - bool y_constrained = popup_ly <= output_box->y || - popup_ly + popup_height >= output_box->y + output_box->height; - - double popup_ox = popup_lx - output_box->x, popup_oy = popup_ly - output_box->y; - - if (x_constrained) { - wlr_popup->geometry.width = output_box->x + output_box->width - popup_ox; + if (!offset_x && !offset_y) { + return true; } - if (y_constrained) { - wlr_popup->geometry.height = output_box->y + output_box->height - popup_oy; + + if (offset_x) { + popup->wlr_popup->geometry.width -= offset_x; } + if (offset_y) { + popup->wlr_popup->geometry.height -= offset_y; + } + + popup_constraint_offset(popup, &offset_y, &offset_y); + + return !offset_x && !offset_y; + } static void popup_unconstrain(struct roots_xdg_popup_v6 *popup) { From e2c4e1ef541f825eeb804d0873d305213c3fbb82 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 28 Mar 2018 12:12:00 -0400 Subject: [PATCH 08/22] fix xdg-positioner left constrain bug --- rootston/xdg_shell_v6.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 5fa016a0..1e85a933 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -94,21 +94,21 @@ static void popup_constraint_offset(struct roots_xdg_popup_v6 *popup, assert(output); struct wlr_box *output_box = wlr_output_layout_get_box(layout, output); - bool x_constrained = popup_lx <= output_box->x || - popup_lx + popup_width >= output_box->x + output_box->width; - bool y_constrained = popup_ly <= output_box->y || - popup_ly + popup_height >= output_box->y + output_box->height; *offset_x = *offset_y = 0; double popup_ox = popup_lx - output_box->x; double popup_oy = popup_ly - output_box->y; - if (x_constrained) { + if (popup_lx < output_box->x) { + *offset_x = output_box->x - popup_lx; + } else if (popup_lx + popup_width > output_box->x + output_box->width) { *offset_x = popup_width - (output_box->width - popup_ox); } - if (y_constrained) { + if (popup_ly < output_box->y) { + *offset_y = output_box->y - popup_ly; + } else if (popup_ly + popup_height > output_box->y + output_box->height) { *offset_y = popup_height - (output_box->height - popup_oy); } } @@ -161,10 +161,10 @@ static bool popup_unconstrain_slide(struct roots_xdg_popup_v6 *popup) { } if (offset_x) { - popup->wlr_popup->geometry.x -= offset_x; + popup->wlr_popup->geometry.x += offset_x; } if (offset_y) { - popup->wlr_popup->geometry.y -= abs(offset_y); + popup->wlr_popup->geometry.y += offset_y; } popup_constraint_offset(popup, &offset_y, &offset_y); From c5cd8050986ad71e954e054445c42120e5868700 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 28 Mar 2018 12:46:41 -0400 Subject: [PATCH 09/22] positioner rootston cleanup and bugfix --- rootston/xdg_shell_v6.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 1e85a933..9bcdb4c9 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -97,19 +97,16 @@ static void popup_constraint_offset(struct roots_xdg_popup_v6 *popup, *offset_x = *offset_y = 0; - double popup_ox = popup_lx - output_box->x; - double popup_oy = popup_ly - output_box->y; - if (popup_lx < output_box->x) { *offset_x = output_box->x - popup_lx; } else if (popup_lx + popup_width > output_box->x + output_box->width) { - *offset_x = popup_width - (output_box->width - popup_ox); + *offset_x = output_box->x + output_box->width - (popup_lx + popup_width); } if (popup_ly < output_box->y) { *offset_y = output_box->y - popup_ly; } else if (popup_ly + popup_height > output_box->y + output_box->height) { - *offset_y = popup_height - (output_box->height - popup_oy); + *offset_y = output_box->y + output_box->height - (popup_ly + popup_height); } } @@ -163,6 +160,7 @@ static bool popup_unconstrain_slide(struct roots_xdg_popup_v6 *popup) { if (offset_x) { popup->wlr_popup->geometry.x += offset_x; } + if (offset_y) { popup->wlr_popup->geometry.y += offset_y; } From dbffda7549de4dba6b595e9bcaaef1628463315f Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 28 Mar 2018 16:27:08 -0400 Subject: [PATCH 10/22] xdg-positioner wlr abstractions --- include/wlr/types/wlr_xdg_shell_v6.h | 31 ++++- rootston/xdg_shell_v6.c | 134 +++------------------- types/wlr_xdg_shell_v6.c | 165 ++++++++++++++++++++------- 3 files changed, 167 insertions(+), 163 deletions(-) diff --git a/include/wlr/types/wlr_xdg_shell_v6.h b/include/wlr/types/wlr_xdg_shell_v6.h index e2a58669..0ab57108 100644 --- a/include/wlr/types/wlr_xdg_shell_v6.h +++ b/include/wlr/types/wlr_xdg_shell_v6.h @@ -302,18 +302,45 @@ struct wlr_xdg_surface_v6 *wlr_xdg_surface_v6_popup_at( struct wlr_xdg_surface_v6 *surface, double sx, double sy, double *popup_sx, double *popup_sy); +/** + * Get the geometry for this positioner based on the anchor rect, gravity, and + * size of this positioner. + */ struct wlr_box wlr_xdg_positioner_v6_get_geometry( struct wlr_xdg_positioner_v6_attributes *positioner); /** - * Get the anchor point for this popup in the root parent's coordinate system. + * Get the anchor point for this popup in the toplevel parent's coordinate system. */ void wlr_xdg_popup_v6_get_anchor_point(struct wlr_xdg_popup_v6 *popup, - int *root_sx, int *root_sy); + int *toplevel_sx, int *toplevel_sy); +/** + * Convert the given coordinates in the popup coordinate system to the toplevel + * surface coordinate system. + */ +void wlr_xdg_popup_v6_get_toplevel_coords(struct wlr_xdg_popup_v6 *popup, + int popup_sx, int popup_sy, int *toplevel_sx, int *toplevel_sy); + +/** + * Set the geometry of this popup to unconstrain it according to its + * xdg-positioner rules. The box should be in the popup's toplevel + * parent surface coordinate system. + */ +void wlr_xdg_popup_v6_unconstrain_from_box(struct wlr_xdg_popup_v6 *popup, + struct wlr_box *toplevel_box); + +/** + Invert the right/left anchor and gravity for this positioner. This can be + used to "flip" the positioner around the anchor rect in the x direction. + */ void wlr_positioner_v6_invert_x( struct wlr_xdg_positioner_v6_attributes *positioner); +/** + Invert the top/bottom anchor and gravity for this positioner. This can be + used to "flip" the positioner around the anchor rect in the y direction. + */ void wlr_positioner_v6_invert_y( struct wlr_xdg_positioner_v6_attributes *positioner); diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 9bcdb4c9..22309e8e 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -50,34 +50,17 @@ static void popup_handle_new_popup(struct wl_listener *listener, void *data) { popup_create(popup->view_child.view, wlr_popup); } -static void popup_get_coords(struct wlr_xdg_popup_v6 *popup, - double *sx, double *sy) { - struct wlr_xdg_surface_v6 *parent = popup->parent; - double popup_sx = popup->geometry.x; - double popup_sy = popup->geometry.y; - while (parent->role != WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL) { - popup_sx += parent->popup->geometry.x; - popup_sy += parent->popup->geometry.y; - parent = parent->popup->parent; - } - - *sx = popup_sx + parent->geometry.x; - *sy = popup_sy + parent->geometry.y; -} - -static void popup_constraint_offset(struct roots_xdg_popup_v6 *popup, - int *offset_x, int *offset_y) { +static void popup_unconstrain(struct roots_xdg_popup_v6 *popup) { struct roots_view *view = popup->view_child.view; struct wlr_output_layout *layout = view->desktop->layout; struct wlr_xdg_popup_v6 *wlr_popup = popup->wlr_popup; - int popup_width = wlr_popup->geometry.width; - int popup_height = wlr_popup->geometry.height; int anchor_lx, anchor_ly; wlr_xdg_popup_v6_get_anchor_point(wlr_popup, &anchor_lx, &anchor_ly); - double popup_lx, popup_ly; - popup_get_coords(wlr_popup, &popup_lx, &popup_ly); + int popup_lx, popup_ly; + wlr_xdg_popup_v6_get_toplevel_coords(wlr_popup, wlr_popup->geometry.x, + wlr_popup->geometry.y, &popup_lx, &popup_ly); popup_lx += view->x; popup_ly += view->y; @@ -93,108 +76,17 @@ static void popup_constraint_offset(struct roots_xdg_popup_v6 *popup, // XXX: handle empty output layout assert(output); - struct wlr_box *output_box = wlr_output_layout_get_box(layout, output); + int width = 0, height = 0; + wlr_output_effective_resolution(output, &width, &height); - *offset_x = *offset_y = 0; + struct wlr_box toplevel_box = { + .x = output->lx - view->x, + .y = output->ly - view->y, + .width = width, + .height = height + }; - if (popup_lx < output_box->x) { - *offset_x = output_box->x - popup_lx; - } else if (popup_lx + popup_width > output_box->x + output_box->width) { - *offset_x = output_box->x + output_box->width - (popup_lx + popup_width); - } - - if (popup_ly < output_box->y) { - *offset_y = output_box->y - popup_ly; - } else if (popup_ly + popup_height > output_box->y + output_box->height) { - *offset_y = output_box->y + output_box->height - (popup_ly + popup_height); - } -} - -static bool popup_unconstrain_flip(struct roots_xdg_popup_v6 *popup) { - int offset_x, offset_y; - popup_constraint_offset(popup, &offset_y, &offset_y); - - if (!offset_x && !offset_y) { - return true; - } - - if (offset_x) { - wlr_positioner_v6_invert_x(&popup->wlr_popup->positioner); - } - if (offset_y) { - wlr_positioner_v6_invert_y(&popup->wlr_popup->positioner); - } - - popup->wlr_popup->geometry = - wlr_xdg_positioner_v6_get_geometry(&popup->wlr_popup->positioner); - - popup_constraint_offset(popup, &offset_x, &offset_y); - - if (!offset_x && !offset_y) { - // no longer constrained - return true; - } - - // revert the positioner back if it didn't fix it and go to the next part - if (offset_x) { - wlr_positioner_v6_invert_x(&popup->wlr_popup->positioner); - } - if (offset_y) { - wlr_positioner_v6_invert_y(&popup->wlr_popup->positioner); - } - - popup->wlr_popup->geometry = - wlr_xdg_positioner_v6_get_geometry(&popup->wlr_popup->positioner); - - return false; -} - -static bool popup_unconstrain_slide(struct roots_xdg_popup_v6 *popup) { - int offset_x, offset_y; - popup_constraint_offset(popup, &offset_x, &offset_y); - - if (!offset_x && !offset_y) { - return true; - } - - if (offset_x) { - popup->wlr_popup->geometry.x += offset_x; - } - - if (offset_y) { - popup->wlr_popup->geometry.y += offset_y; - } - - popup_constraint_offset(popup, &offset_y, &offset_y); - - return !offset_x && !offset_y; -} - -static bool popup_unconstrain_resize(struct roots_xdg_popup_v6 *popup) { - int offset_x, offset_y; - popup_constraint_offset(popup, &offset_x, &offset_y); - - if (!offset_x && !offset_y) { - return true; - } - - if (offset_x) { - popup->wlr_popup->geometry.width -= offset_x; - } - if (offset_y) { - popup->wlr_popup->geometry.height -= offset_y; - } - - popup_constraint_offset(popup, &offset_y, &offset_y); - - return !offset_x && !offset_y; - -} - -static void popup_unconstrain(struct roots_xdg_popup_v6 *popup) { - popup_unconstrain_flip(popup); - popup_unconstrain_slide(popup); - popup_unconstrain_resize(popup); + wlr_xdg_popup_v6_unconstrain_from_box(popup->wlr_popup, &toplevel_box); } static struct roots_xdg_popup_v6 *popup_create(struct roots_view *view, diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index 0a8bbadf..0cf215ab 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -1674,48 +1674,133 @@ void wlr_xdg_popup_v6_get_anchor_point(struct wlr_xdg_popup_v6 *popup, *root_sx = sx; *root_sy = sy; +} - /* - // XXX: THIS IS WILL WORK WITH XDG SHELL STABLE - switch (popup->positioner.anchor) { - case WLR_POSITIONER_ANCHOR_NONE: - sx = (rect.x + rect.width) / 2; - sy = (rect.y + rect.height) / 2; - break; - case WLR_POSITIONER_ANCHOR_TOP: - sx = (rect.x + rect.width) / 2; - sy = rect.y; - break; - case WLR_POSITIONER_ANCHOR_BOTTOM: - sx = (rect.x + rect.width) / 2; - sy = rect.y + rect.height; - break; - case WLR_POSITIONER_ANCHOR_LEFT: - sx = rect.x; - sy = (rect.y + rect.height) / 2; - break; - case WLR_POSITIONER_ANCHOR_RIGHT: - sx = rect.x + rect.width; - sy = (rect.y + rect.height) / 2; - break; - case WLR_POSITIONER_ANCHOR_TOP_LEFT: - sx = rect.x; - sy = rect.y; - break; - case WLR_POSITIONER_ANCHOR_BOTTOM_LEFT: - sx = rect.x; - sy = rect.y + rect.height; - break; - case WLR_POSITIONER_ANCHOR_TOP_RIGHT: - sx = rect.x + rect.width; - sy = rect.y; - break; - case WLR_POSITIONER_ANCHOR_BOTTOM_RIGHT: - sx = rect.x + rect.width; - sy = rect.y + rect.height; - break; +void wlr_xdg_popup_v6_get_toplevel_coords(struct wlr_xdg_popup_v6 *popup, + int popup_sx, int popup_sy, int *toplevel_sx, int *toplevel_sy) { + struct wlr_xdg_surface_v6 *parent = popup->parent; + while (parent->role != WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL) { + popup_sx += parent->popup->geometry.x; + popup_sy += parent->popup->geometry.y; + parent = parent->popup->parent; } - */ + + *toplevel_sx = popup_sx + parent->geometry.x; + *toplevel_sy = popup_sy + parent->geometry.y; + +} + +static void wlr_xdg_popup_v6_box_constraints(struct wlr_xdg_popup_v6 *popup, + struct wlr_box *toplevel_box, int *offset_x, int *offset_y) { + int popup_width = popup->geometry.width; + int popup_height = popup->geometry.height; + int anchor_sx = 0, anchor_sy = 0; + wlr_xdg_popup_v6_get_anchor_point(popup, &anchor_sx, &anchor_sy); + int popup_sx = 0, popup_sy = 0; + wlr_xdg_popup_v6_get_toplevel_coords(popup, popup->geometry.x, + popup->geometry.y, &popup_sx, &popup_sy); + *offset_x = 0, *offset_y = 0; + + if (popup_sx < toplevel_box->x) { + *offset_x = toplevel_box->x - popup_sx; + } else if (popup_sx + popup_width > toplevel_box->x + toplevel_box->width) { + *offset_x = toplevel_box->x + toplevel_box->width - (popup_sx + popup_width); + } + + if (popup_sy < toplevel_box->y) { + *offset_y = toplevel_box->y - popup_sy; + } else if (popup_sy + popup_height > toplevel_box->y + toplevel_box->height) { + *offset_y = toplevel_box->y + toplevel_box->height - (popup_sy + popup_height); + } +} + +static bool wlr_xdg_popup_v6_unconstrain_flip(struct wlr_xdg_popup_v6 *popup, + struct wlr_box *toplevel_box) { + int offset_x = 0, offset_y = 0; + wlr_xdg_popup_v6_box_constraints(popup, toplevel_box, &offset_y, &offset_y); + + if (!offset_x && !offset_y) { + return true; + } + + if (offset_x) { + wlr_positioner_v6_invert_x(&popup->positioner); + } + if (offset_y) { + wlr_positioner_v6_invert_y(&popup->positioner); + } + + popup->geometry = + wlr_xdg_positioner_v6_get_geometry(&popup->positioner); + + wlr_xdg_popup_v6_box_constraints(popup, toplevel_box, &offset_x, &offset_y); + + if (!offset_x && !offset_y) { + // no longer constrained + return true; + } + + // revert the positioner back if it didn't fix it and go to the next part + if (offset_x) { + wlr_positioner_v6_invert_x(&popup->positioner); + } + if (offset_y) { + wlr_positioner_v6_invert_y(&popup->positioner); + } + + popup->geometry = + wlr_xdg_positioner_v6_get_geometry(&popup->positioner); + + return false; +} + +static bool wlr_xdg_popup_v6_unconstrain_slide(struct wlr_xdg_popup_v6 *popup, + struct wlr_box *toplevel_box) { + int offset_x, offset_y; + wlr_xdg_popup_v6_box_constraints(popup, toplevel_box, &offset_x, &offset_y); + + if (!offset_x && !offset_y) { + return true; + } + + if (offset_x) { + popup->geometry.x += offset_x; + } + + if (offset_y) { + popup->geometry.y += offset_y; + } + + wlr_xdg_popup_v6_box_constraints(popup, toplevel_box, &offset_x, &offset_y); + + return !offset_x && !offset_y; +} + +static bool wlr_xdg_popup_v6_unconstrain_resize(struct wlr_xdg_popup_v6 *popup, + struct wlr_box *toplevel_box) { + int offset_x, offset_y; + wlr_xdg_popup_v6_box_constraints(popup, toplevel_box, &offset_x, &offset_y); + + if (!offset_x && !offset_y) { + return true; + } + + if (offset_x) { + popup->geometry.width -= offset_x; + } + if (offset_y) { + popup->geometry.height -= offset_y; + } + + wlr_xdg_popup_v6_box_constraints(popup, toplevel_box, &offset_y, &offset_y); + + return !offset_x && !offset_y; +} + +void wlr_xdg_popup_v6_unconstrain_from_box(struct wlr_xdg_popup_v6 *popup, + struct wlr_box *toplevel_box) { + wlr_xdg_popup_v6_unconstrain_flip(popup, toplevel_box); + wlr_xdg_popup_v6_unconstrain_slide(popup, toplevel_box); } void wlr_positioner_v6_invert_x(struct wlr_xdg_positioner_v6_attributes *positioner) { From 0bfcce50a9e3fe8e06d225c69a686041311ae484 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 28 Mar 2018 16:55:16 -0400 Subject: [PATCH 11/22] xdg-positioner: honor constraint flags --- rootston/xdg_shell_v6.c | 3 +++ types/wlr_xdg_shell_v6.c | 53 +++++++++++++++++++++++++++++++--------- 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 22309e8e..9062995d 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -51,6 +51,9 @@ static void popup_handle_new_popup(struct wl_listener *listener, void *data) { } static void popup_unconstrain(struct roots_xdg_popup_v6 *popup) { + // get the output of the popup's positioner anchor point and convert it to + // the toplevel parent's coordinate system and then pass it to + // wlr_xdg_popup_v6_unconstrain_from_box struct roots_view *view = popup->view_child.view; struct wlr_output_layout *layout = view->desktop->layout; struct wlr_xdg_popup_v6 *wlr_popup = popup->wlr_popup; diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index 0cf215ab..9b700b55 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -1723,28 +1723,34 @@ static bool wlr_xdg_popup_v6_unconstrain_flip(struct wlr_xdg_popup_v6 *popup, return true; } - if (offset_x) { + bool flip_x = offset_x && + (popup->positioner.constraint_adjustment & + WLR_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_FLIP_X); + + bool flip_y = offset_x && + (popup->positioner.constraint_adjustment & + WLR_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_FLIP_Y); + + if (flip_x) { wlr_positioner_v6_invert_x(&popup->positioner); } - if (offset_y) { + if (flip_y) { wlr_positioner_v6_invert_y(&popup->positioner); } popup->geometry = wlr_xdg_positioner_v6_get_geometry(&popup->positioner); - wlr_xdg_popup_v6_box_constraints(popup, toplevel_box, &offset_x, &offset_y); - if (!offset_x && !offset_y) { // no longer constrained return true; } // revert the positioner back if it didn't fix it and go to the next part - if (offset_x) { + if (flip_x) { wlr_positioner_v6_invert_x(&popup->positioner); } - if (offset_y) { + if (flip_y) { wlr_positioner_v6_invert_y(&popup->positioner); } @@ -1763,11 +1769,19 @@ static bool wlr_xdg_popup_v6_unconstrain_slide(struct wlr_xdg_popup_v6 *popup, return true; } - if (offset_x) { + bool slide_x = offset_x && + (popup->positioner.constraint_adjustment & + WLR_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_SLIDE_X); + + bool slide_y = offset_x && + (popup->positioner.constraint_adjustment & + WLR_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_SLIDE_Y); + + if (slide_x) { popup->geometry.x += offset_x; } - if (offset_y) { + if (slide_y) { popup->geometry.y += offset_y; } @@ -1785,10 +1799,18 @@ static bool wlr_xdg_popup_v6_unconstrain_resize(struct wlr_xdg_popup_v6 *popup, return true; } - if (offset_x) { + bool resize_x = offset_x && + (popup->positioner.constraint_adjustment & + WLR_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_RESIZE_X); + + bool resize_y = offset_x && + (popup->positioner.constraint_adjustment & + WLR_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_RESIZE_Y); + + if (resize_x) { popup->geometry.width -= offset_x; } - if (offset_y) { + if (resize_y) { popup->geometry.height -= offset_y; } @@ -1799,8 +1821,15 @@ static bool wlr_xdg_popup_v6_unconstrain_resize(struct wlr_xdg_popup_v6 *popup, void wlr_xdg_popup_v6_unconstrain_from_box(struct wlr_xdg_popup_v6 *popup, struct wlr_box *toplevel_box) { - wlr_xdg_popup_v6_unconstrain_flip(popup, toplevel_box); - wlr_xdg_popup_v6_unconstrain_slide(popup, toplevel_box); + if (wlr_xdg_popup_v6_unconstrain_flip(popup, toplevel_box)) { + return; + } + if (wlr_xdg_popup_v6_unconstrain_slide(popup, toplevel_box)) { + return; + } + if (wlr_xdg_popup_v6_unconstrain_resize(popup, toplevel_box)) { + return; + } } void wlr_positioner_v6_invert_x(struct wlr_xdg_positioner_v6_attributes *positioner) { From 4ab88a533098ee22d2bcd037e07d0c3ede9464fd Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 28 Mar 2018 17:04:55 -0400 Subject: [PATCH 12/22] xdg-positioner bugfix --- types/wlr_xdg_shell_v6.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index 9b700b55..4b2cfc23 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -1717,7 +1717,7 @@ static void wlr_xdg_popup_v6_box_constraints(struct wlr_xdg_popup_v6 *popup, static bool wlr_xdg_popup_v6_unconstrain_flip(struct wlr_xdg_popup_v6 *popup, struct wlr_box *toplevel_box) { int offset_x = 0, offset_y = 0; - wlr_xdg_popup_v6_box_constraints(popup, toplevel_box, &offset_y, &offset_y); + wlr_xdg_popup_v6_box_constraints(popup, toplevel_box, &offset_x, &offset_y); if (!offset_x && !offset_y) { return true; @@ -1727,7 +1727,7 @@ static bool wlr_xdg_popup_v6_unconstrain_flip(struct wlr_xdg_popup_v6 *popup, (popup->positioner.constraint_adjustment & WLR_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_FLIP_X); - bool flip_y = offset_x && + bool flip_y = offset_y && (popup->positioner.constraint_adjustment & WLR_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_FLIP_Y); @@ -1741,6 +1741,8 @@ static bool wlr_xdg_popup_v6_unconstrain_flip(struct wlr_xdg_popup_v6 *popup, popup->geometry = wlr_xdg_positioner_v6_get_geometry(&popup->positioner); + wlr_xdg_popup_v6_box_constraints(popup, toplevel_box, &offset_x, &offset_y); + if (!offset_x && !offset_y) { // no longer constrained return true; From 376d1cc0da0a7cd2bbcb6fcb500caaddd9561a50 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 28 Mar 2018 18:30:38 -0400 Subject: [PATCH 13/22] rename xdg-positioner structs --- include/wlr/types/wlr_xdg_shell_v6.h | 10 +++---- types/wlr_xdg_shell_v6.c | 40 +++++++++++++++------------- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/include/wlr/types/wlr_xdg_shell_v6.h b/include/wlr/types/wlr_xdg_shell_v6.h index 0ab57108..72d1850e 100644 --- a/include/wlr/types/wlr_xdg_shell_v6.h +++ b/include/wlr/types/wlr_xdg_shell_v6.h @@ -88,7 +88,7 @@ enum wlr_positioner_v6_constraint_adjustment { WLR_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_RESIZE_Y = 32, }; -struct wlr_xdg_positioner_v6_attributes { +struct wlr_xdg_positioner_v6 { struct wlr_box anchor_rect; enum wlr_positioner_v6_anchor anchor; enum wlr_positioner_v6_gravity gravity; @@ -116,7 +116,7 @@ struct wlr_xdg_popup_v6 { // geometry of the parent surface struct wlr_box geometry; - struct wlr_xdg_positioner_v6_attributes positioner; + struct wlr_xdg_positioner_v6 positioner; struct wl_list grab_link; // wlr_xdg_popup_grab_v6::popups }; @@ -307,7 +307,7 @@ struct wlr_xdg_surface_v6 *wlr_xdg_surface_v6_popup_at( * size of this positioner. */ struct wlr_box wlr_xdg_positioner_v6_get_geometry( - struct wlr_xdg_positioner_v6_attributes *positioner); + struct wlr_xdg_positioner_v6 *positioner); /** * Get the anchor point for this popup in the toplevel parent's coordinate system. @@ -335,13 +335,13 @@ void wlr_xdg_popup_v6_unconstrain_from_box(struct wlr_xdg_popup_v6 *popup, used to "flip" the positioner around the anchor rect in the x direction. */ void wlr_positioner_v6_invert_x( - struct wlr_xdg_positioner_v6_attributes *positioner); + struct wlr_xdg_positioner_v6 *positioner); /** Invert the top/bottom anchor and gravity for this positioner. This can be used to "flip" the positioner around the anchor rect in the y direction. */ void wlr_positioner_v6_invert_y( - struct wlr_xdg_positioner_v6_attributes *positioner); + struct wlr_xdg_positioner_v6 *positioner); #endif diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index 4b2cfc23..a78546ae 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -16,9 +16,9 @@ static const char *wlr_desktop_xdg_toplevel_role = "xdg_toplevel_v6"; static const char *wlr_desktop_xdg_popup_role = "xdg_popup_v6"; -struct wlr_xdg_positioner_v6 { +struct wlr_xdg_positioner_v6_resource { struct wl_resource *resource; - struct wlr_xdg_positioner_v6_attributes *attrs; + struct wlr_xdg_positioner_v6 *attrs; }; static void resource_handle_destroy(struct wl_client *client, @@ -287,7 +287,7 @@ static void xdg_surface_destroy(struct wlr_xdg_surface_v6 *surface) { static const struct zxdg_positioner_v6_interface zxdg_positioner_v6_implementation; -static struct wlr_xdg_positioner_v6 *xdg_positioner_from_resource( +static struct wlr_xdg_positioner_v6_resource *xdg_positioner_from_resource( struct wl_resource *resource) { assert(wl_resource_instance_of(resource, &zxdg_positioner_v6_interface, &zxdg_positioner_v6_implementation)); @@ -295,7 +295,7 @@ static struct wlr_xdg_positioner_v6 *xdg_positioner_from_resource( } static void xdg_positioner_destroy(struct wl_resource *resource) { - struct wlr_xdg_positioner_v6 *positioner = + struct wlr_xdg_positioner_v6_resource *positioner = xdg_positioner_from_resource(resource); free(positioner->attrs); free(positioner); @@ -303,7 +303,7 @@ static void xdg_positioner_destroy(struct wl_resource *resource) { static void xdg_positioner_handle_set_size(struct wl_client *client, struct wl_resource *resource, int32_t width, int32_t height) { - struct wlr_xdg_positioner_v6 *positioner = + struct wlr_xdg_positioner_v6_resource *positioner = xdg_positioner_from_resource(resource); if (width < 1 || height < 1) { @@ -320,7 +320,7 @@ static void xdg_positioner_handle_set_size(struct wl_client *client, static void xdg_positioner_handle_set_anchor_rect(struct wl_client *client, struct wl_resource *resource, int32_t x, int32_t y, int32_t width, int32_t height) { - struct wlr_xdg_positioner_v6 *positioner = + struct wlr_xdg_positioner_v6_resource *positioner = xdg_positioner_from_resource(resource); if (width < 1 || height < 1) { @@ -338,7 +338,7 @@ static void xdg_positioner_handle_set_anchor_rect(struct wl_client *client, static void xdg_positioner_handle_set_anchor(struct wl_client *client, struct wl_resource *resource, uint32_t anchor) { - struct wlr_xdg_positioner_v6 *positioner = + struct wlr_xdg_positioner_v6_resource *positioner = xdg_positioner_from_resource(resource); if (((anchor & ZXDG_POSITIONER_V6_ANCHOR_TOP ) && @@ -356,7 +356,7 @@ static void xdg_positioner_handle_set_anchor(struct wl_client *client, static void xdg_positioner_handle_set_gravity(struct wl_client *client, struct wl_resource *resource, uint32_t gravity) { - struct wlr_xdg_positioner_v6 *positioner = + struct wlr_xdg_positioner_v6_resource *positioner = xdg_positioner_from_resource(resource); if (((gravity & ZXDG_POSITIONER_V6_GRAVITY_TOP) && @@ -375,7 +375,7 @@ static void xdg_positioner_handle_set_gravity(struct wl_client *client, static void xdg_positioner_handle_set_constraint_adjustment( struct wl_client *client, struct wl_resource *resource, uint32_t constraint_adjustment) { - struct wlr_xdg_positioner_v6 *positioner = + struct wlr_xdg_positioner_v6_resource *positioner = xdg_positioner_from_resource(resource); positioner->attrs->constraint_adjustment = constraint_adjustment; @@ -383,7 +383,7 @@ static void xdg_positioner_handle_set_constraint_adjustment( static void xdg_positioner_handle_set_offset(struct wl_client *client, struct wl_resource *resource, int32_t x, int32_t y) { - struct wlr_xdg_positioner_v6 *positioner = + struct wlr_xdg_positioner_v6_resource *positioner = xdg_positioner_from_resource(resource); positioner->attrs->offset.x = x; @@ -404,8 +404,8 @@ static const struct zxdg_positioner_v6_interface static void xdg_shell_handle_create_positioner(struct wl_client *wl_client, struct wl_resource *resource, uint32_t id) { - struct wlr_xdg_positioner_v6 *positioner = - calloc(1, sizeof(struct wlr_xdg_positioner_v6)); + struct wlr_xdg_positioner_v6_resource *positioner = + calloc(1, sizeof(struct wlr_xdg_positioner_v6_resource)); if (positioner == NULL) { wl_client_post_no_memory(wl_client); return; @@ -413,7 +413,7 @@ static void xdg_shell_handle_create_positioner(struct wl_client *wl_client, // TODO: allocate the positioner attrs? positioner->attrs = - calloc(1, sizeof(struct wlr_xdg_positioner_v6_attributes)); + calloc(1, sizeof(struct wlr_xdg_positioner_v6)); positioner->resource = wl_resource_create(wl_client, &zxdg_positioner_v6_interface, @@ -430,7 +430,7 @@ static void xdg_shell_handle_create_positioner(struct wl_client *wl_client, positioner, xdg_positioner_destroy); } -struct wlr_box wlr_xdg_positioner_v6_get_geometry(struct wlr_xdg_positioner_v6_attributes *positioner) { +struct wlr_box wlr_xdg_positioner_v6_get_geometry(struct wlr_xdg_positioner_v6 *positioner) { struct wlr_box geometry = { .x = positioner->offset.x, .y = positioner->offset.y, @@ -584,7 +584,7 @@ static void xdg_surface_handle_get_popup(struct wl_client *client, xdg_surface_from_resource(resource); struct wlr_xdg_surface_v6 *parent = xdg_surface_from_resource(parent_resource); - struct wlr_xdg_positioner_v6 *positioner = + struct wlr_xdg_positioner_v6_resource *positioner = xdg_positioner_from_resource(positioner_resource); if (positioner->attrs->size.width == 0 || positioner->attrs->anchor_rect.width == 0) { @@ -622,7 +622,7 @@ static void xdg_surface_handle_get_popup(struct wl_client *client, // positioner properties memcpy(&surface->popup->positioner, positioner->attrs, - sizeof(struct wlr_xdg_positioner_v6_attributes)); + sizeof(struct wlr_xdg_positioner_v6)); wl_list_insert(&parent->popups, &surface->popup->link); @@ -1679,12 +1679,14 @@ void wlr_xdg_popup_v6_get_anchor_point(struct wlr_xdg_popup_v6 *popup, void wlr_xdg_popup_v6_get_toplevel_coords(struct wlr_xdg_popup_v6 *popup, int popup_sx, int popup_sy, int *toplevel_sx, int *toplevel_sy) { struct wlr_xdg_surface_v6 *parent = popup->parent; - while (parent->role != WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL) { + while (parent && parent->role != WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL) { popup_sx += parent->popup->geometry.x; popup_sy += parent->popup->geometry.y; parent = parent->popup->parent; } + assert(parent); + *toplevel_sx = popup_sx + parent->geometry.x; *toplevel_sy = popup_sy + parent->geometry.y; @@ -1834,7 +1836,7 @@ void wlr_xdg_popup_v6_unconstrain_from_box(struct wlr_xdg_popup_v6 *popup, } } -void wlr_positioner_v6_invert_x(struct wlr_xdg_positioner_v6_attributes *positioner) { +void wlr_positioner_v6_invert_x(struct wlr_xdg_positioner_v6 *positioner) { if (positioner->anchor & WLR_POSITIONER_V6_ANCHOR_LEFT) { positioner->anchor &= ~WLR_POSITIONER_V6_ANCHOR_LEFT; positioner->anchor |= WLR_POSITIONER_V6_ANCHOR_RIGHT; @@ -1853,7 +1855,7 @@ void wlr_positioner_v6_invert_x(struct wlr_xdg_positioner_v6_attributes *positio } void wlr_positioner_v6_invert_y( - struct wlr_xdg_positioner_v6_attributes *positioner) { + struct wlr_xdg_positioner_v6 *positioner) { if (positioner->anchor & WLR_POSITIONER_V6_ANCHOR_TOP) { positioner->anchor &= ~WLR_POSITIONER_V6_ANCHOR_TOP; positioner->anchor |= WLR_POSITIONER_V6_ANCHOR_BOTTOM; From bd828e23de77789a05ca6972ed3c41402732d19c Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 28 Mar 2018 18:33:21 -0400 Subject: [PATCH 14/22] dont allocate xdg-positioner attrs --- types/wlr_xdg_shell_v6.c | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index a78546ae..aaacbf29 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -18,7 +18,7 @@ static const char *wlr_desktop_xdg_popup_role = "xdg_popup_v6"; struct wlr_xdg_positioner_v6_resource { struct wl_resource *resource; - struct wlr_xdg_positioner_v6 *attrs; + struct wlr_xdg_positioner_v6 attrs; }; static void resource_handle_destroy(struct wl_client *client, @@ -297,7 +297,6 @@ static struct wlr_xdg_positioner_v6_resource *xdg_positioner_from_resource( static void xdg_positioner_destroy(struct wl_resource *resource) { struct wlr_xdg_positioner_v6_resource *positioner = xdg_positioner_from_resource(resource); - free(positioner->attrs); free(positioner); } @@ -313,8 +312,8 @@ static void xdg_positioner_handle_set_size(struct wl_client *client, return; } - positioner->attrs->size.width = width; - positioner->attrs->size.height = height; + positioner->attrs.size.width = width; + positioner->attrs.size.height = height; } static void xdg_positioner_handle_set_anchor_rect(struct wl_client *client, @@ -330,10 +329,10 @@ static void xdg_positioner_handle_set_anchor_rect(struct wl_client *client, return; } - positioner->attrs->anchor_rect.x = x; - positioner->attrs->anchor_rect.y = y; - positioner->attrs->anchor_rect.width = width; - positioner->attrs->anchor_rect.height = height; + positioner->attrs.anchor_rect.x = x; + positioner->attrs.anchor_rect.y = y; + positioner->attrs.anchor_rect.width = width; + positioner->attrs.anchor_rect.height = height; } static void xdg_positioner_handle_set_anchor(struct wl_client *client, @@ -351,7 +350,7 @@ static void xdg_positioner_handle_set_anchor(struct wl_client *client, return; } - positioner->attrs->anchor = anchor; + positioner->attrs.anchor = anchor; } static void xdg_positioner_handle_set_gravity(struct wl_client *client, @@ -369,7 +368,7 @@ static void xdg_positioner_handle_set_gravity(struct wl_client *client, return; } - positioner->attrs->gravity = gravity; + positioner->attrs.gravity = gravity; } static void xdg_positioner_handle_set_constraint_adjustment( @@ -378,7 +377,7 @@ static void xdg_positioner_handle_set_constraint_adjustment( struct wlr_xdg_positioner_v6_resource *positioner = xdg_positioner_from_resource(resource); - positioner->attrs->constraint_adjustment = constraint_adjustment; + positioner->attrs.constraint_adjustment = constraint_adjustment; } static void xdg_positioner_handle_set_offset(struct wl_client *client, @@ -386,8 +385,8 @@ static void xdg_positioner_handle_set_offset(struct wl_client *client, struct wlr_xdg_positioner_v6_resource *positioner = xdg_positioner_from_resource(resource); - positioner->attrs->offset.x = x; - positioner->attrs->offset.y = y; + positioner->attrs.offset.x = x; + positioner->attrs.offset.y = y; } static const struct zxdg_positioner_v6_interface @@ -411,10 +410,6 @@ static void xdg_shell_handle_create_positioner(struct wl_client *wl_client, return; } - // TODO: allocate the positioner attrs? - positioner->attrs = - calloc(1, sizeof(struct wlr_xdg_positioner_v6)); - positioner->resource = wl_resource_create(wl_client, &zxdg_positioner_v6_interface, wl_resource_get_version(resource), @@ -587,7 +582,7 @@ static void xdg_surface_handle_get_popup(struct wl_client *client, struct wlr_xdg_positioner_v6_resource *positioner = xdg_positioner_from_resource(positioner_resource); - if (positioner->attrs->size.width == 0 || positioner->attrs->anchor_rect.width == 0) { + if (positioner->attrs.size.width == 0 || positioner->attrs.anchor_rect.width == 0) { wl_resource_post_error(resource, ZXDG_SHELL_V6_ERROR_INVALID_POSITIONER, "positioner object is not complete"); @@ -618,10 +613,10 @@ static void xdg_surface_handle_get_popup(struct wl_client *client, surface->popup->base = surface; surface->popup->parent = parent; surface->popup->geometry = - wlr_xdg_positioner_v6_get_geometry(positioner->attrs); + wlr_xdg_positioner_v6_get_geometry(&positioner->attrs); // positioner properties - memcpy(&surface->popup->positioner, positioner->attrs, + memcpy(&surface->popup->positioner, &positioner->attrs, sizeof(struct wlr_xdg_positioner_v6)); wl_list_insert(&parent->popups, &surface->popup->link); From 67c8aec77f27aa08528a69894a045a48d67bd658 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 28 Mar 2018 18:36:48 -0400 Subject: [PATCH 15/22] popup constraint handle empty output layout --- rootston/xdg_shell_v6.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 9062995d..fe63e697 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -76,8 +76,10 @@ static void popup_unconstrain(struct roots_xdg_popup_v6 *popup) { struct wlr_output *output = wlr_output_layout_output_at(layout, dest_x, dest_y); - // XXX: handle empty output layout - assert(output); + + if (output == NULL) { + return; + } int width = 0, height = 0; wlr_output_effective_resolution(output, &width, &height); From bf5ae85683963a03b9291dd7ab184ab97abc0fd4 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 28 Mar 2018 18:40:55 -0400 Subject: [PATCH 16/22] return early when no dest_x/y in output layout closest point --- types/wlr_output_layout.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/types/wlr_output_layout.c b/types/wlr_output_layout.c index 8d328c17..fdeef387 100644 --- a/types/wlr_output_layout.c +++ b/types/wlr_output_layout.c @@ -313,6 +313,10 @@ void wlr_output_layout_output_coords(struct wlr_output_layout *layout, void wlr_output_layout_closest_point(struct wlr_output_layout *layout, struct wlr_output *reference, double x, double y, double *dest_x, double *dest_y) { + if (dest_x == NULL && dest_y == NULL) { + return; + } + double min_x = DBL_MAX, min_y = DBL_MAX, min_distance = DBL_MAX; struct wlr_output_layout_output *l_output; wl_list_for_each(l_output, &layout->outputs, link) { From 8b967fc573b2a4d53c59a4cace75434c4b6c94db Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 28 Mar 2018 19:00:49 -0400 Subject: [PATCH 17/22] bug: dont slide over too far --- types/wlr_xdg_shell_v6.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index aaacbf29..85ced7bd 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -1761,7 +1761,7 @@ static bool wlr_xdg_popup_v6_unconstrain_flip(struct wlr_xdg_popup_v6 *popup, static bool wlr_xdg_popup_v6_unconstrain_slide(struct wlr_xdg_popup_v6 *popup, struct wlr_box *toplevel_box) { - int offset_x, offset_y; + int offset_x = 0, offset_y = 0; wlr_xdg_popup_v6_box_constraints(popup, toplevel_box, &offset_x, &offset_y); if (!offset_x && !offset_y) { @@ -1784,6 +1784,17 @@ static bool wlr_xdg_popup_v6_unconstrain_slide(struct wlr_xdg_popup_v6 *popup, popup->geometry.y += offset_y; } + int toplevel_x = 0, toplevel_y = 0; + wlr_xdg_popup_v6_get_toplevel_coords(popup, popup->geometry.x, + popup->geometry.y, &toplevel_x, &toplevel_y); + + if (slide_x && toplevel_x < toplevel_box->x) { + popup->geometry.x += toplevel_box->x - toplevel_x; + } + if (slide_y && toplevel_y < toplevel_box->y) { + popup->geometry.y += toplevel_box->y - toplevel_y; + } + wlr_xdg_popup_v6_box_constraints(popup, toplevel_box, &offset_x, &offset_y); return !offset_x && !offset_y; From 967bccffcd634a6ba2d13185c530f64b4d1eb613 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 28 Mar 2018 19:42:17 -0400 Subject: [PATCH 18/22] remove xdg-positioner wlr wrappers --- include/wlr/types/wlr_xdg_shell_v6.h | 63 ++----------------- types/wlr_xdg_shell_v6.c | 90 ++++++++++++++-------------- 2 files changed, 49 insertions(+), 104 deletions(-) diff --git a/include/wlr/types/wlr_xdg_shell_v6.h b/include/wlr/types/wlr_xdg_shell_v6.h index 72d1850e..04c7e450 100644 --- a/include/wlr/types/wlr_xdg_shell_v6.h +++ b/include/wlr/types/wlr_xdg_shell_v6.h @@ -4,6 +4,7 @@ #include #include #include +#include "xdg-shell-unstable-v6-protocol.h" struct wlr_xdg_shell_v6 { struct wl_global *wl_global; @@ -32,67 +33,11 @@ struct wlr_xdg_client_v6 { struct wl_event_source *ping_timer; }; -enum wlr_positioner_v6_anchor { - /** - * the center of the anchor rectangle - */ - WLR_POSITIONER_V6_ANCHOR_NONE = 0, - /** - * the top edge of the anchor rectangle - */ - WLR_POSITIONER_V6_ANCHOR_TOP = 1, - /** - * the bottom edge of the anchor rectangle - */ - WLR_POSITIONER_V6_ANCHOR_BOTTOM = 2, - /** - * the left edge of the anchor rectangle - */ - WLR_POSITIONER_V6_ANCHOR_LEFT = 4, - /** - * the right edge of the anchor rectangle - */ - WLR_POSITIONER_V6_ANCHOR_RIGHT = 8, -}; - -enum wlr_positioner_v6_gravity { - /** - * center over the anchor edge - */ - WLR_POSITIONER_V6_GRAVITY_NONE = 0, - /** - * position above the anchor edge - */ - WLR_POSITIONER_V6_GRAVITY_TOP = 1, - /** - * position below the anchor edge - */ - WLR_POSITIONER_V6_GRAVITY_BOTTOM = 2, - /** - * position to the left of the anchor edge - */ - WLR_POSITIONER_V6_GRAVITY_LEFT = 4, - /** - * position to the right of the anchor edge - */ - WLR_POSITIONER_V6_GRAVITY_RIGHT = 8, -}; - -enum wlr_positioner_v6_constraint_adjustment { - WLR_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_NONE = 0, - WLR_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_SLIDE_X = 1, - WLR_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_SLIDE_Y = 2, - WLR_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_FLIP_X = 4, - WLR_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_FLIP_Y = 8, - WLR_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_RESIZE_X = 16, - WLR_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_RESIZE_Y = 32, -}; - struct wlr_xdg_positioner_v6 { struct wlr_box anchor_rect; - enum wlr_positioner_v6_anchor anchor; - enum wlr_positioner_v6_gravity gravity; - enum wlr_positioner_v6_constraint_adjustment constraint_adjustment; + enum zxdg_positioner_v6_anchor anchor; + enum zxdg_positioner_v6_gravity gravity; + enum zxdg_positioner_v6_constraint_adjustment constraint_adjustment; struct { int32_t width, height; diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index 85ced7bd..2a780a37 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -469,7 +469,7 @@ struct wlr_box wlr_xdg_positioner_v6_get_geometry(struct wlr_xdg_positioner_v6 * } if (positioner->constraint_adjustment == - WLR_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_NONE) { + ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_NONE) { return geometry; } @@ -1631,38 +1631,38 @@ struct wlr_xdg_surface_v6 *wlr_xdg_surface_v6_popup_at( void wlr_xdg_popup_v6_get_anchor_point(struct wlr_xdg_popup_v6 *popup, int *root_sx, int *root_sy) { struct wlr_box rect = popup->positioner.anchor_rect; - enum wlr_positioner_v6_anchor anchor = popup->positioner.anchor; + enum zxdg_positioner_v6_anchor anchor = popup->positioner.anchor; int sx = 0, sy = 0; - if (anchor == WLR_POSITIONER_V6_ANCHOR_NONE) { + if (anchor == ZXDG_POSITIONER_V6_ANCHOR_NONE) { sx = (rect.x + rect.width) / 2; sy = (rect.y + rect.height) / 2; - } else if (anchor == WLR_POSITIONER_V6_ANCHOR_TOP) { + } else if (anchor == ZXDG_POSITIONER_V6_ANCHOR_TOP) { sx = (rect.x + rect.width) / 2; sy = rect.y; - } else if (anchor == WLR_POSITIONER_V6_ANCHOR_BOTTOM) { + } else if (anchor == ZXDG_POSITIONER_V6_ANCHOR_BOTTOM) { sx = (rect.x + rect.width) / 2; sy = rect.y + rect.height; - } else if (anchor == WLR_POSITIONER_V6_ANCHOR_LEFT) { + } else if (anchor == ZXDG_POSITIONER_V6_ANCHOR_LEFT) { sx = rect.x; sy = (rect.y + rect.height) / 2; - } else if (anchor == WLR_POSITIONER_V6_ANCHOR_RIGHT) { + } else if (anchor == ZXDG_POSITIONER_V6_ANCHOR_RIGHT) { sx = rect.x + rect.width; sy = (rect.y + rect.height) / 2; - } else if (anchor == (WLR_POSITIONER_V6_ANCHOR_TOP | - WLR_POSITIONER_V6_ANCHOR_LEFT)) { + } else if (anchor == (ZXDG_POSITIONER_V6_ANCHOR_TOP | + ZXDG_POSITIONER_V6_ANCHOR_LEFT)) { sx = rect.x; sy = rect.y; - } else if (anchor == (WLR_POSITIONER_V6_ANCHOR_TOP | - WLR_POSITIONER_V6_ANCHOR_RIGHT)) { + } else if (anchor == (ZXDG_POSITIONER_V6_ANCHOR_TOP | + ZXDG_POSITIONER_V6_ANCHOR_RIGHT)) { sx = rect.x + rect.width; sy = rect.y; - } else if (anchor == (WLR_POSITIONER_V6_ANCHOR_BOTTOM | - WLR_POSITIONER_V6_ANCHOR_LEFT)) { + } else if (anchor == (ZXDG_POSITIONER_V6_ANCHOR_BOTTOM | + ZXDG_POSITIONER_V6_ANCHOR_LEFT)) { sx = rect.x; sy = rect.y + rect.height; - } else if (anchor == (WLR_POSITIONER_V6_ANCHOR_BOTTOM | - WLR_POSITIONER_V6_ANCHOR_RIGHT)) { + } else if (anchor == (ZXDG_POSITIONER_V6_ANCHOR_BOTTOM | + ZXDG_POSITIONER_V6_ANCHOR_RIGHT)) { sx = rect.x + rect.width; sy = rect.y + rect.height; } @@ -1722,11 +1722,11 @@ static bool wlr_xdg_popup_v6_unconstrain_flip(struct wlr_xdg_popup_v6 *popup, bool flip_x = offset_x && (popup->positioner.constraint_adjustment & - WLR_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_FLIP_X); + ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_FLIP_X); bool flip_y = offset_y && (popup->positioner.constraint_adjustment & - WLR_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_FLIP_Y); + ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_FLIP_Y); if (flip_x) { wlr_positioner_v6_invert_x(&popup->positioner); @@ -1770,11 +1770,11 @@ static bool wlr_xdg_popup_v6_unconstrain_slide(struct wlr_xdg_popup_v6 *popup, bool slide_x = offset_x && (popup->positioner.constraint_adjustment & - WLR_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_SLIDE_X); + ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_SLIDE_X); bool slide_y = offset_x && (popup->positioner.constraint_adjustment & - WLR_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_SLIDE_Y); + ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_SLIDE_Y); if (slide_x) { popup->geometry.x += offset_x; @@ -1811,11 +1811,11 @@ static bool wlr_xdg_popup_v6_unconstrain_resize(struct wlr_xdg_popup_v6 *popup, bool resize_x = offset_x && (popup->positioner.constraint_adjustment & - WLR_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_RESIZE_X); + ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_RESIZE_X); bool resize_y = offset_x && (popup->positioner.constraint_adjustment & - WLR_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_RESIZE_Y); + ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_RESIZE_Y); if (resize_x) { popup->geometry.width -= offset_x; @@ -1843,38 +1843,38 @@ void wlr_xdg_popup_v6_unconstrain_from_box(struct wlr_xdg_popup_v6 *popup, } void wlr_positioner_v6_invert_x(struct wlr_xdg_positioner_v6 *positioner) { - if (positioner->anchor & WLR_POSITIONER_V6_ANCHOR_LEFT) { - positioner->anchor &= ~WLR_POSITIONER_V6_ANCHOR_LEFT; - positioner->anchor |= WLR_POSITIONER_V6_ANCHOR_RIGHT; - } else if (positioner->anchor & WLR_POSITIONER_V6_ANCHOR_RIGHT) { - positioner->anchor &= ~WLR_POSITIONER_V6_ANCHOR_RIGHT; - positioner->anchor |= WLR_POSITIONER_V6_ANCHOR_LEFT; + if (positioner->anchor & ZXDG_POSITIONER_V6_ANCHOR_LEFT) { + positioner->anchor &= ~ZXDG_POSITIONER_V6_ANCHOR_LEFT; + positioner->anchor |= ZXDG_POSITIONER_V6_ANCHOR_RIGHT; + } else if (positioner->anchor & ZXDG_POSITIONER_V6_ANCHOR_RIGHT) { + positioner->anchor &= ~ZXDG_POSITIONER_V6_ANCHOR_RIGHT; + positioner->anchor |= ZXDG_POSITIONER_V6_ANCHOR_LEFT; } - if (positioner->gravity & WLR_POSITIONER_V6_GRAVITY_RIGHT) { - positioner->gravity &= ~WLR_POSITIONER_V6_GRAVITY_RIGHT; - positioner->gravity |= WLR_POSITIONER_V6_GRAVITY_LEFT; - } else if (positioner->gravity & WLR_POSITIONER_V6_GRAVITY_LEFT) { - positioner->gravity &= ~WLR_POSITIONER_V6_GRAVITY_LEFT; - positioner->gravity |= WLR_POSITIONER_V6_GRAVITY_RIGHT; + if (positioner->gravity & ZXDG_POSITIONER_V6_GRAVITY_RIGHT) { + positioner->gravity &= ~ZXDG_POSITIONER_V6_GRAVITY_RIGHT; + positioner->gravity |= ZXDG_POSITIONER_V6_GRAVITY_LEFT; + } else if (positioner->gravity & ZXDG_POSITIONER_V6_GRAVITY_LEFT) { + positioner->gravity &= ~ZXDG_POSITIONER_V6_GRAVITY_LEFT; + positioner->gravity |= ZXDG_POSITIONER_V6_GRAVITY_RIGHT; } } void wlr_positioner_v6_invert_y( struct wlr_xdg_positioner_v6 *positioner) { - if (positioner->anchor & WLR_POSITIONER_V6_ANCHOR_TOP) { - positioner->anchor &= ~WLR_POSITIONER_V6_ANCHOR_TOP; - positioner->anchor |= WLR_POSITIONER_V6_ANCHOR_BOTTOM; - } else if (positioner->anchor & WLR_POSITIONER_V6_ANCHOR_BOTTOM) { - positioner->anchor &= ~WLR_POSITIONER_V6_ANCHOR_BOTTOM; - positioner->anchor |= WLR_POSITIONER_V6_ANCHOR_TOP; + if (positioner->anchor & ZXDG_POSITIONER_V6_ANCHOR_TOP) { + positioner->anchor &= ~ZXDG_POSITIONER_V6_ANCHOR_TOP; + positioner->anchor |= ZXDG_POSITIONER_V6_ANCHOR_BOTTOM; + } else if (positioner->anchor & ZXDG_POSITIONER_V6_ANCHOR_BOTTOM) { + positioner->anchor &= ~ZXDG_POSITIONER_V6_ANCHOR_BOTTOM; + positioner->anchor |= ZXDG_POSITIONER_V6_ANCHOR_TOP; } - if (positioner->gravity & WLR_POSITIONER_V6_GRAVITY_TOP) { - positioner->gravity &= ~WLR_POSITIONER_V6_GRAVITY_TOP; - positioner->gravity |= WLR_POSITIONER_V6_GRAVITY_BOTTOM; - } else if (positioner->gravity & WLR_POSITIONER_V6_GRAVITY_BOTTOM) { - positioner->gravity &= ~WLR_POSITIONER_V6_GRAVITY_BOTTOM; - positioner->gravity |= WLR_POSITIONER_V6_GRAVITY_TOP; + if (positioner->gravity & ZXDG_POSITIONER_V6_GRAVITY_TOP) { + positioner->gravity &= ~ZXDG_POSITIONER_V6_GRAVITY_TOP; + positioner->gravity |= ZXDG_POSITIONER_V6_GRAVITY_BOTTOM; + } else if (positioner->gravity & ZXDG_POSITIONER_V6_GRAVITY_BOTTOM) { + positioner->gravity &= ~ZXDG_POSITIONER_V6_GRAVITY_BOTTOM; + positioner->gravity |= ZXDG_POSITIONER_V6_GRAVITY_TOP; } } From cf13a6d9c6f4f9a2d97284236131e4b713aa02c8 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 28 Mar 2018 20:09:20 -0400 Subject: [PATCH 19/22] address toplevel coords issue --- types/wlr_xdg_shell_v6.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index 2a780a37..44bd8d9a 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -1674,7 +1674,7 @@ void wlr_xdg_popup_v6_get_anchor_point(struct wlr_xdg_popup_v6 *popup, void wlr_xdg_popup_v6_get_toplevel_coords(struct wlr_xdg_popup_v6 *popup, int popup_sx, int popup_sy, int *toplevel_sx, int *toplevel_sy) { struct wlr_xdg_surface_v6 *parent = popup->parent; - while (parent && parent->role != WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL) { + while (parent != NULL && parent->role == WLR_XDG_SURFACE_V6_ROLE_POPUP) { popup_sx += parent->popup->geometry.x; popup_sy += parent->popup->geometry.y; parent = parent->popup->parent; From 71da20dbdefd137d53bbbdb7bfd6f242c1698548 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 28 Mar 2018 20:51:25 -0400 Subject: [PATCH 20/22] add comment for output box in toplevel coords --- rootston/xdg_shell_v6.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index fe63e697..295d9ff4 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -84,14 +84,16 @@ static void popup_unconstrain(struct roots_xdg_popup_v6 *popup) { int width = 0, height = 0; wlr_output_effective_resolution(output, &width, &height); - struct wlr_box toplevel_box = { + // the output box expressed in the coordinate system of the toplevel parent + // of the popup + struct wlr_box output_box_toplevel = { .x = output->lx - view->x, .y = output->ly - view->y, .width = width, .height = height }; - wlr_xdg_popup_v6_unconstrain_from_box(popup->wlr_popup, &toplevel_box); + wlr_xdg_popup_v6_unconstrain_from_box(popup->wlr_popup, &output_box_toplevel); } static struct roots_xdg_popup_v6 *popup_create(struct roots_view *view, From 27f450ac0eb254dad03c11b14d4785c16dac0c51 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 28 Mar 2018 22:26:56 -0400 Subject: [PATCH 21/22] add todo for rotated unconstrained popup --- rootston/xdg_shell_v6.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 295d9ff4..0aca9638 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -54,6 +54,12 @@ static void popup_unconstrain(struct roots_xdg_popup_v6 *popup) { // get the output of the popup's positioner anchor point and convert it to // the toplevel parent's coordinate system and then pass it to // wlr_xdg_popup_v6_unconstrain_from_box + + // TODO: unconstrain popups for rotated windows + if (popup->view_child.view->rotation != 0.0) { + return; + } + struct roots_view *view = popup->view_child.view; struct wlr_output_layout *layout = view->desktop->layout; struct wlr_xdg_popup_v6 *wlr_popup = popup->wlr_popup; From 2e63d1a0ca01d71de58988593860741b835ba8bb Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 28 Mar 2018 23:24:39 -0400 Subject: [PATCH 22/22] toplevel_box to toplevel_sx_box --- include/wlr/types/wlr_xdg_shell_v6.h | 6 +- rootston/xdg_shell_v6.c | 4 +- types/wlr_xdg_shell_v6.c | 84 +++++++++++++++++----------- 3 files changed, 55 insertions(+), 39 deletions(-) diff --git a/include/wlr/types/wlr_xdg_shell_v6.h b/include/wlr/types/wlr_xdg_shell_v6.h index 04c7e450..d01240eb 100644 --- a/include/wlr/types/wlr_xdg_shell_v6.h +++ b/include/wlr/types/wlr_xdg_shell_v6.h @@ -269,11 +269,11 @@ void wlr_xdg_popup_v6_get_toplevel_coords(struct wlr_xdg_popup_v6 *popup, /** * Set the geometry of this popup to unconstrain it according to its - * xdg-positioner rules. The box should be in the popup's toplevel - * parent surface coordinate system. + * xdg-positioner rules. The box should be in the popup's root toplevel parent + * surface coordinate system. */ void wlr_xdg_popup_v6_unconstrain_from_box(struct wlr_xdg_popup_v6 *popup, - struct wlr_box *toplevel_box); + struct wlr_box *toplevel_sx_box); /** Invert the right/left anchor and gravity for this positioner. This can be diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 0aca9638..39e8a4b7 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -92,14 +92,14 @@ static void popup_unconstrain(struct roots_xdg_popup_v6 *popup) { // the output box expressed in the coordinate system of the toplevel parent // of the popup - struct wlr_box output_box_toplevel = { + struct wlr_box output_toplevel_sx_box = { .x = output->lx - view->x, .y = output->ly - view->y, .width = width, .height = height }; - wlr_xdg_popup_v6_unconstrain_from_box(popup->wlr_popup, &output_box_toplevel); + wlr_xdg_popup_v6_unconstrain_from_box(popup->wlr_popup, &output_toplevel_sx_box); } static struct roots_xdg_popup_v6 *popup_create(struct roots_view *view, diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index 44bd8d9a..64d44f22 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -97,8 +97,8 @@ static void xdg_keyboard_grab_enter(struct wlr_seat_keyboard_grab *grab, // keyboard focus should remain on the popup } -static void xdg_keyboard_grab_key(struct wlr_seat_keyboard_grab *grab, uint32_t time, - uint32_t key, uint32_t state) { +static void xdg_keyboard_grab_key(struct wlr_seat_keyboard_grab *grab, + uint32_t time, uint32_t key, uint32_t state) { wlr_seat_keyboard_send_key(grab->seat, time, key, state); } @@ -425,7 +425,8 @@ static void xdg_shell_handle_create_positioner(struct wl_client *wl_client, positioner, xdg_positioner_destroy); } -struct wlr_box wlr_xdg_positioner_v6_get_geometry(struct wlr_xdg_positioner_v6 *positioner) { +struct wlr_box wlr_xdg_positioner_v6_get_geometry( + struct wlr_xdg_positioner_v6 *positioner) { struct wlr_box geometry = { .x = positioner->offset.x, .y = positioner->offset.y, @@ -582,7 +583,8 @@ static void xdg_surface_handle_get_popup(struct wl_client *client, struct wlr_xdg_positioner_v6_resource *positioner = xdg_positioner_from_resource(positioner_resource); - if (positioner->attrs.size.width == 0 || positioner->attrs.anchor_rect.width == 0) { + if (positioner->attrs.size.width == 0 || + positioner->attrs.anchor_rect.width == 0) { wl_resource_post_error(resource, ZXDG_SHELL_V6_ERROR_INVALID_POSITIONER, "positioner object is not complete"); @@ -1089,7 +1091,8 @@ static void wlr_xdg_toplevel_v6_send_configure( if (surface->toplevel->server_pending.maximized) { s = wl_array_add(&states, sizeof(uint32_t)); if (!s) { - wlr_log(L_ERROR, "Could not allocate state for maximized xdg_toplevel"); + wlr_log(L_ERROR, + "Could not allocate state for maximized xdg_toplevel"); goto error_out; } *s = ZXDG_TOPLEVEL_V6_STATE_MAXIMIZED; @@ -1097,7 +1100,8 @@ static void wlr_xdg_toplevel_v6_send_configure( if (surface->toplevel->server_pending.fullscreen) { s = wl_array_add(&states, sizeof(uint32_t)); if (!s) { - wlr_log(L_ERROR, "Could not allocate state for fullscreen xdg_toplevel"); + wlr_log(L_ERROR, + "Could not allocate state for fullscreen xdg_toplevel"); goto error_out; } *s = ZXDG_TOPLEVEL_V6_STATE_FULLSCREEN; @@ -1105,7 +1109,8 @@ static void wlr_xdg_toplevel_v6_send_configure( if (surface->toplevel->server_pending.resizing) { s = wl_array_add(&states, sizeof(uint32_t)); if (!s) { - wlr_log(L_ERROR, "Could not allocate state for resizing xdg_toplevel"); + wlr_log(L_ERROR, + "Could not allocate state for resizing xdg_toplevel"); goto error_out; } *s = ZXDG_TOPLEVEL_V6_STATE_RESIZING; @@ -1113,7 +1118,8 @@ static void wlr_xdg_toplevel_v6_send_configure( if (surface->toplevel->server_pending.activated) { s = wl_array_add(&states, sizeof(uint32_t)); if (!s) { - wlr_log(L_ERROR, "Could not allocate state for activated xdg_toplevel"); + wlr_log(L_ERROR, + "Could not allocate state for activated xdg_toplevel"); goto error_out; } *s = ZXDG_TOPLEVEL_V6_STATE_ACTIVATED; @@ -1688,7 +1694,7 @@ void wlr_xdg_popup_v6_get_toplevel_coords(struct wlr_xdg_popup_v6 *popup, } static void wlr_xdg_popup_v6_box_constraints(struct wlr_xdg_popup_v6 *popup, - struct wlr_box *toplevel_box, int *offset_x, int *offset_y) { + struct wlr_box *toplevel_sx_box, int *offset_x, int *offset_y) { int popup_width = popup->geometry.width; int popup_height = popup->geometry.height; int anchor_sx = 0, anchor_sy = 0; @@ -1698,23 +1704,28 @@ static void wlr_xdg_popup_v6_box_constraints(struct wlr_xdg_popup_v6 *popup, popup->geometry.y, &popup_sx, &popup_sy); *offset_x = 0, *offset_y = 0; - if (popup_sx < toplevel_box->x) { - *offset_x = toplevel_box->x - popup_sx; - } else if (popup_sx + popup_width > toplevel_box->x + toplevel_box->width) { - *offset_x = toplevel_box->x + toplevel_box->width - (popup_sx + popup_width); + if (popup_sx < toplevel_sx_box->x) { + *offset_x = toplevel_sx_box->x - popup_sx; + } else if (popup_sx + popup_width > + toplevel_sx_box->x + toplevel_sx_box->width) { + *offset_x = toplevel_sx_box->x + toplevel_sx_box->width - + (popup_sx + popup_width); } - if (popup_sy < toplevel_box->y) { - *offset_y = toplevel_box->y - popup_sy; - } else if (popup_sy + popup_height > toplevel_box->y + toplevel_box->height) { - *offset_y = toplevel_box->y + toplevel_box->height - (popup_sy + popup_height); + if (popup_sy < toplevel_sx_box->y) { + *offset_y = toplevel_sx_box->y - popup_sy; + } else if (popup_sy + popup_height > + toplevel_sx_box->y + toplevel_sx_box->height) { + *offset_y = toplevel_sx_box->y + toplevel_sx_box->height - + (popup_sy + popup_height); } } static bool wlr_xdg_popup_v6_unconstrain_flip(struct wlr_xdg_popup_v6 *popup, - struct wlr_box *toplevel_box) { + struct wlr_box *toplevel_sx_box) { int offset_x = 0, offset_y = 0; - wlr_xdg_popup_v6_box_constraints(popup, toplevel_box, &offset_x, &offset_y); + wlr_xdg_popup_v6_box_constraints(popup, toplevel_sx_box, + &offset_x, &offset_y); if (!offset_x && !offset_y) { return true; @@ -1738,7 +1749,8 @@ static bool wlr_xdg_popup_v6_unconstrain_flip(struct wlr_xdg_popup_v6 *popup, popup->geometry = wlr_xdg_positioner_v6_get_geometry(&popup->positioner); - wlr_xdg_popup_v6_box_constraints(popup, toplevel_box, &offset_x, &offset_y); + wlr_xdg_popup_v6_box_constraints(popup, toplevel_sx_box, + &offset_x, &offset_y); if (!offset_x && !offset_y) { // no longer constrained @@ -1760,9 +1772,10 @@ static bool wlr_xdg_popup_v6_unconstrain_flip(struct wlr_xdg_popup_v6 *popup, } static bool wlr_xdg_popup_v6_unconstrain_slide(struct wlr_xdg_popup_v6 *popup, - struct wlr_box *toplevel_box) { + struct wlr_box *toplevel_sx_box) { int offset_x = 0, offset_y = 0; - wlr_xdg_popup_v6_box_constraints(popup, toplevel_box, &offset_x, &offset_y); + wlr_xdg_popup_v6_box_constraints(popup, toplevel_sx_box, + &offset_x, &offset_y); if (!offset_x && !offset_y) { return true; @@ -1788,22 +1801,24 @@ static bool wlr_xdg_popup_v6_unconstrain_slide(struct wlr_xdg_popup_v6 *popup, wlr_xdg_popup_v6_get_toplevel_coords(popup, popup->geometry.x, popup->geometry.y, &toplevel_x, &toplevel_y); - if (slide_x && toplevel_x < toplevel_box->x) { - popup->geometry.x += toplevel_box->x - toplevel_x; + if (slide_x && toplevel_x < toplevel_sx_box->x) { + popup->geometry.x += toplevel_sx_box->x - toplevel_x; } - if (slide_y && toplevel_y < toplevel_box->y) { - popup->geometry.y += toplevel_box->y - toplevel_y; + if (slide_y && toplevel_y < toplevel_sx_box->y) { + popup->geometry.y += toplevel_sx_box->y - toplevel_y; } - wlr_xdg_popup_v6_box_constraints(popup, toplevel_box, &offset_x, &offset_y); + wlr_xdg_popup_v6_box_constraints(popup, toplevel_sx_box, + &offset_x, &offset_y); return !offset_x && !offset_y; } static bool wlr_xdg_popup_v6_unconstrain_resize(struct wlr_xdg_popup_v6 *popup, - struct wlr_box *toplevel_box) { + struct wlr_box *toplevel_sx_box) { int offset_x, offset_y; - wlr_xdg_popup_v6_box_constraints(popup, toplevel_box, &offset_x, &offset_y); + wlr_xdg_popup_v6_box_constraints(popup, toplevel_sx_box, + &offset_x, &offset_y); if (!offset_x && !offset_y) { return true; @@ -1824,20 +1839,21 @@ static bool wlr_xdg_popup_v6_unconstrain_resize(struct wlr_xdg_popup_v6 *popup, popup->geometry.height -= offset_y; } - wlr_xdg_popup_v6_box_constraints(popup, toplevel_box, &offset_y, &offset_y); + wlr_xdg_popup_v6_box_constraints(popup, toplevel_sx_box, + &offset_y, &offset_y); return !offset_x && !offset_y; } void wlr_xdg_popup_v6_unconstrain_from_box(struct wlr_xdg_popup_v6 *popup, - struct wlr_box *toplevel_box) { - if (wlr_xdg_popup_v6_unconstrain_flip(popup, toplevel_box)) { + struct wlr_box *toplevel_sx_box) { + if (wlr_xdg_popup_v6_unconstrain_flip(popup, toplevel_sx_box)) { return; } - if (wlr_xdg_popup_v6_unconstrain_slide(popup, toplevel_box)) { + if (wlr_xdg_popup_v6_unconstrain_slide(popup, toplevel_sx_box)) { return; } - if (wlr_xdg_popup_v6_unconstrain_resize(popup, toplevel_box)) { + if (wlr_xdg_popup_v6_unconstrain_resize(popup, toplevel_sx_box)) { return; } }