feat(brand): "Duo" logo refresh — mint panes mark across all icon assets
Replace the orange window-and-cursor identity with the "Duo" mark: two offset session panes (mint #3FDD8C behind, ink #17171A in front) with a prompt chevron, on a cream tile following the Big Sur icon grid. - app-icon.svg is the master; app-icon.png, tty7.icns and favicon.ico are re-rendered from it (rsvg-convert + iconutil + PIL) - logo.svg/logo.png/logo@256.png carry the tile-less transparent mark - tray.svg redrawn as the same mark in template form: solid front pane with the chevron masked out, back pane at partial alpha - bare (non-bundled) macOS binaries now set the Dock icon at runtime via NSApplication.setApplicationIconImage, so cargo dev/run shows the logo instead of the generic executable icon - README version badge and the social preview switch to the new brand green; social preview copy re-aligned with the current README slogan
@@ -9042,6 +9042,7 @@ dependencies = [
|
||||
"notify-rust",
|
||||
"objc2 0.6.4",
|
||||
"objc2-app-kit 0.3.2",
|
||||
"objc2-foundation 0.3.2",
|
||||
"plist",
|
||||
"portable-pty",
|
||||
"reqwest_client",
|
||||
|
||||
@@ -172,7 +172,10 @@ winresource = "0.1"
|
||||
# so the native traffic-light buttons render in the right light/dark style.
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
objc2 = "0.6"
|
||||
objc2-app-kit = { version = "0.3", features = ["NSApplication", "NSResponder", "NSAppearance", "NSGraphics"] }
|
||||
objc2-app-kit = { version = "0.3", features = ["NSApplication", "NSResponder", "NSAppearance", "NSGraphics", "NSImage"] }
|
||||
# NSData feeds the runtime Dock icon for bare (non-bundled) binaries — see
|
||||
# `set_dock_icon_for_bare_binary` in main.rs.
|
||||
objc2-foundation = { version = "0.3", features = ["NSData"] }
|
||||
|
||||
# x11/wayland are the Linux windowing backends; only pull them on Linux. The
|
||||
# Windows backend (`gpui_windows`) and macOS backend are selected by gpui_platform
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<br />
|
||||
|
||||
[](https://github.com/l0ng-ai/tty7/actions/workflows/ci.yml)
|
||||
[](https://github.com/l0ng-ai/tty7/releases)
|
||||
[](https://github.com/l0ng-ai/tty7/releases)
|
||||
[](LICENSE)
|
||||
[](https://discord.gg/s3dethqz2V)
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<br />
|
||||
|
||||
[](https://github.com/l0ng-ai/tty7/actions/workflows/ci.yml)
|
||||
[](https://github.com/l0ng-ai/tty7/releases)
|
||||
[](https://github.com/l0ng-ai/tty7/releases)
|
||||
[](LICENSE)
|
||||
[](https://discord.gg/s3dethqz2V)
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 27 KiB |
@@ -1,6 +1,11 @@
|
||||
<svg width="120" height="120" viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="8" y="8" width="104" height="104" rx="24" fill="#ff8a5c"/>
|
||||
<rect x="26" y="32" width="68" height="56" rx="13" fill="none" stroke="#0d1117" stroke-width="6"/>
|
||||
<line x1="26" y1="49" x2="94" y2="49" stroke="#0d1117" stroke-width="4" opacity="0.7"/>
|
||||
<rect x="60" y="60" width="12" height="20" rx="2.5" fill="#0d1117"/>
|
||||
<svg width="1024" height="1024" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- "Duo" mark (design 2a): two offset session panes, prompt chevron in the
|
||||
front one. Tile inset + radius follow the macOS Big Sur icon grid
|
||||
(824pt tile @1024). -->
|
||||
<rect x="100" y="100" width="824" height="824" rx="185" fill="#ECEAE4"/>
|
||||
<g transform="translate(108.8 125.6) scale(8.4)">
|
||||
<rect x="28" y="16" width="58" height="46" rx="12" fill="#3FDD8C" opacity="0.8"/>
|
||||
<rect x="10" y="30" width="58" height="46" rx="12" fill="#17171A"/>
|
||||
<path d="M24 42 L35 53 L24 64" fill="none" stroke="#ECEAE4" stroke-width="7" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 427 B After Width: | Height: | Size: 704 B |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 24 KiB |
@@ -1,5 +1,6 @@
|
||||
<svg width="120" height="120" viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="12" y="22" width="96" height="76" rx="15" fill="none" stroke="#3F3F46" stroke-width="6"/>
|
||||
<line x1="12" y1="44" x2="108" y2="44" stroke="#3F3F46" stroke-width="4" opacity="0.7"/>
|
||||
<rect x="52" y="58" width="15" height="26" rx="3" fill="#FF6B35"/>
|
||||
<svg width="120" height="120" viewBox="8 6 80 80" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- "Duo" mark on transparent — same geometry as app-icon.svg, no tile. -->
|
||||
<rect x="28" y="16" width="58" height="46" rx="12" fill="#3FDD8C" opacity="0.8"/>
|
||||
<rect x="10" y="30" width="58" height="46" rx="12" fill="#17171A"/>
|
||||
<path d="M24 42 L35 53 L24 64" fill="none" stroke="#ECEAE4" stroke-width="7" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 356 B After Width: | Height: | Size: 456 B |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 532 KiB After Width: | Height: | Size: 137 KiB |
@@ -1,5 +1,16 @@
|
||||
<svg width="120" height="120" viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="11" y="21" width="98" height="78" rx="18" fill="none" stroke="#000" stroke-width="9"/>
|
||||
<path d="M34 48 L50 61 L34 74" fill="none" stroke="#000" stroke-width="9" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<line x1="60" y1="76" x2="82" y2="76" stroke="#000" stroke-width="9" stroke-linecap="round"/>
|
||||
<svg width="96" height="96" viewBox="0 0 96 96" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- Template (alpha-only) tray glyph: the "Duo" mark, same geometry as
|
||||
app-icon.svg. Solid front pane with the chevron knocked out; the back
|
||||
pane reads through partial alpha (template images keep alpha, drop
|
||||
color). The mask spans both panes so the chevron cuts clean through. -->
|
||||
<defs>
|
||||
<mask id="chevron-cut">
|
||||
<rect width="96" height="96" fill="#fff"/>
|
||||
<path d="M24 42 L35 53 L24 64" fill="none" stroke="#000" stroke-width="7" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</mask>
|
||||
</defs>
|
||||
<g mask="url(#chevron-cut)">
|
||||
<rect x="28" y="16" width="58" height="46" rx="12" fill="#000" opacity="0.35"/>
|
||||
<rect x="10" y="30" width="58" height="46" rx="12" fill="#000"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 414 B After Width: | Height: | Size: 824 B |
@@ -246,6 +246,39 @@ fn enrich_path_from_login_shell() {
|
||||
unsafe { std::env::set_var("PATH", merged) };
|
||||
}
|
||||
|
||||
/// A bare (non-bundled) binary — `cargo dev` / `cargo run` — has no
|
||||
/// `Info.plist` pointing the Dock at `tty7.icns`, so macOS shows the generic
|
||||
/// executable icon. Feed the Dock the bundled logo at runtime in that case;
|
||||
/// launches from the real `.app` keep the `.icns` and skip this.
|
||||
#[cfg(target_os = "macos")]
|
||||
fn set_dock_icon_for_bare_binary() {
|
||||
use objc2::{AnyThread, MainThreadMarker};
|
||||
use objc2_app_kit::{NSApplication, NSImage};
|
||||
use objc2_foundation::NSData;
|
||||
|
||||
let bundled = std::env::current_exe().is_ok_and(|p| {
|
||||
p.components()
|
||||
.any(|c| c.as_os_str().to_string_lossy().ends_with(".app"))
|
||||
});
|
||||
if bundled {
|
||||
return;
|
||||
}
|
||||
// gpui's `run` closure executes on the main thread; bail defensively
|
||||
// rather than panic if that ever stops holding.
|
||||
let Some(mtm) = MainThreadMarker::new() else {
|
||||
return;
|
||||
};
|
||||
static ICON_PNG: &[u8] = include_bytes!("../assets/app-icon.png");
|
||||
let data = NSData::with_bytes(ICON_PNG);
|
||||
if let Some(image) = NSImage::initWithData(NSImage::alloc(), &data) {
|
||||
// SAFETY: passing a valid NSImage on the main thread; AppKit copies the
|
||||
// reference, no ownership transferred.
|
||||
unsafe {
|
||||
NSApplication::sharedApplication(mtm).setApplicationIconImage(Some(&image));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Agent-hook mode: `tty7 agent-hook <agent> <event>` is the tiny emitter
|
||||
// Claude Code's hooks invoke (see `core::agent_hooks`). It reads the hook
|
||||
@@ -323,6 +356,8 @@ fn main() {
|
||||
gpui_component::init(cx);
|
||||
register_bundled_fonts(cx);
|
||||
cx.activate(true);
|
||||
#[cfg(target_os = "macos")]
|
||||
set_dock_icon_for_bare_binary();
|
||||
// Load user config once and stash it as a global for views to read.
|
||||
cx.set_global(Config::load());
|
||||
// Build the theme registry (built-ins + user theme files) before the
|
||||
|
||||