diff options
author | emersion <contact@emersion.fr> | 2018-04-05 11:38:14 -0400 |
---|---|---|
committer | emersion <contact@emersion.fr> | 2018-04-05 11:40:39 -0400 |
commit | dcd15a2d3dd93e057fe702238eb21dd70331b44f (patch) | |
tree | d3fb74ee77369ad52edeba7bac1f3ada907d3099 /sway/desktop/xwayland.c | |
parent | Error handling in swaylock daemonize() (diff) | |
download | sway-dcd15a2d3dd93e057fe702238eb21dd70331b44f.tar.gz sway-dcd15a2d3dd93e057fe702238eb21dd70331b44f.tar.zst sway-dcd15a2d3dd93e057fe702238eb21dd70331b44f.zip |
Implement shell views
Diffstat (limited to 'sway/desktop/xwayland.c')
-rw-r--r-- | sway/desktop/xwayland.c | 123 |
1 files changed, 66 insertions, 57 deletions
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index a793928c..384f4236 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c | |||
@@ -41,13 +41,17 @@ static void create_unmanaged(struct wlr_xwayland_surface *xsurface) { | |||
41 | } | 41 | } |
42 | 42 | ||
43 | 43 | ||
44 | static bool assert_xwayland(struct sway_view *view) { | 44 | static struct sway_xwayland_view *xwayland_view_from_view( |
45 | return sway_assert(view->type == SWAY_VIEW_XWAYLAND, | 45 | struct sway_view *view) { |
46 | "Expected xwayland view!"); | 46 | if (!sway_assert(view->type == SWAY_VIEW_XWAYLAND, |
47 | "Expected xwayland view")) { | ||
48 | return NULL; | ||
49 | } | ||
50 | return (struct sway_xwayland_view *)view; | ||
47 | } | 51 | } |
48 | 52 | ||
49 | static const char *get_prop(struct sway_view *view, enum sway_view_prop prop) { | 53 | static const char *get_prop(struct sway_view *view, enum sway_view_prop prop) { |
50 | if (!assert_xwayland(view)) { | 54 | if (xwayland_view_from_view(view) == NULL) { |
51 | return NULL; | 55 | return NULL; |
52 | } | 56 | } |
53 | switch (prop) { | 57 | switch (prop) { |
@@ -62,7 +66,8 @@ static const char *get_prop(struct sway_view *view, enum sway_view_prop prop) { | |||
62 | 66 | ||
63 | static void configure(struct sway_view *view, double ox, double oy, int width, | 67 | static void configure(struct sway_view *view, double ox, double oy, int width, |
64 | int height) { | 68 | int height) { |
65 | if (!assert_xwayland(view)) { | 69 | struct sway_xwayland_view *xwayland_view = xwayland_view_from_view(view); |
70 | if (xwayland_view == NULL) { | ||
66 | return; | 71 | return; |
67 | } | 72 | } |
68 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; | 73 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; |
@@ -84,14 +89,14 @@ static void configure(struct sway_view *view, double ox, double oy, int width, | |||
84 | 89 | ||
85 | view_update_position(view, ox, oy); | 90 | view_update_position(view, ox, oy); |
86 | 91 | ||
87 | view->sway_xwayland_surface->pending_width = width; | 92 | xwayland_view->pending_width = width; |
88 | view->sway_xwayland_surface->pending_height = height; | 93 | xwayland_view->pending_height = height; |
89 | wlr_xwayland_surface_configure(xsurface, ox + loutput->x, oy + loutput->y, | 94 | wlr_xwayland_surface_configure(xsurface, ox + loutput->x, oy + loutput->y, |
90 | width, height); | 95 | width, height); |
91 | } | 96 | } |
92 | 97 | ||
93 | static void set_activated(struct sway_view *view, bool activated) { | 98 | static void set_activated(struct sway_view *view, bool activated) { |
94 | if (!assert_xwayland(view)) { | 99 | if (xwayland_view_from_view(view) == NULL) { |
95 | return; | 100 | return; |
96 | } | 101 | } |
97 | struct wlr_xwayland_surface *surface = view->wlr_xwayland_surface; | 102 | struct wlr_xwayland_surface *surface = view->wlr_xwayland_surface; |
@@ -99,12 +104,24 @@ static void set_activated(struct sway_view *view, bool activated) { | |||
99 | } | 104 | } |
100 | 105 | ||
101 | static void _close(struct sway_view *view) { | 106 | static void _close(struct sway_view *view) { |
102 | if (!assert_xwayland(view)) { | 107 | if (xwayland_view_from_view(view) == NULL) { |
103 | return; | 108 | return; |
104 | } | 109 | } |
105 | wlr_xwayland_surface_close(view->wlr_xwayland_surface); | 110 | wlr_xwayland_surface_close(view->wlr_xwayland_surface); |
106 | } | 111 | } |
107 | 112 | ||
113 | static void destroy(struct sway_view *view) { | ||
114 | struct sway_xwayland_view *xwayland_view = xwayland_view_from_view(view); | ||
115 | if (xwayland_view == NULL) { | ||
116 | return; | ||
117 | } | ||
118 | wl_list_remove(&xwayland_view->destroy.link); | ||
119 | wl_list_remove(&xwayland_view->request_configure.link); | ||
120 | wl_list_remove(&xwayland_view->map.link); | ||
121 | wl_list_remove(&xwayland_view->unmap.link); | ||
122 | free(xwayland_view); | ||
123 | } | ||
124 | |||
108 | static const struct sway_view_impl view_impl = { | 125 | static const struct sway_view_impl view_impl = { |
109 | .get_prop = get_prop, | 126 | .get_prop = get_prop, |
110 | .configure = configure, | 127 | .configure = configure, |
@@ -113,50 +130,50 @@ static const struct sway_view_impl view_impl = { | |||
113 | }; | 130 | }; |
114 | 131 | ||
115 | static void handle_commit(struct wl_listener *listener, void *data) { | 132 | static void handle_commit(struct wl_listener *listener, void *data) { |
116 | struct sway_xwayland_surface *sway_surface = | 133 | struct sway_xwayland_view *xwayland_view = |
117 | wl_container_of(listener, sway_surface, commit); | 134 | wl_container_of(listener, xwayland_view, commit); |
118 | struct sway_view *view = sway_surface->view; | 135 | struct sway_view *view = &xwayland_view->view; |
119 | // NOTE: We intentionally discard the view's desired width here | 136 | // NOTE: We intentionally discard the view's desired width here |
120 | // TODO: Let floating views do whatever | 137 | // TODO: Let floating views do whatever |
121 | view_update_size(view, sway_surface->pending_width, | 138 | view_update_size(view, xwayland_view->pending_width, |
122 | sway_surface->pending_height); | 139 | xwayland_view->pending_height); |
123 | view_damage_from(view); | 140 | view_damage_from(view); |
124 | } | 141 | } |
125 | 142 | ||
126 | static void handle_destroy(struct wl_listener *listener, void *data) { | 143 | static void handle_destroy(struct wl_listener *listener, void *data) { |
127 | struct sway_xwayland_surface *sway_surface = | 144 | struct sway_xwayland_view *xwayland_view = |
128 | wl_container_of(listener, sway_surface, destroy); | 145 | wl_container_of(listener, xwayland_view, destroy); |
129 | wl_list_remove(&sway_surface->commit.link); | 146 | view_destroy(&xwayland_view->view); |
130 | wl_list_remove(&sway_surface->destroy.link); | ||
131 | wl_list_remove(&sway_surface->request_configure.link); | ||
132 | wl_list_remove(&sway_surface->map.link); | ||
133 | wl_list_remove(&sway_surface->unmap.link); | ||
134 | view_destroy(sway_surface->view); | ||
135 | free(sway_surface); | ||
136 | } | 147 | } |
137 | 148 | ||
138 | static void handle_unmap(struct wl_listener *listener, void *data) { | 149 | static void handle_unmap(struct wl_listener *listener, void *data) { |
139 | struct sway_xwayland_surface *sway_surface = | 150 | struct sway_xwayland_view *xwayland_view = |
140 | wl_container_of(listener, sway_surface, unmap); | 151 | wl_container_of(listener, xwayland_view, unmap); |
141 | view_unmap(sway_surface->view); | 152 | wl_list_remove(&xwayland_view->commit.link); |
153 | view_unmap(&xwayland_view->view); | ||
142 | } | 154 | } |
143 | 155 | ||
144 | static void handle_map(struct wl_listener *listener, void *data) { | 156 | static void handle_map(struct wl_listener *listener, void *data) { |
145 | struct sway_xwayland_surface *sway_surface = | 157 | struct sway_xwayland_view *xwayland_view = |
146 | wl_container_of(listener, sway_surface, map); | 158 | wl_container_of(listener, xwayland_view, map); |
147 | struct wlr_xwayland_surface *xsurface = data; | 159 | struct wlr_xwayland_surface *xsurface = data; |
148 | struct sway_view *view = sway_surface->view; | 160 | struct sway_view *view = &xwayland_view->view; |
161 | |||
162 | // Wire up the commit listener here, because xwayland map/unmap can change | ||
163 | // the underlying wlr_surface | ||
164 | wl_signal_add(&xsurface->surface->events.commit, &xwayland_view->commit); | ||
165 | xwayland_view->commit.notify = handle_commit; | ||
149 | 166 | ||
150 | // put it back into the tree | 167 | // Put it back into the tree |
151 | wlr_xwayland_surface_set_maximized(xsurface, true); | 168 | wlr_xwayland_surface_set_maximized(xsurface, true); |
152 | view_map(view, xsurface->surface); | 169 | view_map(view, xsurface->surface); |
153 | } | 170 | } |
154 | 171 | ||
155 | static void handle_request_configure(struct wl_listener *listener, void *data) { | 172 | static void handle_request_configure(struct wl_listener *listener, void *data) { |
156 | struct sway_xwayland_surface *sway_surface = | 173 | struct sway_xwayland_view *xwayland_view = |
157 | wl_container_of(listener, sway_surface, request_configure); | 174 | wl_container_of(listener, xwayland_view, request_configure); |
158 | struct wlr_xwayland_surface_configure_event *ev = data; | 175 | struct wlr_xwayland_surface_configure_event *ev = data; |
159 | struct sway_view *view = sway_surface->view; | 176 | struct sway_view *view = &xwayland_view->view; |
160 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; | 177 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; |
161 | // TODO: floating windows are allowed to move around like this, but make | 178 | // TODO: floating windows are allowed to move around like this, but make |
162 | // sure tiling windows always stay in place. | 179 | // sure tiling windows always stay in place. |
@@ -165,8 +182,8 @@ static void handle_request_configure(struct wl_listener *listener, void *data) { | |||
165 | } | 182 | } |
166 | 183 | ||
167 | void handle_xwayland_surface(struct wl_listener *listener, void *data) { | 184 | void handle_xwayland_surface(struct wl_listener *listener, void *data) { |
168 | struct sway_server *server = wl_container_of( | 185 | struct sway_server *server = wl_container_of(listener, server, |
169 | listener, server, xwayland_surface); | 186 | xwayland_surface); |
170 | struct wlr_xwayland_surface *xsurface = data; | 187 | struct wlr_xwayland_surface *xsurface = data; |
171 | 188 | ||
172 | if (wlr_xwayland_surface_is_unmanaged(xsurface) || | 189 | if (wlr_xwayland_surface_is_unmanaged(xsurface) || |
@@ -179,39 +196,31 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { | |||
179 | wlr_log(L_DEBUG, "New xwayland surface title='%s' class='%s'", | 196 | wlr_log(L_DEBUG, "New xwayland surface title='%s' class='%s'", |
180 | xsurface->title, xsurface->class); | 197 | xsurface->title, xsurface->class); |
181 | 198 | ||
182 | struct sway_xwayland_surface *sway_surface = | 199 | struct sway_xwayland_view *xwayland_view = |
183 | calloc(1, sizeof(struct sway_xwayland_surface)); | 200 | calloc(1, sizeof(struct sway_xwayland_view)); |
184 | if (!sway_assert(sway_surface, "Failed to allocate surface")) { | 201 | if (!sway_assert(xwayland_view, "Failed to allocate view")) { |
185 | return; | 202 | return; |
186 | } | 203 | } |
187 | 204 | ||
188 | struct sway_view *view = view_create(SWAY_VIEW_XWAYLAND, &view_impl); | 205 | view_init(&xwayland_view->view, SWAY_VIEW_XWAYLAND, &view_impl); |
189 | if (!sway_assert(view, "Failed to allocate view")) { | 206 | xwayland_view->view.wlr_xwayland_surface = xsurface; |
190 | return; | ||
191 | } | ||
192 | view->wlr_xwayland_surface = xsurface; | ||
193 | view->sway_xwayland_surface = sway_surface; | ||
194 | sway_surface->view = view; | ||
195 | 207 | ||
196 | // TODO: | 208 | // TODO: |
197 | // - Look up pid and open on appropriate workspace | 209 | // - Look up pid and open on appropriate workspace |
198 | // - Criteria | 210 | // - Criteria |
199 | 211 | ||
200 | wl_signal_add(&xsurface->surface->events.commit, &sway_surface->commit); | 212 | wl_signal_add(&xsurface->events.destroy, &xwayland_view->destroy); |
201 | sway_surface->commit.notify = handle_commit; | 213 | xwayland_view->destroy.notify = handle_destroy; |
202 | |||
203 | wl_signal_add(&xsurface->events.destroy, &sway_surface->destroy); | ||
204 | sway_surface->destroy.notify = handle_destroy; | ||
205 | 214 | ||
206 | wl_signal_add(&xsurface->events.request_configure, | 215 | wl_signal_add(&xsurface->events.request_configure, |
207 | &sway_surface->request_configure); | 216 | &xwayland_view->request_configure); |
208 | sway_surface->request_configure.notify = handle_request_configure; | 217 | xwayland_view->request_configure.notify = handle_request_configure; |
209 | 218 | ||
210 | wl_signal_add(&xsurface->events.unmap, &sway_surface->unmap); | 219 | wl_signal_add(&xsurface->events.unmap, &xwayland_view->unmap); |
211 | sway_surface->unmap.notify = handle_unmap; | 220 | xwayland_view->unmap.notify = handle_unmap; |
212 | 221 | ||
213 | wl_signal_add(&xsurface->events.map, &sway_surface->map); | 222 | wl_signal_add(&xsurface->events.map, &xwayland_view->map); |
214 | sway_surface->map.notify = handle_map; | 223 | xwayland_view->map.notify = handle_map; |
215 | 224 | ||
216 | handle_map(&sway_surface->map, xsurface); | 225 | handle_map(&xwayland_view->map, xsurface); |
217 | } | 226 | } |