diff --git a/rootston/output.c b/rootston/output.c index 90ba1eb7..29a4413f 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -100,7 +100,7 @@ static void render_xdg_v6_popups(struct wlr_xdg_surface_v6 *surface, static void render_wl_shell_surface(struct wlr_wl_shell_surface *surface, struct roots_desktop *desktop, struct wlr_output *wlr_output, struct timespec *when, double lx, double ly, float rotation, bool is_child) { - if (is_child || !wlr_wl_shell_surface_is_transient(surface)) { + if (is_child || surface->state != WLR_WL_SHELL_SURFACE_STATE_POPUP) { render_surface(surface->surface, desktop, wlr_output, when, lx, ly, rotation); struct wlr_wl_shell_surface *child; diff --git a/rootston/wl_shell.c b/rootston/wl_shell.c index 009a8c06..34f53c7a 100644 --- a/rootston/wl_shell.c +++ b/rootston/wl_shell.c @@ -73,6 +73,14 @@ static void handle_destroy(struct wl_listener *listener, void *data) { free(roots_surface); } +static int shell_surface_compare_equals(const void *item, const void *cmp_to) { + const struct roots_view *view = item; + if (view->type == ROOTS_WL_SHELL_VIEW && view->wl_shell_surface == cmp_to) { + return 0; + } + return -1; +} + void handle_wl_shell_surface(struct wl_listener *listener, void *data) { struct roots_desktop *desktop = wl_container_of(listener, desktop, wl_shell_surface); @@ -107,7 +115,20 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) { struct roots_view *view = calloc(1, sizeof(struct roots_view)); view->type = ROOTS_WL_SHELL_VIEW; - view->x = view->y = 200; + + if (surface->state == WLR_WL_SHELL_SURFACE_STATE_TRANSIENT) { + // we need to map it relative to the parent + int i = + list_seq_find(desktop->views, + shell_surface_compare_equals, surface->parent); + if (i != -1) { + struct roots_view *parent = desktop->views->items[i]; + view->x = parent->x + surface->transient_state->x; + view->y = parent->y + surface->transient_state->y; + } + } else { + view->x = view->y = 200; + } view->wl_shell_surface = surface; view->roots_wl_shell_surface = roots_surface; view->wlr_surface = surface->surface; diff --git a/types/wlr_wl_shell.c b/types/wlr_wl_shell.c index c5394d97..6421cc45 100644 --- a/types/wlr_wl_shell.c +++ b/types/wlr_wl_shell.c @@ -195,9 +195,9 @@ static void shell_surface_set_toplevel(struct wl_client *client, NULL); } -static void shell_surface_set_parent(struct wlr_wl_shell_surface *surface, +static void popup_set_parent(struct wlr_wl_shell_surface *surface, struct wlr_wl_shell_surface *parent) { - assert(surface); + assert(surface && surface->state == WLR_WL_SHELL_SURFACE_STATE_POPUP); if (surface->parent == parent) { return; } @@ -243,7 +243,7 @@ static void shell_surface_set_transient(struct wl_client *client, return; } - shell_surface_set_parent(surface, wl_parent); + surface->parent = wl_parent; transient_state->x = x; transient_state->y = y; transient_state->flags = flags; @@ -307,7 +307,7 @@ static void shell_surface_set_popup(struct wl_client *client, if (surface->state == WLR_WL_SHELL_SURFACE_STATE_POPUP) { surface->transient_state->x = x; surface->transient_state->y = y; - shell_surface_set_parent(surface, wl_parent); + popup_set_parent(surface, wl_parent); grab->client = surface->client; wlr_seat_pointer_start_grab(seat_handle->wlr_seat, &grab->pointer_grab); return; @@ -319,7 +319,6 @@ static void shell_surface_set_popup(struct wl_client *client, wl_client_post_no_memory(client); return; } - shell_surface_set_parent(surface, wl_parent); transient_state->x = x; transient_state->y = y; transient_state->flags = flags; @@ -337,6 +336,7 @@ static void shell_surface_set_popup(struct wl_client *client, shell_surface_set_state(surface, WLR_WL_SHELL_SURFACE_STATE_POPUP, transient_state, popup_state); + popup_set_parent(surface, wl_parent); grab->client = surface->client; wl_list_insert(&grab->popups, &surface->grab_link); wlr_seat_pointer_start_grab(seat_handle->wlr_seat, &grab->pointer_grab); @@ -422,7 +422,7 @@ static void wl_shell_surface_destroy(struct wlr_wl_shell_surface *surface) { struct wlr_wl_shell_surface *child; wl_list_for_each(child, &surface->children, child_link) { - shell_surface_set_parent(child, NULL); + popup_set_parent(child, NULL); } wl_list_remove(&surface->child_link);