21 Commits
Author SHA1 Message Date
78ef4a8c77 Linux: draw on the desktop's GPU, not always the discrete one (#164)
* Linux: draw on the desktop's GPU, not always the discrete one

egui asks wgpu for the high-performance adapter. On a hybrid laptop in
PRIME on-demand mode (Intel + NVIDIA, X11, GNOME) that is the NVIDIA GPU
while the display server runs on the Intel one, so every frame is copied
between the GPUs. During a resize the window then shows stale or garbled
frames and can stop drawing until it is resized again.

On Linux and the BSDs, ask for no power preference instead: wgpu then
takes the first adapter Vulkan lists, and Mesa's device-select layer lists
the display server's GPU first (or the one DRI_PRIME picks). Measured on
an RTX 4060 + Intel RPL-S laptop: in on-demand mode the list starts with
the Intel GPU, in `prime-select nvidia` mode with the NVIDIA one, so the
launcher draws on whichever GPU drives the screens. WGPU_POWER_PREF still
overrides it. Windows and macOS keep their current choice.

Refs #69

* Linux GPU: keep wgpu's adapter order, but a software rasterizer last

Without Mesa's device-select layer the Vulkan order follows the ICD files, and lavapipe can come
before the real driver.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 02:50:10 -04:00
1c03e2d2ea Accessibility/UI: follow the OS's animation setting (#201)
* Add a Polish interface

- pl.tsv: the full catalog (287 rows), written clean-room from the English
  labels; plurals use the same one|few|many rule as Russian.
- Registered as the seventh language: "Polski" in the picker, locales pl,
  pl-PL and pl_PL.UTF-8, complete_menus = true so the completeness tests
  cover it.
- tests/polish.rs: the Polish UI test, modeled on the French one.
- README and AGENTS updated for the new language.

* Add Hungarian localization and fix responsive settings layout

* i18n: add Czech (cs) interface language

Czech catalog with every key of the most complete catalog (287 rows), the
cs language entry with locale detection (cs-CZ, cs_CZ.UTF-8, ?lang=cs),
a Czech plural rule (1 / 2-4 / other) with a unit test, and the README
language list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* i18n: add Japanese (ja) interface language

ja.tsv translates the whole interface, the tray menu and tooltip, each app's
tagline and the backend's install/update messages into Japanese, and
Settings > Language offers 日本語. Japanese locales (ja, ja-JP, ja_JP.UTF-8…)
select it; Japanese has one plural form.

Japanese is a CJK language, so cjk_font.rs now looks for a Japanese system
font (Hiragino Sans on macOS; Yu Gothic, Meiryo or MS Gothic on Windows;
Noto Sans CJK JP, Noto Sans JP, IPAGothic, Takao or VL Gothic on Linux and
FreeBSD), falling back to a Chinese one, which draws kana and most kanji,
where the system has none. The font is loaded per language, so switching
between Japanese and Chinese reloads the right face.

A fallback face is nudged onto the body font's baseline: egui puts a fallback
glyph's baseline at that face's own ascent and only centres the two line
boxes, which left a face whose metrics differ from Inter's riding high. On
Windows, Yu Gothic's line gap is half an em, so its kana and kanji sat about
0.29 em above the Latin text beside them (Microsoft YaHei, used for Chinese,
happens to match). The nudge, applied through a FontTweak, is the difference
in ascent and line height, and helps the Chinese faces too.

The README and AGENTS list the new language. Tests: the complete-catalog
checks cover ja.tsv (placeholders, plural forms, every tl! literal, taglines,
package formats), plus a locale/plural test, a Japanese glyph-coverage test,
a baseline test and tests/japanese.rs (grid, table, dates, a backend message).

* i18n: make the CJK font choice language-neutral

The CJK comments, the missing-font note and the plural-rule docs named the
languages, so each new one meant editing them all; they now say "CJK". Each
language's writing system (its `script`) now lives in the registry, and a
language is drawn only with a face for its own script — never another's,
which would leave characters as tofu — so a language the system has no font
for stays in English, like any other. Adding Korean or Traditional Chinese is
a registry row and a candidate list, not a special case.

* Hide Craft apps the user is not interested in.

* Read the Linux desktop appearance portal so system theme matching works on Wayland.

* UI: follow the OS's animation setting

With Windows' "Animation effects" switched off, the launcher still glided each
notch of the mouse wheel over several frames and faded its dropdowns in. egui
does both by default, and nothing asked the OS.

The shell now says what the OS wants (Host::reduce_motion) and the UI asks it
about once a second while it draws, so a change shows without a restart. With
fewer animations asked for:

- a mouse wheel scrolls at once. egui has no switch for its wheel smoothing but
  applies a trackpad's small steps as they come, so each wheel event is
  rewritten as a run of those in the shell's raw_input_hook;
- dropdowns, tooltips and dialogs appear without a fade, and scrolling to a
  place jumps there (style.animation_time, style.scroll_animation);
- the rule along the top of a hovered card appears instead of wiping in.

Progress bars and spinners keep moving: they say that work is going on.

Where the setting comes from:

- Windows: SPI_GETCLIENTAREAANIMATION, read as bit 33 of UserPreferencesMask in
  the registry, as SystemParametersInfoW needs unsafe;
- macOS: NSWorkspace's accessibilityDisplayShouldReduceMotion;
- Linux and the BSDs: the XDG settings portal over D-Bus (its reduced-motion,
  GNOME's enable-animations, KDE's AnimationDurationFactor), followed on a
  thread so the UI never waits for D-Bus;
- web: prefers-reduced-motion.

Animations stay on wherever the setting can't be read. winreg and zbus become
direct dependencies of the desktop app; both were already in Cargo.lock.

The Windows path was run on a machine with the setting off. The macOS and Linux
paths were type-checked for those targets but never run, and the web one only
compiled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* UI tests: hovering a card follows the OS's animation setting

With animations off, moving the pointer onto a card leaves the window still
within 3 frames: its rule and its icon's rise show at once. With them on, the
0.3 s wipe takes 19 frames at 60 frames a second. Each test fails when the
card's timing is made to ignore the setting.

The test window no longer has a download in progress, so it is still unless
something animates.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* i18n(pl): use Polish plural rule, so 21 is "21 aplikacji"

plural_east_slavic treats 21, 31 and 101 as "one", which is right for
Russian but not Polish, where only 1 itself takes the singular.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* system theme: back off to every 5 minutes when there's no appearance portal

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Merge #189 and main into #201: one raw_input_hook, and test anchors on taglines

Main no longer shows the "Like …" product lines, so the tests find cards by their taglines.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* i18n(cs): translate "Installed · latest {latest}" (added by #195)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* i18n(pl): translate "Installed · latest {latest}" (added by #195)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* i18n(hu): translate "Installed · latest {latest}" (added by #195)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* i18n(ja): translate "Installed · latest {latest}" (added by #195)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* i18n: hide/unhide strings for the Spanish, Czech, Polish, Hungarian and Japanese catalogs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* hungarian test: count only the settings body's links, not the cards' Website links behind the modal

#198 gave every card a Website link, and Hungarian labels both Webhely.

* hungarian test: card links are 14px text, settings icons 24px; filter on that

---------

Co-authored-by: DzikStar <82441193+DzikStar@users.noreply.github.com>
Co-authored-by: ferivoq <ferikegameplay@gmail.com>
Co-authored-by: Losminek <301412321+Losminek@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: leonaci <leonacism@gmail.com>
Co-authored-by: satchmo91 <eherrmann1991@gmail.com>
Co-authored-by: Vikram Bhaskaran <vikram.bhaskaran@outlook.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-12 02:49:59 -04:00
cf573b2d35 Fix system theme matching on Linux Wayland (#189)
* Read the Linux desktop appearance portal so system theme matching works on Wayland.

* system theme: back off to every 5 minutes when there's no appearance portal

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 02:49:47 -04:00
0c3e639b4d Windows: compile DX12 shaders with FXC (#173)
wgpu's default DX12 compiler (Auto) loads whichever dxcompiler.dll the DLL
search path finds. The launcher ships none, and without a matching dxil.dll
the unsigned-DXIL warning fails wgpu's indirect-validation pipeline, the
device is lost and the launcher exits before the first frame. Pin the
compiler to FXC, which is part of Windows; WGPU_DX12_COMPILER still
overrides it. GL stays in the Windows backends: it is the deliberate
fallback for machines whose D3D12 adapters can't present to the window.

Fixes #126

Co-authored-by: Fabio Lussi <198260595+itrycodinganditsbad@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 01:56:24 -04:00
96ed437966 Desktop: write log records to standard error and a rotating log file (#178)
A launcher started from the Dock, the Start menu or at login has no
terminal, and the Windows build has no console, so its log records and
panic reports were lost.

env_logger now writes each record to standard error and to
logs/artcraft-launcher.log in the launcher's data folder (portable mode
included). Each start keeps the previous two runs' logs; the file is
capped at 16 MiB. The file is opened once this is the only launcher
running, so a second start doesn't rotate the first one's log away.
Panics are reported through the logger. The default filter is now info
for the launcher's crates and warn for the rest; RUST_LOG still wins.

Ported from storytold/pdfcraft#239.

Co-authored-by: Fabio Lussi <198260595+itrycodinganditsbad@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 01:53:54 -04:00
0358cda174 Linux: name the tray icon instead of showing the process id (#140)
tray-icon's default id is "<pid>-<n>" and the title is empty, so
StatusNotifierItem hosts showed numbers like "61965-1". On Linux and the
BSDs, give the icon the id "artcraft-launcher" and the title
"ArtCraft Launcher". Windows and macOS are unchanged.

Fixes #136

Co-authored-by: Fabio Lussi <198260595+itrycodinganditsbad@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 01:53:46 -04:00
MarekSpodBiedry 7938ed90ac macOS: set the notification bundle id so no 'Where is use_default?' picker appears (#95) (#116) 2026-10-12 01:53:42 -04:00
Val EnfysandClaude Opus 5.5 ba8a704908 macOS: keep the bundle's icon in the Dock while the launcher runs (#127)
eframe sets the app icon at runtime, and on macOS that replaces the
Dock icon with a raw bitmap (the 256 px PNG we passed, or egui's logo
when none is given), which skips the system's icon treatment. Pass the
empty icon on macOS so eframe leaves the bundle's .icns alone.

Fixes #32.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 01:53:38 -04:00
Dylan M. Taylor c273a94a9a linux: fix Flatpak bundle updates, serialize installs, filter detection by arch, and add status logging (#149)
* linux: allow updating Flatpak bundles with --reinstall and improve error reporting

* linux: filter flatpak detection by arch, queue bundle installs, and log actions

* test(core): verify strict arch matching across all linux package formats
2026-10-11 14:49:33 -04:00
648546e942 Add an option to install Craft apps from local builds instead of GitHub (dev builds only) (#64)
* Install and update Craft apps from a local mirror

Add an opt-in developer mode for installing the Craft apps from builds on
this machine instead of GitHub:

- ARTCRAFT_LAUNCHER_DOWNLOAD_BASE (loopback http only) points the launcher
  at a local mirror. While set, every check reads the mirror's
  release_info.json, trusts download links under the mirror, never treats
  entries as stale, and never falls back to GitHub or ArtCraft's API.
- cargo xtask local sync pulls every sibling app checkout (git pull
  --ff-only --recurse-submodules), packages each app whose version isn't
  mirrored yet with its own packaging script, and files the results under
  <mirror>/<app>/<version>/ with SHA256SUMS.txt and notes from git log.
- cargo xtask local serve serves the mirror on 127.0.0.1 (with range
  requests, so paused downloads resume) and writes the feed fresh from the
  mirror's contents on every request.
- cargo xtask local status compares each checkout with what's mirrored.

* Sync the local mirror on an interval while serving it

cargo xtask local serve --sync-every <30m|1h|1d…> runs the same sync as
cargo xtask local sync on a background thread, one after another, so the
mirror follows origin without a second process. Downloads keep being
served during a build, and a version only joins the feed once its build
is complete. Pulls are --no-stat to keep the server's log readable.

* Build every new commit as a dev version with --every-commit

cargo xtask local sync --every-commit (and serve --sync-every … --every-commit)
builds each new commit rather than only new versions. A commit of a 0.4.0
checkout is packaged as 0.4.1-dev.<commit time> through the app's
<APP>_VERSION override, so it orders after 0.4.0, after earlier commits,
and before the real 0.4.1. The full version lands in the bundle's
<App>Version key, which the launcher reads, so it offers each build as an
update and sees it as current once installed.

* Keep the local mirror out of release builds; parse loopback URLs strictly

ARTCRAFT_LAUNCHER_DOWNLOAD_BASE makes the launcher trust the mirror's own
checksums and skip GitHub, so a shipped launcher must not read it: it now
needs the local-mirror cargo feature (cargo run --features local-mirror),
which release builds never enable. The loopback check parsed the URL by
prefix, so http://127.0.0.1:1@evil.example/ passed; it now requires the host
to be exactly 127.0.0.1, localhost or [::1] with a numeric port. The same
check guards ARTCRAFT_LAUNCHER_FEED_URL.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: khutchings <7854672+khutchings@users.noreply.github.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 05:03:14 -04:00
6f9722c91a Let a newer launcher take over from an older one that's already running (#59)
Issue #29's window wasn't 0.1.2: its tagline and header are 0.1.0's, and
it offered Download where a portable 0.1.2 offers Update and restart. A
0.1.0 launcher sat in the tray; starting 0.1.2 asked it to show its
window and exited, and that window still offered 0.1.1, found while 0.1.1
was the latest release.

A second start now says hello with its version and the running launcher
answers with its own. A newer start makes the running one quit (unless
it's downloading or installing; then it shows its window) and takes over
the port. The same version or older shows the running window as before.
Launchers from before the handshake hang up without an answer and can't
be asked to quit, so the new start runs anyway. A bare "show" from an
old launcher is still understood.

Tests: the handshake over loopback, including a running launcher that
predates it.

Co-authored-by: Fabio Lussi <198260595+itrycodinganditsbad@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 05:02:09 -04:00
MarekSpodBiedry 714522d577 Quit from the tray even when the window is minimized and gets no frames (#77) 2026-10-11 04:35:06 -04:00
92e23e0348 Windows: prefer Direct3D 12 (including WARP) over GL when picking a GPU (#105)
* fix(wgpu): prefer D3D12 (incl. WARP) over GL on Windows (#2087)

On Windows, rank any Direct3D 12 adapter (WARP included) above GL when
WGPU_BACKEND is unset. wgpu ranks WARP last, so GPUs without a D3D12
driver (Intel HD 4000, Radeon TeraScale) got the GL adapter, whose legacy
driver fails Surface::configure; wgpu panics on that before any app code
runs. Hardware D3D12 adapters keep wgpu's order. Reporter verified
WGPU_BACKEND=d3d12 (WARP) works on the affected machine.

Refs storytold/artcraft#2087

* Drop a reference to an issue number from another tracker

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 02:38:31 -04:00
FlowershangfromthebranchesandClaude Opus 5.5 bf452db810 Add a Simplified Chinese interface, drawn with the system's Chinese font
zh-CN.tsv translates the whole interface, the tray menu and tooltip, each
app's tagline and the backend's install/update messages into Simplified
Chinese, and Settings > Language offers 简体中文. Simplified Chinese
locales (zh-CN, zh-SG, zh-Hans, zh_CN.UTF-8, a bare zh) select it; an
explicit Traditional script (zh-Hant-CN) or a Traditional region (zh-TW,
zh-HK, zh-MO) doesn't. Chinese has one plural form. The tray's menu and
tooltip now follow the interface language (Russian rows added too).

The bundled faces have no Chinese glyphs, so on the desktop the
launcher borrows the system's own Chinese font (cjk_font.rs): PingFang
(in /System/Library/Fonts on older macOS, a downloaded font asset on
newer ones), Hiragino Sans GB or Heiti on macOS; Microsoft YaHei or
SimSun on Windows; Noto Sans CJK (static or variable) or WenQuanYi on
Linux and FreeBSD. The face is picked by its family name (PingFang SC,
Noto Sans CJK SC…), regular weight, rather than a hard-coded index in
the collection. Files over 100 MB are skipped and nothing panics. The
font (PingFang is 78 MB) is read only when Chinese is the language in
use, chosen or through Auto, and then kept for the session. Until then
the picker says "Simplified Chinese", and "Simplified Chinese (简体中文)"
once the font is loaded. With no Chinese font (and on the web), the
interface stays in English and Settings explains why, instead of boxes
for every character.

Rebased onto main from the original PR (#34). Changed from the original:
- No bundled font: NotoSansSC-Regular.ttf (10.6 MB), its OFL and README,
  their ATTRIBUTION and NOTICE rows and the zh-CN screenshots are left
  out; the system font replaces them, as above.
- The i18n framework fixes in that PR (trim_end in the catalog tests,
  the n == 1 plural fallback, 1-3 @plural forms, the registry-driven
  language label) landed with the Russian catalog; this adds the
  script-aware zh tag matching on top.
- zh-CN.tsv: "Verifying checksum…" mentions the checksum (正在验证校验和…),
  update.check_auto keeps "automatically" (自动检查更新), "Launcher" stays
  in English like the rest of the product name, rows were added for
  every string main gained since, and rows for messages the launcher
  never sends were dropped.
- tests/chinese.rs works with or without a system Chinese font: with
  one it switches to 简体中文 and checks the grid, table, web and saved
  setting; without one it checks the English fallback and the note. The
  glyph-coverage test now covers the system font, when there is one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 13:11:51 -04:00
MaksimandClaude Opus 5.5 cf5604dc65 Add UI localisation (i18n) with a Russian catalog
Every user-visible string in the interface is now looked up from a
per-language catalog at render time instead of being compiled in as
English. English stays the source of truth and the lookup key; a missing
row falls back to English rather than failing.

- crates/ui-egui/src/i18n: `t`/`tl!` for literals, `tr_ctx` (one English
  word needing different translations), `tr_id` (command-id keyed),
  `trn`/`tn` (plurals), `fmt` ({name} placeholders filled after the
  lookup) and `message`/`msg` (backend status and error text, translated
  where it is shown). Split into lang.rs (the registry and locale tags),
  detect.rs (the system language), translate.rs (lookups) and catalog.rs
  (the TSV parser); mod.rs only declares them.
- ru.tsv: the whole interface in Russian, with East Slavic plural forms,
  month abbreviations, a day-month-year date template and each app's
  tagline. Product and app names (ArtCraft Launcher, Craft App Suite,
  PhotoCraft…) stay in English.
- The language follows the system by default: ARTCRAFT_LAUNCHER_LOCALE,
  then the OS's preferred UI languages through the sys-locale crate
  (desktop only; LANGUAGE/LC_*/LANG on Linux and the BSDs, the preferred
  languages on macOS, the user's UI languages on Windows), and `?lang=`
  then `navigator.languages` on the web. Settings > Language overrides it.
- core stays pure and wasm-safe: `time::ago_kind` and `month_short_en`
  let the UI render relative times and dates in the current language.

Ported onto main from the original PR (#28): every string main added
since (feed notices and alerts, the "using ArtCraft API and GitHub"
footer, window buttons, waiting and retry states, the install-cancelled
toasts, filter tooltips, package formats, the reveal label) goes through
the catalog, with Russian rows. Also changed from the original:
- `@msg` templates now match real messages: `Couldn't open {name}: {e}`
  translates "Couldn't open PhotoCraft: …", the most specific template
  wins. Rows for messages the launcher never sends (clipboard, recovery
  data) are gone; rows for its install/update/remove toasts are added.
- The locale probes no longer spawn /usr/bin/defaults or reg.exe; the
  small, dependency-free sys-locale crate asks the OS instead.
- Folded in from #34's framework fixes: catalog tests split rows with
  trim_end (trim dropped the leading TAB, so plain rows were silently
  skipped), the English plural fallback goes by n == 1, @plural rows take
  1 to 3 forms, and Settings::language_label comes from the registry.
- Tests are registry-driven: placeholders, plural form counts and, for
  every catalog marked complete, coverage of every tl!/t literal, every
  tn plural key, each tagline and the package formats. A Russian UI test
  renders the grid and table. Catalog warnings go to the log, not stderr.
- ru.tsv: "Launcher" and "Craft App Suite" stay in English; "лаунчер" is
  spelled one way; "Verifying…" (Проверка целостности…) and "Discard
  download" (Удалить скачанное) no longer read like "Checking…" and
  "Cancel download"; the table's Installed/Latest headers are short
  enough to fit; the reveal rows match the backend's "Show in …" labels.
- The toolbar drops its "Sort" caption when longer labels leave no room
  for it, rather than drawing over the filters.
- Unused settings helpers and LANGUAGE_CODES were removed, and core's doc
  comments now describe what the UI actually translates.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 13:06:46 -04:00
RealtaNuaandClaude Opus 5.5 7a193042fd Stay in the tray on Wayland when the window closes
winit cannot hide a Wayland window, so closing to the tray cancelled the
close and then did nothing. Where the window cannot hide, the close now
goes through and the launcher keeps running with only the tray; a tray
click or a second launch opens a new window in the same process. Other
platforms keep the single hidden window. The header's own close button
(no decorations) takes the same path as the window manager's.

With no window, settings that change (the last check, updates announced)
are saved to eframe's app.ron as they change, so quitting from the tray
no longer loses them. A --hidden start at login on Wayland now starts in
the tray without mapping a window first, so none flashes up.

Rebased onto main from the original PR: the Launcher/Shell split now
carries main's custom title bar, has_desktops, macOS "show on the current
desktop", wgpu options and theme-token clear colour. The settings saving
with no window and the windowless start at login were added here.

Fixes #4

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 12:32:53 -04:00
Jeremy YaoandClaude Fable 5.1 bee2ffc283 Default wgpu to Direct3D 12 on Windows: fixes startup crash on hybrid AMD laptops
On Windows the launcher now asks wgpu for DX12 with GL as the fallback instead
of wgpu's default list, which starts with Vulkan. WGPU_BACKEND still overrides
it; other platforms keep wgpu's defaults.

Without this the launcher died on startup with STATUS_ACCESS_VIOLATION on an
ASUS G513QY (Ryzen 9 5900HX integrated Radeon + Radeon RX 6800M). The crash is
inside AMD's Vulkan driver (amdvlk64.dll): the integrated GPU runs the OEM
driver from 2021 while the 6800M runs Adrenalin from 2026, both register a
Vulkan ICD, the loader reports the 6800M twice, and wgpu's pick dies right
after the surface is configured. AMD's installer never updates the OEM iGPU
driver, so this state is common on hybrid laptops. DX12 and GL both work.

Also reorders one import in self_update.rs that stable rustfmt flagged, so
`cargo xtask ci` passes again.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-10 12:19:39 -04:00
BFlatandClaude Opus 5.5 019330f99a Restyle to match getartcraft.com, add an installer wizard, blue app icon (#23)
The launcher now looks like the apps page on getartcraft.com: the site's
colour tokens, square corners, 1 px hairlines instead of shadows, app cards
in a shared-hairline grid with numbered tabs and "Photo*Craft*" wordmarks,
mono upper-case labels and buttons, and square badges for status.

Fonts are the site's own, embedded in the binary: Archivo (620, 118 % width)
for headings and app names, Inter for body text and Geist Mono for labels,
all variable fonts from google/fonts (OFL-1.1) set to the site's weights.

The window has a custom title bar on Windows and Linux (drag to move,
double-click to maximize, minimize/maximize/close, resize from the edges)
and a transparent one on macOS with the traffic lights in the header.

The MSI used to flash a progress bar and close. Double-clicked, it now opens
a WixUI wizard (Welcome, Ready, progress, Finish with "Launch ArtCraft
Launcher"), with art drawn by package.ps1 from the ArtCraft mark and the
Craft apps' icons. Self-update still runs it with /passive. CI installs the
WiX UI and Util extensions.

The app icon is now the blue "A" mark, getartcraft.com's favicon.
packaging/icons.sh runs on any OS: `cargo xtask icns` packs the .icns.

Also: two clippy fixes in crates/native that newer clippy rejects, and
refreshed README screenshots.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 17:39:01 +07:00
Brandon ThomasandClaude Opus 5.5 8766e29547 macOS: show the window on the current desktop
Opening the launcher from the menu bar used to switch to the desktop
(Space) its window was last on, which is jarring when you're working on
another one. A new setting, "Show the window on the current desktop"
(on by default), sets AppKit's "move to active space" behavior on the
window whenever it's shown, so it comes to the desktop you're on instead.
Turning it off restores macOS's default of switching to the window.

macOS only: the code and its dependencies compile only for macOS, and
the setting appears only where the host has desktops. objc2,
objc2-foundation and objc2-app-kit are already in Cargo.lock through
winit and tray-icon; they're pinned to those versions, and only safe
AppKit calls are used.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 03:03:12 -04:00
Brandon ThomasandClaude Opus 5.5 d4f5a33ea4 Brand header, sortable table, links to ArtCraft and each app
- Header: the ArtCraft wordmark (white on dark, ink on light), "Launcher ·
  Craft App Suite" and the tagline "Open Source Tools for Creatives,
  Makers, and Builders"
- Tray / menu-bar icon is now the ArtCraft "A" mark, rendered unmodified
  from docs/brand; the old self-drawn tray icons are gone
- Repo docs (NOTICE, ATTRIBUTION, README, asset licenses, AGENTS.md)
  call out that the ArtCraft name, logo and mark are not MIT/Apache
- Table: "Inspired by" column; every column sorts both ways, empty cells
  last; the grid's sort menu has the same options
- Adobe / Microsoft / Autodesk / Avid trademark notice under both views;
  inspirations shown with ®
- Links: Discord button in the header; Website · GitHub · Discord in the
  footer, tray menu and Settings; each card links to its app's website
  (classic apps) and GitHub repo, and the … menu has both
- Fix links never opening: enable eframe's "links" feature
- Clear stale partial downloads at startup

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 22:17:41 -04:00
Brandon ThomasandClaude Opus 5.5 ec69f0be2c ArtCraft Launcher: install and update the Craft App Suite
A native Rust/egui launcher for the 12 Craft Apps (7 classic + 5 new).

- Grid (icon cards) or sortable table view, filters and search
- Status per app: available, installed and up to date, or update
  available with version and release date
- Installs where each OS keeps apps, from the official release packages:
  /Applications (DMG), Program Files (MSI), deb/rpm via the system
  package manager (Flatpak/AppImage fallback), /usr/local on FreeBSD
- Detects apps installed by hand; updates keep the installed format
- Every download verified against its published SHA-256; running apps
  are never replaced
- Tray/menu-bar mode, start at login, one notification per new version
- GitHub API with ETag cache, falling back to release pages when
  rate-limited; release source is pluggable for a future catalog API
- Web build lists latest releases with per-platform downloads
- Packaging and release workflows for macOS, Windows (x64/x86/arm64),
  Linux (x86_64/aarch64), FreeBSD and web

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 21:08:24 -04:00