aboutsummaryrefslogtreecommitdiffstats
path: root/sway/desktop/output.c
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-05-15 23:29:54 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-05-17 08:29:14 +1000
commitebb0d051db2f73fd13a4e844a51e70f09703372a (patch)
treeba0248bf61b783299e8dea938a1ae90299fd62f4 /sway/desktop/output.c
parentUpdate show_marks documentation (diff)
downloadsway-ebb0d051db2f73fd13a4e844a51e70f09703372a.tar.gz
sway-ebb0d051db2f73fd13a4e844a51e70f09703372a.tar.zst
sway-ebb0d051db2f73fd13a4e844a51e70f09703372a.zip
Fix many border opacity issues
Diffstat (limited to 'sway/desktop/output.c')
-rw-r--r--sway/desktop/output.c159
1 files changed, 100 insertions, 59 deletions
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index 57d71d5e..3f680b36 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -287,7 +287,6 @@ static void render_rect(struct wlr_output *wlr_output,
287 wlr_backend_get_renderer(wlr_output->backend); 287 wlr_backend_get_renderer(wlr_output->backend);
288 288
289 struct wlr_box box = *_box; 289 struct wlr_box box = *_box;
290 scale_box(&box, wlr_output->scale);
291 290
292 pixman_region32_t damage; 291 pixman_region32_t damage;
293 pixman_region32_init(&damage); 292 pixman_region32_init(&damage);
@@ -313,6 +312,9 @@ damage_finish:
313 312
314/** 313/**
315 * Render decorations for a view with "border normal". 314 * Render decorations for a view with "border normal".
315 *
316 * Care must be taken not to render over the same pixel multiple times,
317 * otherwise the colors will be incorrect when using opacity.
316 */ 318 */
317static void render_container_simple_border_normal(struct sway_output *output, 319static void render_container_simple_border_normal(struct sway_output *output,
318 pixman_region32_t *output_damage, 320 pixman_region32_t *output_damage,
@@ -320,19 +322,23 @@ static void render_container_simple_border_normal(struct sway_output *output,
320 struct wlr_texture *title_texture, struct wlr_texture *marks_texture) { 322 struct wlr_texture *title_texture, struct wlr_texture *marks_texture) {
321 struct wlr_box box; 323 struct wlr_box box;
322 float color[4]; 324 float color[4];
325 struct sway_view *view = con->sway_view;
326 float output_scale = output->wlr_output->scale;
323 327
324 if (con->sway_view->border_left) { 328 if (view->border_left) {
325 // Child border - left edge 329 // Child border - left edge
326 memcpy(&color, colors->child_border, sizeof(float) * 4); 330 memcpy(&color, colors->child_border, sizeof(float) * 4);
327 color[3] *= con->alpha; 331 color[3] *= con->alpha;
328 box.x = con->x; 332 box.x = con->x;
329 box.y = con->y + 1; 333 box.y = con->y + 1;
330 box.width = con->sway_view->border_thickness; 334 box.width = view->border_thickness;
331 box.height = con->height - 1; 335 box.height = con->height - 1
336 - view->border_thickness * view->border_bottom;
337 scale_box(&box, output_scale);
332 render_rect(output->wlr_output, output_damage, &box, color); 338 render_rect(output->wlr_output, output_damage, &box, color);
333 } 339 }
334 340
335 if (con->sway_view->border_right) { 341 if (view->border_right) {
336 // Child border - right edge 342 // Child border - right edge
337 if (con->parent->children->length == 1 343 if (con->parent->children->length == 1
338 && con->parent->layout == L_HORIZ) { 344 && con->parent->layout == L_HORIZ) {
@@ -341,14 +347,16 @@ static void render_container_simple_border_normal(struct sway_output *output,
341 memcpy(&color, colors->child_border, sizeof(float) * 4); 347 memcpy(&color, colors->child_border, sizeof(float) * 4);
342 } 348 }
343 color[3] *= con->alpha; 349 color[3] *= con->alpha;
344 box.x = con->x + con->width - con->sway_view->border_thickness; 350 box.x = con->x + con->width - view->border_thickness;
345 box.y = con->y + 1; 351 box.y = con->y + 1;
346 box.width = con->sway_view->border_thickness; 352 box.width = view->border_thickness;
347 box.height = con->height - 1; 353 box.height = con->height - 1
354 - view->border_thickness * view->border_bottom;
355 scale_box(&box, output_scale);
348 render_rect(output->wlr_output, output_damage, &box, color); 356 render_rect(output->wlr_output, output_damage, &box, color);
349 } 357 }
350 358
351 if (con->sway_view->border_bottom) { 359 if (view->border_bottom) {
352 // Child border - bottom edge 360 // Child border - bottom edge
353 if (con->parent->children->length == 1 361 if (con->parent->children->length == 1
354 && con->parent->layout == L_VERT) { 362 && con->parent->layout == L_VERT) {
@@ -358,9 +366,10 @@ static void render_container_simple_border_normal(struct sway_output *output,
358 } 366 }
359 color[3] *= con->alpha; 367 color[3] *= con->alpha;
360 box.x = con->x; 368 box.x = con->x;
361 box.y = con->y + con->height - con->sway_view->border_thickness; 369 box.y = con->y + con->height - view->border_thickness;
362 box.width = con->width; 370 box.width = con->width;
363 box.height = con->sway_view->border_thickness; 371 box.height = view->border_thickness;
372 scale_box(&box, output_scale);
364 render_rect(output->wlr_output, output_damage, &box, color); 373 render_rect(output->wlr_output, output_damage, &box, color);
365 } 374 }
366 375
@@ -371,90 +380,118 @@ static void render_container_simple_border_normal(struct sway_output *output,
371 box.y = con->y; 380 box.y = con->y;
372 box.width = con->width; 381 box.width = con->width;
373 box.height = 1; 382 box.height = 1;
383 scale_box(&box, output_scale);
374 render_rect(output->wlr_output, output_damage, &box, color); 384 render_rect(output->wlr_output, output_damage, &box, color);
375 385
376 // Single pixel bar below title 386 // Single pixel bar below title
377 memcpy(&color, colors->border, sizeof(float) * 4); 387 memcpy(&color, colors->border, sizeof(float) * 4);
378 color[3] *= con->alpha; 388 color[3] *= con->alpha;
379 box.x = con->x + con->sway_view->border_thickness; 389 box.x = con->x + view->border_thickness;
380 box.y = con->sway_view->y - 1; 390 box.y = view->y - 1;
381 box.width = con->width - con->sway_view->border_thickness * 2; 391 box.width = con->width - view->border_thickness * 2;
382 box.height = 1; 392 box.height = 1;
393 scale_box(&box, output_scale);
383 render_rect(output->wlr_output, output_damage, &box, color); 394 render_rect(output->wlr_output, output_damage, &box, color);
384 395
385 // Title background 396 // Setting these makes marks and title easier
386 memcpy(&color, colors->background, sizeof(float) * 4); 397 size_t inner_x = con->x + view->border_thickness * view->border_left;
387 color[3] *= con->alpha; 398 size_t inner_width = con->width - view->border_thickness * view->border_left
388 box.x = con->x 399 - view->border_thickness * view->border_right;
389 + con->sway_view->border_thickness * con->sway_view->border_left;
390 box.y = con->y + 1;
391 box.width = con->width
392 - con->sway_view->border_thickness * con->sway_view->border_left
393 - con->sway_view->border_thickness * con->sway_view->border_right;
394 box.height = con->sway_view->y - con->y - 2;
395 render_rect(output->wlr_output, output_damage, &box, color);
396 400
397 // Title text 401 // Marks
398 if (title_texture) { 402 size_t marks_width = 0;
399 float output_scale = output->wlr_output->scale; 403 if (config->show_marks && marks_texture) {
400 struct wlr_box texture_box = { 404 struct wlr_box texture_box;
401 .x = box.x * output_scale, 405 wlr_texture_get_size(marks_texture,
402 .y = box.y * output_scale,
403 };
404 wlr_texture_get_size(title_texture,
405 &texture_box.width, &texture_box.height); 406 &texture_box.width, &texture_box.height);
407 texture_box.x = (inner_x + inner_width) * output_scale - texture_box.width;
408 texture_box.y = (con->y + view->border_thickness) * output_scale;
406 409
407 float matrix[9]; 410 float matrix[9];
408 wlr_matrix_project_box(matrix, &texture_box, 411 wlr_matrix_project_box(matrix, &texture_box,
409 WL_OUTPUT_TRANSFORM_NORMAL, 412 WL_OUTPUT_TRANSFORM_NORMAL,
410 0.0, output->wlr_output->transform_matrix); 413 0.0, output->wlr_output->transform_matrix);
411 414
412 texture_box.width = box.width * output_scale; 415 render_texture(output->wlr_output, output_damage, marks_texture,
413 render_texture(output->wlr_output, output_damage, title_texture, 416 &texture_box, matrix, con->alpha);
414 &texture_box, matrix, 1.0); 417 marks_width = texture_box.width;
415 } 418 }
416 419
417 // Marks 420 // Title text
418 if (config->show_marks && marks_texture) { 421 size_t title_width = 0;
419 float output_scale = output->wlr_output->scale; 422 if (title_texture) {
420 struct wlr_box texture_box; 423 struct wlr_box texture_box;
421 wlr_texture_get_size(marks_texture, 424 wlr_texture_get_size(title_texture,
422 &texture_box.width, &texture_box.height); 425 &texture_box.width, &texture_box.height);
423 texture_box.x = (box.x + box.width) * output_scale - texture_box.width; 426 texture_box.x = inner_x * output_scale;
424 texture_box.y = (box.y + box.height) 427 texture_box.y = (con->y + view->border_thickness) * output_scale;
425 * output_scale - texture_box.height;
426 428
427 float matrix[9]; 429 float matrix[9];
428 wlr_matrix_project_box(matrix, &texture_box, 430 wlr_matrix_project_box(matrix, &texture_box,
429 WL_OUTPUT_TRANSFORM_NORMAL, 431 WL_OUTPUT_TRANSFORM_NORMAL,
430 0.0, output->wlr_output->transform_matrix); 432 0.0, output->wlr_output->transform_matrix);
431 433
432 render_texture(output->wlr_output, output_damage, marks_texture, 434 if (inner_width * output_scale - marks_width < texture_box.width) {
433 &texture_box, matrix, 1.0); 435 texture_box.width = inner_width * output_scale - marks_width;
436 }
437 render_texture(output->wlr_output, output_damage, title_texture,
438 &texture_box, matrix, con->alpha);
439 title_width = texture_box.width;
440 }
441
442 // Title background - above the text
443 memcpy(&color, colors->background, sizeof(float) * 4);
444 color[3] *= con->alpha;
445 box.x = inner_x;
446 box.y = con->y + 1;
447 box.width = inner_width;
448 box.height = view->border_thickness - 1;
449 scale_box(&box, output_scale);
450 render_rect(output->wlr_output, output_damage, &box, color);
451
452 // Title background - below the text
453 box.y = (con->y + view->border_thickness + config->font_height)
454 * output_scale;
455 render_rect(output->wlr_output, output_damage, &box, color);
456
457 // Title background - filler between title and marks
458 box.width = inner_width * output_scale - title_width - marks_width;
459 if (box.width > 0) {
460 box.x = inner_x * output_scale + title_width;
461 box.y = (con->y + view->border_thickness) * output_scale;
462 box.height = config->font_height * output_scale;
463 render_rect(output->wlr_output, output_damage, &box, color);
434 } 464 }
435} 465}
436 466
437/** 467/**
438 * Render decorations for a view with "border pixel". 468 * Render decorations for a view with "border pixel".
469 *
470 * Care must be taken not to render over the same pixel multiple times,
471 * otherwise the colors will be incorrect when using opacity.
439 */ 472 */
440static void render_container_simple_border_pixel(struct sway_output *output, 473static void render_container_simple_border_pixel(struct sway_output *output,
441 pixman_region32_t *output_damage, struct sway_container *con, 474 pixman_region32_t *output_damage, struct sway_container *con,
442 struct border_colors *colors) { 475 struct border_colors *colors) {
443 struct wlr_box box; 476 struct wlr_box box;
444 float color[4]; 477 float color[4];
478 struct sway_view *view = con->sway_view;
479 float output_scale = output->wlr_output->scale;
445 480
446 if (con->sway_view->border_left) { 481 if (view->border_left) {
447 // Child border - left edge 482 // Child border - left edge
448 memcpy(&color, colors->child_border, sizeof(float) * 4); 483 memcpy(&color, colors->child_border, sizeof(float) * 4);
449 color[3] *= con->alpha; 484 color[3] *= con->alpha;
450 box.x = con->x; 485 box.x = con->x;
451 box.y = con->y; 486 box.y = con->y + view->border_thickness * view->border_top;
452 box.width = con->sway_view->border_thickness; 487 box.width = view->border_thickness;
453 box.height = con->height; 488 box.height = con->height - view->border_thickness
489 * (view->border_top + view->border_bottom);
490 scale_box(&box, output_scale);
454 render_rect(output->wlr_output, output_damage, &box, color); 491 render_rect(output->wlr_output, output_damage, &box, color);
455 } 492 }
456 493
457 if (con->sway_view->border_right) { 494 if (view->border_right) {
458 // Child border - right edge 495 // Child border - right edge
459 if (con->parent->children->length == 1 496 if (con->parent->children->length == 1
460 && con->parent->layout == L_HORIZ) { 497 && con->parent->layout == L_HORIZ) {
@@ -463,25 +500,28 @@ static void render_container_simple_border_pixel(struct sway_output *output,
463 memcpy(&color, colors->child_border, sizeof(float) * 4); 500 memcpy(&color, colors->child_border, sizeof(float) * 4);
464 } 501 }
465 color[3] *= con->alpha; 502 color[3] *= con->alpha;
466 box.x = con->x + con->width - con->sway_view->border_thickness; 503 box.x = con->x + con->width - view->border_thickness;
467 box.y = con->y; 504 box.y = con->y + view->border_thickness * view->border_top;
468 box.width = con->sway_view->border_thickness; 505 box.width = view->border_thickness;
469 box.height = con->height; 506 box.height = con->height - view->border_thickness
507 * (view->border_top + view->border_bottom);
508 scale_box(&box, output_scale);
470 render_rect(output->wlr_output, output_damage, &box, color); 509 render_rect(output->wlr_output, output_damage, &box, color);
471 } 510 }
472 511
473 if (con->sway_view->border_top) { 512 if (view->border_top) {
474 // Child border - top edge 513 // Child border - top edge
475 memcpy(&color, colors->child_border, sizeof(float) * 4); 514 memcpy(&color, colors->child_border, sizeof(float) * 4);
476 color[3] *= con->alpha; 515 color[3] *= con->alpha;
477 box.x = con->x; 516 box.x = con->x;
478 box.y = con->y; 517 box.y = con->y;
479 box.width = con->width; 518 box.width = con->width;
480 box.height = con->sway_view->border_thickness; 519 box.height = view->border_thickness;
520 scale_box(&box, output_scale);
481 render_rect(output->wlr_output, output_damage, &box, color); 521 render_rect(output->wlr_output, output_damage, &box, color);
482 } 522 }
483 523
484 if (con->sway_view->border_bottom) { 524 if (view->border_bottom) {
485 // Child border - bottom edge 525 // Child border - bottom edge
486 if (con->parent->children->length == 1 526 if (con->parent->children->length == 1
487 && con->parent->layout == L_VERT) { 527 && con->parent->layout == L_VERT) {
@@ -491,9 +531,10 @@ static void render_container_simple_border_pixel(struct sway_output *output,
491 } 531 }
492 color[3] *= con->alpha; 532 color[3] *= con->alpha;
493 box.x = con->x; 533 box.x = con->x;
494 box.y = con->y + con->height - con->sway_view->border_thickness; 534 box.y = con->y + con->height - view->border_thickness;
495 box.width = con->width; 535 box.width = con->width;
496 box.height = con->sway_view->border_thickness; 536 box.height = view->border_thickness;
537 scale_box(&box, output_scale);
497 render_rect(output->wlr_output, output_damage, &box, color); 538 render_rect(output->wlr_output, output_damage, &box, color);
498 } 539 }
499} 540}