diff options
Diffstat (limited to 'sway/desktop/xdg_shell.c')
-rw-r--r-- | sway/desktop/xdg_shell.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index be14adbe..17b7b750 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c | |||
@@ -45,6 +45,53 @@ static void popup_handle_destroy(struct wl_listener *listener, void *data) { | |||
45 | view_child_destroy(&popup->child); | 45 | view_child_destroy(&popup->child); |
46 | } | 46 | } |
47 | 47 | ||
48 | static void popup_unconstrain(struct sway_xdg_popup *popup) { | ||
49 | // get the output of the popup's positioner anchor point and convert it to | ||
50 | // the toplevel parent's coordinate system and then pass it to | ||
51 | // wlr_xdg_popup_unconstrain_from_box | ||
52 | |||
53 | struct sway_view *view = popup->child.view; | ||
54 | struct wlr_output_layout *output_layout = | ||
55 | root_container.sway_root->output_layout; | ||
56 | struct wlr_xdg_popup *wlr_popup = popup->wlr_xdg_surface->popup; | ||
57 | |||
58 | int anchor_lx, anchor_ly; | ||
59 | wlr_xdg_popup_get_anchor_point(wlr_popup, &anchor_lx, &anchor_ly); | ||
60 | |||
61 | int popup_lx, popup_ly; | ||
62 | wlr_xdg_popup_get_toplevel_coords(wlr_popup, wlr_popup->geometry.x, | ||
63 | wlr_popup->geometry.y, &popup_lx, &popup_ly); | ||
64 | popup_lx += view->x; | ||
65 | popup_ly += view->y; | ||
66 | |||
67 | anchor_lx += popup_lx; | ||
68 | anchor_ly += popup_ly; | ||
69 | |||
70 | double dest_x = 0, dest_y = 0; | ||
71 | wlr_output_layout_closest_point(output_layout, NULL, anchor_lx, anchor_ly, | ||
72 | &dest_x, &dest_y); | ||
73 | |||
74 | struct wlr_output *output = | ||
75 | wlr_output_layout_output_at(output_layout, dest_x, dest_y); | ||
76 | if (output == NULL) { | ||
77 | return; | ||
78 | } | ||
79 | |||
80 | int width = 0, height = 0; | ||
81 | wlr_output_effective_resolution(output, &width, &height); | ||
82 | |||
83 | // the output box expressed in the coordinate system of the toplevel parent | ||
84 | // of the popup | ||
85 | struct wlr_box output_toplevel_sx_box = { | ||
86 | .x = output->lx - view->x, | ||
87 | .y = output->ly - view->y, | ||
88 | .width = width, | ||
89 | .height = height | ||
90 | }; | ||
91 | |||
92 | wlr_xdg_popup_unconstrain_from_box(wlr_popup, &output_toplevel_sx_box); | ||
93 | } | ||
94 | |||
48 | static struct sway_xdg_popup *popup_create( | 95 | static struct sway_xdg_popup *popup_create( |
49 | struct wlr_xdg_popup *wlr_popup, struct sway_view *view) { | 96 | struct wlr_xdg_popup *wlr_popup, struct sway_view *view) { |
50 | struct wlr_xdg_surface *xdg_surface = wlr_popup->base; | 97 | struct wlr_xdg_surface *xdg_surface = wlr_popup->base; |
@@ -55,12 +102,15 @@ static struct sway_xdg_popup *popup_create( | |||
55 | return NULL; | 102 | return NULL; |
56 | } | 103 | } |
57 | view_child_init(&popup->child, &popup_impl, view, xdg_surface->surface); | 104 | view_child_init(&popup->child, &popup_impl, view, xdg_surface->surface); |
105 | popup->wlr_xdg_surface = xdg_surface; | ||
58 | 106 | ||
59 | wl_signal_add(&xdg_surface->events.new_popup, &popup->new_popup); | 107 | wl_signal_add(&xdg_surface->events.new_popup, &popup->new_popup); |
60 | popup->new_popup.notify = popup_handle_new_popup; | 108 | popup->new_popup.notify = popup_handle_new_popup; |
61 | wl_signal_add(&xdg_surface->events.destroy, &popup->destroy); | 109 | wl_signal_add(&xdg_surface->events.destroy, &popup->destroy); |
62 | popup->destroy.notify = popup_handle_destroy; | 110 | popup->destroy.notify = popup_handle_destroy; |
63 | 111 | ||
112 | popup_unconstrain(popup); | ||
113 | |||
64 | return popup; | 114 | return popup; |
65 | } | 115 | } |
66 | 116 | ||