diff options
Diffstat (limited to 'sway/desktop/output.c')
-rw-r--r-- | sway/desktop/output.c | 165 |
1 files changed, 117 insertions, 48 deletions
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index b12130d9..94562052 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,26 +312,33 @@ 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, |
319 | struct sway_container *con, struct border_colors *colors, | 321 | struct sway_container *con, struct border_colors *colors, |
320 | struct wlr_texture *title_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,71 +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; | 400 | |
390 | box.y = con->y + 1; | 401 | // Marks |
391 | box.width = con->width | 402 | size_t marks_width = 0; |
392 | - con->sway_view->border_thickness * con->sway_view->border_left | 403 | if (config->show_marks && marks_texture) { |
393 | - con->sway_view->border_thickness * con->sway_view->border_right; | 404 | struct wlr_box texture_box; |
394 | box.height = con->sway_view->y - con->y - 2; | 405 | wlr_texture_get_size(marks_texture, |
395 | render_rect(output->wlr_output, output_damage, &box, color); | 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; | ||
409 | |||
410 | float matrix[9]; | ||
411 | wlr_matrix_project_box(matrix, &texture_box, | ||
412 | WL_OUTPUT_TRANSFORM_NORMAL, | ||
413 | 0.0, output->wlr_output->transform_matrix); | ||
414 | |||
415 | render_texture(output->wlr_output, output_damage, marks_texture, | ||
416 | &texture_box, matrix, con->alpha); | ||
417 | marks_width = texture_box.width; | ||
418 | } | ||
396 | 419 | ||
397 | // Title text | 420 | // Title text |
421 | size_t title_width = 0; | ||
398 | if (title_texture) { | 422 | if (title_texture) { |
399 | float output_scale = output->wlr_output->scale; | 423 | struct wlr_box texture_box; |
400 | struct wlr_box texture_box = { | ||
401 | .x = box.x * output_scale, | ||
402 | .y = box.y * output_scale, | ||
403 | }; | ||
404 | wlr_texture_get_size(title_texture, | 424 | wlr_texture_get_size(title_texture, |
405 | &texture_box.width, &texture_box.height); | 425 | &texture_box.width, &texture_box.height); |
426 | texture_box.x = inner_x * output_scale; | ||
427 | texture_box.y = (con->y + view->border_thickness) * output_scale; | ||
406 | 428 | ||
407 | float matrix[9]; | 429 | float matrix[9]; |
408 | wlr_matrix_project_box(matrix, &texture_box, | 430 | wlr_matrix_project_box(matrix, &texture_box, |
409 | WL_OUTPUT_TRANSFORM_NORMAL, | 431 | WL_OUTPUT_TRANSFORM_NORMAL, |
410 | 0.0, output->wlr_output->transform_matrix); | 432 | 0.0, output->wlr_output->transform_matrix); |
411 | 433 | ||
412 | texture_box.width = box.width * output_scale; | 434 | if (inner_width * output_scale - marks_width < texture_box.width) { |
435 | texture_box.width = inner_width * output_scale - marks_width; | ||
436 | } | ||
413 | render_texture(output->wlr_output, output_damage, title_texture, | 437 | render_texture(output->wlr_output, output_damage, title_texture, |
414 | &texture_box, matrix, 1.0); | 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); | ||
415 | } | 464 | } |
416 | } | 465 | } |
417 | 466 | ||
418 | /** | 467 | /** |
419 | * 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. | ||
420 | */ | 472 | */ |
421 | static void render_container_simple_border_pixel(struct sway_output *output, | 473 | static void render_container_simple_border_pixel(struct sway_output *output, |
422 | pixman_region32_t *output_damage, struct sway_container *con, | 474 | pixman_region32_t *output_damage, struct sway_container *con, |
423 | struct border_colors *colors) { | 475 | struct border_colors *colors) { |
424 | struct wlr_box box; | 476 | struct wlr_box box; |
425 | float color[4]; | 477 | float color[4]; |
478 | struct sway_view *view = con->sway_view; | ||
479 | float output_scale = output->wlr_output->scale; | ||
426 | 480 | ||
427 | if (con->sway_view->border_left) { | 481 | if (view->border_left) { |
428 | // Child border - left edge | 482 | // Child border - left edge |
429 | memcpy(&color, colors->child_border, sizeof(float) * 4); | 483 | memcpy(&color, colors->child_border, sizeof(float) * 4); |
430 | color[3] *= con->alpha; | 484 | color[3] *= con->alpha; |
431 | box.x = con->x; | 485 | box.x = con->x; |
432 | box.y = con->y; | 486 | box.y = con->y + view->border_thickness * view->border_top; |
433 | box.width = con->sway_view->border_thickness; | 487 | box.width = view->border_thickness; |
434 | 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); | ||
435 | render_rect(output->wlr_output, output_damage, &box, color); | 491 | render_rect(output->wlr_output, output_damage, &box, color); |
436 | } | 492 | } |
437 | 493 | ||
438 | if (con->sway_view->border_right) { | 494 | if (view->border_right) { |
439 | // Child border - right edge | 495 | // Child border - right edge |
440 | if (con->parent->children->length == 1 | 496 | if (con->parent->children->length == 1 |
441 | && con->parent->layout == L_HORIZ) { | 497 | && con->parent->layout == L_HORIZ) { |
@@ -444,25 +500,28 @@ static void render_container_simple_border_pixel(struct sway_output *output, | |||
444 | memcpy(&color, colors->child_border, sizeof(float) * 4); | 500 | memcpy(&color, colors->child_border, sizeof(float) * 4); |
445 | } | 501 | } |
446 | color[3] *= con->alpha; | 502 | color[3] *= con->alpha; |
447 | box.x = con->x + con->width - con->sway_view->border_thickness; | 503 | box.x = con->x + con->width - view->border_thickness; |
448 | box.y = con->y; | 504 | box.y = con->y + view->border_thickness * view->border_top; |
449 | box.width = con->sway_view->border_thickness; | 505 | box.width = view->border_thickness; |
450 | 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); | ||
451 | render_rect(output->wlr_output, output_damage, &box, color); | 509 | render_rect(output->wlr_output, output_damage, &box, color); |
452 | } | 510 | } |
453 | 511 | ||
454 | if (con->sway_view->border_top) { | 512 | if (view->border_top) { |
455 | // Child border - top edge | 513 | // Child border - top edge |
456 | memcpy(&color, colors->child_border, sizeof(float) * 4); | 514 | memcpy(&color, colors->child_border, sizeof(float) * 4); |
457 | color[3] *= con->alpha; | 515 | color[3] *= con->alpha; |
458 | box.x = con->x; | 516 | box.x = con->x; |
459 | box.y = con->y; | 517 | box.y = con->y; |
460 | box.width = con->width; | 518 | box.width = con->width; |
461 | box.height = con->sway_view->border_thickness; | 519 | box.height = view->border_thickness; |
520 | scale_box(&box, output_scale); | ||
462 | render_rect(output->wlr_output, output_damage, &box, color); | 521 | render_rect(output->wlr_output, output_damage, &box, color); |
463 | } | 522 | } |
464 | 523 | ||
465 | if (con->sway_view->border_bottom) { | 524 | if (view->border_bottom) { |
466 | // Child border - bottom edge | 525 | // Child border - bottom edge |
467 | if (con->parent->children->length == 1 | 526 | if (con->parent->children->length == 1 |
468 | && con->parent->layout == L_VERT) { | 527 | && con->parent->layout == L_VERT) { |
@@ -472,9 +531,10 @@ static void render_container_simple_border_pixel(struct sway_output *output, | |||
472 | } | 531 | } |
473 | color[3] *= con->alpha; | 532 | color[3] *= con->alpha; |
474 | box.x = con->x; | 533 | box.x = con->x; |
475 | box.y = con->y + con->height - con->sway_view->border_thickness; | 534 | box.y = con->y + con->height - view->border_thickness; |
476 | box.width = con->width; | 535 | box.width = con->width; |
477 | box.height = con->sway_view->border_thickness; | 536 | box.height = view->border_thickness; |
537 | scale_box(&box, output_scale); | ||
478 | render_rect(output->wlr_output, output_damage, &box, color); | 538 | render_rect(output->wlr_output, output_damage, &box, color); |
479 | } | 539 | } |
480 | } | 540 | } |
@@ -501,20 +561,24 @@ static void render_container_simple(struct sway_output *output, | |||
501 | if (child->sway_view->border != B_NONE) { | 561 | if (child->sway_view->border != B_NONE) { |
502 | struct border_colors *colors; | 562 | struct border_colors *colors; |
503 | struct wlr_texture *title_texture; | 563 | struct wlr_texture *title_texture; |
564 | struct wlr_texture *marks_texture; | ||
504 | if (focus == child || parent_focused) { | 565 | if (focus == child || parent_focused) { |
505 | colors = &config->border_colors.focused; | 566 | colors = &config->border_colors.focused; |
506 | title_texture = child->title_focused; | 567 | title_texture = child->title_focused; |
568 | marks_texture = child->sway_view->marks_focused; | ||
507 | } else if (seat_get_focus_inactive(seat, con) == child) { | 569 | } else if (seat_get_focus_inactive(seat, con) == child) { |
508 | colors = &config->border_colors.focused_inactive; | 570 | colors = &config->border_colors.focused_inactive; |
509 | title_texture = child->title_focused_inactive; | 571 | title_texture = child->title_focused_inactive; |
572 | marks_texture = child->sway_view->marks_focused_inactive; | ||
510 | } else { | 573 | } else { |
511 | colors = &config->border_colors.unfocused; | 574 | colors = &config->border_colors.unfocused; |
512 | title_texture = child->title_unfocused; | 575 | title_texture = child->title_unfocused; |
576 | marks_texture = child->sway_view->marks_unfocused; | ||
513 | } | 577 | } |
514 | 578 | ||
515 | if (child->sway_view->border == B_NORMAL) { | 579 | if (child->sway_view->border == B_NORMAL) { |
516 | render_container_simple_border_normal(output, damage, | 580 | render_container_simple_border_normal(output, damage, |
517 | child, colors, title_texture); | 581 | child, colors, title_texture, marks_texture); |
518 | } else { | 582 | } else { |
519 | render_container_simple_border_pixel(output, damage, child, | 583 | render_container_simple_border_pixel(output, damage, child, |
520 | colors); | 584 | colors); |
@@ -898,10 +962,15 @@ static void handle_transform(struct wl_listener *listener, void *data) { | |||
898 | arrange_output(output->swayc); | 962 | arrange_output(output->swayc); |
899 | } | 963 | } |
900 | 964 | ||
965 | static void handle_scale_iterator(struct sway_container *view, void *data) { | ||
966 | view_update_marks_textures(view->sway_view); | ||
967 | } | ||
968 | |||
901 | static void handle_scale(struct wl_listener *listener, void *data) { | 969 | static void handle_scale(struct wl_listener *listener, void *data) { |
902 | struct sway_output *output = wl_container_of(listener, output, scale); | 970 | struct sway_output *output = wl_container_of(listener, output, scale); |
903 | arrange_layers(output); | 971 | arrange_layers(output); |
904 | arrange_output(output->swayc); | 972 | arrange_output(output->swayc); |
973 | container_descendants(output->swayc, C_VIEW, handle_scale_iterator, NULL); | ||
905 | } | 974 | } |
906 | 975 | ||
907 | void handle_new_output(struct wl_listener *listener, void *data) { | 976 | void handle_new_output(struct wl_listener *listener, void *data) { |