mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
Merge pull request #2717 from dotCooCoo/fix/linux-tablet-xwayland
Linux Display Server: XWayland when a pen is attached, where a drawing tablet's pen draws
This commit is contained in:
@@ -194,8 +194,10 @@ drag-and-drop, set **Preferences › Performance › Linux Display Server** to *
|
||||
the app with `WAYLAND_DISPLAY= vectorcraft`: the window then opens through XWayland, where drops work
|
||||
(see [`docs/development.md`](docs/development.md#linux-wayland-and-x11)).
|
||||
|
||||
On Linux under KDE Plasma 6.3 or later with Wayland, a drawing tablet's pen moves the cursor but VectorCraft doesn't
|
||||
respond to it yet (#491). Open the window through XWayland instead, with the same preference or `WAYLAND_DISPLAY= vectorcraft` (see
|
||||
On Linux with Wayland, under KDE Plasma 6.3 or later and under GNOME, VectorCraft doesn't respond to a drawing tablet's
|
||||
pen yet (#491, #2028). Open the window through XWayland instead, where the pen works as a mouse: set the same
|
||||
preference to **X11 (XWayland)**, or to **X11 (XWayland) When a Pen Is Attached** to use XWayland only when a pen is
|
||||
attached as VectorCraft starts, and restart; or start the app with `WAYLAND_DISPLAY= vectorcraft` (see
|
||||
[`docs/development.md`](docs/development.md#linux-wayland-and-x11)).
|
||||
|
||||
### Use it from Claude Code and other agents
|
||||
|
||||
@@ -788,14 +788,19 @@ fn main() -> std::process::ExitCode {
|
||||
let custom_titlebar = custom_titlebar(saved.as_ref());
|
||||
let options = native_options(custom_titlebar);
|
||||
// winit picks Wayland whenever `WAYLAND_DISPLAY` is set; Preferences › Performance › Linux
|
||||
// Display Server › X11 opens the window through XWayland instead, where file drops work (#1151).
|
||||
// Display Server › X11 opens the window through XWayland instead, where file drops work (#1151),
|
||||
// and X11 (XWayland) When a Pen Is Attached does so when a pen is attached, where the pen draws (#2028).
|
||||
#[cfg(target_os = "linux")]
|
||||
let options = {
|
||||
let mut options = options;
|
||||
let pref = saved.as_ref().and_then(|ui| ui.engine_prefs.get("linuxDisplayServer")).and_then(serde_json::Value::as_str);
|
||||
if xwayland::wanted(pref, |name| std::env::var_os(name)) {
|
||||
if xwayland::wanted(pref, |name| std::env::var_os(name), xwayland::pen_attached) {
|
||||
if xwayland::x11_libraries_found() {
|
||||
log::info!("opening the window through XWayland (Preferences › Performance › Linux Display Server)");
|
||||
if pref == Some("x11WithPen") {
|
||||
log::info!("pen found: opening the window through XWayland (Preferences › Performance › Linux Display Server)");
|
||||
} else {
|
||||
log::info!("opening the window through XWayland (Preferences › Performance › Linux Display Server)");
|
||||
}
|
||||
use winit::platform::x11::EventLoopBuilderExtX11 as _;
|
||||
options.event_loop_builder = Some(Box::new(|builder| {
|
||||
builder.with_x11();
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
//! Linux: Preferences › Performance › Linux Display Server › X11 opens the window through XWayland
|
||||
//! on a Wayland session, where dropped files arrive (winit 0.30 has no Wayland drag and drop,
|
||||
//! #1151). Only when XWayland can run the window: an X display is set and the X11 libraries winit
|
||||
//! loads at runtime are installed. Otherwise the window opens on Wayland, so a missing library
|
||||
//! never keeps the app from starting.
|
||||
//! #1151). X11 (XWayland) When a Pen Is Attached does so only when a pen is attached as the app
|
||||
//! starts: winit 0.30 doesn't bind the Wayland tablet protocol, and XWayland hands the pen to X11
|
||||
//! windows as a pointer (#2028). Only when XWayland can run the window: an X display is set and
|
||||
//! the X11 libraries winit loads at runtime are installed. Otherwise the window opens on Wayland,
|
||||
//! so a missing library never keeps the app from starting.
|
||||
//!
|
||||
//! The library check comes from PhotoCraft's `linux_libs.rs`: no `dlopen` (that needs `unsafe`),
|
||||
//! just the dynamic linker's cache (`ldconfig -p`) and the usual library directories.
|
||||
//! just the dynamic linker's cache (`ldconfig -p`) and the usual library directories. The pen
|
||||
//! check comes from PhotoCraft's `tablet.rs`: the input devices the kernel lists in
|
||||
//! `/proc/bus/input/devices`.
|
||||
#![cfg_attr(not(target_os = "linux"), allow(dead_code))]
|
||||
|
||||
use std::ffi::OsString;
|
||||
@@ -16,12 +20,50 @@ use std::path::{Path, PathBuf};
|
||||
const X11_LIBS: &[&str] =
|
||||
&["libX11.so.6", "libX11-xcb.so.1", "libxcb.so.1", "libXcursor.so.1", "libXi.so.6", "libxkbcommon.so.0", "libxkbcommon-x11.so.0"];
|
||||
|
||||
/// Whether the saved `linuxDisplayServer` and the environment ask for XWayland: `x11` chosen, a
|
||||
/// Wayland session (winit picks Wayland whenever `WAYLAND_DISPLAY` or `WAYLAND_SOCKET` is set)
|
||||
/// and an X display to open.
|
||||
pub fn wanted(pref: Option<&str>, var: impl Fn(&str) -> Option<OsString>) -> bool {
|
||||
/// Whether the saved `linuxDisplayServer` and the environment ask for XWayland: `x11` chosen, or
|
||||
/// `x11WithPen` chosen and `pen` finding a pen; a Wayland session (winit picks Wayland whenever
|
||||
/// `WAYLAND_DISPLAY` or `WAYLAND_SOCKET` is set); and an X display to open. `pen` runs only for
|
||||
/// `x11WithPen`, after the session checks.
|
||||
pub fn wanted(pref: Option<&str>, var: impl Fn(&str) -> Option<OsString>, pen: impl FnOnce() -> bool) -> bool {
|
||||
let set = |name: &str| var(name).is_some_and(|v| !v.is_empty());
|
||||
pref == Some("x11") && (set("WAYLAND_DISPLAY") || set("WAYLAND_SOCKET")) && set("DISPLAY")
|
||||
let session = (set("WAYLAND_DISPLAY") || set("WAYLAND_SOCKET")) && set("DISPLAY");
|
||||
match pref {
|
||||
Some("x11") => session,
|
||||
Some("x11WithPen") => session && pen(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// `BTN_TOOL_PEN` (linux/input-event-codes.h): the key that a pen tablet's stylus, a pen display's
|
||||
/// pen or a pen-enabled touchscreen's pen reports.
|
||||
const BTN_TOOL_PEN: u32 = 0x140;
|
||||
/// `ABS_X` and `ABS_Y` (linux/input-event-codes.h): the absolute axes every pen reports.
|
||||
const ABS_X: u32 = 0x00;
|
||||
const ABS_Y: u32 = 0x01;
|
||||
|
||||
/// Is a pen attached? Reads `/proc/bus/input/devices`; a file that can't be read has no pen.
|
||||
pub fn pen_attached() -> bool {
|
||||
std::fs::read_to_string("/proc/bus/input/devices").is_ok_and(|devices| has_pen(&devices))
|
||||
}
|
||||
|
||||
/// Is a pen among the input devices `/proc/bus/input/devices` lists? A pen is a device whose
|
||||
/// `B: KEY=` bitmap has `BTN_TOOL_PEN` and whose `B: ABS=` bitmap has `ABS_X` and `ABS_Y`, as
|
||||
/// libinput asks of a tablet tool. A virtual keyboard made with uinput can claim every key code,
|
||||
/// `BTN_TOOL_PEN` included, but has no absolute axes.
|
||||
fn has_pen(devices: &str) -> bool {
|
||||
devices.split("\n\n").any(|device| {
|
||||
let bitmap = |name: &str| device.lines().find_map(|l| l.strip_prefix(name));
|
||||
bitmap("B: KEY=").is_some_and(|keys| bit_set(keys, BTN_TOOL_PEN))
|
||||
&& bitmap("B: ABS=").is_some_and(|axes| bit_set(axes, ABS_X) && bit_set(axes, ABS_Y))
|
||||
})
|
||||
}
|
||||
|
||||
/// Bit `bit` of a `/proc/bus/input/devices` bitmap: hex words of the kernel's `long`, most
|
||||
/// significant first. Short or malformed bitmaps have no bits set.
|
||||
fn bit_set(bitmap: &str, bit: u32) -> bool {
|
||||
let bits = usize::BITS;
|
||||
let word = usize::try_from(bit / bits).unwrap_or(usize::MAX);
|
||||
bitmap.split_whitespace().rev().nth(word).and_then(|w| u64::from_str_radix(w, 16).ok()).is_some_and(|w| (w >> (bit % bits)) & 1 == 1)
|
||||
}
|
||||
|
||||
/// Are all the libraries an X11 window needs found on this system? Libraries the check can't find
|
||||
@@ -98,18 +140,88 @@ mod tests {
|
||||
move |k| pairs.iter().find(|(name, _)| *name == k).map(|(_, v)| OsString::from(v))
|
||||
}
|
||||
|
||||
fn no_probe() -> bool {
|
||||
panic!("the pen check ran")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn xwayland_only_when_chosen_on_wayland_with_an_x_display() {
|
||||
let wayland = env(&[("WAYLAND_DISPLAY", "wayland-0"), ("DISPLAY", ":0")]);
|
||||
assert!(wanted(Some("x11"), &wayland));
|
||||
assert!(wanted(Some("x11"), env(&[("WAYLAND_SOCKET", "3"), ("DISPLAY", ":0")])));
|
||||
assert!(!wanted(Some("automatic"), &wayland));
|
||||
assert!(!wanted(None, &wayland));
|
||||
assert!(!wanted(Some("wayland"), &wayland));
|
||||
assert!(wanted(Some("x11"), &wayland, no_probe));
|
||||
assert!(wanted(Some("x11"), env(&[("WAYLAND_SOCKET", "3"), ("DISPLAY", ":0")]), no_probe));
|
||||
assert!(!wanted(Some("automatic"), &wayland, no_probe));
|
||||
assert!(!wanted(None, &wayland, no_probe));
|
||||
assert!(!wanted(Some("wayland"), &wayland, no_probe));
|
||||
// An X11 session already opens on X11; without an X display there is no XWayland to use.
|
||||
assert!(!wanted(Some("x11"), env(&[("DISPLAY", ":0")])));
|
||||
assert!(!wanted(Some("x11"), env(&[("WAYLAND_DISPLAY", "wayland-0"), ("DISPLAY", "")])));
|
||||
assert!(!wanted(Some("x11"), env(&[("WAYLAND_DISPLAY", "wayland-0")])));
|
||||
assert!(!wanted(Some("x11"), env(&[("DISPLAY", ":0")]), no_probe));
|
||||
assert!(!wanted(Some("x11"), env(&[("WAYLAND_DISPLAY", "wayland-0"), ("DISPLAY", "")]), no_probe));
|
||||
assert!(!wanted(Some("x11"), env(&[("WAYLAND_DISPLAY", "wayland-0")]), no_probe));
|
||||
}
|
||||
|
||||
/// X11 (XWayland) When a Pen Is Attached (#2028): XWayland on a Wayland session with an X
|
||||
/// display when a pen is found, the session's own display server otherwise. The pen check
|
||||
/// runs only on such a session.
|
||||
#[test]
|
||||
fn the_pen_choice_opens_xwayland_only_with_a_pen() {
|
||||
let wayland = env(&[("WAYLAND_DISPLAY", "wayland-0"), ("DISPLAY", ":0")]);
|
||||
assert!(wanted(Some("x11WithPen"), &wayland, || true));
|
||||
assert!(wanted(Some("x11WithPen"), env(&[("WAYLAND_SOCKET", "3"), ("DISPLAY", ":0")]), || true));
|
||||
assert!(!wanted(Some("x11WithPen"), &wayland, || false));
|
||||
assert!(!wanted(Some("x11WithPen"), env(&[("DISPLAY", ":0")]), no_probe));
|
||||
assert!(!wanted(Some("x11WithPen"), env(&[("WAYLAND_DISPLAY", "wayland-0")]), no_probe));
|
||||
assert!(!wanted(Some("x11WithPen"), env(&[("WAYLAND_DISPLAY", "wayland-0"), ("DISPLAY", "")]), no_probe));
|
||||
}
|
||||
|
||||
/// `/proc/bus/input/devices` of a laptop with a Wacom Intuos Pro attached (64-bit longs: the
|
||||
/// pen's `KEY=1c03 0 0 0 0 0` has bit 0x140, `BTN_TOOL_PEN`), from PhotoCraft's tests.
|
||||
const WITH_PEN: &str = "I: Bus=0011 Vendor=0001 Product=0001 Version=ab83\n\
|
||||
N: Name=\"AT Translated Set 2 keyboard\"\n\
|
||||
H: Handlers=sysrq kbd event3 leds\n\
|
||||
B: KEY=402000000 3803078f800d001 feffffdfffefffff fffffffffffffffe\n\
|
||||
\n\
|
||||
I: Bus=0018 Vendor=06cb Product=ce26 Version=0100\n\
|
||||
N: Name=\"SYNA2B33:00 06CB:CE26 Touchpad\"\n\
|
||||
H: Handlers=mouse1 event7\n\
|
||||
B: KEY=e520 10000 0 0 0 0\n\
|
||||
B: ABS=2e0800000000003\n\
|
||||
\n\
|
||||
I: Bus=0003 Vendor=056a Product=0357 Version=0110\n\
|
||||
N: Name=\"Wacom Intuos Pro M Pen\"\n\
|
||||
H: Handlers=mouse2 event10\n\
|
||||
B: KEY=1c03 0 0 0 0 0\n\
|
||||
B: ABS=1000f000003\n";
|
||||
|
||||
/// A uinput virtual keyboard that claims every key code, `BTN_TOOL_PEN` included, and has no
|
||||
/// absolute axes (`EV=20013`, no `B: ABS=` line), from PhotoCraft's tests.
|
||||
const VIRTUAL_KEYBOARD: &str = "I: Bus=0003 Vendor=1234 Product=5678 Version=0111\n\
|
||||
N: Name=\"Virtual Keyboard\"\n\
|
||||
H: Handlers=sysrq rfkill kbd event256 leds \n\
|
||||
B: EV=20013\n\
|
||||
B: KEY=ffffffffff 0 7ffffff000301ff 1000f7fffffff 7fe001fffff000f 7ffffffffffffff ffffffff0003fdff 7fff8fff00ff03ff 1ffffffffffff07 ffffffffffffffff ffffffffffefffff fffffffffffffffe\n";
|
||||
|
||||
#[test]
|
||||
fn a_pen_is_a_device_with_btn_tool_pen_and_absolute_axes() {
|
||||
assert!(has_pen(WITH_PEN));
|
||||
let without = WITH_PEN.split("\n\n").take(2).collect::<Vec<_>>().join("\n\n");
|
||||
assert!(!has_pen(&without), "a touchpad's BTN_TOOL_FINGER (0x145) is not a pen");
|
||||
// A pen display reports the pen with its own axes.
|
||||
assert!(has_pen("N: Name=\"Wacom One Pen\"\nB: KEY=1c03 0 0 0 0 0\nB: ABS=3\n"));
|
||||
// Axes without ABS_X or ABS_Y, or no axes at all, are no pen.
|
||||
assert!(!has_pen("B: KEY=1c03 0 0 0 0 0\nB: ABS=1000f000002\n"));
|
||||
assert!(!has_pen("B: KEY=1c03 0 0 0 0 0\nB: ABS=1000f000001\n"));
|
||||
let pen_without_axes = WITH_PEN.lines().filter(|l| !l.starts_with("B: ABS=1000f")).collect::<Vec<_>>().join("\n");
|
||||
assert!(!has_pen(&pen_without_axes));
|
||||
// The virtual keyboard claims the key but is no pen, and a real pen beside it is still found.
|
||||
assert!(VIRTUAL_KEYBOARD.lines().find_map(|l| l.strip_prefix("B: KEY=")).is_some_and(|k| bit_set(k, BTN_TOOL_PEN)));
|
||||
assert!(!has_pen(VIRTUAL_KEYBOARD));
|
||||
assert!(has_pen(&format!("{VIRTUAL_KEYBOARD}\n{WITH_PEN}")));
|
||||
// Short or malformed bitmaps are no pen, never a panic.
|
||||
for keys in ["", "B: KEY=", "B: KEY=1", "B: KEY=zz 0 0 0 0 0", "B: KEY=ffffffffffffffffff 0 0 0 0 0", "B: KEY=0 0 0 0 0 0 0 0"] {
|
||||
assert!(!has_pen(&format!("{keys}\nB: ABS=3")), "{keys:?}");
|
||||
}
|
||||
for abs in ["B: ABS=", "B: ABS=zz", "B: ABS=ffffffffffffffffff", "B: ABS=0 0"] {
|
||||
assert!(!has_pen(&format!("B: KEY=1c03 0 0 0 0 0\n{abs}")), "{abs:?}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -89,8 +89,10 @@ pub const GPU_PREFERENCES: &[(&str, &str)] =
|
||||
&[("automatic", "Automatic"), ("lowPower", "Power Saving (integrated)"), ("highPerformance", "High Performance (discrete)")];
|
||||
/// Performance › Linux Display Server (`linuxDisplayServer`), read by the desktop app at startup:
|
||||
/// `x11` opens the window through XWayland on a Wayland session, where dropped files arrive
|
||||
/// (winit 0.30 has no Wayland drag and drop, #1151).
|
||||
const LINUX_DISPLAY_SERVERS: &[(&str, &str)] = &[("automatic", "Automatic"), ("x11", "X11 (XWayland)")];
|
||||
/// (winit 0.30 has no Wayland drag and drop, #1151); `x11WithPen` does the same only when a pen is
|
||||
/// attached as the app starts: under XWayland a drawing tablet's pen draws as a mouse (#2028).
|
||||
const LINUX_DISPLAY_SERVERS: &[(&str, &str)] =
|
||||
&[("automatic", "Automatic"), ("x11", "X11 (XWayland)"), ("x11WithPen", "X11 (XWayland) When a Pen Is Attached")];
|
||||
const BLACK: &[(&str, &str)] = &[("accurate", "Display All Blacks Accurately"), ("rich", "Display All Blacks as Rich Black")];
|
||||
const BLACK_OUT: &[(&str, &str)] = &[("accurate", "Output All Blacks Accurately"), ("rich", "Output All Blacks as Rich Black")];
|
||||
|
||||
|
||||
@@ -918,7 +918,8 @@ pub struct Prefs {
|
||||
/// Rasterizer worker threads; -1 = automatic.
|
||||
pub render_threads: i32,
|
||||
/// Linux: `automatic` opens the window on the session's display server; `x11` opens it through
|
||||
/// XWayland on a Wayland session, where dropped files arrive (#1151). Read when the app starts.
|
||||
/// XWayland on a Wayland session, where dropped files arrive (#1151); `x11WithPen` opens it
|
||||
/// through XWayland only when a pen is attached (#2028). Read when the app starts.
|
||||
pub linux_display_server: String,
|
||||
// File Handling
|
||||
pub background_save: bool,
|
||||
|
||||
@@ -240,6 +240,20 @@ fn linux_display_server_defaults_to_automatic_and_validates() {
|
||||
assert_eq!(s.prefs.linux_display_server, "automatic");
|
||||
}
|
||||
|
||||
/// Linux Display Server's pen choice (#2028): set by value or by label, saved, and off by default.
|
||||
#[test]
|
||||
fn linux_display_server_has_a_choice_for_an_attached_pen() {
|
||||
let mut s = Session::new();
|
||||
s.execute("prefs.set", &json!({"key": "linuxDisplayServer", "value": "x11WithPen"})).unwrap();
|
||||
assert_eq!(s.prefs.linux_display_server, "x11WithPen");
|
||||
assert_eq!(s.prefs.to_json()["linuxDisplayServer"], "x11WithPen");
|
||||
s.execute("prefs.set", &json!({"key": "linuxDisplayServer", "value": "automatic"})).unwrap();
|
||||
s.execute("prefs.set", &json!({"key": "linuxDisplayServer", "value": "X11 (XWayland) When a Pen Is Attached"})).unwrap();
|
||||
assert_eq!(s.prefs.linux_display_server, "x11WithPen");
|
||||
s.execute("prefs.reset", &json!({"category": "Performance"})).unwrap();
|
||||
assert_eq!(s.prefs.linux_display_server, "automatic");
|
||||
}
|
||||
|
||||
/// Selection & Anchor Display › Tolerance, Object Selection by Path Only and Command Click to
|
||||
/// Select Objects Behind, and General › Double Click To Isolate, as the Selection tool sees them
|
||||
/// (#394).
|
||||
|
||||
@@ -4462,6 +4462,8 @@ lighting Light Светлина
|
||||
@msg missing panel layout липсващо оформление на панели
|
||||
@msg unsupported native docking operation неподдържана вградена операция за скачване
|
||||
Linux Display Server Дисплейен сървър за Linux
|
||||
X11 (XWayland) When a Pen Is Attached X11 (XWayland) при свързана писалка
|
||||
If a drawing tablet's pen doesn't draw, choose an X11 (XWayland) option. Ако писалката на графичния таблет не рисува, изберете опция X11 (XWayland).
|
||||
X11 (XWayland) X11 (XWayland)
|
||||
Ruler Origin Начало на линийката
|
||||
Reset Ruler Origin Нулиране началото на линийката
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -3607,6 +3607,8 @@ axis Both Obě
|
||||
Star Hvězda
|
||||
Power Saving (integrated) Úsporný režim (integrovaná)
|
||||
Target Cíl
|
||||
X11 (XWayland) When a Pen Is Attached X11 (XWayland) při připojeném peru
|
||||
If a drawing tablet's pen doesn't draw, choose an X11 (XWayland) option. Pokud pero grafického tabletu nekreslí, zvolte možnost X11 (XWayland).
|
||||
X11 (XWayland) X11 (XWayland)
|
||||
Print as Bitmap Tisknout jako bitmapu
|
||||
Draft Koncept
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -3377,6 +3377,8 @@ axis Both Begge
|
||||
Star Stjerne
|
||||
Power Saving (integrated) Strømbesparende (integreret)
|
||||
Target Mål
|
||||
X11 (XWayland) When a Pen Is Attached X11 (XWayland), når en pen er tilsluttet
|
||||
If a drawing tablet's pen doesn't draw, choose an X11 (XWayland) option. Hvis pennen til en tegneplade ikke tegner, skal du vælge en X11 (XWayland)-indstilling.
|
||||
X11 (XWayland) X11 (XWayland)
|
||||
Print as Bitmap Udskriv som bitmap
|
||||
Draft Udkast
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4525,6 +4525,8 @@ lighting Light Licht
|
||||
@msg missing panel layout Bedienfeldanordnung fehlt
|
||||
@msg unsupported native docking operation Nicht unterstützte native Docking-Operation
|
||||
Linux Display Server Linux-Anzeigeserver
|
||||
X11 (XWayland) When a Pen Is Attached X11 (XWayland), wenn ein Stift angeschlossen ist
|
||||
If a drawing tablet's pen doesn't draw, choose an X11 (XWayland) option. Wenn der Stift eines Grafiktabletts nicht zeichnet, wählen Sie eine Option mit X11 (XWayland).
|
||||
X11 (XWayland) X11 (XWayland)
|
||||
Ruler Origin Linealursprung
|
||||
Reset Ruler Origin Linealursprung zurücksetzen
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4951,6 +4951,8 @@ effect Points Σημεία
|
||||
Unicode Unicode
|
||||
Unicode (UTF-16) Unicode (UTF-16)
|
||||
Unicode (UTF-8) Unicode (UTF-8)
|
||||
X11 (XWayland) When a Pen Is Attached X11 (XWayland) όταν είναι συνδεδεμένη πένα
|
||||
If a drawing tablet's pen doesn't draw, choose an X11 (XWayland) option. Αν η πένα μιας ταμπλέτας σχεδίασης δεν σχεδιάζει, επιλέξτε μία από τις ρυθμίσεις X11 (XWayland).
|
||||
X11 (XWayland) X11 (XWayland)
|
||||
Mac Mac
|
||||
Phone 360×800 Phone 360×800
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2000 and column 19.
|
@@ -4529,6 +4529,8 @@ lighting Light Luz
|
||||
@msg missing panel layout Falta la distribución de paneles
|
||||
@msg unsupported native docking operation Operación nativa de anclaje no admitida
|
||||
Linux Display Server Servidor de pantalla de Linux
|
||||
X11 (XWayland) When a Pen Is Attached X11 (XWayland) cuando hay un lápiz conectado
|
||||
If a drawing tablet's pen doesn't draw, choose an X11 (XWayland) option. Si el lápiz de una tableta digitalizadora no dibuja, elige una opción X11 (XWayland).
|
||||
X11 (XWayland) X11 (XWayland)
|
||||
Ruler Origin Origen de las reglas
|
||||
Reset Ruler Origin Restablecer el origen de las reglas
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -3542,6 +3542,8 @@ axis Both Molemmat
|
||||
Star Tähti
|
||||
Power Saving (integrated) Virransäästö (integroitu)
|
||||
Target Kohde
|
||||
X11 (XWayland) When a Pen Is Attached X11 (XWayland), kun kynä on liitetty
|
||||
If a drawing tablet's pen doesn't draw, choose an X11 (XWayland) option. Jos piirtopöydän kynä ei piirrä, valitse jokin X11 (XWayland) -vaihtoehto.
|
||||
X11 (XWayland) X11 (XWayland)
|
||||
Print as Bitmap Tulosta bittikarttana
|
||||
Draft Vedos
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4539,6 +4539,8 @@ lighting Light Lumière
|
||||
@msg missing panel layout Disposition des panneaux manquante
|
||||
@msg unsupported native docking operation Opération native d’ancrage non prise en charge
|
||||
Linux Display Server Serveur d’affichage Linux
|
||||
X11 (XWayland) When a Pen Is Attached X11 (XWayland) quand un stylet est branché
|
||||
If a drawing tablet's pen doesn't draw, choose an X11 (XWayland) option. Si le stylet d’une tablette graphique ne dessine pas, choisissez une option X11 (XWayland).
|
||||
X11 (XWayland) X11 (XWayland)
|
||||
Ruler Origin Origine des règles
|
||||
Reset Ruler Origin Réinitialiser l’origine des règles
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4212,6 +4212,8 @@ mark-style Japanese Japán
|
||||
Wrinkle Tool Gyűrés
|
||||
Write Layers Rétegek írása
|
||||
x Height x-magasság
|
||||
X11 (XWayland) When a Pen Is Attached X11 (XWayland), ha toll csatlakozik
|
||||
If a drawing tablet's pen doesn't draw, choose an X11 (XWayland) option. Ha a grafikus tábla tolla nem rajzol, válassz egy X11 (XWayland) beállítást.
|
||||
X11 (XWayland) X11 (XWayland)
|
||||
X: X:
|
||||
XML ID XML-azonosító
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -3377,6 +3377,8 @@ axis Both Keduanya
|
||||
Star Bintang
|
||||
Power Saving (integrated) Hemat daya (terintegrasi)
|
||||
Target Target
|
||||
X11 (XWayland) When a Pen Is Attached X11 (XWayland) saat pena terpasang
|
||||
If a drawing tablet's pen doesn't draw, choose an X11 (XWayland) option. Jika pena tablet gambar tidak menggambar, pilih opsi X11 (XWayland).
|
||||
X11 (XWayland) X11 (XWayland)
|
||||
Print as Bitmap Cetak sebagai bitmap
|
||||
Draft Draf
|
||||
|
||||
|
@@ -4570,6 +4570,8 @@ lighting Light Luce
|
||||
@msg missing panel layout Disposizione dei pannelli mancante
|
||||
@msg unsupported native docking operation Operazione nativa di ancoraggio non supportata
|
||||
Linux Display Server Server di visualizzazione Linux
|
||||
X11 (XWayland) When a Pen Is Attached X11 (XWayland) quando è collegata una penna
|
||||
If a drawing tablet's pen doesn't draw, choose an X11 (XWayland) option. Se la penna di una tavoletta grafica non disegna, scegli un'opzione X11 (XWayland).
|
||||
X11 (XWayland) X11 (XWayland)
|
||||
Ruler Origin Origine dei righelli
|
||||
Reset Ruler Origin Ripristina origine dei righelli
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4610,6 +4610,8 @@ lighting Light ライト
|
||||
@msg missing panel layout パネル配置がありません
|
||||
@msg unsupported native docking operation ネイティブドッキング操作は未対応です
|
||||
Linux Display Server Linux ディスプレイサーバー
|
||||
X11 (XWayland) When a Pen Is Attached ペン接続時は X11 (XWayland)
|
||||
If a drawing tablet's pen doesn't draw, choose an X11 (XWayland) option. ペンタブレットのペンで描画できない場合は、X11 (XWayland) のいずれかを選択してください。
|
||||
X11 (XWayland) X11 (XWayland)
|
||||
Ruler Origin 定規の原点
|
||||
Reset Ruler Origin 定規の原点をリセット
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4536,6 +4536,8 @@ lighting Light 광원
|
||||
@msg missing panel layout 패널 레이아웃이 없습니다
|
||||
@msg unsupported native docking operation 지원되지 않는 기본 도킹 작업
|
||||
Linux Display Server Linux 디스플레이 서버
|
||||
X11 (XWayland) When a Pen Is Attached 펜 연결 시 X11 (XWayland)
|
||||
If a drawing tablet's pen doesn't draw, choose an X11 (XWayland) option. 드로잉 태블릿의 펜으로 그려지지 않으면 X11 (XWayland) 옵션을 선택하세요.
|
||||
X11 (XWayland) X11 (XWayland)
|
||||
Artistic 예술 효과
|
||||
Film Grain… 필름 그레인…
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -3391,6 +3391,8 @@ axis Both Beide
|
||||
Star Ster
|
||||
Power Saving (integrated) Energiebesparend (geïntegreerd)
|
||||
Target Doel
|
||||
X11 (XWayland) When a Pen Is Attached X11 (XWayland) als er een pen is aangesloten
|
||||
If a drawing tablet's pen doesn't draw, choose an X11 (XWayland) option. Als de pen van een tekentablet niet tekent, kies dan een X11 (XWayland)-optie.
|
||||
X11 (XWayland) X11 (XWayland)
|
||||
Print as Bitmap Afdrukken als bitmap
|
||||
Draft Concept
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -3449,6 +3449,8 @@ axis Both Obie
|
||||
Star Gwiazda
|
||||
Power Saving (integrated) Oszczędzanie energii (zintegrowany)
|
||||
Target Cel
|
||||
X11 (XWayland) When a Pen Is Attached X11 (XWayland), gdy podłączone jest pióro
|
||||
If a drawing tablet's pen doesn't draw, choose an X11 (XWayland) option. Jeśli pióro tabletu graficznego nie rysuje, wybierz opcję X11 (XWayland).
|
||||
X11 (XWayland) X11 (XWayland)
|
||||
Print as Bitmap Drukuj jako bitmapę
|
||||
Draft Robocza
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4560,6 +4560,8 @@ axis Both Ambos
|
||||
Right Diagonal Diagonal Direita
|
||||
Left Diagonal Diagonal Esquerda
|
||||
Linux Display Server Servidor de Exibição do Linux
|
||||
X11 (XWayland) When a Pen Is Attached X11 (XWayland) Quando Houver uma Caneta Conectada
|
||||
If a drawing tablet's pen doesn't draw, choose an X11 (XWayland) option. Se a caneta de uma mesa digitalizadora não desenhar, escolha uma opção X11 (XWayland).
|
||||
X11 (XWayland) X11 (XWayland)
|
||||
@id pathfinder.add Unir
|
||||
3 x 3 Average Média 3 x 3
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -4566,6 +4566,8 @@ lighting Light Свет
|
||||
@msg missing panel layout Отсутствует расположение панелей
|
||||
@msg unsupported native docking operation Неподдерживаемая собственная операция прикрепления
|
||||
Linux Display Server Дисплейный сервер Linux
|
||||
X11 (XWayland) When a Pen Is Attached X11 (XWayland) при подключенном пере
|
||||
If a drawing tablet's pen doesn't draw, choose an X11 (XWayland) option. Если перо графического планшета не рисует, выберите вариант X11 (XWayland).
|
||||
X11 (XWayland) X11 (XWayland)
|
||||
Ruler Origin Начало координат линеек
|
||||
Reset Ruler Origin Сбросить начало координат линеек
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4461,6 +4461,8 @@ lighting Light Ljus
|
||||
@msg missing panel layout panellayout saknas
|
||||
@msg unsupported native docking operation inbyggd dockningsåtgärd som inte stöds
|
||||
Linux Display Server Linux-skärmserver
|
||||
X11 (XWayland) When a Pen Is Attached X11 (XWayland) när en penna är ansluten
|
||||
If a drawing tablet's pen doesn't draw, choose an X11 (XWayland) option. Om ritplattans penna inte ritar väljer du ett X11 (XWayland)-alternativ.
|
||||
X11 (XWayland) X11 (XWayland)
|
||||
Ruler Origin Linjalens origo
|
||||
Reset Ruler Origin Återställ linjalens origo
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 5 and column 25.
|
@@ -4550,6 +4550,8 @@ lighting Light Світло
|
||||
@msg missing panel layout Відсутнє розташування панелей
|
||||
@msg unsupported native docking operation Непідтримувана власна операція прикріплення
|
||||
Linux Display Server Дисплейний сервер Linux
|
||||
X11 (XWayland) When a Pen Is Attached X11 (XWayland), коли підключено перо
|
||||
If a drawing tablet's pen doesn't draw, choose an X11 (XWayland) option. Якщо перо графічного планшета не малює, виберіть варіант X11 (XWayland).
|
||||
X11 (XWayland) X11 (XWayland)
|
||||
Ruler Origin Початок координат лінійок
|
||||
Reset Ruler Origin Скинути початок координат лінійок
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 725 and column 40.
|
@@ -3873,6 +3873,8 @@ mark-style Japanese Kiểu Nhật
|
||||
Workspace {i} Không gian làm việc {i}
|
||||
Wrinkle Tool Công cụ nhăn
|
||||
Write Layers Ghi các lớp
|
||||
X11 (XWayland) When a Pen Is Attached X11 (XWayland) khi có bút được kết nối
|
||||
If a drawing tablet's pen doesn't draw, choose an X11 (XWayland) option. Nếu bút của bảng vẽ không vẽ được, hãy chọn một tùy chọn X11 (XWayland).
|
||||
X11 (XWayland) X11 (XWayland)
|
||||
XML ID XML ID
|
||||
Yards Yard
|
||||
|
||||
|
@@ -4832,6 +4832,8 @@ lighting Light 光源
|
||||
Horizontal Guide 水平参考线
|
||||
Move Guide to Layer 将参考线移至图层
|
||||
Linux Display Server Linux 显示服务器
|
||||
X11 (XWayland) When a Pen Is Attached 连接手写笔时使用 X11 (XWayland)
|
||||
If a drawing tablet's pen doesn't draw, choose an X11 (XWayland) option. 如果数位板的笔无法绘画,请选择一个 X11 (XWayland) 选项。
|
||||
X11 (XWayland) X11 (XWayland)
|
||||
Ruler Origin 标尺原点
|
||||
Reset Ruler Origin 重置标尺原点
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -3909,6 +3909,8 @@ lighting Light 光源
|
||||
Horizontal Guide 水平參考線
|
||||
Move Guide to Layer 將參考線移至圖層
|
||||
Linux Display Server Linux 顯示伺服器
|
||||
X11 (XWayland) When a Pen Is Attached 連接觸控筆時使用 X11 (XWayland)
|
||||
If a drawing tablet's pen doesn't draw, choose an X11 (XWayland) option. 如果繪圖板的筆無法繪圖,請選擇一個 X11 (XWayland) 選項。
|
||||
X11 (XWayland) X11 (XWayland)
|
||||
Ruler Origin 尺標原點
|
||||
Reset Ruler Origin 重設尺標原點
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -324,6 +324,14 @@ fn category_fields(ui: &mut egui::Ui, d: &mut Dialog, cat: &str) {
|
||||
// The window's graphics device and display server are chosen once, when the app starts.
|
||||
ui.label(egui::RichText::new(tl!("Applies the next time VectorCraft starts.")).color(t.text_dim).size(11.0));
|
||||
}
|
||||
if sp.key == "linuxDisplayServer" {
|
||||
// Many Wayland desktops give a drawing tablet's pen to the window only through XWayland (#2028).
|
||||
ui.label(
|
||||
egui::RichText::new(tl!("If a drawing tablet's pen doesn't draw, choose an X11 (XWayland) option."))
|
||||
.color(t.text_dim)
|
||||
.size(11.0),
|
||||
);
|
||||
}
|
||||
}
|
||||
PrefKind::Color => {
|
||||
labeled(ui, sp.label, |ui| {
|
||||
@@ -614,6 +622,40 @@ mod tests {
|
||||
assert_eq!(saved["engine_prefs"]["systemTitleBar"], json!(true));
|
||||
}
|
||||
|
||||
/// Performance › Linux Display Server (#2028): on Linux it shows the drawing-tablet note, and
|
||||
/// X11 (XWayland) When a Pen Is Attached is applied by OK and saved under the key the desktop
|
||||
/// app reads before the window opens.
|
||||
#[test]
|
||||
fn linux_display_server_offers_the_pen_choice() {
|
||||
fn texts(s: &egui::Shape, out: &mut Vec<String>) {
|
||||
match s {
|
||||
egui::Shape::Text(t) => out.push(t.galley.text().to_string()),
|
||||
egui::Shape::Vec(v) => v.iter().for_each(|s| texts(s, out)),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
let mut a = app();
|
||||
open(&mut a, Some("Performance"));
|
||||
let ctx = egui::Context::default();
|
||||
crate::theme::install_fonts(&ctx);
|
||||
// The window sizes itself on the first frame and draws on the second.
|
||||
let mut out = ctx.run_ui(egui::RawInput::default(), |ui| show(&mut a, ui.ctx()));
|
||||
out.textures_delta.clear();
|
||||
let mut out = ctx.run_ui(egui::RawInput::default(), |ui| show(&mut a, ui.ctx()));
|
||||
out.textures_delta.clear();
|
||||
let mut shown = vec![];
|
||||
out.shapes.iter().for_each(|c| texts(&c.shape, &mut shown));
|
||||
let linux = cfg!(target_os = "linux");
|
||||
assert_eq!(shown.iter().any(|t| t.starts_with("Linux Display Server")), linux, "{shown:?}");
|
||||
let note = "If a drawing tablet's pen doesn't draw, choose an X11 (XWayland) option.";
|
||||
assert_eq!(shown.iter().any(|t| t == note), linux, "{shown:?}");
|
||||
a.ui.dialog.as_mut().unwrap().fields.insert("linuxDisplayServer".into(), json!("x11WithPen"));
|
||||
confirm(&mut a).unwrap();
|
||||
assert_eq!(a.session.prefs.linux_display_server, "x11WithPen");
|
||||
let saved: Value = serde_json::from_slice(&serde_json::to_vec(&a.ui).unwrap()).unwrap();
|
||||
assert_eq!(saved["engine_prefs"]["linuxDisplayServer"], json!("x11WithPen"));
|
||||
}
|
||||
|
||||
/// #1866: the category shown is highlighted in the list while the pointer is elsewhere.
|
||||
#[test]
|
||||
fn the_category_shown_is_highlighted() {
|
||||
|
||||
+1
-1
@@ -110,7 +110,7 @@ The window runs natively on Wayland (eframe's `wayland` feature) and on X11. On
|
||||
- **Clipboard owners that never answer (#510):** reading the clipboard waits on the app that owns it: arboard gives up on an X11 owner after 4 s, and a Wayland read waits for the owner to send its data. So on Linux the check that enables the Paste menu items runs on a background thread with a second clipboard handle (`crates/ui-egui/src/clipboard_probe.rs`, installed as `Services::clipboard_probe`), only while nothing is copied in the app and a document is open, and the window keeps drawing. A paste itself still reads on the UI thread, so pasting from such an owner waits for it once. Windows and macOS keep the check on the UI thread: Windows only asks which formats the clipboard holds, macOS asks the pasteboard server.
|
||||
- **Copied files:** files copied in a file manager (`text/uri-list`; `CF_HDROP` on Windows, file URLs on macOS) paste as the first one that is art (SVG, PDF, EPS, EMF/WMF or a bitmap; a `.ai` or `.ait` file as the PDF or PostScript it holds), before the clipboard's other formats (which include the files' paths as text).
|
||||
- **Dropping files on the window does not work under Wayland:** winit 0.30, which eframe 0.36 runs on, has no Wayland drag and drop ([winit#1881](https://github.com/rust-windowing/winit/issues/1881), added in winit 0.31; [egui#1563](https://github.com/emilk/egui/issues/1563)), so no `dropped_files` arrive. Until eframe moves to winit 0.31: copy the files in the file manager and paste them, use File › Place or Open, or open the window through XWayland, where drops work: set **Preferences › Performance › Linux Display Server** to **X11 (XWayland)** and restart (#1151), or start the app with `WAYLAND_DISPLAY= vectorcraft`. The preference (`linuxDisplayServer`, read at startup in `apps/vectorcraft/src/main.rs`, shown on Linux only) has winit open the window on X11 (`EventLoopBuilderExtX11::with_x11`) when the session is Wayland, `DISPLAY` is set and the X11 libraries winit loads are installed (`apps/vectorcraft/src/xwayland.rs` reads `ldconfig -p` and the usual library directories); otherwise the window opens on Wayland and the log says why. Unlike clearing `WAYLAND_DISPLAY`, it leaves the clipboard on the compositor's own.
|
||||
- **Pens and pen displays under Wayland (#491):** winit 0.30 doesn't bind the Wayland tablet protocol (`zwp_tablet_v2`; tablet input arrives in winit 0.31, [winit#4318](https://github.com/rust-windowing/winit/pull/4318), [egui#7731](https://github.com/emilk/egui/pull/7731)). Since Plasma 6.3, KWin no longer turns tablet input into pointer input for such apps ([kwin!6336](https://invent.kde.org/plasma/kwin/-/merge_requests/6336)): the pen moves the compositor's cursor over the window, but the app gets no motion or presses and shows none of its own cursors. Until eframe moves to winit 0.31, either run the app under XWayland, which supports the tablet protocol and hands the pen to X11 apps as a pointer (Preferences › Performance › Linux Display Server › X11 (XWayland), `WAYLAND_DISPLAY= vectorcraft`, or `env -u WAYLAND_DISPLAY vectorcraft`; for a desktop launcher, put `env WAYLAND_DISPLAY=` before the command in its `Exec=` line), or turn KWin's deprecated emulation back on for the whole session by setting `KWIN_WAYLAND_EMULATE_TABLET=1` in KWin's environment (for example in a file under `~/.config/environment.d/` or in `/etc/environment`) and logging in again. The pen then works as a mouse, without pressure: winit 0.30 reads pen pressure on Windows only (Windows Ink, which reaches the Liquify tools' Use Pressure Pen). Other compositors that don't emulate a pointer for tablets behave the same way.
|
||||
- **Pens and pen displays under Wayland (#491, #2028):** winit 0.30 doesn't bind the Wayland tablet protocol (`zwp_tablet_v2`; tablet input arrives in winit 0.31, [winit#4318](https://github.com/rust-windowing/winit/pull/4318), [egui#7731](https://github.com/emilk/egui/pull/7731)). Since Plasma 6.3, KWin no longer turns tablet input into pointer input for such apps ([kwin!6336](https://invent.kde.org/plasma/kwin/-/merge_requests/6336), commit [25c65abd](https://invent.kde.org/plasma/kwin/-/commit/25c65abddd95eb87fb892a8594faccbf509ff62f)), and GNOME's Mutter does not turn it into pointer input either (that commit's message): on KWin the pen moves the compositor's cursor over the window, but the app gets no motion or presses and shows none of its own cursors. Until eframe moves to winit 0.31, either run the app under XWayland, which supports the tablet protocol and hands the pen to X11 apps as a pointer (Preferences › Performance › Linux Display Server › X11 (XWayland); X11 (XWayland) When a Pen Is Attached (`x11WithPen`), which opens the window through XWayland only when `/proc/bus/input/devices` lists a pen as the app starts, a device with the `BTN_TOOL_PEN` key and the `ABS_X` and `ABS_Y` axes, and logs `pen found: opening the window through XWayland`; `WAYLAND_DISPLAY= vectorcraft`, or `env -u WAYLAND_DISPLAY vectorcraft`; for a desktop launcher, put `env WAYLAND_DISPLAY=` before the command in its `Exec=` line), or turn KWin's deprecated emulation back on for the whole session by setting `KWIN_WAYLAND_EMULATE_TABLET=1` in KWin's environment (for example in a file under `~/.config/environment.d/` or in `/etc/environment`) and logging in again. The pen then works as a mouse, without pressure: winit 0.30 reads pen pressure on Windows only (Windows Ink, which reaches the Liquify tools' Use Pressure Pen). Other compositors that don't emulate a pointer for tablets behave the same way.
|
||||
|
||||
## Fonts: craft-fonts (optional build input)
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ on huge documents. Pen input is pressure-only and Windows-first.
|
||||
| Multithreaded rendering off the UI thread | partial | yes | yes | yes | single-threaded | beyond Illustrator |
|
||||
| Hybrid-graphics GPU choice | automatic | power-saving GPU by default, Preferences › Graphics Processor | same; DX12 then OpenGL; no Vulkan unless asked (#545, #806) | the desktop's GPU | browser | done |
|
||||
| Restart on another GPU when the first fails to present | — | yes (#502, #964) | yes | yes | restart on lost device (#369) | done |
|
||||
| Pen pressure | yes (Wacom, Windows Ink, macOS tablet events) | **no** (winit reports none, #852) | yes (pointer force via `WM_POINTER`) | X11 only via XWayland (Preferences › Performance › Linux Display Server, #1151); none on Wayland (#491, #764) | browser pointer events, with coalesced events; Apple Pencil on iPad (hover, palm rejection: fingers navigate after a pen contact until reload) | partial: 4–8 h for macOS and Wayland (winit 0.31) |
|
||||
| Pen pressure | yes (Wacom, Windows Ink, macOS tablet events) | **no** (winit reports none, #852) | yes (pointer force via `WM_POINTER`) | **no** (winit reports none on X11 or Wayland); through XWayland (Preferences › Performance › Linux Display Server, #1151, #2028) the pen works as a mouse, and on Wayland it may not reach the window (#491, #764) | browser pointer events, with coalesced events; Apple Pencil on iPad (hover, palm rejection: fingers navigate after a pen contact until reload) | partial: 4–8 h for macOS and Wayland (winit 0.31) |
|
||||
| Pen tilt, bearing, barrel rotation (6D Art Pen) | yes, drives brushes | no | no | no | no | missing: 4–8 h after the input layer (#372) |
|
||||
| Pen eraser end | yes | no | no | no | no | missing |
|
||||
| Touch gestures (pinch zoom, two-finger pan, rotate view, Touch workspace) | yes (Windows touch, Surface) | trackpad pinch, scroll and rotate | pinch, pan; two-finger tap undo, three-finger redo (#585) | same where winit reports touch | eframe until the first pen contact, then Pointer Events (pen and fingers told apart); long press opens the context menu | partial: touch workspace and touch-screen rotation missing, 3–5 h |
|
||||
|
||||
@@ -740,6 +740,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
|
||||
The Layers panel's Delete Selection, Duplicate Selection, Collect in New Layer, Merge Selected, Flatten Artwork, Release to Layers (Sequence) and row drags also take time in proportion to the size of the document, and so do Cut Artboard and Duplicate Artboard with their art and each move of an Alt-drag of one artboard with the Artboard tool while Move/Copy Artwork with Artboard is on (#1429).
|
||||
In Outline view the renderer draws paths and compound paths from the geometry it keeps for them between frames, and it culls the members of clip groups by the bounds it keeps for them. Layers with Preview off and the outlines of Image Trace objects are drawn the same way.
|
||||
- **Graphics processor:** the canvas is rasterized on the CPU and the GPU only composites it, so any GPU that can show the window will do. Preferences › Performance › Graphics Processor (`gpuPreference`) is Automatic by default: the power-saving GPU on Windows and macOS (the integrated one on hybrid-graphics laptops, where presenting from the discrete GPU made the window flicker, #306), and the GPU the desktop runs on under Linux, where KWin on an NVIDIA GPU refused frames from a Ryzen's integrated GPU and 0.5.0 crashed at startup (#502). Power Saving and High Performance pick a kind of GPU; `WGPU_POWER_PREF`, `WGPU_ADAPTER_NAME` and `WGPU_BACKEND` override them. The app picks among the adapters that can present to the window (native backends before OpenGL, hardware before software, and on Windows a GPU's DX12 adapter before its Vulkan one: Intel's Vulkan driver made the whole window flicker black, #545), and if the window fails on one while starting up it starts again without it instead of crashing; after a start that a graphics driver crashed before its first frame, the next starts leave that adapter out, or list OpenGL's adapters alone when the crash came while the adapters were being listed (#2243; verified by unit tests, not on the reporter's Intel UHD Graphics 605); Help › About, `ui.inspect` and the log name the adapter in use. When the browser drops the page's WebGPU device or WebGL context, the web build writes recovery copies, starts again on new graphics with the same app and uploads its textures again; if it can't, it removes the stale canvas and says to reload, which offers the copies back. The desktop app writes the copies and says to restart (#369). On Windows and Linux the tools' cursors are OS cursors (bitmaps rasterized once per display scale), which the system moves itself: painted into the window, they trailed the pointer by the frames waiting to be shown, and the window now queues one frame instead of two (#444). macOS and the web still paint them (macOS sizes cursor bitmaps in points, eframe has no bitmap cursors on the web). Tool states have cursors of their own as the public manual describes them: Direct Selection shows a hollow or filled square on its white arrow over an anchor (path unselected or selected) and the Reshape Segment cursor over a curved segment, as do the Anchor Point tool and the Pen with Alt (whose caret it lends); Group Selection, and Direct Selection with Alt, show a plus; a drag shows the filled arrow, hollow while it snaps to a point or a guide, and an Alt-drag copy a double arrowhead; Curvature has its own pen and Free Transform's Cmd/Ctrl side-shear two arrows passing along the side. Lasso, Magic Wand, the freehand tools, Shaper, Live Paint Bucket, Measure, Print Tiling, the symbolism tools, vertical type, Scissors, Mesh and Puppet Warp return cursors of their own, which borrow the crosshair, the I-beam, the Pen's add cursor or not-allowed until they're drawn; there's no busy cursor yet. `crates/tools/src/cursors.toml` lists every cursor, when it shows and its hotspot, for whoever draws them. Pens and touch drive the tools as the mouse does, and a tap pressed and lifted within one frame clicks where it tapped (#491); pen pressure reaches the Liquify tools' Use Pressure Pen on Windows, while winit 0.30 reports none on macOS or Linux and egui none on the web. On Linux, see `docs/development.md` for pens under Wayland.
|
||||
- **Linux display server for pens (part of #2028):** Preferences › Performance › Linux Display Server has X11 (XWayland) When a Pen Is Attached (`x11WithPen`, off by default), which opens the window through XWayland on a Wayland session only when a pen is attached as the app starts. Under XWayland a drawing tablet's pen draws as a mouse. Below the choice, the Performance page tells users whose tablet pen doesn't draw to choose an X11 (XWayland) option.
|
||||
- **Control transport:** idle sockets expire after 5 minutes, partial lines after an absolute 30 seconds from their first byte, and reply writes after 60 seconds (#1726). Real TCP regressions cover stalled peers and slot recovery; command execution has its separate existing timeout. MCP limits: 16 MiB lines, 64-message batches, 256-step `command_batch` with 8 MiB of kept results and 256 MiB control replies (#1764, fixes #1727). MCP requires the JSON-RPC 2.0 envelope and matches control replies by id, and an app refusal without an id reports the app's reason (#1768, fixes #1728). The MCP server reconnects to the app before a call when the connection was closed or holds stray bytes, after an app restart or an idle expiry (#1739).
|
||||
- **MCP vertical type:** `add_text {vertical: true}` forwards to `text.create` or `text.createInPath`. Regression coverage checks point type, rectangular area type, type in a path and type on a path with true, false and omitted direction. This exposes an existing engine option; it does not change glyph orientation, CJK composition or the type/automation scores.
|
||||
- **Malformed MCP replies:** invalid JSON from the app drops the connection, reports that the operation may have completed and leaves the next call to reconnect; it never replays the edit (#1761). TCP regressions cover malformed and uncorrelated replies, connection closure and a subsequent inspection. Envelope regressions also verify zero backend calls and unchanged initialization state for invalid versions.
|
||||
|
||||
Reference in New Issue
Block a user