diff --git a/README.md b/README.md index 6a602cc..875fad4 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,50 @@ Built-in definitions are loaded from `printers.json` at startup. When the Bluetooth device picker appears, select the device showing a **signal strength indicator**. Devices listed without signal strength may be cached/ghost entries that won't connect properly. +## USB on Linux + +On Linux, the kernel's generic USB printer driver (`usblp`) auto-binds to thermal printers when they're plugged in and claims the printer interface. WebUSB then can't claim the same interface and you'll see: + +``` +Failed to execute 'claimInterface' on 'USBDevice': Unable to claim interface. +``` + +You need to release the device from `usblp`. Pick one: + +**Quick test (non-persistent):** unload the module without unplugging the printer. + +```bash +sudo modprobe -r usblp +``` + +Click Connect again. `usblp` will rebind on the next replug or reboot. + +**Persistent (blacklist):** prevents `usblp` from ever loading. Simple, but **breaks CUPS / `lp` printing for all USB printers** on this machine. + +```bash +echo 'blacklist usblp' | sudo tee /etc/modprobe.d/blacklist-usblp.conf +sudo modprobe -r usblp +``` + +**Persistent (per-device, recommended if you also use CUPS):** detach `usblp` only from the Phomemo. Get the printer's vendor/product ID with `lsusb`, then create `/etc/udev/rules.d/70-phomemo-webusb.rules`: + +``` +# Replace XXXX:YYYY with your IDs from `lsusb` +SUBSYSTEM=="usb", ATTR{idVendor}=="XXXX", ATTR{idProduct}=="YYYY", MODE="0660", TAG+="uaccess" +ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="XXXX", ATTR{idProduct}=="YYYY", \ + RUN+="/bin/sh -c 'echo -n %k:1.0 > /sys/bus/usb/drivers/usblp/unbind 2>/dev/null || true'" +``` + +Reload and replug: + +```bash +sudo udevadm control --reload-rules +``` + +### Printer model not auto-detected on USB + +Many Phomemo printers report a generic name like "USB Composite Device" over USB rather than a recognizable model string. When this happens, the app will prompt you to pick the model on first connection and remember your choice for next time. You can also set it manually in Print Settings → Printer Model. + ## Project Structure ``` diff --git a/src/web/app.js b/src/web/app.js index 1ef485d..6917027 100644 --- a/src/web/app.js +++ b/src/web/app.js @@ -4622,9 +4622,13 @@ function initPrinterModelPrompt() { * @param {MouseEvent} event - Click event (shift+click shows all devices) */ async function handleConnect(event) { - // Check if printing is supported in this browser + // No transports at all → tell the user which browsers do work if (!state.canPrint) { - alert('Printing is not available in this browser.\n\nPlease use Chrome, Edge, or Opera on desktop for Bluetooth printing.'); + alert( + 'Printing is not available in this browser.\n\n' + + 'Bluetooth and USB printing are both unavailable. Please use Chrome, ' + + 'Edge, Opera, or another Chromium-based browser to print.' + ); return; } @@ -5619,6 +5623,26 @@ function hideShortcutsModal() { $('#shortcuts-modal').classList.add('hidden'); } +/** + * Disable options in a connection-type