From 6b611b1d09b8fbffd5fb0b68d0d8d80e03ba94a5 Mon Sep 17 00:00:00 2001 From: omigamedev Date: Mon, 19 Jan 2026 17:01:31 +0100 Subject: [PATCH] Fix icon loading for third-party apps with file:// URL scheme - Add file:// URL handling to AssetFilesInterface in kernel.cpp - Update home.lua to use file:// prefix for absolute filesystem paths - Add file:// URL handling to desktop file interface for consistency This fixes RmlUi stripping the leading slash from absolute paths when resolving img src URLs relative to the document base. Co-Authored-By: Claude Opus 4.5 --- designer/src/desktop_file_interface.cpp | 5 +++++ src/main/assets/apps/home/home.lua | 9 +++++++-- src/main/cpp/kernel.cpp | 18 ++++++++++++++---- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/designer/src/desktop_file_interface.cpp b/designer/src/desktop_file_interface.cpp index 66205aa..baa1f0b 100644 --- a/designer/src/desktop_file_interface.cpp +++ b/designer/src/desktop_file_interface.cpp @@ -19,6 +19,11 @@ void DesktopFileInterface::SetAssetsPath(const std::string& path) { std::string DesktopFileInterface::ResolvePath(const std::string& path) const { std::string resolved = path; + // Handle file:// URLs + if (resolved.rfind("file://", 0) == 0) { + resolved = resolved.substr(7); // Strip "file://" + } + // Handle URL-encoded Windows drive letters (D| -> D:) // RmlUi sometimes encodes the colon in Windows paths if (resolved.size() >= 2 && std::isalpha(resolved[0]) && resolved[1] == '|') { diff --git a/src/main/assets/apps/home/home.lua b/src/main/assets/apps/home/home.lua index 82c8f1d..bbdadca 100644 --- a/src/main/assets/apps/home/home.lua +++ b/src/main/assets/apps/home/home.lua @@ -121,9 +121,14 @@ function renderThirdPartyApps() else icon_path = app.icon end + -- Use file:// prefix for absolute paths to prevent RmlUi URL resolution + local src_path = icon_path + if icon_path:sub(1, 1) == "/" then + src_path = "file://" .. icon_path + end -- Use img tag for actual icon - icon_html = '' - print("[Home] Loading icon: " .. icon_path) + icon_html = '' + print("[Home] Loading icon: " .. src_path) else -- Fallback to initial letter icon_html = '' .. initial .. '' diff --git a/src/main/cpp/kernel.cpp b/src/main/cpp/kernel.cpp index 678b446..835b02d 100644 --- a/src/main/cpp/kernel.cpp +++ b/src/main/cpp/kernel.cpp @@ -66,9 +66,17 @@ public: return instance; } - // Check if path is a filesystem path (starts with /) + // Check if path is a filesystem path (starts with / or file://) static bool IsFilesystemPath(const Rml::String& path) { - return !path.empty() && path[0] == '/'; + return !path.empty() && (path[0] == '/' || path.rfind("file://", 0) == 0); + } + + // Get the actual filesystem path, stripping file:// prefix if present + static Rml::String GetFilesystemPath(const Rml::String& path) { + if (path.rfind("file://", 0) == 0) { + return path.substr(7); // Strip "file://" + } + return path; } Rml::FileHandle Open(const Rml::String &path) override @@ -77,7 +85,8 @@ public: if (IsFilesystemPath(path)) { // Filesystem path - auto* file = new std::ifstream(path, std::ios::binary); + Rml::String fs_path = GetFilesystemPath(path); + auto* file = new std::ifstream(fs_path, std::ios::binary); if (!file->is_open()) { delete file; delete wrapper; @@ -175,7 +184,8 @@ public: { if (IsFilesystemPath(path)) { // Load from filesystem - std::ifstream file(path, std::ios::binary | std::ios::ate); + Rml::String fs_path = GetFilesystemPath(path); + std::ifstream file(fs_path, std::ios::binary | std::ios::ate); if (!file.is_open()) return false; size_t size = file.tellg();