summaryrefslogtreecommitdiffstats
path: root/sway/desktop/output.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/desktop/output.c')
-rw-r--r--sway/desktop/output.c165
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 */
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,
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 */
421static void render_container_simple_border_pixel(struct sway_output *output, 473static 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
965static void handle_scale_iterator(struct sway_container *view, void *data) {
966 view_update_marks_textures(view->sway_view);
967}
968
901static void handle_scale(struct wl_listener *listener, void *data) { 969static 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
907void handle_new_output(struct wl_listener *listener, void *data) { 976void handle_new_output(struct wl_listener *listener, void *data) {