diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md
index 96615bc..62600a6 100644
--- a/ARCHITECTURE.md
+++ b/ARCHITECTURE.md
@@ -84,7 +84,7 @@ This is the heart of the app. Follow it once in the code and everything else mak
▼
KeymapSession.press (Core/KeymapSession.swift)
│ Returns one of:
- ├─ .passThrough → not ours, Xcode gets the key
+ ├─ .passThrough → not ours, the key goes to which ever app is in front
├─ .awaiting → swallow; OverlayController shows the which-key panel after ~350 ms
├─ .cancelled → swallow; hide the panel (Esc, unbound key, timeout)
└─ .fired(id) → swallow; run the command on the next run loop turn
diff --git a/Design/XCommander.icns b/Design/XCommander.icns
index 810d780..8d1c90e 100644
Binary files a/Design/XCommander.icns and b/Design/XCommander.icns differ
diff --git a/Graphics/X-hat-black-on-white.png b/Graphics/X-hat-black-on-white.png
deleted file mode 100644
index bc6ee55..0000000
Binary files a/Graphics/X-hat-black-on-white.png and /dev/null differ
diff --git a/Graphics/X-hat-black-on-white.svg b/Graphics/X-hat-black-on-white.svg
deleted file mode 100644
index 3270ab2..0000000
--- a/Graphics/X-hat-black-on-white.svg
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
\ No newline at end of file
diff --git a/Graphics/X-hat-black-on-white2.svg b/Graphics/X-hat-black-on-white2.svg
deleted file mode 100644
index 1f6f4f0..0000000
--- a/Graphics/X-hat-black-on-white2.svg
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
\ No newline at end of file
diff --git a/Graphics/X-hat-white-on-black.png b/Graphics/X-hat-white-on-black.png
deleted file mode 100644
index e7e5503..0000000
Binary files a/Graphics/X-hat-white-on-black.png and /dev/null differ
diff --git a/Graphics/X-hat-white-on-black.svg b/Graphics/X-hat-white-on-black.svg
deleted file mode 100644
index 18b2277..0000000
--- a/Graphics/X-hat-white-on-black.svg
+++ /dev/null
@@ -1,60 +0,0 @@
-
-
\ No newline at end of file
diff --git a/Graphics/X-hat-white-on-black2.svg b/Graphics/X-hat-white-on-black2.svg
deleted file mode 100644
index ee521e6..0000000
--- a/Graphics/X-hat-white-on-black2.svg
+++ /dev/null
@@ -1,58 +0,0 @@
-
-
\ No newline at end of file
diff --git a/Graphics/XCommander-black-on-white.png b/Graphics/XCommander-black-on-white.png
new file mode 100644
index 0000000..799561e
Binary files /dev/null and b/Graphics/XCommander-black-on-white.png differ
diff --git a/Graphics/XCommander-black-on-white.svg b/Graphics/XCommander-black-on-white.svg
new file mode 100644
index 0000000..69fa35e
--- /dev/null
+++ b/Graphics/XCommander-black-on-white.svg
@@ -0,0 +1,175 @@
+
+
diff --git a/Graphics/XCommander-black.png b/Graphics/XCommander-black.png
new file mode 100644
index 0000000..bc74f94
Binary files /dev/null and b/Graphics/XCommander-black.png differ
diff --git a/Graphics/XCommander-black.svg b/Graphics/XCommander-black.svg
new file mode 100644
index 0000000..2d6c530
--- /dev/null
+++ b/Graphics/XCommander-black.svg
@@ -0,0 +1,133 @@
+
+
diff --git a/Graphics/XCommander-white-on-black.png b/Graphics/XCommander-white-on-black.png
new file mode 100644
index 0000000..0347c8e
Binary files /dev/null and b/Graphics/XCommander-white-on-black.png differ
diff --git a/Graphics/XCommander-white-on-black.svg b/Graphics/XCommander-white-on-black.svg
new file mode 100644
index 0000000..3da53c0
--- /dev/null
+++ b/Graphics/XCommander-white-on-black.svg
@@ -0,0 +1,158 @@
+
+
diff --git a/Graphics/XCommander-white.png b/Graphics/XCommander-white.png
new file mode 100644
index 0000000..33dc84b
Binary files /dev/null and b/Graphics/XCommander-white.png differ
diff --git a/Graphics/XCommander-white.svg b/Graphics/XCommander-white.svg
new file mode 100644
index 0000000..012d3b4
--- /dev/null
+++ b/Graphics/XCommander-white.svg
@@ -0,0 +1,115 @@
+
+
diff --git a/Graphics/XCommanderAppIconBlack-macOS-Dark-1024@1x.png b/Graphics/XCommanderAppIconBlack-macOS-Dark-1024@1x.png
index 600fced..4511112 100644
Binary files a/Graphics/XCommanderAppIconBlack-macOS-Dark-1024@1x.png and b/Graphics/XCommanderAppIconBlack-macOS-Dark-1024@1x.png differ
diff --git a/Graphics/XCommanderAppIconBlack.icon/Assets/X-hat-white-on-black2 3.svg b/Graphics/XCommanderAppIconBlack.icon/Assets/X-hat-white-on-black2 3.svg
deleted file mode 100644
index ee521e6..0000000
--- a/Graphics/XCommanderAppIconBlack.icon/Assets/X-hat-white-on-black2 3.svg
+++ /dev/null
@@ -1,58 +0,0 @@
-
-
\ No newline at end of file
diff --git a/Graphics/XCommanderAppIconBlack.icon/Assets/XCommander-white.svg b/Graphics/XCommanderAppIconBlack.icon/Assets/XCommander-white.svg
new file mode 100644
index 0000000..012d3b4
--- /dev/null
+++ b/Graphics/XCommanderAppIconBlack.icon/Assets/XCommander-white.svg
@@ -0,0 +1,115 @@
+
+
diff --git a/Graphics/XCommanderAppIconBlack.icon/icon.json b/Graphics/XCommanderAppIconBlack.icon/icon.json
index 613837f..a1bd795 100644
--- a/Graphics/XCommanderAppIconBlack.icon/icon.json
+++ b/Graphics/XCommanderAppIconBlack.icon/icon.json
@@ -9,8 +9,8 @@
{
"layers" : [
{
- "image-name" : "X-hat-white-on-black2 3.svg",
- "name" : "X-hat-white-on-black2 3"
+ "image-name" : "XCommander-white.svg",
+ "name" : "XCommander-white"
}
],
"shadow" : {
diff --git a/Graphics/XCommanderAppIconDefault-macOS-Default-1024@1x.png b/Graphics/XCommanderAppIconDefault-macOS-Default-1024@1x.png
index 1cca01b..628b0d1 100644
Binary files a/Graphics/XCommanderAppIconDefault-macOS-Default-1024@1x.png and b/Graphics/XCommanderAppIconDefault-macOS-Default-1024@1x.png differ
diff --git a/Graphics/XCommanderAppIconDefault.icon/Assets/X-hat-black-on-white2.svg b/Graphics/XCommanderAppIconDefault.icon/Assets/X-hat-black-on-white2.svg
deleted file mode 100644
index 1f6f4f0..0000000
--- a/Graphics/XCommanderAppIconDefault.icon/Assets/X-hat-black-on-white2.svg
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
\ No newline at end of file
diff --git a/Graphics/XCommanderAppIconDefault.icon/Assets/XCommander-black.svg b/Graphics/XCommanderAppIconDefault.icon/Assets/XCommander-black.svg
new file mode 100644
index 0000000..2d6c530
--- /dev/null
+++ b/Graphics/XCommanderAppIconDefault.icon/Assets/XCommander-black.svg
@@ -0,0 +1,133 @@
+
+
diff --git a/Graphics/XCommanderAppIconDefault.icon/icon.json b/Graphics/XCommanderAppIconDefault.icon/icon.json
index 6c7762e..117a63c 100644
--- a/Graphics/XCommanderAppIconDefault.icon/icon.json
+++ b/Graphics/XCommanderAppIconDefault.icon/icon.json
@@ -9,8 +9,8 @@
{
"layers" : [
{
- "image-name" : "X-hat-black-on-white2.svg",
- "name" : "X-hat-black-on-white2"
+ "image-name" : "XCommander-black.svg",
+ "name" : "XCommander-black"
}
],
"shadow" : {
diff --git a/Sources/Companion/Assets.xcassets/MenuBarMark.imageset/mark.png b/Sources/Companion/Assets.xcassets/MenuBarMark.imageset/mark.png
index 79a8322..7a61275 100644
Binary files a/Sources/Companion/Assets.xcassets/MenuBarMark.imageset/mark.png and b/Sources/Companion/Assets.xcassets/MenuBarMark.imageset/mark.png differ
diff --git a/Sources/Companion/Assets.xcassets/MenuBarMark.imageset/mark@2x.png b/Sources/Companion/Assets.xcassets/MenuBarMark.imageset/mark@2x.png
index f7a9177..c8b84cd 100644
Binary files a/Sources/Companion/Assets.xcassets/MenuBarMark.imageset/mark@2x.png and b/Sources/Companion/Assets.xcassets/MenuBarMark.imageset/mark@2x.png differ
diff --git a/Sources/Companion/MenuBarController.swift b/Sources/Companion/MenuBarController.swift
index 5278631..7575a1e 100644
--- a/Sources/Companion/MenuBarController.swift
+++ b/Sources/Companion/MenuBarController.swift
@@ -171,15 +171,15 @@ final class MenuBarController {
return brandMark(opacity: opacity, description: status.explanation)
}
- /// The hat from the app icon, without its tile, as a **template** image — the idiomatic
+ /// The app icon's artwork, hat and sabres without the tile, as a **template** image — the idiomatic
/// menu-bar image on macOS. The system discards a template's colours and uses its alpha
/// as a mask, so the mark goes black on a light bar, white on a dark one, and tints under
/// a tinted wallpaper.
///
/// The *whole* app icon can never do this. A template's alpha is its shape, and the
/// icon's alpha is a filled rounded rectangle, so it renders as a blank white square.
- /// `xcdev icons` renders the hat from `Graphics/X-hat-black-on-white2.svg` and cuts the
- /// light ⌘ and crossbones out of it, so the bar draws them in its own colour.
+ /// `xcdev icons` renders it from `Graphics/XCommander-black.svg` and cuts the light ⌘ out
+ /// of it, so the bar draws it in its own colour.
private func brandMark(opacity: CGFloat, description: String) -> NSImage? {
guard let mark = NSImage(named: "MenuBarMark") else { return nil }
guard opacity < 1 else {
diff --git a/Sources/Companion/XCommanderAppIcon.icon/Assets/X-hat-black-on-white2.svg b/Sources/Companion/XCommanderAppIcon.icon/Assets/X-hat-black-on-white2.svg
deleted file mode 100644
index 1f6f4f0..0000000
--- a/Sources/Companion/XCommanderAppIcon.icon/Assets/X-hat-black-on-white2.svg
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
\ No newline at end of file
diff --git a/Sources/Companion/XCommanderAppIcon.icon/Assets/XCommander-black.svg b/Sources/Companion/XCommanderAppIcon.icon/Assets/XCommander-black.svg
new file mode 100644
index 0000000..2d6c530
--- /dev/null
+++ b/Sources/Companion/XCommanderAppIcon.icon/Assets/XCommander-black.svg
@@ -0,0 +1,133 @@
+
+
diff --git a/Sources/Companion/XCommanderAppIcon.icon/icon.json b/Sources/Companion/XCommanderAppIcon.icon/icon.json
index 6c7762e..117a63c 100644
--- a/Sources/Companion/XCommanderAppIcon.icon/icon.json
+++ b/Sources/Companion/XCommanderAppIcon.icon/icon.json
@@ -9,8 +9,8 @@
{
"layers" : [
{
- "image-name" : "X-hat-black-on-white2.svg",
- "name" : "X-hat-black-on-white2"
+ "image-name" : "XCommander-black.svg",
+ "name" : "XCommander-black"
}
],
"shadow" : {
diff --git a/Sources/xcdev/IconMaker.swift b/Sources/xcdev/IconMaker.swift
index 9470a8c..cbbba06 100644
--- a/Sources/xcdev/IconMaker.swift
+++ b/Sources/xcdev/IconMaker.swift
@@ -8,7 +8,8 @@ import UniformTypeIdentifiers
///
/// - The app icon is an Icon Composer document. It's copied as is: it already is the design,
/// and macOS draws it with its own geometry.
-/// - The menu bar mark is rendered from the hat SVG as a template image (see `makeMenuBarMark`).
+/// - The menu bar mark is rendered from the same artwork, hat and sabres, as a template image
+/// (see `makeMenuBarMark`).
/// - The `.icns` for a DMG's volume icon is compiled from the app icon by `actool`.
///
/// Needs `rsvg-convert` to render the SVG: `brew install librsvg`.
@@ -16,7 +17,7 @@ struct IconMaker {
let project: Project
let iconSource = "Graphics/XCommanderAppIconDefault.icon"
- let hatSource = "Graphics/X-hat-black-on-white2.svg"
+ let markSource = "Graphics/XCommander-black.svg"
let iconDestination = "Sources/Companion/XCommanderAppIcon.icon"
let markDestination = "Sources/Companion/Assets.xcassets/MenuBarMark.imageset"
@@ -33,7 +34,7 @@ struct IconMaker {
try? FileManager.default.removeItem(at: destination)
try FileManager.default.copyItem(at: project.path(iconSource), to: destination)
- print("Menu bar mark: rendering \(hatSource)")
+ print("Menu bar mark: rendering \(markSource)")
try makeMenuBarMark(work: work)
print("DMG icon: compiling Design/XCommander.icns")
@@ -57,21 +58,22 @@ struct IconMaker {
/// grey, so it's opaque. Using alpha alone would give a solid hat with no ⌘. Multiplying
/// alpha by darkness turns the light details into holes the menu bar can show through.
/// 2. **Fill the trim.** The thin white line along the hat's edge is lovely at 1024 pixels
- /// and just makes the hat look faint at 13 points. It's one long hole, so every hole wider
- /// than half the hat is filled. The ⌘ and the crossbones are small and stay cut out.
- /// 3. **Size it for the menu bar.** The hat is 2.3 times wider than tall. In the usual 18 pt
- /// square it would be 8 pt high, much smaller than the icons next to it, so the canvas is
- /// 31 × 18 pt and the hat ends up about 13 pt high.
+ /// and just makes the hat look faint at menu bar size. It's one long hole, so every hole
+ /// wider than half the artwork is filled. The ⌘ and the lines down the blades are small and
+ /// stay cut out.
+ /// 3. **Size it for the menu bar.** The artwork fills the usual 18 pt height, and the canvas
+ /// is as wide as its proportions need (about 21 pt), rounded down so it never overflows.
private func makeMenuBarMark(work: URL) throws {
let rendered = work.appending(path: "hat.png")
try shell("rsvg-convert", "-w", "2048", "-h", "2048", "-f", "png",
- "-o", rendered.path, project.path(hatSource).path)
+ "-o", rendered.path, project.path(markSource).path)
var mask = try Mask(inkFrom: rendered)
mask.cropToInk()
mask.fillHoles(widerThan: mask.width / 2)
- let canvasWidth = 31, canvasHeight = 18
+ let canvasHeight = 18
+ let canvasWidth = Int(Double(canvasHeight) * Double(mask.width) / Double(mask.height))
let markset = project.path(markDestination)
for scale in [1, 2] {
let name = scale == 1 ? "mark.png" : "mark@\(scale)x.png"
@@ -212,7 +214,7 @@ struct Mask {
let targetHeight = max(1, Int((Double(height) * Double(targetWidth) / Double(width)).rounded()))
// Scale the mask down with a Lanczos filter (vImage's high-quality resampling). It
- // keeps the ⌘ and the crossbones crisp; Core Graphics' interpolation blurs them at this
+ // keeps the ⌘ crisp; Core Graphics' interpolation blurs them at this
// size.
var scaledPixels = [UInt8](repeating: 0, count: targetWidth * targetHeight)
var sourcePixels = pixels
diff --git a/TRADEMARKS.md b/TRADEMARKS.md
index 5ea899a..1032656 100644
--- a/TRADEMARKS.md
+++ b/TRADEMARKS.md
@@ -17,7 +17,7 @@ The XCommander source code is free software under the [GPLv3](LICENSE). The lice
## Artwork
-The hat artwork and app icon are © 2026 Wassim Mansouri, all rights reserved. That covers the files in `Graphics/`, the icon in `Sources/Companion/XCommanderAppIcon.icon` and the images generated from them. They're in this repository so the official app can be built from source. They're not under the GPLv3, and a fork that's distributed needs its own icon.
+The artwork (the hat over crossed sabres) and the app icon are © 2026 Wassim Mansouri, all rights reserved. That covers the files in `Graphics/`, the icon in `Sources/Companion/XCommanderAppIcon.icon` and the images generated from them. They're in this repository so the official app can be built from source. They're not under the GPLv3, and a fork that's distributed needs its own icon.
## Official builds
diff --git a/XCommander.xcodeproj/xcshareddata/xcschemes/XCommander.xcscheme b/XCommander.xcodeproj/xcshareddata/xcschemes/XCommander.xcscheme
index 4aadb75..1359df1 100644
--- a/XCommander.xcodeproj/xcshareddata/xcschemes/XCommander.xcscheme
+++ b/XCommander.xcodeproj/xcshareddata/xcschemes/XCommander.xcscheme
@@ -1,11 +1,10 @@
+ version = "1.3">
+ buildImplicitDependencies = "YES">
+ shouldUseLaunchSchemeArgsEnv = "YES">
-
-
-
-
-
-