1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 14:07:46 +00:00

LaunchServer+LibDesktop: Add API to list handlers for a given URL

You can now ask for a list of applications that can handle opening
a given URL. This will be useful for creating context menus.
This commit is contained in:
Andreas Kling 2020-05-12 18:43:55 +02:00
parent 3775983dfe
commit 512c04c64f
7 changed files with 48 additions and 0 deletions

View file

@ -57,4 +57,10 @@ bool Launcher::open(const URL& url)
return connection->send_sync<Messages::LaunchServer::OpenUrl>(url.to_string())->response(); return connection->send_sync<Messages::LaunchServer::OpenUrl>(url.to_string())->response();
} }
Vector<String> Launcher::get_handlers_for_url(const URL& url)
{
auto connection = LaunchServerConnection::construct();
return connection->send_sync<Messages::LaunchServer::GetHandlersForURL>(url.to_string())->handlers();
}
} }

View file

@ -30,9 +30,14 @@
namespace Desktop { namespace Desktop {
struct Opener {
};
class Launcher { class Launcher {
public: public:
static bool open(const URL&); static bool open(const URL&);
static Vector<String> get_handlers_for_url(const URL&);
}; };
} }

View file

@ -59,4 +59,12 @@ OwnPtr<Messages::LaunchServer::OpenUrlResponse> ClientConnection::handle(const M
auto result = Launcher::the().open_url(url); auto result = Launcher::the().open_url(url);
return make<Messages::LaunchServer::OpenUrlResponse>(result); return make<Messages::LaunchServer::OpenUrlResponse>(result);
} }
OwnPtr<Messages::LaunchServer::GetHandlersForURLResponse> ClientConnection::handle(const Messages::LaunchServer::GetHandlersForURL& request)
{
URL url(request.url());
auto result = Launcher::the().handlers_for_url(url);
return make<Messages::LaunchServer::GetHandlersForURLResponse>(result);
}
} }

View file

@ -44,5 +44,6 @@ private:
virtual OwnPtr<Messages::LaunchServer::GreetResponse> handle(const Messages::LaunchServer::Greet&) override; virtual OwnPtr<Messages::LaunchServer::GreetResponse> handle(const Messages::LaunchServer::Greet&) override;
virtual OwnPtr<Messages::LaunchServer::OpenUrlResponse> handle(const Messages::LaunchServer::OpenUrl&) override; virtual OwnPtr<Messages::LaunchServer::OpenUrlResponse> handle(const Messages::LaunchServer::OpenUrl&) override;
virtual OwnPtr<Messages::LaunchServer::GetHandlersForURLResponse> handle(const Messages::LaunchServer::GetHandlersForURL&) override;
}; };
} }

View file

@ -2,4 +2,5 @@ endpoint LaunchServer = 101
{ {
Greet() => (i32 client_id) Greet() => (i32 client_id)
OpenUrl(String url) => (bool response) OpenUrl(String url) => (bool response)
GetHandlersForURL(String url) => (Vector<String> handlers)
} }

View file

@ -25,6 +25,7 @@
*/ */
#include "Launcher.h" #include "Launcher.h"
#include <AK/FileSystemPath.h>
#include <LibCore/ConfigFile.h> #include <LibCore/ConfigFile.h>
#include <stdio.h> #include <stdio.h>
#include <sys/stat.h> #include <sys/stat.h>
@ -57,6 +58,14 @@ void Launcher::load_config(const Core::ConfigFile& cfg)
} }
} }
Vector<String> 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) bool Launcher::open_url(const URL& url)
{ {
if (url.protocol() == "file") if (url.protocol() == "file")
@ -98,6 +107,22 @@ bool Launcher::open_with_handlers(const HashMap<String, String>& handlers, const
return spawn(default_program, argument); return spawn(default_program, argument);
} }
Vector<String> 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) bool Launcher::open_file_url(const URL& url)
{ {
struct stat st; struct stat st;

View file

@ -39,11 +39,13 @@ public:
void load_config(const Core::ConfigFile&); void load_config(const Core::ConfigFile&);
bool open_url(const URL&); bool open_url(const URL&);
Vector<String> handlers_for_url(const URL&);
private: private:
HashMap<String, String> m_protocol_handlers; HashMap<String, String> m_protocol_handlers;
HashMap<String, String> m_file_handlers; HashMap<String, String> m_file_handlers;
Vector<String> handlers_for_path(const String&);
bool open_file_url(const URL&); bool open_file_url(const URL&);
bool open_with_handlers(const HashMap<String, String>& handlers, const String key, const String argument, const String default_program); bool open_with_handlers(const HashMap<String, String>& handlers, const String key, const String argument, const String default_program);
}; };