diff options
author | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-05-15 23:29:54 +1000 |
---|---|---|
committer | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-05-17 08:29:14 +1000 |
commit | ebb0d051db2f73fd13a4e844a51e70f09703372a (patch) | |
tree | ba0248bf61b783299e8dea938a1ae90299fd62f4 /sway/desktop/output.c | |
parent | Update show_marks documentation (diff) | |
download | sway-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.c | 159 |
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 | */ |
317 | static void render_container_simple_border_normal(struct sway_output *output, | 319 | static 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 | */ |
440 | static void render_container_simple_border_pixel(struct sway_output *output, | 473 | static 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 | } |