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