diff options
author | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-05-24 22:30:44 +1000 |
---|---|---|
committer | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-06-01 23:14:58 +1000 |
commit | 1f2e399ade77070a2d0b82856ad9a3eef96b8676 (patch) | |
tree | c469197e140051aea912cb173723c7e55ce1e410 /sway/desktop/xwayland.c | |
parent | Send frame done to floating views (diff) | |
download | sway-1f2e399ade77070a2d0b82856ad9a3eef96b8676.tar.gz sway-1f2e399ade77070a2d0b82856ad9a3eef96b8676.tar.zst sway-1f2e399ade77070a2d0b82856ad9a3eef96b8676.zip |
Implement floating
Diffstat (limited to 'sway/desktop/xwayland.c')
-rw-r--r-- | sway/desktop/xwayland.c | 97 |
1 files changed, 77 insertions, 20 deletions
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index 6a99a66a..56cac1bd 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c | |||
@@ -152,7 +152,9 @@ static uint32_t get_int_prop(struct sway_view *view, enum sway_view_prop prop) { | |||
152 | } | 152 | } |
153 | } | 153 | } |
154 | 154 | ||
155 | static void configure(struct sway_view *view, double ox, double oy, int width, | 155 | // The x and y arguments are output-local for tiled views, and layout |
156 | // coordinates for floating views. | ||
157 | static void configure(struct sway_view *view, double x, double y, int width, | ||
156 | int height) { | 158 | int height) { |
157 | struct sway_xwayland_view *xwayland_view = xwayland_view_from_view(view); | 159 | struct sway_xwayland_view *xwayland_view = xwayland_view_from_view(view); |
158 | if (xwayland_view == NULL) { | 160 | if (xwayland_view == NULL) { |
@@ -160,25 +162,33 @@ static void configure(struct sway_view *view, double ox, double oy, int width, | |||
160 | } | 162 | } |
161 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; | 163 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; |
162 | 164 | ||
163 | struct sway_container *output = container_parent(view->swayc, C_OUTPUT); | 165 | double lx, ly; |
164 | if (!sway_assert(output, "view must be within tree to set position")) { | 166 | if (view->swayc->is_floating) { |
165 | return; | 167 | lx = x; |
166 | } | 168 | ly = y; |
167 | struct sway_container *root = container_parent(output, C_ROOT); | 169 | } else { |
168 | if (!sway_assert(root, "output must be within tree to set position")) { | 170 | struct sway_container *output = container_parent(view->swayc, C_OUTPUT); |
169 | return; | 171 | if (!sway_assert(output, "view must be within tree to set position")) { |
170 | } | 172 | return; |
171 | struct wlr_output_layout *layout = root->sway_root->output_layout; | 173 | } |
172 | struct wlr_output_layout_output *loutput = | 174 | struct sway_container *root = container_parent(output, C_ROOT); |
173 | wlr_output_layout_get(layout, output->sway_output->wlr_output); | 175 | if (!sway_assert(root, "output must be within tree to set position")) { |
174 | if (!sway_assert(loutput, "output must be within layout to set position")) { | 176 | return; |
175 | return; | 177 | } |
178 | struct wlr_output_layout *layout = root->sway_root->output_layout; | ||
179 | struct wlr_output_layout_output *loutput = | ||
180 | wlr_output_layout_get(layout, output->sway_output->wlr_output); | ||
181 | if (!sway_assert(loutput, | ||
182 | "output must be within layout to set position")) { | ||
183 | return; | ||
184 | } | ||
185 | lx = x + loutput->x; | ||
186 | ly = y + loutput->y; | ||
176 | } | 187 | } |
177 | 188 | ||
178 | xwayland_view->pending_width = width; | 189 | xwayland_view->pending_width = width; |
179 | xwayland_view->pending_height = height; | 190 | xwayland_view->pending_height = height; |
180 | wlr_xwayland_surface_configure(xsurface, ox + loutput->x, oy + loutput->y, | 191 | wlr_xwayland_surface_configure(xsurface, lx, ly, width, height); |
181 | width, height); | ||
182 | } | 192 | } |
183 | 193 | ||
184 | static void set_activated(struct sway_view *view, bool activated) { | 194 | static void set_activated(struct sway_view *view, bool activated) { |
@@ -189,6 +199,14 @@ static void set_activated(struct sway_view *view, bool activated) { | |||
189 | wlr_xwayland_surface_activate(surface, activated); | 199 | wlr_xwayland_surface_activate(surface, activated); |
190 | } | 200 | } |
191 | 201 | ||
202 | static void set_maximized(struct sway_view *view, bool maximized) { | ||
203 | if (xwayland_view_from_view(view) == NULL) { | ||
204 | return; | ||
205 | } | ||
206 | struct wlr_xwayland_surface *surface = view->wlr_xwayland_surface; | ||
207 | wlr_xwayland_surface_set_maximized(surface, maximized); | ||
208 | } | ||
209 | |||
192 | static void set_fullscreen(struct sway_view *view, bool fullscreen) { | 210 | static void set_fullscreen(struct sway_view *view, bool fullscreen) { |
193 | if (xwayland_view_from_view(view) == NULL) { | 211 | if (xwayland_view_from_view(view) == NULL) { |
194 | return; | 212 | return; |
@@ -197,6 +215,35 @@ static void set_fullscreen(struct sway_view *view, bool fullscreen) { | |||
197 | wlr_xwayland_surface_set_fullscreen(surface, fullscreen); | 215 | wlr_xwayland_surface_set_fullscreen(surface, fullscreen); |
198 | } | 216 | } |
199 | 217 | ||
218 | static bool wants_floating(struct sway_view *view) { | ||
219 | // TODO: | ||
220 | // We want to return true if the window type contains any of these: | ||
221 | // NET_WM_WINDOW_TYPE_DIALOG | ||
222 | // NET_WM_WINDOW_TYPE_UTILITY | ||
223 | // NET_WM_WINDOW_TYPE_TOOLBAR | ||
224 | // NET_WM_WINDOW_TYPE_SPLASH | ||
225 | // | ||
226 | // We also want to return true if the NET_WM_STATE is MODAL. | ||
227 | // wlroots doesn't appear to provide all this information at the moment. | ||
228 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; | ||
229 | uint32_t *atom = xsurface->window_type; | ||
230 | for (size_t i = 0; i < xsurface->window_type_len; ++i) { | ||
231 | wlr_log(L_DEBUG, "xwayland window type %i", *atom); | ||
232 | // TODO: Come up with a better way of doing this | ||
233 | switch (*atom) { | ||
234 | case 36: // NET_WM_WINDOW_TYPE_UTILITY | ||
235 | case 44: // NET_WM_WINDOW_TYPE_SPLASH | ||
236 | case 276: // ? PGP passphrase dialog | ||
237 | case 337: // ? Firefox open file dialog | ||
238 | case 338: // ? Firefox open file dialog | ||
239 | return true; | ||
240 | } | ||
241 | ++atom; | ||
242 | } | ||
243 | |||
244 | return false; | ||
245 | } | ||
246 | |||
200 | static void _close(struct sway_view *view) { | 247 | static void _close(struct sway_view *view) { |
201 | if (xwayland_view_from_view(view) == NULL) { | 248 | if (xwayland_view_from_view(view) == NULL) { |
202 | return; | 249 | return; |
@@ -225,7 +272,9 @@ static const struct sway_view_impl view_impl = { | |||
225 | .get_int_prop = get_int_prop, | 272 | .get_int_prop = get_int_prop, |
226 | .configure = configure, | 273 | .configure = configure, |
227 | .set_activated = set_activated, | 274 | .set_activated = set_activated, |
275 | .set_maximized = set_maximized, | ||
228 | .set_fullscreen = set_fullscreen, | 276 | .set_fullscreen = set_fullscreen, |
277 | .wants_floating = wants_floating, | ||
229 | .close = _close, | 278 | .close = _close, |
230 | .destroy = destroy, | 279 | .destroy = destroy, |
231 | }; | 280 | }; |
@@ -234,10 +283,18 @@ static void handle_commit(struct wl_listener *listener, void *data) { | |||
234 | struct sway_xwayland_view *xwayland_view = | 283 | struct sway_xwayland_view *xwayland_view = |
235 | wl_container_of(listener, xwayland_view, commit); | 284 | wl_container_of(listener, xwayland_view, commit); |
236 | struct sway_view *view = &xwayland_view->view; | 285 | struct sway_view *view = &xwayland_view->view; |
237 | // NOTE: We intentionally discard the view's desired width here | 286 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; |
238 | // TODO: Let floating views do whatever | 287 | if (!view->natural_width && !view->natural_height) { |
239 | view_update_size(view, xwayland_view->pending_width, | 288 | view->natural_width = xsurface->width; |
240 | xwayland_view->pending_height); | 289 | view->natural_height = xsurface->height; |
290 | } | ||
291 | if (view->swayc && view->swayc->is_floating) { | ||
292 | view_update_size(view, xsurface->width, xsurface->height); | ||
293 | view_update_position(view, xsurface->x, xsurface->y); | ||
294 | } else { | ||
295 | view_update_size(view, xwayland_view->pending_width, | ||
296 | xwayland_view->pending_height); | ||
297 | } | ||
241 | view_damage_from(view); | 298 | view_damage_from(view); |
242 | } | 299 | } |
243 | 300 | ||