diff --git a/Libraries/LibDesktop/Launcher.cpp b/Libraries/LibDesktop/Launcher.cpp index 734ade0e57..43fd5a7c3b 100644 --- a/Libraries/LibDesktop/Launcher.cpp +++ b/Libraries/LibDesktop/Launcher.cpp @@ -57,4 +57,10 @@ bool Launcher::open(const URL& url) return connection->send_sync(url.to_string())->response(); } +Vector Launcher::get_handlers_for_url(const URL& url) +{ + auto connection = LaunchServerConnection::construct(); + return connection->send_sync(url.to_string())->handlers(); +} + } diff --git a/Libraries/LibDesktop/Launcher.h b/Libraries/LibDesktop/Launcher.h index ed75043855..0830c00385 100644 --- a/Libraries/LibDesktop/Launcher.h +++ b/Libraries/LibDesktop/Launcher.h @@ -30,9 +30,14 @@ namespace Desktop { +struct Opener { + +}; + class Launcher { public: static bool open(const URL&); + static Vector get_handlers_for_url(const URL&); }; } diff --git a/Services/LaunchServer/ClientConnection.cpp b/Services/LaunchServer/ClientConnection.cpp index 7a69300684..60c89ed956 100644 --- a/Services/LaunchServer/ClientConnection.cpp +++ b/Services/LaunchServer/ClientConnection.cpp @@ -59,4 +59,12 @@ OwnPtr ClientConnection::handle(const M auto result = Launcher::the().open_url(url); return make(result); } + +OwnPtr ClientConnection::handle(const Messages::LaunchServer::GetHandlersForURL& request) +{ + URL url(request.url()); + auto result = Launcher::the().handlers_for_url(url); + return make(result); +} + } diff --git a/Services/LaunchServer/ClientConnection.h b/Services/LaunchServer/ClientConnection.h index bab6033573..29be882da9 100644 --- a/Services/LaunchServer/ClientConnection.h +++ b/Services/LaunchServer/ClientConnection.h @@ -44,5 +44,6 @@ private: virtual OwnPtr handle(const Messages::LaunchServer::Greet&) override; virtual OwnPtr handle(const Messages::LaunchServer::OpenUrl&) override; + virtual OwnPtr handle(const Messages::LaunchServer::GetHandlersForURL&) override; }; } diff --git a/Services/LaunchServer/LaunchServer.ipc b/Services/LaunchServer/LaunchServer.ipc index dd34ae473d..f2bb3bbd1d 100644 --- a/Services/LaunchServer/LaunchServer.ipc +++ b/Services/LaunchServer/LaunchServer.ipc @@ -2,4 +2,5 @@ endpoint LaunchServer = 101 { Greet() => (i32 client_id) OpenUrl(String url) => (bool response) + GetHandlersForURL(String url) => (Vector handlers) } diff --git a/Services/LaunchServer/Launcher.cpp b/Services/LaunchServer/Launcher.cpp index 14afddbf66..bda5ad70a0 100644 --- a/Services/LaunchServer/Launcher.cpp +++ b/Services/LaunchServer/Launcher.cpp @@ -25,6 +25,7 @@ */ #include "Launcher.h" +#include #include #include #include @@ -57,6 +58,14 @@ void Launcher::load_config(const Core::ConfigFile& cfg) } } +Vector Launcher::handlers_for_url(const URL& url) +{ + if (url.protocol() == "file") + return handlers_for_path(url.path()); + + return { m_protocol_handlers.get(url.protocol()).value_or(m_protocol_handlers.get("*").value_or({})) }; +} + bool Launcher::open_url(const URL& url) { if (url.protocol() == "file") @@ -98,6 +107,22 @@ bool Launcher::open_with_handlers(const HashMap& handlers, const return spawn(default_program, argument); } +Vector Launcher::handlers_for_path(const String& path) +{ + struct stat st; + if (stat(path.characters(), &st) < 0) { + perror("stat"); + return {}; + } + + // TODO: Make directory opening configurable + if (S_ISDIR(st.st_mode)) + return { "/bin/FileManager" }; + + auto extension = FileSystemPath(path).extension().to_lowercase(); + return { m_file_handlers.get(extension).value_or(m_file_handlers.get("*").value_or({})) }; +} + bool Launcher::open_file_url(const URL& url) { struct stat st; diff --git a/Services/LaunchServer/Launcher.h b/Services/LaunchServer/Launcher.h index 26ae697773..0559c3c04b 100644 --- a/Services/LaunchServer/Launcher.h +++ b/Services/LaunchServer/Launcher.h @@ -39,11 +39,13 @@ public: void load_config(const Core::ConfigFile&); bool open_url(const URL&); + Vector handlers_for_url(const URL&); private: HashMap m_protocol_handlers; HashMap m_file_handlers; + Vector handlers_for_path(const String&); bool open_file_url(const URL&); bool open_with_handlers(const HashMap& handlers, const String key, const String argument, const String default_program); };