diff options
Diffstat (limited to 'sway/desktop/xwayland.c')
-rw-r--r-- | sway/desktop/xwayland.c | 132 |
1 files changed, 103 insertions, 29 deletions
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index 384f4236..e3da1da7 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c | |||
@@ -2,42 +2,110 @@ | |||
2 | #include <stdbool.h> | 2 | #include <stdbool.h> |
3 | #include <stdlib.h> | 3 | #include <stdlib.h> |
4 | #include <wayland-server.h> | 4 | #include <wayland-server.h> |
5 | #include <wlr/xwayland.h> | ||
6 | #include <wlr/types/wlr_output_layout.h> | 5 | #include <wlr/types/wlr_output_layout.h> |
7 | #include <wlr/types/wlr_output.h> | 6 | #include <wlr/types/wlr_output.h> |
7 | #include <wlr/xwayland.h> | ||
8 | #include "log.h" | ||
9 | #include "sway/desktop.h" | ||
10 | #include "sway/input/input-manager.h" | ||
11 | #include "sway/input/seat.h" | ||
12 | #include "sway/output.h" | ||
13 | #include "sway/server.h" | ||
8 | #include "sway/tree/container.h" | 14 | #include "sway/tree/container.h" |
9 | #include "sway/tree/layout.h" | 15 | #include "sway/tree/layout.h" |
10 | #include "sway/server.h" | ||
11 | #include "sway/tree/view.h" | 16 | #include "sway/tree/view.h" |
12 | #include "sway/output.h" | ||
13 | #include "sway/input/seat.h" | ||
14 | #include "sway/input/input-manager.h" | ||
15 | #include "log.h" | ||
16 | 17 | ||
17 | static void unmanaged_handle_destroy(struct wl_listener *listener, void *data) { | 18 | static void unmanaged_handle_request_configure(struct wl_listener *listener, |
18 | struct sway_xwayland_unmanaged *sway_surface = | 19 | void *data) { |
19 | wl_container_of(listener, sway_surface, destroy); | 20 | struct sway_xwayland_unmanaged *surface = |
20 | wl_list_remove(&sway_surface->destroy.link); | 21 | wl_container_of(listener, surface, request_configure); |
21 | wl_list_remove(&sway_surface->link); | 22 | struct wlr_xwayland_surface *xsurface = surface->wlr_xwayland_surface; |
22 | free(sway_surface); | 23 | struct wlr_xwayland_surface_configure_event *ev = data; |
24 | wlr_xwayland_surface_configure(xsurface, ev->x, ev->y, | ||
25 | ev->width, ev->height); | ||
23 | } | 26 | } |
24 | 27 | ||
25 | static void create_unmanaged(struct wlr_xwayland_surface *xsurface) { | 28 | static void unmanaged_handle_commit(struct wl_listener *listener, void *data) { |
26 | struct sway_xwayland_unmanaged *sway_surface = | 29 | struct sway_xwayland_unmanaged *surface = |
27 | calloc(1, sizeof(struct sway_xwayland_unmanaged)); | 30 | wl_container_of(listener, surface, commit); |
28 | if (!sway_assert(sway_surface, "Failed to allocate surface")) { | 31 | struct wlr_xwayland_surface *xsurface = surface->wlr_xwayland_surface; |
29 | return; | 32 | |
33 | if (xsurface->x != surface->lx || xsurface->y != surface->ly) { | ||
34 | // Surface has moved | ||
35 | desktop_damage_whole_surface(xsurface->surface, | ||
36 | surface->lx, surface->ly); | ||
37 | surface->lx = xsurface->x; | ||
38 | surface->ly = xsurface->y; | ||
39 | desktop_damage_whole_surface(xsurface->surface, | ||
40 | surface->lx, surface->ly); | ||
41 | } else { | ||
42 | desktop_damage_from_surface(xsurface->surface, | ||
43 | xsurface->x, xsurface->y); | ||
30 | } | 44 | } |
45 | } | ||
31 | 46 | ||
32 | sway_surface->wlr_xwayland_surface = xsurface; | 47 | static void unmanaged_handle_map(struct wl_listener *listener, void *data) { |
33 | 48 | struct sway_xwayland_unmanaged *surface = | |
34 | wl_signal_add(&xsurface->events.destroy, &sway_surface->destroy); | 49 | wl_container_of(listener, surface, map); |
35 | sway_surface->destroy.notify = unmanaged_handle_destroy; | 50 | struct wlr_xwayland_surface *xsurface = surface->wlr_xwayland_surface; |
36 | 51 | ||
37 | wl_list_insert(&root_container.sway_root->xwayland_unmanaged, | 52 | wl_list_insert(&root_container.sway_root->xwayland_unmanaged, |
38 | &sway_surface->link); | 53 | &surface->link); |
54 | |||
55 | wl_signal_add(&xsurface->surface->events.commit, &surface->commit); | ||
56 | surface->commit.notify = unmanaged_handle_commit; | ||
57 | |||
58 | surface->lx = xsurface->x; | ||
59 | surface->ly = xsurface->y; | ||
60 | desktop_damage_whole_surface(xsurface->surface, surface->lx, surface->ly); | ||
61 | } | ||
62 | |||
63 | static void unmanaged_handle_unmap(struct wl_listener *listener, void *data) { | ||
64 | struct sway_xwayland_unmanaged *surface = | ||
65 | wl_container_of(listener, surface, unmap); | ||
66 | struct wlr_xwayland_surface *xsurface = surface->wlr_xwayland_surface; | ||
67 | desktop_damage_whole_surface(xsurface->surface, xsurface->x, xsurface->y); | ||
68 | wl_list_remove(&surface->link); | ||
69 | wl_list_remove(&surface->commit.link); | ||
70 | } | ||
39 | 71 | ||
40 | // TODO: damage tracking | 72 | static void unmanaged_handle_destroy(struct wl_listener *listener, void *data) { |
73 | struct sway_xwayland_unmanaged *surface = | ||
74 | wl_container_of(listener, surface, destroy); | ||
75 | struct wlr_xwayland_surface *xsurface = surface->wlr_xwayland_surface; | ||
76 | if (xsurface->mapped) { | ||
77 | unmanaged_handle_unmap(&surface->unmap, xsurface); | ||
78 | } | ||
79 | wl_list_remove(&surface->map.link); | ||
80 | wl_list_remove(&surface->unmap.link); | ||
81 | wl_list_remove(&surface->destroy.link); | ||
82 | free(surface); | ||
83 | } | ||
84 | |||
85 | static struct sway_xwayland_unmanaged *create_unmanaged( | ||
86 | struct wlr_xwayland_surface *xsurface) { | ||
87 | struct sway_xwayland_unmanaged *surface = | ||
88 | calloc(1, sizeof(struct sway_xwayland_unmanaged)); | ||
89 | if (surface == NULL) { | ||
90 | wlr_log(L_ERROR, "Allocation failed"); | ||
91 | return NULL; | ||
92 | } | ||
93 | |||
94 | surface->wlr_xwayland_surface = xsurface; | ||
95 | |||
96 | wl_signal_add(&xsurface->events.request_configure, | ||
97 | &surface->request_configure); | ||
98 | surface->request_configure.notify = unmanaged_handle_request_configure; | ||
99 | wl_signal_add(&xsurface->events.map, &surface->map); | ||
100 | surface->map.notify = unmanaged_handle_map; | ||
101 | wl_signal_add(&xsurface->events.unmap, &surface->unmap); | ||
102 | surface->unmap.notify = unmanaged_handle_unmap; | ||
103 | wl_signal_add(&xsurface->events.destroy, &surface->destroy); | ||
104 | surface->destroy.notify = unmanaged_handle_destroy; | ||
105 | |||
106 | unmanaged_handle_map(&surface->map, xsurface); | ||
107 | |||
108 | return surface; | ||
41 | } | 109 | } |
42 | 110 | ||
43 | 111 | ||
@@ -127,6 +195,7 @@ static const struct sway_view_impl view_impl = { | |||
127 | .configure = configure, | 195 | .configure = configure, |
128 | .set_activated = set_activated, | 196 | .set_activated = set_activated, |
129 | .close = _close, | 197 | .close = _close, |
198 | .destroy = destroy, | ||
130 | }; | 199 | }; |
131 | 200 | ||
132 | static void handle_commit(struct wl_listener *listener, void *data) { | 201 | static void handle_commit(struct wl_listener *listener, void *data) { |
@@ -140,12 +209,6 @@ static void handle_commit(struct wl_listener *listener, void *data) { | |||
140 | view_damage_from(view); | 209 | view_damage_from(view); |
141 | } | 210 | } |
142 | 211 | ||
143 | static void handle_destroy(struct wl_listener *listener, void *data) { | ||
144 | struct sway_xwayland_view *xwayland_view = | ||
145 | wl_container_of(listener, xwayland_view, destroy); | ||
146 | view_destroy(&xwayland_view->view); | ||
147 | } | ||
148 | |||
149 | static void handle_unmap(struct wl_listener *listener, void *data) { | 212 | static void handle_unmap(struct wl_listener *listener, void *data) { |
150 | struct sway_xwayland_view *xwayland_view = | 213 | struct sway_xwayland_view *xwayland_view = |
151 | wl_container_of(listener, xwayland_view, unmap); | 214 | wl_container_of(listener, xwayland_view, unmap); |
@@ -169,6 +232,17 @@ static void handle_map(struct wl_listener *listener, void *data) { | |||
169 | view_map(view, xsurface->surface); | 232 | view_map(view, xsurface->surface); |
170 | } | 233 | } |
171 | 234 | ||
235 | static void handle_destroy(struct wl_listener *listener, void *data) { | ||
236 | struct sway_xwayland_view *xwayland_view = | ||
237 | wl_container_of(listener, xwayland_view, destroy); | ||
238 | struct sway_view *view = &xwayland_view->view; | ||
239 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; | ||
240 | if (xsurface->mapped) { | ||
241 | handle_unmap(&xwayland_view->unmap, xsurface); | ||
242 | } | ||
243 | view_destroy(&xwayland_view->view); | ||
244 | } | ||
245 | |||
172 | static void handle_request_configure(struct wl_listener *listener, void *data) { | 246 | static void handle_request_configure(struct wl_listener *listener, void *data) { |
173 | struct sway_xwayland_view *xwayland_view = | 247 | struct sway_xwayland_view *xwayland_view = |
174 | wl_container_of(listener, xwayland_view, request_configure); | 248 | wl_container_of(listener, xwayland_view, request_configure); |