aboutsummaryrefslogtreecommitdiffstats
path: root/sway/desktop
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-09-24 20:54:57 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-09-27 22:51:37 +1000
commit7b138e5ef0f679c9bb0078019d7c9c63fef36273 (patch)
tree2cdbeb394889065e0606a1fcbe38c1e99e25d260 /sway/desktop
parentMerge pull request #2717 from ianyfan/tablet-config (diff)
downloadsway-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.c108
-rw-r--r--sway/desktop/transaction.c1
-rw-r--r--sway/desktop/xdg_shell.c22
-rw-r--r--sway/desktop/xdg_shell_v6.c22
-rw-r--r--sway/desktop/xwayland.c20
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
178static 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
187static void for_each_surface(struct sway_view *view, 178static 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
174static 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
183static void for_each_surface(struct sway_view *view, 174static 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
246static bool has_client_side_decorations(struct sway_view *view) { 246static 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
254static void _close(struct sway_view *view) { 256static 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