diff options
-rw-r--r-- | include/wlr/types/wlr_xdg_shell_v6.h | 88 | ||||
-rw-r--r-- | rootston/xdg_shell_v6.c | 183 | ||||
-rw-r--r-- | types/wlr_output_layout.c | 8 | ||||
-rw-r--r-- | types/wlr_xdg_shell_v6.c | 181 |
4 files changed, 425 insertions, 35 deletions
diff --git a/include/wlr/types/wlr_xdg_shell_v6.h b/include/wlr/types/wlr_xdg_shell_v6.h index 0867b2f6..e2a58669 100644 --- a/include/wlr/types/wlr_xdg_shell_v6.h +++ b/include/wlr/types/wlr_xdg_shell_v6.h @@ -32,6 +32,77 @@ 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_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; @@ -45,6 +116,8 @@ struct wlr_xdg_popup_v6 { // geometry of the parent surface struct wlr_box geometry; + struct wlr_xdg_positioner_v6_attributes positioner; + struct wl_list grab_link; // wlr_xdg_popup_grab_v6::popups }; @@ -229,4 +302,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_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 ad33c4b0..e3c70e96 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -50,6 +50,186 @@ 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 && !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); + } + 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_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; + + 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 (y_constrained) { + wlr_popup->geometry.y -= popup_height - (output_box->height - popup_oy); + } +} + +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; + + 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 (y_constrained) { + wlr_popup->geometry.height = output_box->y + output_box->height - popup_oy; + } +} + +static void popup_unconstrain(struct roots_xdg_popup_v6 *popup) { + popup_unconstrain_flip(popup); + popup_unconstrain_slide(popup); + 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 = @@ -68,6 +248,9 @@ static struct roots_xdg_popup_v6 *popup_create(struct roots_view *view, wl_signal_add(&wlr_popup->base->events.unmap, &popup->unmap); 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_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 65b461b7..0a8bbadf 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); @@ -310,6 +297,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); } @@ -325,8 +313,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, @@ -342,10 +330,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, @@ -363,7 +351,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, @@ -381,7 +369,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( @@ -390,7 +378,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, @@ -398,8 +386,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 @@ -423,6 +411,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), @@ -438,9 +430,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 *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, @@ -484,7 +474,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; } @@ -493,7 +483,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( @@ -598,7 +587,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"); @@ -629,7 +618,12 @@ 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); + wlr_xdg_positioner_v6_get_geometry(positioner->attrs); + + // positioner properties + memcpy(&surface->popup->positioner, positioner->attrs, + sizeof(struct wlr_xdg_positioner_v6_attributes)); + wl_list_insert(&parent->popups, &surface->popup->link); wl_resource_set_implementation(surface->popup->resource, @@ -639,7 +633,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( @@ -1639,3 +1632,125 @@ 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_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; + } + + 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; + } +} |