Merge feature/wayland-app-id (Tim t998u.2)
@@ -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 = false7
description = "Paperdoll Renderer with project files, model import and a live glTF preview."7
description = "Paperdoll Renderer with project files, model import and a live glTF preview."8
8
9
[dependencies]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
egui_glow = "0.29.1"11
egui_glow = "0.29.1"12
glow = "0.14.2"12
glow = "0.14.2"13
gltf = { version = "1.4.1", default-features = false, features = ["import", "names", "utils", "KHR_texture_transform"] }13
gltf = { version = "1.4.1", default-features = false, features = ["import", "names", "utils", "KHR_texture_transform"] }@@ -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 pixels196
- **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
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
## Tests201
## Tests202
202
@@ -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-renderer8
Terminal=false8
Terminal=false9
Categories=Graphics;9
Categories=Graphics;10
StartupNotify=true10
StartupNotify=true11
StartupWMClass=paperdoll-renderer11
MimeType=application/x-paperdoll-project;12
MimeType=application/x-paperdoll-project;@@ -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
135
pub fn write_linux_integration(data: &Path, exe: &Path) -> Result<(), String> {135
pub fn write_linux_integration(data: &Path, exe: &Path) -> Result<(), String> {@@ -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 @@6
use std::io::Cursor;6
use 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 the10
/// `.desktop` file name and its `StartupWMClass` so the desktop maps the11
/// window to the entry and its icon (Tim t998u.2).12
pub const APP_ID: &str = "paperdoll-renderer";13
9
pub const SOURCE_PNG: &[u8] = include_bytes!("../assets/icons/paperdoll-renderer.png");14
pub 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.@@ -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::Resul105
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 {@@ -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!(desktop110
assert!(desktop111
.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!(desktop117
.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!(generated123
.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 [