BlueGit

golden-age paperdoll-renderer

Merge feature/wayland-app-id (Tim t998u.2)

timfa Grok Bot · pushed by timfa

Authored 2026-11-07 · 6 days ago

Hash
49a2ee9334a159a31b51ada70eae0813a36f9b28
Pipeline
Passed
7 files changed +26 −3
Cargo.toml +1 −1
@@ -7,7 +7,7 @@ publish = false
7 7 description = "Paperdoll Renderer with project files, model import and a live glTF preview."
8 8
9 9 [dependencies]
10 eframe = { version = "0.29.1", default-features = false, features = ["default_fonts", "glow", "x11"] }
10 eframe = { version = "0.29.1", default-features = false, features = ["default_fonts", "glow", "x11", "wayland"] }
11 11 egui_glow = "0.29.1"
12 12 glow = "0.14.2"
13 13 gltf = { version = "1.4.1", default-features = false, features = ["import", "names", "utils", "KHR_texture_transform"] }
@@ -7,7 +7,7 @@ publish = false
7description = "Paperdoll Renderer with project files, model import and a live glTF preview."
7description = "Paperdoll Renderer with project files, model import and a live glTF preview."
8
8
9[dependencies]
9[dependencies]
10eframe = { version = "0.29.1", default-features = false, features = ["default_fonts", "glow", "x11"] }
10eframe = { version = "0.29.1", default-features = false, features = ["default_fonts", "glow", "x11", "wayland"] }
11egui_glow = "0.29.1"
11egui_glow = "0.29.1"
12glow = "0.14.2"
12glow = "0.14.2"
13gltf = { version = "1.4.1", default-features = false, features = ["import", "names", "utils", "KHR_texture_transform"] }
13gltf = { version = "1.4.1", default-features = false, features = ["import", "names", "utils", "KHR_texture_transform"] }
README.md +1 −1
@@ -196,7 +196,7 @@ Highres is exact 8× beide assen; batch-targets zijn momenteel **1–256 pixels
196 196 - **Debian/Arch:** de pakketten installeren de `.ppd`-MIME-koppeling, desktopstarter en iconen. Kies de editor in **Openen met**.
197 197 - **Linux AppImage/losse binary:** bewaar het bestand op zijn vaste plek en voer `"/pad/Paperdoll.AppImage" --install-desktop` uit. Hiervoor zijn `shared-mime-info` en `desktop-file-utils` nodig. Daarna staat de editor in **Openen met**. Herhaal dit na verplaatsen van de AppImage.
198 198
199 Het venster, de Linux-starter en de Windows-executable gebruiken Tims applicatie-icoon.
199 Het venster, de Linux-starter en de Windows-executable gebruiken Tims applicatie-icoon. Het venster heeft app-id `paperdoll-renderer` (gelijk aan `paperdoll-renderer.desktop` en `StartupWMClass`), zodat KDE en GNOME onder Wayland het venster aan de starter en het icoon koppelen; de app draait onder Wayland native en onder X11 via X11. Onder Wayland verschijnt het icoon pas als de desktopfile geïnstalleerd is (pakket, of bestandskoppeling vanuit de app).
200 200
201 201 ## Tests
202 202
@@ -196,7 +196,7 @@ Highres is exact 8× beide assen; batch-targets zijn momenteel **1–256 pixels
196- **Debian/Arch:** de pakketten installeren de `.ppd`-MIME-koppeling, desktopstarter en iconen. Kies de editor in **Openen met**.
196- **Debian/Arch:** de pakketten installeren de `.ppd`-MIME-koppeling, desktopstarter en iconen. Kies de editor in **Openen met**.
197- **Linux AppImage/losse binary:** bewaar het bestand op zijn vaste plek en voer `"/pad/Paperdoll.AppImage" --install-desktop` uit. Hiervoor zijn `shared-mime-info` en `desktop-file-utils` nodig. Daarna staat de editor in **Openen met**. Herhaal dit na verplaatsen van de AppImage.
197- **Linux AppImage/losse binary:** bewaar het bestand op zijn vaste plek en voer `"/pad/Paperdoll.AppImage" --install-desktop` uit. Hiervoor zijn `shared-mime-info` en `desktop-file-utils` nodig. Daarna staat de editor in **Openen met**. Herhaal dit na verplaatsen van de AppImage.
198
198
199Het venster, de Linux-starter en de Windows-executable gebruiken Tims applicatie-icoon.
199Het venster, de Linux-starter en de Windows-executable gebruiken Tims applicatie-icoon. Het venster heeft app-id `paperdoll-renderer` (gelijk aan `paperdoll-renderer.desktop` en `StartupWMClass`), zodat KDE en GNOME onder Wayland het venster aan de starter en het icoon koppelen; de app draait onder Wayland native en onder X11 via X11. Onder Wayland verschijnt het icoon pas als de desktopfile geïnstalleerd is (pakket, of bestandskoppeling vanuit de app).
200
200
201## Tests
201## Tests
202
202
packaging/linux/paperdoll-renderer.desktop +1 −0
@@ -8,4 +8,5 @@ Icon=paperdoll-renderer
8 8 Terminal=false
9 9 Categories=Graphics;
10 10 StartupNotify=true
11 StartupWMClass=paperdoll-renderer
11 12 MimeType=application/x-paperdoll-project;
@@ -8,4 +8,5 @@ Icon=paperdoll-renderer
8Terminal=false
8Terminal=false
9Categories=Graphics;
9Categories=Graphics;
10StartupNotify=true
10StartupNotify=true
11StartupWMClass=paperdoll-renderer
11MimeType=application/x-paperdoll-project;
12MimeType=application/x-paperdoll-project;
src/file_assoc.rs +1 −1
@@ -129,7 +129,7 @@ pub fn linux_desktop_entry(exe: &Path) -> Result<String, String> {
129 129 .replace('`', "\\\\`")
130 130 .replace('$', "\\\\$")
131 131 .replace('%', "%%");
132 Ok(format!("[Desktop Entry]\nType=Application\nName=Paperdoll Renderer\nExec=\"{escaped}\" %f\nIcon=paperdoll-renderer\nTerminal=false\nCategories=Graphics;3DGraphics;\nMimeType={MIME_TYPE};\n"))
132 Ok(format!("[Desktop Entry]\nType=Application\nName=Paperdoll Renderer\nExec=\"{escaped}\" %f\nIcon=paperdoll-renderer\nStartupWMClass=paperdoll-renderer\nTerminal=false\nCategories=Graphics;3DGraphics;\nMimeType={MIME_TYPE};\n"))
133 133 }
134 134
135 135 pub fn write_linux_integration(data: &Path, exe: &Path) -> Result<(), String> {
@@ -129,7 +129,7 @@ pub fn linux_desktop_entry(exe: &Path) -> Result<String, String> {
129 .replace('`', "\\\\`")
129 .replace('`', "\\\\`")
130 .replace('$', "\\\\$")
130 .replace('$', "\\\\$")
131 .replace('%', "%%");
131 .replace('%', "%%");
132 Ok(format!("[Desktop Entry]\nType=Application\nName=Paperdoll Renderer\nExec=\"{escaped}\" %f\nIcon=paperdoll-renderer\nTerminal=false\nCategories=Graphics;3DGraphics;\nMimeType={MIME_TYPE};\n"))
132 Ok(format!("[Desktop Entry]\nType=Application\nName=Paperdoll Renderer\nExec=\"{escaped}\" %f\nIcon=paperdoll-renderer\nStartupWMClass=paperdoll-renderer\nTerminal=false\nCategories=Graphics;3DGraphics;\nMimeType={MIME_TYPE};\n"))
133}
133}
134
134
135pub fn write_linux_integration(data: &Path, exe: &Path) -> Result<(), String> {
135pub fn write_linux_integration(data: &Path, exe: &Path) -> Result<(), String> {
src/icon.rs +5 −0
@@ -6,6 +6,11 @@
6 6 use std::io::Cursor;
7 7
8 8 /// Tim Falken's original icon, unchanged.
9 /// Window app id (Wayland xdg-shell app_id, X11 WM_CLASS). Must equal the
10 /// `.desktop` file name and its `StartupWMClass` so the desktop maps the
11 /// window to the entry and its icon (Tim t998u.2).
12 pub const APP_ID: &str = "paperdoll-renderer";
13
9 14 pub const SOURCE_PNG: &[u8] = include_bytes!("../assets/icons/paperdoll-renderer.png");
10 15
11 16 /// Freedesktop hicolor sizes installed by the Linux packages.
@@ -6,6 +6,11 @@
6use std::io::Cursor;
6use std::io::Cursor;
7
7
8/// Tim Falken's original icon, unchanged.
8/// Tim Falken's original icon, unchanged.
9/// Window app id (Wayland xdg-shell app_id, X11 WM_CLASS). Must equal the
10/// `.desktop` file name and its `StartupWMClass` so the desktop maps the
11/// window to the entry and its icon (Tim t998u.2).
12pub const APP_ID: &str = "paperdoll-renderer";
13
9pub const SOURCE_PNG: &[u8] = include_bytes!("../assets/icons/paperdoll-renderer.png");
14pub const SOURCE_PNG: &[u8] = include_bytes!("../assets/icons/paperdoll-renderer.png");
10
15
11/// Freedesktop hicolor sizes installed by the Linux packages.
16/// Freedesktop hicolor sizes installed by the Linux packages.
src/main.rs +1 −0
@@ -105,6 +105,7 @@ fn run_window(fixtures: bool, path: Option<std::path::PathBuf>) -> eframe::Resul
105 105 let options = eframe::NativeOptions {
106 106 viewport: eframe::egui::ViewportBuilder::default()
107 107 .with_title("Paperdoll Renderer")
108 .with_app_id(paperdoll_renderer::icon::APP_ID)
108 109 .with_inner_size(paperdoll_renderer::session::START_WINDOW)
109 110 .with_min_inner_size([420.0, 220.0])
110 111 .with_icon(eframe::egui::IconData {
@@ -105,6 +105,7 @@ fn run_window(fixtures: bool, path: Option<std::path::PathBuf>) -> eframe::Resul
105 let options = eframe::NativeOptions {
105 let options = eframe::NativeOptions {
106 viewport: eframe::egui::ViewportBuilder::default()
106 viewport: eframe::egui::ViewportBuilder::default()
107 .with_title("Paperdoll Renderer")
107 .with_title("Paperdoll Renderer")
108 .with_app_id(paperdoll_renderer::icon::APP_ID)
108 .with_inner_size(paperdoll_renderer::session::START_WINDOW)
109 .with_inner_size(paperdoll_renderer::session::START_WINDOW)
109 .with_min_inner_size([420.0, 220.0])
110 .with_min_inner_size([420.0, 220.0])
110 .with_icon(eframe::egui::IconData {
111 .with_icon(eframe::egui::IconData {
tests/app_icon.rs +16 −0
@@ -110,6 +110,22 @@ fn desktop_and_appdata_name_the_same_icon() {
110 110 assert!(desktop
111 111 .lines()
112 112 .any(|line| line == "Icon=paperdoll-renderer"));
113 // Wayland maps the window app_id to the desktop entry (and its icon).
114 let app_id = paperdoll_renderer::icon::APP_ID;
115 assert_eq!(app_id, "paperdoll-renderer");
116 assert!(desktop
117 .lines()
118 .any(|line| line == format!("StartupWMClass={app_id}")));
119 let generated =
120 paperdoll_renderer::file_assoc::linux_desktop_entry(std::path::Path::new("/opt/p/app"))
121 .unwrap();
122 assert!(generated
123 .lines()
124 .any(|line| line == format!("StartupWMClass={app_id}")));
125 let main = read("src/main.rs");
126 assert!(main.contains(".with_app_id(paperdoll_renderer::icon::APP_ID)"));
127 assert!(main.contains(".with_icon("));
128 assert!(read("Cargo.toml").contains("\"wayland\""));
113 129 assert!(metainfo.contains("<icon type=\"stock\">paperdoll-renderer</icon>"));
114 130 assert!(metainfo.contains("paperdoll-renderer.desktop"));
115 131 for script in [
@@ -110,6 +110,22 @@ fn desktop_and_appdata_name_the_same_icon() {
110 assert!(desktop
110 assert!(desktop
111 .lines()
111 .lines()
112 .any(|line| line == "Icon=paperdoll-renderer"));
112 .any(|line| line == "Icon=paperdoll-renderer"));
113 // Wayland maps the window app_id to the desktop entry (and its icon).
114 let app_id = paperdoll_renderer::icon::APP_ID;
115 assert_eq!(app_id, "paperdoll-renderer");
116 assert!(desktop
117 .lines()
118 .any(|line| line == format!("StartupWMClass={app_id}")));
119 let generated =
120 paperdoll_renderer::file_assoc::linux_desktop_entry(std::path::Path::new("/opt/p/app"))
121 .unwrap();
122 assert!(generated
123 .lines()
124 .any(|line| line == format!("StartupWMClass={app_id}")));
125 let main = read("src/main.rs");
126 assert!(main.contains(".with_app_id(paperdoll_renderer::icon::APP_ID)"));
127 assert!(main.contains(".with_icon("));
128 assert!(read("Cargo.toml").contains("\"wayland\""));
113 assert!(metainfo.contains("<icon type=\"stock\">paperdoll-renderer</icon>"));
129 assert!(metainfo.contains("<icon type=\"stock\">paperdoll-renderer</icon>"));
114 assert!(metainfo.contains("paperdoll-renderer.desktop"));
130 assert!(metainfo.contains("paperdoll-renderer.desktop"));
115 for script in [
131 for script in [