╭ changed ─╮ │src/ui.zig│ ╰──────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────╮ │426 login_failure: ?Home.Auth.Login.Failure = null, │ │427 current_page: RoutablePage = .default, │ │428 // whether to render the ANSI art backdrop │ │429 - enable_ansi: bool = false, │ │429 + enable_ansi: bool = true, │ │430 }; │ │431 │ │432 // a user-initiated state change. widgets enqueue these on the session during│ ╰──────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────╮ │1597 cell.style.fg == null and cell.style.bg == null and !cell.style.inverted;│ │1598 } │ │1599 return true; │ │1600 - } │ │1601 - │ │1602 - // a single representative color for an art cell │ │1603 - fn artCellColor(style: Grid.Style) ?Grid.Color { │ │1604 - const f = style.fg orelse return style.bg; │ │1605 - const b = style.bg orelse return f; │ │1606 - return .{ │ │1607 - .r = @intCast((@as(u16, f.r) + b.r) / 2), │ │1608 - .g = @intCast((@as(u16, f.g) + b.g) / 2), │ │1609 - .b = @intCast((@as(u16, f.b) + b.b) / 2), │ │1610 - }; │ │1600 } │ │1601 │ │1613 - // behind a visible glyph the art color is dimmed to this fraction of its │ │1614 - // brightness so light terminal text stays legible on top of it │ │1615 - const glyph_bg_brightness = 45; // percent │ │1602 + // the art is dimmed to this fraction of its brightness so foreground text │ │1603 + // stays legible over it │ │1604 + const art_brightness = 45; // percent │ │1605 │ │1617 - // a glyph sitting over the art also gets its foreground pinned to this color │ │1618 - // (unless it set its own), so the text stays legible │ │1619 - const glyph_fg_over_art = Grid.Color{ .r = 235, .g = 235, .b = 235 }; │ │1620 - │ │1606 fn dimColor(color: ?Grid.Color) ?Grid.Color { │ │1607 const c = color orelse return null; │ │1608 return .{ │ ╰───────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────╮ │1624 - .r = @intCast(@as(u16, c.r) * glyph_bg_brightness / 100),│ │1625 - .g = @intCast(@as(u16, c.g) * glyph_bg_brightness / 100),│ │1626 - .b = @intCast(@as(u16, c.b) * glyph_bg_brightness / 100),│ │1609 + .r = @intCast(@as(u16, c.r) * art_brightness / 100), │ │1610 + .g = @intCast(@as(u16, c.g) * art_brightness / 100), │ │1611 + .b = @intCast(@as(u16, c.b) * art_brightness / 100), │ │1612 }; │ │1613 } │ │1614 │ ╰───────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────╮ │1650 if (src.rune == null) continue; │ │1651 const idx = out.cells.at(.{ y, anchor_x + x }) catch continue; │ │1652 const dst = &out.cells.items[idx]; │ │1653 + // composite the dimmed art behind every cell so it shows │ │1654 + // through the whole UI: a blank cell becomes the art, while a │ │1655 + // cell with a glyph keeps the glyph but takes the dimmed art as │ │1656 + // its background (replacing whatever background it had, which │ │1657 + // would otherwise obscure the art). │ │1658 if (cellIsBlank(dst.*)) { │ │1659 dst.* = src; │ │1670 - dst.style.fg = sgrSafe(dst.style.fg); │ │1671 - dst.style.bg = sgrSafe(dst.style.bg); │ │1672 - } else if (dst.style.bg == null) { │ │1673 - dst.style.bg = sgrSafe(dimColor(artCellColor(src.style))); │ │1674 - if (dst.style.fg == null) dst.style.fg = glyph_fg_over_art; │ │1660 + dst.style.fg = sgrSafe(dimColor(dst.style.fg)); │ │1661 + dst.style.bg = sgrSafe(dimColor(dst.style.bg)); │ │1662 + } else { │ │1663 + dst.style.bg = sgrSafe(dimColor(src.style.bg orelse src.style.fg));│ │1664 } │ │1665 } │ │1666 } │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────╯