* packaging: Flatpak finds and prints to CUPS printers
The Print dialog listed no printers in the Flatpak: the runtime has libcups but not
lpstat/lp, the sandbox couldn't reach the CUPS socket, and driverless network printers
(lpstat -e) need Avahi. Bundle lpstat/lp/lpoptions from CUPS 2.4.20 (Apache-2.0,
statically linked, licence installed) and grant --socket=cups and
--system-talk-name=org.freedesktop.Avahi in both manifests.
* print: lp takes the job only when CUPS lists a printer; the only printer by default; ~/.cups read-only
Review (CodeRabbit) on bundling lp in the Flatpak:
- With lp present but CUPS down or empty, the job failed on lp instead of reaching the
IPP route and the print portal. lp_route now gives up the route when lpstat lists no
printer, before anything is submitted.
- With no printer named, no default and one queue, IPP picked it but lp failed. lp_route
names the only printer.
- The sandbox ignored the user's default printer, saved options and client.conf server:
grant ~/.cups read-only in both manifests.
* print: no printers for lp means the portal, not IPP; bounded listing; CUPS socket wrapper
Review:
- When lp is there but CUPS lists no printer, the job went to the IPP route, whose
server detection ignores ~/.cups/client.conf and could print to a local default
printer instead of the configured server. It now goes to the print portal, or fails
with no portal.
- The lpstat listing before a job is bounded (10 s, then lp takes the job as before)
and runs outside SPOOLER, which guards only Windows driver calls.
- Flatpak mounts the host's CUPS socket at /var/run/cups/cups.sock whatever path
client.conf or CUPS_SERVER names; the CUPS tools now run through a wrapper that
points a socket path missing in the sandbox there, leaving server names alone.
* packaging: redirect a custom CUPS socket only when it is the one Flatpak mounted
Review (CodeRabbit): Flatpak picks the socket it mounts at /var/run/cups/cups.sock
with stricter rules than CUPS (flatpak-run-cups.c: a socket CUPS_SERVER, else the
first line spelled exactly "ServerName /path" in ~/.cups/client.conf, else the
default), while CUPS reads the keyword in any case and takes the last ServerName. The
wrapper now redirects only when CUPS' socket is the one Flatpak chose, so a job can't
reach a different server; otherwise CUPS fails on the missing path.
* print: a printer listing past its deadline kills and reaps lpstat
Review: the 10 s limit stopped waiting but left a hung lpstat and its thread
running, so repeated print attempts could pile them up. photocraft now runs the two
lpstat listings itself (craft-print's lpstat_command and an equivalent lpstat -e,
parsed by printers_parsed) and kills and reaps each one at the shared deadline. The
output is read on a thread that ends with the process, so nothing outlives the job.
* packaging: never redirect a CUPS_SERVER the sandbox was given
Review (CodeRabbit): Flatpak picks the socket it mounts from the host's CUPS_SERVER,
so one set by flatpak run --env or an override may not be what it mounted. The
wrapper now leaves any CUPS_SERVER alone and redirects only a client.conf socket that
matches Flatpak's choice; otherwise CUPS fails on the missing path instead of
reaching a different server.
* packaging: point CUPS at the mounted socket only when it is the one Flatpak chose, else fail
Review (CodeRabbit): with a custom socket listed first and the default last in
~/.cups/client.conf, Flatpak mounts the custom one at /var/run/cups/cups.sock while
CUPS picks the last line, finds that path, and talks to the custom server. The
wrapper now compares CUPS' socket with Flatpak's choice even when the path exists:
equal, CUPS is pointed at the mount; different, the tool fails with an error instead
of reaching another server.
Also (CodeRabbit):
- A printer named in the job goes to lp even when CUPS lists none: listing can be
forbidden while printing is not, and the portal can't honour a name.
- A failed lpstat -e (CUPS unreachable, listing forbidden) means the list can't be
told, so lp takes the job, instead of an empty list sending it to the portal.
- A listing longer than 1 MiB counts as no answer, instead of growing without bound.
- The kill test checks the process with kill -0, which works on every Unix.
- docs/printing.md: the only-printer fallback is on the lp and IPP routes, and the
portal is Linux only.
The font menu from #6526 (preview, filter bar, class list, favourite stars,
style expanders, format badges) now sits under the editable family field:
the field is the search, so the menu has no search box of its own. The list
keeps the viewport measured when the menu opens and shrinks to its message
when nothing matches, ending with the class list.
keys.rs takes main's split key handlers with this branch's changes: caret
moves and Cmd+A clear the pending typing font, and Cmd+Enter waits for the
IME. Explicit imports replace `use super::*` for the strict lints;
`with_target` is gone on main.
A native Swedish speaker answered the terminology questionnaire on #10021;
his choices now apply to every row that uses the term, so each concept
still has one Swedish word: arbetsyta (workspace), fjädring (feather),
ombilda (transform), rutnät (grid), förhandsgranskning (preview),
klippmask, skiva (slice), ta prov (sample), gradient, placera, snedställ,
rasterisera, Kombinera lager (Flatten Image), indefinite tool names
(Penselverktyg), and the blend modes Skärm, Överlägg, Färgskuggning,
Differens and Luminositet. 243 rows changed.
Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds Swedish (sv, Svenska) as an interface language. The catalog combines
the open Swedish catalogs of #5985 and #9536: each row takes the best of
their translations, with one Swedish term per concept across the UI and
the reference application's established Swedish terms where they are
unambiguous, and the strings added since are filled in. 4,537 rows, every
measured key; plural rule one|other.
Where the rows come from: 2,710 both catalogs agreed on, 979 from #5985,
655 from #9536, 193 written new; 177 of the taken rows
were edited for consistency.
The tests that used sv-SE as an unsupported locale now use sw-KE and
fi-FI, and sv-SE / sv_FI.UTF-8 are positive cases. macOS lists sv in
CFBundleLocalizations.
Fixes#10020.
Co-authored-by: kler <966132+kler@users.noreply.github.com>
Co-authored-by: davvarn <1687962+davvarn@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The web build has no system fonts and embeds no craft fonts, so an Arabic
(or Japanese, Chinese, Korean, Hindi) interface had no font for its labels:
served fonts were registered only in the document text engine. A served
script fallback now also joins the end of every egui font family, and the
font stack theme::install_fonts rebuilds on a language change includes it
again. The web shell asks for the interface language's script font, not
only the browser languages'.
Review finding on #10006.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicts in perf/budgets.toml and docs/scorecard.md: both sides added perf rows (P80 here, P81 and P82 from #9942). Kept all three; scorecard regenerated with cargo xtask scorecard.
Track-only rows that check they hit the whole-document-redraw path and
print the refreshed pixel count: undo of a brush dab on a 16-bit
15000x10000 full-canvas layer (reps capped at 5) and a fill of a 2 %
selection on a 24 MP full-canvas layer.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Track-only row, the slow-frame recorder's worst case. A 24 MP photo plus
three full-canvas blended copies (Multiply, Screen, Overlay); each sample
toggles the top copy and times one harness.step(), so every frame
recomposites all 24 MP on the CPU (the photo's tiles are never uniform,
which keeps the reduced render's one-colour shortcut out of the way).
The row errors unless each frame recorded a CPU refresh covering at least
95 % of the canvas, so it can't silently take a fast path. 10 samples.
Maintenance keeps the existing installation context, and a major upgrade of an
existing per-machine installation without ALLUSERS=1 is rejected rather than
installed per-user.
CodeRabbit on #9775: the 12-of-181 count changed today, so ui-parity.md and gaps.md get the date in their status lines and a revision-history row, as AGENTS.md asks.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Conflicts with main's batch #9880:
- psd file.rs / layer.rs: #5287 (PSB by encoded size, RLE tables widened on
promotion) against #6583's lazy reader. Main's new widening and length code
read `.data`, which #6583 leaves empty while the bytes stay in the source;
it now goes through `encoded()` / `encoded_len()` (also the auto-merged
lines in `rle_widening`, `encoded_len` and `LayerRecord::write`), and the
lazy reader sets `write_as_psb: false`. New test
`a_lazy_psd_promotes_to_the_same_psb_as_an_eager_one`: a lazily read PSD
writes the same PSB bytes as an eager one; it fails with a `.data` read.
- direct_select.rs / vector_ui.rs: #9321's Type Path and #6353's hidden
Work Path both kept.
- io tests main.rs: both modules. scorecard.md regenerated (12 of 181);
ui-parity.md and gaps.md follow it.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
CodeRabbit on #9775: Place::AutoEditable puts type, shapes, pastes, placed files and frames above a group whose lock would refuse them; ui-parity.md's status line and checklist row said every new layer goes into an open active group.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
CodeRabbit on #9775: FontLibrary::finish wrote a failed type.font.favorite to the status bar as plain information; it now sets status_error like the other status writes. The regenerated scorecard counts 12 of 179 preferences that do nothing; ui-parity.md and gaps.md still said 178.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Main moved the engine commands into crates/engine/src/cmd/ and the
dialogs and panels into submodules. The PR's placement calls follow
them, and main's new insert sites (new_adjustment in adjust_params.rs,
Place in file_cmds/open.rs, shapes in vector_cmds/shape.rs) use
layer_place::insert_new like the PR's originals. The New Group dialog
moves to dialogs/new_group_ui.rs; the Layers panel flyout's New Group…
opens it.
Main's Session::precheck now also checks layer.new.group's and
layer.new.groupFromLayers' new params (name, color, mode, opacity,
position), so precheck_agrees_with_execute holds. Main had since added
"New Group…" to every catalog: the PR's duplicate rows are dropped.
Main's newer tests that made a layer with an open group active now
open the group last, as the PR did for the older ones.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Character section: a style picked under a family's ">" with type layers
selected set the layers but not the style for new type (the options bar
did both). Pick "Inter > Thin" in Properties > Character: new type stayed
Regular.
- Faux bold: a pointed tip moved r/sin(half its angle) along its bisector,
uncapped (3.9 r at 30 degrees, an A apex grew a spike), and tips sharper
than about 20 degrees did not move at all. Every tip now moves at most
2r, continuously; inner corners (the crotch of a V) keep their exact
miter.
- Faux bold: each point searched past runs of coincident points for its
neighbours, O(n^2); a contour of 50 000 copies of one point took ~8 s per
glyph. Neighbours now come from one O(n) pass over the runs.
- prefs.reset {"path":"type"} and Preferences > Type > Reset Section wiped
the favourite fonts; they are kept now (type.favoriteFonts by name, or
Reset All, still clear them).
- An expanded family whose own row scrolled out of view lost its style
rows, so the list below jumped up.
- Show Similar Fonts re-sorted around each font an arrow step applied, so
Down went back and forth between two fonts; the list now compares with
the font current when the filter was turned on (or the menu opened).
- Docs: an uninstalled favourite is kept but not listed; FAUX_BOLD_RADIUS
and the raster budget describe the thickened outline; the unused
"Recent font list" rows are gone; docs/scorecard.md regenerated (the
favourite fonts are one more setting).
Co-authored-by: D-monized <341904702+D-monized@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>