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 @@ - - - - - -image/svg+xml - -XCommander hat -Wassim Mansouri -Copyright © 2026 Wassim Mansouri. All rights reserved. The XCommander name and icon are not covered by the GPL; see TRADEMARKS.md. -2026 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ 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 @@ - - - - - -image/svg+xml - -XCommander hat -Wassim Mansouri -Copyright © 2026 Wassim Mansouri. All rights reserved. The XCommander name and icon are not covered by the GPL; see TRADEMARKS.md. -2026 - - - - - - - - - - - - - - - - - - - - - - - - - - - \ 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 @@ - - - - - -image/svg+xml - -XCommander hat -Wassim Mansouri -Copyright © 2026 Wassim Mansouri. All rights reserved. The XCommander name and icon are not covered by the GPL; see TRADEMARKS.md. -2026 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ 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 @@ - - - - - -image/svg+xml - -XCommander hat -Wassim Mansouri -Copyright © 2026 Wassim Mansouri. All rights reserved. The XCommander name and icon are not covered by the GPL; see TRADEMARKS.md. -2026 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ 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 @@ + + + + XCommander icon on a light tile + + + + image/svg+xml + + XCommander icon on a light tile + + + Wassim Mansouri + + + + + Copyright © 2026 Wassim Mansouri. All rights reserved. The XCommander name and icon are not covered by the GPL; see TRADEMARKS.md. + + + + + XCommander + + + 2026 + en + + + XCommander + app icon + tricorne + sabres + command key + + + The artwork on a light rounded tile, for places that need a finished icon without Icon Composer. XCommander's artwork: a captain's tricorne with ⌘ on its crown, over two crossed sabres that form an X. Created by Wassim Mansouri in Inkscape. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + XCommander + + + + image/svg+xml + + XCommander + + + Wassim Mansouri + + + + + Copyright © 2026 Wassim Mansouri. All rights reserved. The XCommander name and icon are not covered by the GPL; see TRADEMARKS.md. + + + + + XCommander + + + 2026 + en + + + XCommander + app icon + tricorne + sabres + command key + + + Black on transparent, with a light ⌘. The layer of the app icon (XCommanderAppIconDefault.icon). XCommander's artwork: a captain's tricorne with ⌘ on its crown, over two crossed sabres that form an X. Created by Wassim Mansouri in Inkscape. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + XCommander icon on a dark tile + + + + image/svg+xml + + XCommander icon on a dark tile + + + Wassim Mansouri + + + + + Copyright © 2026 Wassim Mansouri. All rights reserved. The XCommander name and icon are not covered by the GPL; see TRADEMARKS.md. + + + + + XCommander + + + 2026 + en + + + XCommander + app icon + tricorne + sabres + command key + + + The artwork on a dark rounded tile, for places that need a finished icon without Icon Composer. XCommander's artwork: a captain's tricorne with ⌘ on its crown, over two crossed sabres that form an X. Created by Wassim Mansouri in Inkscape. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + XCommander (white) + + + + image/svg+xml + + XCommander (white) + + + Wassim Mansouri + + + + + Copyright © 2026 Wassim Mansouri. All rights reserved. The XCommander name and icon are not covered by the GPL; see TRADEMARKS.md. + + + + + XCommander + + + 2026 + en + + + XCommander + app icon + tricorne + sabres + command key + + + White on transparent, with a dark ⌘. The layer of the dark app icon (XCommanderAppIconBlack.icon). XCommander's artwork: a captain's tricorne with ⌘ on its crown, over two crossed sabres that form an X. Created by Wassim Mansouri in Inkscape. + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ - - - - - -image/svg+xml - -XCommander hat -Wassim Mansouri -Copyright © 2026 Wassim Mansouri. All rights reserved. The XCommander name and icon are not covered by the GPL; see TRADEMARKS.md. -2026 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ 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 @@ + + + + XCommander (white) + + + + image/svg+xml + + XCommander (white) + + + Wassim Mansouri + + + + + Copyright © 2026 Wassim Mansouri. All rights reserved. The XCommander name and icon are not covered by the GPL; see TRADEMARKS.md. + + + + + XCommander + + + 2026 + en + + + XCommander + app icon + tricorne + sabres + command key + + + White on transparent, with a dark ⌘. The layer of the dark app icon (XCommanderAppIconBlack.icon). XCommander's artwork: a captain's tricorne with ⌘ on its crown, over two crossed sabres that form an X. Created by Wassim Mansouri in Inkscape. + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ - - - - - -image/svg+xml - -XCommander hat -Wassim Mansouri -Copyright © 2026 Wassim Mansouri. All rights reserved. The XCommander name and icon are not covered by the GPL; see TRADEMARKS.md. -2026 - - - - - - - - - - - - - - - - - - - - - - - - - - - \ 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 @@ + + + + XCommander + + + + image/svg+xml + + XCommander + + + Wassim Mansouri + + + + + Copyright © 2026 Wassim Mansouri. All rights reserved. The XCommander name and icon are not covered by the GPL; see TRADEMARKS.md. + + + + + XCommander + + + 2026 + en + + + XCommander + app icon + tricorne + sabres + command key + + + Black on transparent, with a light ⌘. The layer of the app icon (XCommanderAppIconDefault.icon). XCommander's artwork: a captain's tricorne with ⌘ on its crown, over two crossed sabres that form an X. Created by Wassim Mansouri in Inkscape. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ - - - - - -image/svg+xml - -XCommander hat -Wassim Mansouri -Copyright © 2026 Wassim Mansouri. All rights reserved. The XCommander name and icon are not covered by the GPL; see TRADEMARKS.md. -2026 - - - - - - - - - - - - - - - - - - - - - - - - - - - \ 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 @@ + + + + XCommander + + + + image/svg+xml + + XCommander + + + Wassim Mansouri + + + + + Copyright © 2026 Wassim Mansouri. All rights reserved. The XCommander name and icon are not covered by the GPL; see TRADEMARKS.md. + + + + + XCommander + + + 2026 + en + + + XCommander + app icon + tricorne + sabres + command key + + + Black on transparent, with a light ⌘. The layer of the app icon (XCommanderAppIconDefault.icon). XCommander's artwork: a captain's tricorne with ⌘ on its crown, over two crossed sabres that form an X. Created by Wassim Mansouri in Inkscape. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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"> - - - - - -