diff options
author | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-09-24 20:54:57 +1000 |
---|---|---|
committer | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-09-27 22:51:37 +1000 |
commit | 7b138e5ef0f679c9bb0078019d7c9c63fef36273 (patch) | |
tree | 2cdbeb394889065e0606a1fcbe38c1e99e25d260 /sway/desktop | |
parent | Merge pull request #2717 from ianyfan/tablet-config (diff) | |
download | sway-7b138e5ef0f679c9bb0078019d7c9c63fef36273.tar.gz sway-7b138e5ef0f679c9bb0078019d7c9c63fef36273.tar.zst sway-7b138e5ef0f679c9bb0078019d7c9c63fef36273.zip |
Add CSD to border modes
This replaces view.using_csd with a new border mode: B_CSD. This also
removes sway_xdg_shell{_v6}_view.deco_mode and
view->has_client_side_decorations as we can now get these from the
border.
You can use `border toggle` to cycle through the modes including CSD, or
use `border csd` to set it directly. The client must support the
xdg-decoration protocol, and the only client I know of that does is the
example in wlroots.
If the client switches from SSD to CSD without us expecting it (via the
server-decoration protocol), we stash the previous border type into
view.saved_border so we can restore it if the client returns to SSD. I
haven't found a way to test this though.
Diffstat (limited to 'sway/desktop')
-rw-r--r-- | sway/desktop/render.c | 108 | ||||
-rw-r--r-- | sway/desktop/transaction.c | 1 | ||||
-rw-r--r-- | sway/desktop/xdg_shell.c | 22 | ||||
-rw-r--r-- | sway/desktop/xdg_shell_v6.c | 22 | ||||
-rw-r--r-- | sway/desktop/xwayland.c | 20 |
5 files changed, 74 insertions, 99 deletions
diff --git a/sway/desktop/render.c b/sway/desktop/render.c index af4e2905..c8b08a58 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c | |||
@@ -272,7 +272,7 @@ static void render_view(struct sway_output *output, pixman_region32_t *damage, | |||
272 | render_view_toplevels(view, output, damage, view->container->alpha); | 272 | render_view_toplevels(view, output, damage, view->container->alpha); |
273 | } | 273 | } |
274 | 274 | ||
275 | if (view->container->current.using_csd) { | 275 | if (con->current.border == B_NONE || con->current.border == B_CSD) { |
276 | return; | 276 | return; |
277 | } | 277 | } |
278 | 278 | ||
@@ -281,51 +281,49 @@ static void render_view(struct sway_output *output, pixman_region32_t *damage, | |||
281 | float color[4]; | 281 | float color[4]; |
282 | struct sway_container_state *state = &con->current; | 282 | struct sway_container_state *state = &con->current; |
283 | 283 | ||
284 | if (state->border != B_NONE) { | 284 | if (state->border_left) { |
285 | if (state->border_left) { | 285 | memcpy(&color, colors->child_border, sizeof(float) * 4); |
286 | memcpy(&color, colors->child_border, sizeof(float) * 4); | 286 | premultiply_alpha(color, con->alpha); |
287 | premultiply_alpha(color, con->alpha); | 287 | box.x = state->con_x; |
288 | box.x = state->con_x; | 288 | box.y = state->view_y; |
289 | box.y = state->view_y; | 289 | box.width = state->border_thickness; |
290 | box.width = state->border_thickness; | 290 | box.height = state->view_height; |
291 | box.height = state->view_height; | 291 | scale_box(&box, output_scale); |
292 | scale_box(&box, output_scale); | 292 | render_rect(output->wlr_output, damage, &box, color); |
293 | render_rect(output->wlr_output, damage, &box, color); | 293 | } |
294 | } | ||
295 | 294 | ||
296 | list_t *siblings = container_get_current_siblings(con); | 295 | list_t *siblings = container_get_current_siblings(con); |
297 | enum sway_container_layout layout = | 296 | enum sway_container_layout layout = |
298 | container_current_parent_layout(con); | 297 | container_current_parent_layout(con); |
299 | 298 | ||
300 | if (state->border_right) { | 299 | if (state->border_right) { |
301 | if (siblings->length == 1 && layout == L_HORIZ) { | 300 | if (siblings->length == 1 && layout == L_HORIZ) { |
302 | memcpy(&color, colors->indicator, sizeof(float) * 4); | 301 | memcpy(&color, colors->indicator, sizeof(float) * 4); |
303 | } else { | 302 | } else { |
304 | memcpy(&color, colors->child_border, sizeof(float) * 4); | 303 | memcpy(&color, colors->child_border, sizeof(float) * 4); |
305 | } | ||
306 | premultiply_alpha(color, con->alpha); | ||
307 | box.x = state->view_x + state->view_width; | ||
308 | box.y = state->view_y; | ||
309 | box.width = state->border_thickness; | ||
310 | box.height = state->view_height; | ||
311 | scale_box(&box, output_scale); | ||
312 | render_rect(output->wlr_output, damage, &box, color); | ||
313 | } | 304 | } |
305 | premultiply_alpha(color, con->alpha); | ||
306 | box.x = state->view_x + state->view_width; | ||
307 | box.y = state->view_y; | ||
308 | box.width = state->border_thickness; | ||
309 | box.height = state->view_height; | ||
310 | scale_box(&box, output_scale); | ||
311 | render_rect(output->wlr_output, damage, &box, color); | ||
312 | } | ||
314 | 313 | ||
315 | if (state->border_bottom) { | 314 | if (state->border_bottom) { |
316 | if (siblings->length == 1 && layout == L_VERT) { | 315 | if (siblings->length == 1 && layout == L_VERT) { |
317 | memcpy(&color, colors->indicator, sizeof(float) * 4); | 316 | memcpy(&color, colors->indicator, sizeof(float) * 4); |
318 | } else { | 317 | } else { |
319 | memcpy(&color, colors->child_border, sizeof(float) * 4); | 318 | memcpy(&color, colors->child_border, sizeof(float) * 4); |
320 | } | ||
321 | premultiply_alpha(color, con->alpha); | ||
322 | box.x = state->con_x; | ||
323 | box.y = state->view_y + state->view_height; | ||
324 | box.width = state->con_width; | ||
325 | box.height = state->border_thickness; | ||
326 | scale_box(&box, output_scale); | ||
327 | render_rect(output->wlr_output, damage, &box, color); | ||
328 | } | 319 | } |
320 | premultiply_alpha(color, con->alpha); | ||
321 | box.x = state->con_x; | ||
322 | box.y = state->view_y + state->view_height; | ||
323 | box.width = state->con_width; | ||
324 | box.height = state->border_thickness; | ||
325 | scale_box(&box, output_scale); | ||
326 | render_rect(output->wlr_output, damage, &box, color); | ||
329 | } | 327 | } |
330 | } | 328 | } |
331 | 329 | ||
@@ -645,14 +643,12 @@ static void render_containers_linear(struct sway_output *output, | |||
645 | marks_texture = view->marks_unfocused; | 643 | marks_texture = view->marks_unfocused; |
646 | } | 644 | } |
647 | 645 | ||
648 | if (!view->container->current.using_csd) { | 646 | if (state->border == B_NORMAL) { |
649 | if (state->border == B_NORMAL) { | 647 | render_titlebar(output, damage, child, state->con_x, |
650 | render_titlebar(output, damage, child, state->con_x, | 648 | state->con_y, state->con_width, colors, |
651 | state->con_y, state->con_width, colors, | 649 | title_texture, marks_texture); |
652 | title_texture, marks_texture); | 650 | } else if (state->border == B_PIXEL) { |
653 | } else { | 651 | render_top_border(output, damage, child, colors); |
654 | render_top_border(output, damage, child, colors); | ||
655 | } | ||
656 | } | 652 | } |
657 | render_view(output, damage, child, colors); | 653 | render_view(output, damage, child, colors); |
658 | } else { | 654 | } else { |
@@ -859,14 +855,12 @@ static void render_floating_container(struct sway_output *soutput, | |||
859 | marks_texture = view->marks_unfocused; | 855 | marks_texture = view->marks_unfocused; |
860 | } | 856 | } |
861 | 857 | ||
862 | if (!view->container->current.using_csd) { | 858 | if (con->current.border == B_NORMAL) { |
863 | if (con->current.border == B_NORMAL) { | 859 | render_titlebar(soutput, damage, con, con->current.con_x, |
864 | render_titlebar(soutput, damage, con, con->current.con_x, | 860 | con->current.con_y, con->current.con_width, colors, |
865 | con->current.con_y, con->current.con_width, colors, | 861 | title_texture, marks_texture); |
866 | title_texture, marks_texture); | 862 | } else if (con->current.border == B_PIXEL) { |
867 | } else if (con->current.border != B_NONE) { | 863 | render_top_border(soutput, damage, con, colors); |
868 | render_top_border(soutput, damage, con, colors); | ||
869 | } | ||
870 | } | 864 | } |
871 | render_view(soutput, damage, con, colors); | 865 | render_view(soutput, damage, con, colors); |
872 | } else { | 866 | } else { |
diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index 797f6b4c..4624d824 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c | |||
@@ -167,7 +167,6 @@ static void copy_container_state(struct sway_container *container, | |||
167 | state->border_left = view->border_left; | 167 | state->border_left = view->border_left; |
168 | state->border_right = view->border_right; | 168 | state->border_right = view->border_right; |
169 | state->border_bottom = view->border_bottom; | 169 | state->border_bottom = view->border_bottom; |
170 | state->using_csd = view->using_csd; | ||
171 | } else { | 170 | } else { |
172 | state->children = create_list(); | 171 | state->children = create_list(); |
173 | list_cat(state->children, container->children); | 172 | list_cat(state->children, container->children); |
diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index 6d1ccdd7..d563edae 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c | |||
@@ -175,15 +175,6 @@ static bool wants_floating(struct sway_view *view) { | |||
175 | || toplevel->parent; | 175 | || toplevel->parent; |
176 | } | 176 | } |
177 | 177 | ||
178 | static bool has_client_side_decorations(struct sway_view *view) { | ||
179 | struct sway_xdg_shell_view *xdg_shell_view = | ||
180 | xdg_shell_view_from_view(view); | ||
181 | if (xdg_shell_view == NULL) { | ||
182 | return true; | ||
183 | } | ||
184 | return xdg_shell_view->deco_mode != WLR_SERVER_DECORATION_MANAGER_MODE_SERVER; | ||
185 | } | ||
186 | |||
187 | static void for_each_surface(struct sway_view *view, | 178 | static void for_each_surface(struct sway_view *view, |
188 | wlr_surface_iterator_func_t iterator, void *user_data) { | 179 | wlr_surface_iterator_func_t iterator, void *user_data) { |
189 | if (xdg_shell_view_from_view(view) == NULL) { | 180 | if (xdg_shell_view_from_view(view) == NULL) { |
@@ -240,7 +231,6 @@ static const struct sway_view_impl view_impl = { | |||
240 | .set_tiled = set_tiled, | 231 | .set_tiled = set_tiled, |
241 | .set_fullscreen = set_fullscreen, | 232 | .set_fullscreen = set_fullscreen, |
242 | .wants_floating = wants_floating, | 233 | .wants_floating = wants_floating, |
243 | .has_client_side_decorations = has_client_side_decorations, | ||
244 | .for_each_surface = for_each_surface, | 234 | .for_each_surface = for_each_surface, |
245 | .for_each_popup = for_each_popup, | 235 | .for_each_popup = for_each_popup, |
246 | .close = _close, | 236 | .close = _close, |
@@ -385,15 +375,13 @@ static void handle_map(struct wl_listener *listener, void *data) { | |||
385 | view->natural_height = view->wlr_xdg_surface->surface->current.height; | 375 | view->natural_height = view->wlr_xdg_surface->surface->current.height; |
386 | } | 376 | } |
387 | 377 | ||
378 | view_map(view, view->wlr_xdg_surface->surface); | ||
379 | |||
388 | struct sway_server_decoration *deco = | 380 | struct sway_server_decoration *deco = |
389 | decoration_from_surface(xdg_surface->surface); | 381 | decoration_from_surface(xdg_surface->surface); |
390 | if (deco != NULL) { | 382 | bool csd = !deco || deco->wlr_server_decoration->mode == |
391 | xdg_shell_view->deco_mode = deco->wlr_server_decoration->mode; | 383 | WLR_SERVER_DECORATION_MANAGER_MODE_CLIENT; |
392 | } else { | 384 | view_set_csd_from_client(view, csd); |
393 | xdg_shell_view->deco_mode = WLR_SERVER_DECORATION_MANAGER_MODE_CLIENT; | ||
394 | } | ||
395 | |||
396 | view_map(view, view->wlr_xdg_surface->surface); | ||
397 | 385 | ||
398 | if (xdg_surface->toplevel->client_pending.fullscreen) { | 386 | if (xdg_surface->toplevel->client_pending.fullscreen) { |
399 | container_set_fullscreen(view->container, true); | 387 | container_set_fullscreen(view->container, true); |
diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index 95ca396c..8c8085f7 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c | |||
@@ -171,15 +171,6 @@ static bool wants_floating(struct sway_view *view) { | |||
171 | || toplevel->parent; | 171 | || toplevel->parent; |
172 | } | 172 | } |
173 | 173 | ||
174 | static bool has_client_side_decorations(struct sway_view *view) { | ||
175 | struct sway_xdg_shell_v6_view *xdg_shell_v6_view = | ||
176 | xdg_shell_v6_view_from_view(view); | ||
177 | if (xdg_shell_v6_view == NULL) { | ||
178 | return true; | ||
179 | } | ||
180 | return xdg_shell_v6_view->deco_mode != WLR_SERVER_DECORATION_MANAGER_MODE_SERVER; | ||
181 | } | ||
182 | |||
183 | static void for_each_surface(struct sway_view *view, | 174 | static void for_each_surface(struct sway_view *view, |
184 | wlr_surface_iterator_func_t iterator, void *user_data) { | 175 | wlr_surface_iterator_func_t iterator, void *user_data) { |
185 | if (xdg_shell_v6_view_from_view(view) == NULL) { | 176 | if (xdg_shell_v6_view_from_view(view) == NULL) { |
@@ -237,7 +228,6 @@ static const struct sway_view_impl view_impl = { | |||
237 | .set_tiled = set_tiled, | 228 | .set_tiled = set_tiled, |
238 | .set_fullscreen = set_fullscreen, | 229 | .set_fullscreen = set_fullscreen, |
239 | .wants_floating = wants_floating, | 230 | .wants_floating = wants_floating, |
240 | .has_client_side_decorations = has_client_side_decorations, | ||
241 | .for_each_surface = for_each_surface, | 231 | .for_each_surface = for_each_surface, |
242 | .for_each_popup = for_each_popup, | 232 | .for_each_popup = for_each_popup, |
243 | .close = _close, | 233 | .close = _close, |
@@ -382,15 +372,13 @@ static void handle_map(struct wl_listener *listener, void *data) { | |||
382 | view->natural_height = view->wlr_xdg_surface_v6->surface->current.height; | 372 | view->natural_height = view->wlr_xdg_surface_v6->surface->current.height; |
383 | } | 373 | } |
384 | 374 | ||
375 | view_map(view, view->wlr_xdg_surface_v6->surface); | ||
376 | |||
385 | struct sway_server_decoration *deco = | 377 | struct sway_server_decoration *deco = |
386 | decoration_from_surface(xdg_surface->surface); | 378 | decoration_from_surface(xdg_surface->surface); |
387 | if (deco != NULL) { | 379 | bool csd = !deco || deco->wlr_server_decoration->mode == |
388 | xdg_shell_v6_view->deco_mode = deco->wlr_server_decoration->mode; | 380 | WLR_SERVER_DECORATION_MANAGER_MODE_CLIENT; |
389 | } else { | 381 | view_set_csd_from_client(view, csd); |
390 | xdg_shell_v6_view->deco_mode = WLR_SERVER_DECORATION_MANAGER_MODE_CLIENT; | ||
391 | } | ||
392 | |||
393 | view_map(view, view->wlr_xdg_surface_v6->surface); | ||
394 | 382 | ||
395 | if (xdg_surface->toplevel->client_pending.fullscreen) { | 383 | if (xdg_surface->toplevel->client_pending.fullscreen) { |
396 | container_set_fullscreen(view->container, true); | 384 | container_set_fullscreen(view->container, true); |
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index a12ac854..f1205518 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c | |||
@@ -243,12 +243,14 @@ static bool wants_floating(struct sway_view *view) { | |||
243 | return false; | 243 | return false; |
244 | } | 244 | } |
245 | 245 | ||
246 | static bool has_client_side_decorations(struct sway_view *view) { | 246 | static void handle_set_decorations(struct wl_listener *listener, void *data) { |
247 | if (xwayland_view_from_view(view) == NULL) { | 247 | struct sway_xwayland_view *xwayland_view = |
248 | return false; | 248 | wl_container_of(listener, xwayland_view, set_decorations); |
249 | } | 249 | struct sway_view *view = &xwayland_view->view; |
250 | struct wlr_xwayland_surface *surface = view->wlr_xwayland_surface; | 250 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; |
251 | return surface->decorations != WLR_XWAYLAND_SURFACE_DECORATIONS_ALL; | 251 | |
252 | bool csd = xsurface->decorations != WLR_XWAYLAND_SURFACE_DECORATIONS_ALL; | ||
253 | view_set_csd_from_client(view, csd); | ||
252 | } | 254 | } |
253 | 255 | ||
254 | static void _close(struct sway_view *view) { | 256 | static void _close(struct sway_view *view) { |
@@ -274,7 +276,6 @@ static const struct sway_view_impl view_impl = { | |||
274 | .set_tiled = set_tiled, | 276 | .set_tiled = set_tiled, |
275 | .set_fullscreen = set_fullscreen, | 277 | .set_fullscreen = set_fullscreen, |
276 | .wants_floating = wants_floating, | 278 | .wants_floating = wants_floating, |
277 | .has_client_side_decorations = has_client_side_decorations, | ||
278 | .close = _close, | 279 | .close = _close, |
279 | .destroy = destroy, | 280 | .destroy = destroy, |
280 | }; | 281 | }; |
@@ -343,6 +344,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) { | |||
343 | wl_list_remove(&xwayland_view->set_role.link); | 344 | wl_list_remove(&xwayland_view->set_role.link); |
344 | wl_list_remove(&xwayland_view->set_window_type.link); | 345 | wl_list_remove(&xwayland_view->set_window_type.link); |
345 | wl_list_remove(&xwayland_view->set_hints.link); | 346 | wl_list_remove(&xwayland_view->set_hints.link); |
347 | wl_list_remove(&xwayland_view->set_decorations.link); | ||
346 | wl_list_remove(&xwayland_view->map.link); | 348 | wl_list_remove(&xwayland_view->map.link); |
347 | wl_list_remove(&xwayland_view->unmap.link); | 349 | wl_list_remove(&xwayland_view->unmap.link); |
348 | view_begin_destroy(&xwayland_view->view); | 350 | view_begin_destroy(&xwayland_view->view); |
@@ -613,6 +615,10 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { | |||
613 | wl_signal_add(&xsurface->events.set_hints, &xwayland_view->set_hints); | 615 | wl_signal_add(&xsurface->events.set_hints, &xwayland_view->set_hints); |
614 | xwayland_view->set_hints.notify = handle_set_hints; | 616 | xwayland_view->set_hints.notify = handle_set_hints; |
615 | 617 | ||
618 | wl_signal_add(&xsurface->events.set_decorations, | ||
619 | &xwayland_view->set_decorations); | ||
620 | xwayland_view->set_decorations.notify = handle_set_decorations; | ||
621 | |||
616 | wl_signal_add(&xsurface->events.unmap, &xwayland_view->unmap); | 622 | wl_signal_add(&xsurface->events.unmap, &xwayland_view->unmap); |
617 | xwayland_view->unmap.notify = handle_unmap; | 623 | xwayland_view->unmap.notify = handle_unmap; |
618 | 624 | ||