fix(deep-link): robust qobuzapp:// handler across all packages
- Auto-detect installed .desktop filename (com.blitzfc.qbz.desktop, qbz.desktop, qbz-nix.desktop) instead of hardcoding - Run update-desktop-database after register/deregister so xdg-open and browsers pick up the MIME association immediately - Fix v2_check_qobuzapp_handler to match all known desktop filenames - Align StartupWMClass to com.blitzfc.qbz across all packaging formats - Add StartupNotify=true to Arch/AUR/Snap desktop files Fixes browser URI handler not working for .deb users (Discussion #44)
This commit is contained in:
6 files changed
+72
-13
No files matched your search
@@ -6,6 +6,6 @@ Type=Application
|
|||||||
Icon=com.blitzfc.qbz
|
Icon=com.blitzfc.qbz
|
||||||
Categories=AudioVideo;Audio;Music;Player;
|
Categories=AudioVideo;Audio;Music;Player;
|
||||||
Terminal=false
|
Terminal=false
|
||||||
StartupWMClass=QBZ
|
StartupWMClass=com.blitzfc.qbz
|
||||||
Keywords=music;audio;qobuz;hifi;streaming;audiophile;
|
Keywords=music;audio;qobuz;hifi;streaming;audiophile;
|
||||||
MimeType=x-scheme-handler/qbz;x-scheme-handler/qobuzapp;
|
MimeType=x-scheme-handler/qbz;x-scheme-handler/qobuzapp;
|
||||||
@@ -6,6 +6,7 @@ Type=Application
|
|||||||
Icon=qbz
|
Icon=qbz
|
||||||
Categories=AudioVideo;Audio;Music;Player;
|
Categories=AudioVideo;Audio;Music;Player;
|
||||||
Terminal=false
|
Terminal=false
|
||||||
StartupWMClass=QBZ
|
StartupWMClass=com.blitzfc.qbz
|
||||||
|
StartupNotify=true
|
||||||
Keywords=music;audio;qobuz;hifi;streaming;audiophile;
|
Keywords=music;audio;qobuz;hifi;streaming;audiophile;
|
||||||
MimeType=x-scheme-handler/qbz;x-scheme-handler/qobuzapp;
|
MimeType=x-scheme-handler/qbz;x-scheme-handler/qobuzapp;
|
||||||
@@ -6,6 +6,7 @@ Type=Application
|
|||||||
Icon=qbz
|
Icon=qbz
|
||||||
Categories=AudioVideo;Audio;Music;Player;
|
Categories=AudioVideo;Audio;Music;Player;
|
||||||
Terminal=false
|
Terminal=false
|
||||||
StartupWMClass=QBZ
|
StartupWMClass=com.blitzfc.qbz
|
||||||
|
StartupNotify=true
|
||||||
Keywords=music;audio;qobuz;hifi;streaming;audiophile;
|
Keywords=music;audio;qobuz;hifi;streaming;audiophile;
|
||||||
MimeType=x-scheme-handler/qbz;x-scheme-handler/qobuzapp;
|
MimeType=x-scheme-handler/qbz;x-scheme-handler/qobuzapp;
|
||||||
@@ -6,6 +6,6 @@ Type=Application
|
|||||||
Icon=com.blitzfc.qbz
|
Icon=com.blitzfc.qbz
|
||||||
Categories=AudioVideo;Audio;Music;Player;
|
Categories=AudioVideo;Audio;Music;Player;
|
||||||
Terminal=false
|
Terminal=false
|
||||||
StartupWMClass=QBZ
|
StartupWMClass=com.blitzfc.qbz
|
||||||
Keywords=music;audio;qobuz;hifi;streaming;audiophile;
|
Keywords=music;audio;qobuz;hifi;streaming;audiophile;
|
||||||
MimeType=x-scheme-handler/qbz;x-scheme-handler/qobuzapp;
|
MimeType=x-scheme-handler/qbz;x-scheme-handler/qobuzapp;
|
||||||
@@ -6,5 +6,6 @@ Icon=${SNAP}/meta/gui/qbz.png
|
|||||||
Type=Application
|
Type=Application
|
||||||
Categories=AudioVideo;Audio;Music;Player;
|
Categories=AudioVideo;Audio;Music;Player;
|
||||||
Terminal=false
|
Terminal=false
|
||||||
StartupWMClass=QBZ
|
StartupWMClass=com.blitzfc.qbz
|
||||||
|
StartupNotify=true
|
||||||
MimeType=x-scheme-handler/qbz;x-scheme-handler/qobuzapp;
|
MimeType=x-scheme-handler/qbz;x-scheme-handler/qobuzapp;
|
||||||
@@ -1937,6 +1937,55 @@ pub fn v2_get_qobuz_track_url(trackId: u64) -> Result<String, RuntimeError> {
|
|||||||
Ok(format!("https://play.qobuz.com/track/{}", trackId))
|
Ok(format!("https://play.qobuz.com/track/{}", trackId))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Known .desktop filenames across packaging formats.
|
||||||
|
const QBZ_DESKTOP_CANDIDATES: &[&str] = &[
|
||||||
|
"com.blitzfc.qbz.desktop", // Tauri deb, Flatpak
|
||||||
|
"qbz.desktop", // Arch, AUR, Snap
|
||||||
|
"qbz-nix.desktop", // Possible alternative
|
||||||
|
];
|
||||||
|
|
||||||
|
/// Search standard directories for the installed QBZ .desktop file.
|
||||||
|
fn find_qbz_desktop_file() -> String {
|
||||||
|
let home = std::env::var("HOME").unwrap_or_default();
|
||||||
|
let search_dirs = [
|
||||||
|
"/usr/share/applications".to_string(),
|
||||||
|
"/usr/local/share/applications".to_string(),
|
||||||
|
format!("{}/.local/share/applications", home),
|
||||||
|
"/var/lib/flatpak/exports/share/applications".to_string(),
|
||||||
|
format!("{}/.local/share/flatpak/exports/share/applications", home),
|
||||||
|
];
|
||||||
|
|
||||||
|
for candidate in QBZ_DESKTOP_CANDIDATES {
|
||||||
|
for dir in &search_dirs {
|
||||||
|
let path = format!("{}/{}", dir, candidate);
|
||||||
|
if std::path::Path::new(&path).exists() {
|
||||||
|
log::info!("[URI Handler] Found desktop file: {}", path);
|
||||||
|
return candidate.to_string();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log::warn!("[URI Handler] No desktop file found in standard dirs, using default");
|
||||||
|
"com.blitzfc.qbz.desktop".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Refresh the desktop MIME database so xdg-open picks up changes.
|
||||||
|
fn refresh_desktop_database() {
|
||||||
|
// User-level applications dir
|
||||||
|
if let Some(data_dir) = dirs::data_dir() {
|
||||||
|
let user_apps = data_dir.join("applications");
|
||||||
|
if user_apps.exists() {
|
||||||
|
let _ = std::process::Command::new("update-desktop-database")
|
||||||
|
.arg(&user_apps)
|
||||||
|
.status();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// System-level (may fail without root, that's OK)
|
||||||
|
let _ = std::process::Command::new("update-desktop-database")
|
||||||
|
.arg("/usr/share/applications")
|
||||||
|
.status();
|
||||||
|
}
|
||||||
|
|
||||||
/// Check if QBZ is the default handler for qobuzapp:// links.
|
/// Check if QBZ is the default handler for qobuzapp:// links.
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn v2_check_qobuzapp_handler() -> Result<bool, RuntimeError> {
|
pub fn v2_check_qobuzapp_handler() -> Result<bool, RuntimeError> {
|
||||||
@@ -1945,23 +1994,29 @@ pub fn v2_check_qobuzapp_handler() -> Result<bool, RuntimeError> {
|
|||||||
.output()
|
.output()
|
||||||
.map_err(|e| RuntimeError::Internal(format!("Failed to run xdg-mime: {}", e)))?;
|
.map_err(|e| RuntimeError::Internal(format!("Failed to run xdg-mime: {}", e)))?;
|
||||||
|
|
||||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
let result = String::from_utf8_lossy(&output.stdout).trim().to_string();
|
||||||
Ok(stdout.trim().contains("com.blitzfc.qbz"))
|
Ok(QBZ_DESKTOP_CANDIDATES.iter().any(|c| *c == result))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Register QBZ as the default handler for qobuzapp:// links.
|
/// Register QBZ as the default handler for qobuzapp:// links.
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn v2_register_qobuzapp_handler() -> Result<bool, RuntimeError> {
|
pub fn v2_register_qobuzapp_handler() -> Result<bool, RuntimeError> {
|
||||||
|
let desktop_file = find_qbz_desktop_file();
|
||||||
|
log::info!("[URI Handler] Registering {} for x-scheme-handler/qobuzapp", desktop_file);
|
||||||
|
|
||||||
let status = std::process::Command::new("xdg-mime")
|
let status = std::process::Command::new("xdg-mime")
|
||||||
.args([
|
.args(["default", &desktop_file, "x-scheme-handler/qobuzapp"])
|
||||||
"default",
|
|
||||||
"com.blitzfc.qbz.desktop",
|
|
||||||
"x-scheme-handler/qobuzapp",
|
|
||||||
])
|
|
||||||
.status()
|
.status()
|
||||||
.map_err(|e| RuntimeError::Internal(format!("Failed to run xdg-mime: {}", e)))?;
|
.map_err(|e| RuntimeError::Internal(format!("Failed to run xdg-mime: {}", e)))?;
|
||||||
|
|
||||||
Ok(status.success())
|
if !status.success() {
|
||||||
|
log::error!("[URI Handler] xdg-mime default failed");
|
||||||
|
return Ok(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
refresh_desktop_database();
|
||||||
|
log::info!("[URI Handler] Registration complete, desktop database refreshed");
|
||||||
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove QBZ as the default handler for qobuzapp:// links.
|
/// Remove QBZ as the default handler for qobuzapp:// links.
|
||||||
@@ -1994,6 +2049,7 @@ pub fn v2_deregister_qobuzapp_handler() -> Result<bool, RuntimeError> {
|
|||||||
std::fs::write(&mimeapps, filtered)
|
std::fs::write(&mimeapps, filtered)
|
||||||
.map_err(|e| RuntimeError::Internal(format!("Failed to write mimeapps.list: {}", e)))?;
|
.map_err(|e| RuntimeError::Internal(format!("Failed to write mimeapps.list: {}", e)))?;
|
||||||
|
|
||||||
|
refresh_desktop_database();
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user