aboutsummaryrefslogtreecommitdiffstats
path: root/sway/desktop/xdg_shell.c
diff options
context:
space:
mode:
authorLibravatar emersion <contact@emersion.fr>2018-07-12 20:30:10 +0100
committerLibravatar emersion <contact@emersion.fr>2018-07-12 20:31:55 +0100
commita96f1c22fe92a46ea0242fa63e8c8cc2bbd09c3f (patch)
tree9ab2cef2970a02ef4639d088b9dd7221ac87ee08 /sway/desktop/xdg_shell.c
parentMerge pull request #2250 from RyanDwyer/fix-crash (diff)
downloadsway-a96f1c22fe92a46ea0242fa63e8c8cc2bbd09c3f.tar.gz
sway-a96f1c22fe92a46ea0242fa63e8c8cc2bbd09c3f.tar.zst
sway-a96f1c22fe92a46ea0242fa63e8c8cc2bbd09c3f.zip
Add xdg-positioner support
Diffstat (limited to 'sway/desktop/xdg_shell.c')
-rw-r--r--sway/desktop/xdg_shell.c50
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
48static 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
48static struct sway_xdg_popup *popup_create( 95static 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