diff options
Diffstat (limited to 'sway/desktop/xwayland.c')
-rw-r--r-- | sway/desktop/xwayland.c | 92 |
1 files changed, 33 insertions, 59 deletions
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index 38ee4656..01c993b3 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c | |||
@@ -14,10 +14,10 @@ | |||
14 | #include "sway/input/input-manager.h" | 14 | #include "sway/input/input-manager.h" |
15 | #include "log.h" | 15 | #include "log.h" |
16 | 16 | ||
17 | static bool assert_xwayland(struct sway_view *view) { | 17 | static bool assert_xwayland(struct sway_view *view) { |
18 | return sway_assert(view->type == SWAY_XWAYLAND_VIEW && view->wlr_xwayland_surface, | 18 | return sway_assert(view->type == SWAY_XWAYLAND_VIEW, |
19 | "Expected xwayland view!"); | 19 | "Expected xwayland view!"); |
20 | } | 20 | } |
21 | 21 | ||
22 | static const char *get_prop(struct sway_view *view, enum sway_view_prop prop) { | 22 | static const char *get_prop(struct sway_view *view, enum sway_view_prop prop) { |
23 | if (!assert_xwayland(view)) { | 23 | if (!assert_xwayland(view)) { |
@@ -99,73 +99,59 @@ static void handle_commit(struct wl_listener *listener, void *data) { | |||
99 | // TODO: Let floating views do whatever | 99 | // TODO: Let floating views do whatever |
100 | view->width = sway_surface->pending_width; | 100 | view->width = sway_surface->pending_width; |
101 | view->height = sway_surface->pending_height; | 101 | view->height = sway_surface->pending_height; |
102 | view_damage_from(view); | ||
102 | } | 103 | } |
103 | 104 | ||
104 | static void handle_destroy(struct wl_listener *listener, void *data) { | 105 | static void handle_destroy(struct wl_listener *listener, void *data) { |
105 | struct sway_xwayland_surface *sway_surface = | 106 | struct sway_xwayland_surface *sway_surface = |
106 | wl_container_of(listener, sway_surface, destroy); | 107 | wl_container_of(listener, sway_surface, destroy); |
107 | struct wlr_xwayland_surface *xsurface = data; | 108 | |
108 | wl_list_remove(&sway_surface->commit.link); | 109 | wl_list_remove(&sway_surface->commit.link); |
109 | wl_list_remove(&sway_surface->destroy.link); | 110 | wl_list_remove(&sway_surface->destroy.link); |
110 | wl_list_remove(&sway_surface->request_configure.link); | 111 | wl_list_remove(&sway_surface->request_configure.link); |
111 | if (xsurface->override_redirect && xsurface->mapped) { | 112 | wl_list_remove(&sway_surface->view->unmanaged_view_link); |
112 | wl_list_remove(&sway_surface->view->unmanaged_view_link); | 113 | container_view_destroy(sway_surface->view->swayc); |
113 | wl_list_init(&sway_surface->view->unmanaged_view_link); | 114 | sway_surface->view->swayc = NULL; |
114 | } | 115 | sway_surface->view->surface = NULL; |
115 | |||
116 | struct sway_container *parent = container_view_destroy(sway_surface->view->swayc); | ||
117 | if (parent) { | ||
118 | arrange_windows(parent, -1, -1); | ||
119 | } | ||
120 | |||
121 | free(sway_surface->view); | ||
122 | free(sway_surface); | ||
123 | } | 116 | } |
124 | 117 | ||
125 | static void handle_unmap_notify(struct wl_listener *listener, void *data) { | 118 | static void handle_unmap(struct wl_listener *listener, void *data) { |
126 | struct sway_xwayland_surface *sway_surface = | 119 | struct sway_xwayland_surface *sway_surface = |
127 | wl_container_of(listener, sway_surface, unmap_notify); | 120 | wl_container_of(listener, sway_surface, unmap); |
128 | struct wlr_xwayland_surface *xsurface = data; | 121 | view_damage_whole(sway_surface->view); |
129 | if (xsurface->override_redirect && xsurface->mapped) { | 122 | wl_list_remove(&sway_surface->view->unmanaged_view_link); |
130 | wl_list_remove(&sway_surface->view->unmanaged_view_link); | 123 | wl_list_init(&sway_surface->view->unmanaged_view_link); |
131 | wl_list_init(&sway_surface->view->unmanaged_view_link); | 124 | container_view_destroy(sway_surface->view->swayc); |
132 | } | ||
133 | |||
134 | // take it out of the tree | ||
135 | struct sway_container *parent = container_view_destroy(sway_surface->view->swayc); | ||
136 | if (parent) { | ||
137 | arrange_windows(parent, -1, -1); | ||
138 | } | ||
139 | |||
140 | sway_surface->view->swayc = NULL; | 125 | sway_surface->view->swayc = NULL; |
141 | sway_surface->view->surface = NULL; | 126 | sway_surface->view->surface = NULL; |
142 | } | 127 | } |
143 | 128 | ||
144 | static void handle_map_notify(struct wl_listener *listener, void *data) { | 129 | static void handle_map(struct wl_listener *listener, void *data) { |
145 | // TODO put the view back into the tree | ||
146 | struct sway_xwayland_surface *sway_surface = | 130 | struct sway_xwayland_surface *sway_surface = |
147 | wl_container_of(listener, sway_surface, map_notify); | 131 | wl_container_of(listener, sway_surface, map); |
148 | struct wlr_xwayland_surface *xsurface = data; | 132 | struct wlr_xwayland_surface *xsurface = data; |
149 | 133 | ||
150 | sway_surface->view->surface = xsurface->surface; | 134 | sway_surface->view->surface = xsurface->surface; |
151 | 135 | ||
152 | // put it back into the tree | 136 | // put it back into the tree |
153 | if (xsurface->override_redirect) { | 137 | if (wlr_xwayland_surface_is_unmanaged(xsurface) || |
138 | xsurface->override_redirect) { | ||
139 | wl_list_remove(&sway_surface->view->unmanaged_view_link); | ||
154 | wl_list_insert(&root_container.sway_root->unmanaged_views, | 140 | wl_list_insert(&root_container.sway_root->unmanaged_views, |
155 | &sway_surface->view->unmanaged_view_link); | 141 | &sway_surface->view->unmanaged_view_link); |
156 | } else { | 142 | } else { |
157 | struct sway_view *view = sway_surface->view; | 143 | struct sway_view *view = sway_surface->view; |
158 | container_view_destroy(view->swayc); | 144 | container_view_destroy(view->swayc); |
159 | 145 | ||
160 | struct sway_container *parent = root_container.children->items[0]; | 146 | struct sway_seat *seat = input_manager_current_seat(input_manager); |
161 | parent = parent->children->items[0]; // workspace | 147 | struct sway_container *focus = sway_seat_get_focus_inactive(seat, &root_container); |
162 | 148 | struct sway_container *cont = container_view_create(focus, view); | |
163 | struct sway_container *cont = container_view_create(parent, view); | ||
164 | view->swayc = cont; | 149 | view->swayc = cont; |
165 | |||
166 | arrange_windows(cont->parent, -1, -1); | 150 | arrange_windows(cont->parent, -1, -1); |
167 | sway_input_manager_set_focus(input_manager, cont); | 151 | sway_input_manager_set_focus(input_manager, cont); |
168 | } | 152 | } |
153 | |||
154 | view_damage_whole(sway_surface->view); | ||
169 | } | 155 | } |
170 | 156 | ||
171 | static void handle_configure_request(struct wl_listener *listener, void *data) { | 157 | static void handle_configure_request(struct wl_listener *listener, void *data) { |
@@ -206,9 +192,10 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { | |||
206 | sway_view->iface.close = close_view; | 192 | sway_view->iface.close = close_view; |
207 | sway_view->wlr_xwayland_surface = xsurface; | 193 | sway_view->wlr_xwayland_surface = xsurface; |
208 | sway_view->sway_xwayland_surface = sway_surface; | 194 | sway_view->sway_xwayland_surface = sway_surface; |
209 | sway_view->surface = xsurface->surface; | ||
210 | sway_surface->view = sway_view; | 195 | sway_surface->view = sway_view; |
211 | 196 | ||
197 | wl_list_init(&sway_view->unmanaged_view_link); | ||
198 | |||
212 | // TODO: | 199 | // TODO: |
213 | // - Look up pid and open on appropriate workspace | 200 | // - Look up pid and open on appropriate workspace |
214 | // - Set new view to maximized so it behaves nicely | 201 | // - Set new view to maximized so it behaves nicely |
@@ -224,24 +211,11 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { | |||
224 | &sway_surface->request_configure); | 211 | &sway_surface->request_configure); |
225 | sway_surface->request_configure.notify = handle_configure_request; | 212 | sway_surface->request_configure.notify = handle_configure_request; |
226 | 213 | ||
227 | wl_signal_add(&xsurface->events.unmap_notify, &sway_surface->unmap_notify); | 214 | wl_signal_add(&xsurface->events.unmap, &sway_surface->unmap); |
228 | sway_surface->unmap_notify.notify = handle_unmap_notify; | 215 | sway_surface->unmap.notify = handle_unmap; |
229 | |||
230 | wl_signal_add(&xsurface->events.map_notify, &sway_surface->map_notify); | ||
231 | sway_surface->map_notify.notify = handle_map_notify; | ||
232 | |||
233 | if (wlr_xwayland_surface_is_unmanaged(xsurface)) { | ||
234 | // these don't get a container in the tree | ||
235 | wl_list_insert(&root_container.sway_root->unmanaged_views, | ||
236 | &sway_view->unmanaged_view_link); | ||
237 | return; | ||
238 | } | ||
239 | 216 | ||
240 | struct sway_seat *seat = input_manager_current_seat(input_manager); | 217 | wl_signal_add(&xsurface->events.map, &sway_surface->map); |
241 | struct sway_container *focus = sway_seat_get_focus_inactive(seat, &root_container); | 218 | sway_surface->map.notify = handle_map; |
242 | struct sway_container *cont = container_view_create(focus, sway_view); | ||
243 | sway_view->swayc = cont; | ||
244 | 219 | ||
245 | arrange_windows(cont->parent, -1, -1); | 220 | handle_map(&sway_surface->map, xsurface); |
246 | sway_input_manager_set_focus(input_manager, cont); | ||
247 | } | 221 | } |