fix(linux): repair CUPS queue usability for Chromium
Some checks failed
Desktop Release / Bootstrap updater signing key (push) Has been cancelled
Desktop Release / Windows x64 NSIS (push) Has been cancelled
Desktop Release / Linux x64 DEB + AppImage (push) Has been cancelled
Desktop Release / Publish public desktop release (push) Has been cancelled

This commit is contained in:
Admin 2026-09-24 02:43:07 +00:00
parent 9b572f6c91
commit 341f3eb04e
5 changed files with 93 additions and 17 deletions

View File

@ -1,6 +1,6 @@
{
"name": "@fieldlens/print",
"version": "0.1.5",
"version": "0.1.6",
"private": true,
"type": "module",
"scripts": {

View File

@ -1,6 +1,6 @@
[package]
name = "fieldlens-print"
version = "0.1.5"
version = "0.1.6"
description = "FieldLens print-stream barcode capture companion"
authors = ["Arrowstack"]
edition = "2021"

View File

@ -52,6 +52,11 @@ pub fn list_system_printers() -> Result<Vec<SystemPrinter>> {
}
pub fn virtual_printer_status() -> Result<VirtualPrinterStatus> {
#[cfg(target_os = "linux")]
{
return linux_virtual_printer_status();
}
let installed = list_system_printers()?
.iter()
.any(|printer| is_virtual_printer_name(&printer.name));
@ -270,6 +275,13 @@ fn list_linux_printers() -> Result<Vec<SystemPrinter>> {
let Some((name, uri)) = rest.split_once(": ") else {
continue;
};
// Ignore placeholder/dummy queues. They can expose a PPD but are not a
// usable physical destination and can make Chromium reject the cloned
// FieldLens queue as "not installed correctly".
if uri == "///dev/null" || uri == "file:///dev/null" {
continue;
}
let address = socket_uri_to_address(uri);
printers.push(SystemPrinter {
name: name.to_string(),
@ -296,6 +308,67 @@ fn socket_uri_to_address(uri: &str) -> Option<String> {
}
}
#[cfg(target_os = "linux")]
fn linux_virtual_printer_status() -> Result<VirtualPrinterStatus> {
let printers = list_linux_printers()?;
let installed = printers
.iter()
.any(|printer| is_virtual_printer_name(&printer.name));
if !installed {
return Ok(VirtualPrinterStatus {
installed: false,
name: VIRTUAL_PRINTER_NAME.into(),
detail: "Not installed yet. Choose the physical destination printer, then create it.".into(),
});
}
let state = Command::new("lpstat")
.args(["-p", "FieldLens-Print"])
.output()
.context("query FieldLens Print CUPS state")?;
let accepting = Command::new("lpstat")
.args(["-a", "FieldLens-Print"])
.output()
.context("query FieldLens Print accepting state")?;
let state_text = String::from_utf8_lossy(&state.stdout);
let accepting_text = String::from_utf8_lossy(&accepting.stdout);
let enabled = state.status.success()
&& !state_text.to_ascii_lowercase().contains("disabled");
let accepts_jobs = accepting.status.success()
&& accepting_text.to_ascii_lowercase().contains("accepting requests");
let ready = enabled && accepts_jobs;
Ok(VirtualPrinterStatus {
installed: ready,
name: VIRTUAL_PRINTER_NAME.into(),
detail: if ready {
"Ready and accepting jobs in the system print dialog.".into()
} else {
"FieldLens Print exists but CUPS has it disabled or not accepting jobs. Click Create / repair FieldLens Print.".into()
},
})
}
#[cfg(target_os = "linux")]
fn run_cups_repair_command(program: &str, args: &[&str]) -> Result<()> {
let direct = Command::new(program).args(args).status();
if matches!(direct, Ok(status) if status.success()) {
return Ok(());
}
let status = Command::new("pkexec")
.arg(program)
.args(args)
.status()
.with_context(|| format!("run elevated {program}"))?;
if !status.success() {
return Err(anyhow!("{program} failed; administrator approval may be required"));
}
Ok(())
}
#[cfg(target_os = "linux")]
fn install_linux_virtual_printer(target_printer: &str) -> Result<()> {
let printers = list_linux_printers()?;
@ -326,21 +399,24 @@ fn install_linux_virtual_printer(target_printer: &str) -> Result<()> {
args.push(VIRTUAL_PRINTER_NAME.to_string());
let direct = Command::new("lpadmin").args(&args).status();
if matches!(direct, Ok(status) if status.success()) {
return Ok(());
if !matches!(direct, Ok(status) if status.success()) {
let status = Command::new("pkexec")
.arg("lpadmin")
.args(&args)
.status()
.context("run elevated CUPS printer setup")?;
if !status.success() {
return Err(anyhow!(
"CUPS printer setup failed; administrator approval may be required"
));
}
}
let status = Command::new("pkexec")
.arg("lpadmin")
.args(&args)
.status()
.context("run elevated CUPS printer setup")?;
if !status.success() {
return Err(anyhow!(
"CUPS printer setup failed; administrator approval may be required"
));
}
// lpadmin -E normally enables the queue, but explicitly repair both CUPS
// state flags because Chromium disables Print when either is stale.
run_cups_repair_command("cupsenable", &["FieldLens-Print"])?;
run_cups_repair_command("cupsaccept", &["FieldLens-Print"])?;
Ok(())
}

View File

@ -1,7 +1,7 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "FieldLens Print",
"version": "0.1.5",
"version": "0.1.6",
"identifier": "dev.arrowstack.fieldlens.print",
"build": {
"beforeDevCommand": "npm run dev",

View File

@ -85,7 +85,7 @@ let config: AppConfig
let jobs: Job[] = []
let status: Status
let loginTimer: number | undefined
let currentVersion = '0.1.5'
let currentVersion = '0.1.6'
let bundleType: BundleType | null = null
let availableUpdate: Update | null = null
let availableManualUpdate: ManualUpdate | null = null