|
|
|
@ -51,16 +51,6 @@ static void resource_handle_destroy(struct wl_client *client,
|
|
|
|
|
wl_resource_destroy(resource);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct wlr_xdg_surface *xdg_popup_grab_get_topmost(
|
|
|
|
|
struct wlr_xdg_popup_grab *grab) {
|
|
|
|
|
struct wlr_xdg_popup *popup;
|
|
|
|
|
wl_list_for_each(popup, &grab->popups, grab_link) {
|
|
|
|
|
return popup->base;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void xdg_pointer_grab_end(struct wlr_seat_pointer_grab *grab) {
|
|
|
|
|
struct wlr_xdg_popup_grab *popup_grab = grab->data;
|
|
|
|
|
|
|
|
|
@ -447,9 +437,9 @@ 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 *positioner,
|
|
|
|
|
struct wlr_xdg_surface *surface, struct wlr_xdg_surface *parent) {
|
|
|
|
|
struct wlr_box wlr_xdg_popup_get_geometry(struct wlr_xdg_popup *popup) {
|
|
|
|
|
assert(popup && popup->positioner);
|
|
|
|
|
struct wlr_xdg_positioner *positioner = popup->positioner;
|
|
|
|
|
struct wlr_box geometry = {
|
|
|
|
|
.x = positioner->offset.x,
|
|
|
|
|
.y = positioner->offset.y,
|
|
|
|
@ -563,12 +553,7 @@ static void xdg_popup_handle_grab(struct wl_client *client,
|
|
|
|
|
xdg_shell_popup_grab_from_seat(surface->client->shell,
|
|
|
|
|
seat_client->seat);
|
|
|
|
|
|
|
|
|
|
struct wlr_xdg_surface *topmost = xdg_popup_grab_get_topmost(popup_grab);
|
|
|
|
|
bool parent_is_toplevel =
|
|
|
|
|
surface->popup->parent->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL;
|
|
|
|
|
|
|
|
|
|
if ((topmost == NULL && !parent_is_toplevel) ||
|
|
|
|
|
(topmost != NULL && topmost != surface->popup->parent)) {
|
|
|
|
|
if (!wl_list_empty(&surface->popups)) {
|
|
|
|
|
wl_resource_post_error(surface->client->resource,
|
|
|
|
|
XDG_WM_BASE_ERROR_NOT_THE_TOPMOST_POPUP,
|
|
|
|
|
"xdg_popup was not created on the topmost popup");
|
|
|
|
@ -616,8 +601,12 @@ static void xdg_popup_resource_destroy(struct wl_resource *resource) {
|
|
|
|
|
|
|
|
|
|
static const struct xdg_surface_interface xdg_surface_implementation;
|
|
|
|
|
|
|
|
|
|
static struct wlr_xdg_surface *xdg_surface_from_resource(
|
|
|
|
|
struct wlr_xdg_surface *wlr_xdg_surface_from_resource(
|
|
|
|
|
struct wl_resource *resource) {
|
|
|
|
|
// TODO: Double check that all of the callers can deal with NULL
|
|
|
|
|
if (!resource) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
assert(wl_resource_instance_of(resource, &xdg_surface_interface,
|
|
|
|
|
&xdg_surface_implementation));
|
|
|
|
|
return wl_resource_get_user_data(resource);
|
|
|
|
@ -628,9 +617,9 @@ static void xdg_surface_handle_get_popup(struct wl_client *client,
|
|
|
|
|
struct wl_resource *parent_resource,
|
|
|
|
|
struct wl_resource *positioner_resource) {
|
|
|
|
|
struct wlr_xdg_surface *surface =
|
|
|
|
|
xdg_surface_from_resource(resource);
|
|
|
|
|
wlr_xdg_surface_from_resource(resource);
|
|
|
|
|
struct wlr_xdg_surface *parent =
|
|
|
|
|
xdg_surface_from_resource(parent_resource);
|
|
|
|
|
wlr_xdg_surface_from_resource(parent_resource);
|
|
|
|
|
struct wlr_xdg_positioner *positioner =
|
|
|
|
|
xdg_positioner_from_resource(positioner_resource);
|
|
|
|
|
|
|
|
|
@ -663,17 +652,19 @@ static void xdg_surface_handle_get_popup(struct wl_client *client,
|
|
|
|
|
|
|
|
|
|
surface->role = WLR_XDG_SURFACE_ROLE_POPUP;
|
|
|
|
|
surface->popup->base = surface;
|
|
|
|
|
surface->popup->parent = parent;
|
|
|
|
|
surface->popup->geometry =
|
|
|
|
|
xdg_positioner_get_geometry(positioner, surface, parent);
|
|
|
|
|
wl_list_insert(&parent->popups, &surface->popup->link);
|
|
|
|
|
surface->popup->positioner = positioner;
|
|
|
|
|
|
|
|
|
|
wl_resource_set_implementation(surface->popup->resource,
|
|
|
|
|
&xdg_popup_implementation, surface,
|
|
|
|
|
xdg_popup_resource_destroy);
|
|
|
|
|
|
|
|
|
|
if (parent) {
|
|
|
|
|
surface->popup->parent = parent->surface;
|
|
|
|
|
surface->popup->geometry = wlr_xdg_popup_get_geometry(surface->popup);
|
|
|
|
|
wl_list_insert(&parent->popups, &surface->popup->link);
|
|
|
|
|
wlr_signal_emit_safe(&parent->events.new_popup, surface->popup);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static const struct xdg_toplevel_interface xdg_toplevel_implementation;
|
|
|
|
@ -913,7 +904,7 @@ static const struct xdg_toplevel_interface xdg_toplevel_implementation = {
|
|
|
|
|
|
|
|
|
|
static void xdg_surface_resource_destroy(struct wl_resource *resource) {
|
|
|
|
|
struct wlr_xdg_surface *surface =
|
|
|
|
|
xdg_surface_from_resource(resource);
|
|
|
|
|
wlr_xdg_surface_from_resource(resource);
|
|
|
|
|
if (surface != NULL) {
|
|
|
|
|
xdg_surface_destroy(surface);
|
|
|
|
|
}
|
|
|
|
@ -929,7 +920,7 @@ static void xdg_toplevel_resource_destroy(struct wl_resource *resource) {
|
|
|
|
|
|
|
|
|
|
static void xdg_surface_handle_get_toplevel(struct wl_client *client,
|
|
|
|
|
struct wl_resource *resource, uint32_t id) {
|
|
|
|
|
struct wlr_xdg_surface *surface = xdg_surface_from_resource(resource);
|
|
|
|
|
struct wlr_xdg_surface *surface = wlr_xdg_surface_from_resource(resource);
|
|
|
|
|
|
|
|
|
|
if (wlr_surface_set_role(surface->surface, wlr_desktop_xdg_toplevel_role,
|
|
|
|
|
resource, XDG_WM_BASE_ERROR_ROLE)) {
|
|
|
|
@ -984,7 +975,7 @@ static void wlr_xdg_toplevel_ack_configure(
|
|
|
|
|
|
|
|
|
|
static void xdg_surface_handle_ack_configure(struct wl_client *client,
|
|
|
|
|
struct wl_resource *resource, uint32_t serial) {
|
|
|
|
|
struct wlr_xdg_surface *surface = xdg_surface_from_resource(resource);
|
|
|
|
|
struct wlr_xdg_surface *surface = wlr_xdg_surface_from_resource(resource);
|
|
|
|
|
|
|
|
|
|
if (surface->role == WLR_XDG_SURFACE_ROLE_NONE) {
|
|
|
|
|
wl_resource_post_error(surface->resource,
|
|
|
|
@ -1032,7 +1023,7 @@ static void xdg_surface_handle_ack_configure(struct wl_client *client,
|
|
|
|
|
static void xdg_surface_handle_set_window_geometry(struct wl_client *client,
|
|
|
|
|
struct wl_resource *resource, int32_t x, int32_t y, int32_t width,
|
|
|
|
|
int32_t height) {
|
|
|
|
|
struct wlr_xdg_surface *surface = xdg_surface_from_resource(resource);
|
|
|
|
|
struct wlr_xdg_surface *surface = wlr_xdg_surface_from_resource(resource);
|
|
|
|
|
|
|
|
|
|
if (surface->role == WLR_XDG_SURFACE_ROLE_NONE) {
|
|
|
|
|
wl_resource_post_error(surface->resource,
|
|
|
|
@ -1050,7 +1041,7 @@ static void xdg_surface_handle_set_window_geometry(struct wl_client *client,
|
|
|
|
|
|
|
|
|
|
static void xdg_surface_handle_destroy(struct wl_client *client,
|
|
|
|
|
struct wl_resource *resource) {
|
|
|
|
|
struct wlr_xdg_surface *surface = xdg_surface_from_resource(resource);
|
|
|
|
|
struct wlr_xdg_surface *surface = wlr_xdg_surface_from_resource(resource);
|
|
|
|
|
|
|
|
|
|
if (surface->role != WLR_XDG_SURFACE_ROLE_NONE) {
|
|
|
|
|
wlr_log(L_ERROR, "Tried to destroy an xdg_surface before its role "
|
|
|
|
@ -1627,11 +1618,12 @@ void wlr_xdg_surface_send_close(struct wlr_xdg_surface *surface) {
|
|
|
|
|
void wlr_xdg_surface_popup_get_position(struct wlr_xdg_surface *surface,
|
|
|
|
|
double *popup_sx, double *popup_sy) {
|
|
|
|
|
assert(surface->role == WLR_XDG_SURFACE_ROLE_POPUP);
|
|
|
|
|
struct wlr_xdg_surface *parent = surface->popup->parent;
|
|
|
|
|
*popup_sx = parent->geometry.x + surface->popup->geometry.x -
|
|
|
|
|
surface->geometry.x;
|
|
|
|
|
*popup_sy = parent->geometry.y + surface->popup->geometry.y -
|
|
|
|
|
surface->geometry.y;
|
|
|
|
|
struct wlr_xdg_popup *popup = surface->popup;
|
|
|
|
|
assert(strcmp(popup->parent->role, wlr_desktop_xdg_toplevel_role) == 0
|
|
|
|
|
|| strcmp(popup->parent->role, wlr_desktop_xdg_popup_role) == 0);
|
|
|
|
|
struct wlr_xdg_surface *parent = popup->parent->role_data;
|
|
|
|
|
*popup_sx = parent->geometry.x + popup->geometry.x - surface->geometry.x;
|
|
|
|
|
*popup_sy = parent->geometry.y + popup->geometry.y - surface->geometry.y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct wlr_surface *wlr_xdg_surface_surface_at(
|
|
|
|
|