diff options
Diffstat (limited to 'rootston')
-rw-r--r-- | rootston/xdg_shell.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/rootston/xdg_shell.c b/rootston/xdg_shell.c index 927bd018..bd670a87 100644 --- a/rootston/xdg_shell.c +++ b/rootston/xdg_shell.c @@ -48,6 +48,59 @@ static void popup_handle_new_popup(struct wl_listener *listener, void *data) { popup_create(popup->view_child.view, wlr_popup); } +static void popup_unconstrain(struct roots_xdg_popup *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 *wlr_popup = popup->wlr_popup; + + int anchor_lx, anchor_ly; + wlr_xdg_popup_get_anchor_point(wlr_popup, &anchor_lx, &anchor_ly); + + int popup_lx, popup_ly; + wlr_xdg_popup_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; + + 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); + + if (output == NULL) { + return; + } + + int width = 0, height = 0; + wlr_output_effective_resolution(output, &width, &height); + + // the output box expressed in the coordinate system of the toplevel parent + // of the popup + struct wlr_box output_toplevel_sx_box = { + .x = output->lx - view->x, + .y = output->ly - view->y, + .width = width, + .height = height + }; + + wlr_xdg_popup_unconstrain_from_box( + popup->wlr_popup, &output_toplevel_sx_box); +} + static struct roots_xdg_popup *popup_create(struct roots_view *view, struct wlr_xdg_popup *wlr_popup) { struct roots_xdg_popup *popup = @@ -66,6 +119,9 @@ static struct roots_xdg_popup *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; } |