diff --git a/plugins/ipc/demo-ipc.cpp b/plugins/ipc/demo-ipc.cpp index 35037bd0c..a232da06d 100644 --- a/plugins/ipc/demo-ipc.cpp +++ b/plugins/ipc/demo-ipc.cpp @@ -6,10 +6,8 @@ #include #include "ipc-helpers.hpp" -#include "ipc.hpp" #include "ipc-method-repository.hpp" #include "wayfire/core.hpp" -#include "wayfire/object.hpp" #include "wayfire/plugins/common/shared-core-data.hpp" #include "wayfire/signal-definitions.hpp" #include "wayfire/signal-provider.hpp" @@ -23,7 +21,7 @@ class wayfire_demo_ipc : public wf::plugin_interface_t method_repository->register_method("demo-ipc/view-info", get_view_info); method_repository->register_method("demo-ipc/output-info", get_output_info); method_repository->register_method("demo-ipc/view-set-geometry", set_view_geometry); - ipc_server->connect(&on_client_disconnected); + method_repository->connect(&on_client_disconnected); wf::get_core().connect(&on_view_mapped); } @@ -35,9 +33,10 @@ class wayfire_demo_ipc : public wf::plugin_interface_t method_repository->unregister_method("demo-ipc/view-set-geometry"); } - wf::ipc::method_callback on_client_watch = [=] (nlohmann::json data) + wf::ipc::method_callback_full on_client_watch = + [=] (nlohmann::json data, wf::ipc::client_interface_t *client) { - clients.insert(ipc_server->get_current_request_client()); + clients.insert(client); return wf::ipc::json_ok(); }; @@ -99,8 +98,7 @@ class wayfire_demo_ipc : public wf::plugin_interface_t private: wf::shared_data::ref_ptr_t method_repository; - wf::shared_data::ref_ptr_t ipc_server; - std::set clients; + std::set clients; wf::signal::connection_t on_client_disconnected = [=] (wf::ipc::client_disconnected_signal *ev) diff --git a/plugins/ipc/ipc-method-repository.hpp b/plugins/ipc/ipc-method-repository.hpp index 6a4dc93d4..ed7047117 100644 --- a/plugins/ipc/ipc-method-repository.hpp +++ b/plugins/ipc/ipc-method-repository.hpp @@ -3,35 +3,71 @@ #include #include #include +#include "wayfire/signal-provider.hpp" namespace wf { namespace ipc { +/** + * A client_interface_t represents a client which has connected to the IPC socket. + * It can be used by plugins to send back data to a specific client. + */ +class client_interface_t +{ + public: + virtual void send_json(nlohmann::json json) = 0; +}; + +/** + * A signal emitted on the ipc method repository when a client disconnects. + */ +struct client_disconnected_signal +{ + client_interface_t *client; +}; + /** * An IPC method has a name and a callback. The callback is a simple function which takes a json object which * contains the method's parameters and returns the result of the operation. */ using method_callback = std::function; +/** + * Same as @method_callback, but also supports getting information about the connected ipc client. + */ +using method_callback_full = std::function; + /** * The IPC method repository keeps track of all registered IPC methods. It can be used even without the IPC * plugin itself, as it facilitates inter-plugin calls similarly to signals. * * The method_repository_t is a singleton and is accessed by creating a shared_data::ref_ptr_t to it. */ -class method_repository_t +class method_repository_t : public wf::signal::provider_t { public: /** * Register a new method to the method repository. If the method already exists, the old handler will be * overwritten. */ - void register_method(std::string method, method_callback handler) + void register_method(std::string method, method_callback_full handler) { this->methods[method] = handler; } + /** + * Register a new method to the method repository. If the method already exists, the old handler will be + * overwritten. + */ + void register_method(std::string method, method_callback handler) + { + this->methods[method] = [handler] (const nlohmann::json& data, client_interface_t*) + { + return handler(data); + }; + } + /** * Remove the last registered handler for the given method. */ @@ -44,11 +80,12 @@ class method_repository_t * Call an IPC method with the given name and given parameters. * If the method was not registered, a JSON object containing an error will be returned. */ - nlohmann::json call_method(std::string method, nlohmann::json data) + nlohmann::json call_method(std::string method, nlohmann::json data, + client_interface_t *client = nullptr) { if (this->methods.count(method)) { - return this->methods[method](std::move(data)); + return this->methods[method](std::move(data), client); } return { @@ -72,7 +109,7 @@ class method_repository_t } private: - std::map methods; + std::map methods; }; // A few helper definitions for IPC method implementations. diff --git a/plugins/ipc/ipc.cpp b/plugins/ipc/ipc.cpp index 82e6f9bde..5cf9e1bbf 100644 --- a/plugins/ipc/ipc.cpp +++ b/plugins/ipc/ipc.cpp @@ -123,7 +123,7 @@ void wf::ipc::server_t::client_disappeared(client_t *client) client_disconnected_signal ev; ev.client = client; - this->emit(&ev); + method_repository->emit(&ev); auto it = std::remove_if(clients.begin(), clients.end(), [&] (const auto& cl) { return cl.get() == client; }); @@ -133,9 +133,7 @@ void wf::ipc::server_t::client_disappeared(client_t *client) void wf::ipc::server_t::handle_incoming_message( client_t *client, nlohmann::json message) { - this->current_client = client; - client->send_json(method_repository->call_method(message["method"], message["data"])); - this->current_client = nullptr; + client->send_json(method_repository->call_method(message["method"], message["data"], client)); } /* --------------------------- Per-client code ------------------------------*/ diff --git a/plugins/ipc/ipc.hpp b/plugins/ipc/ipc.hpp index 6815bb7a7..2f4666061 100644 --- a/plugins/ipc/ipc.hpp +++ b/plugins/ipc/ipc.hpp @@ -3,11 +3,9 @@ #include #include #include -#include #include #include #include "ipc-method-repository.hpp" -#include "wayfire/signal-provider.hpp" namespace wf { @@ -17,12 +15,12 @@ namespace ipc * Represents a single connected client to the IPC socket. */ class server_t; -class client_t +class client_t : public client_interface_t { public: client_t(server_t *server, int client_fd); ~client_t(); - void send_json(nlohmann::json json); + void send_json(nlohmann::json json) override; private: int fd; @@ -38,40 +36,21 @@ class client_t void handle_fd_incoming(uint32_t); }; -/** - * A signal emitted on the ipc server when a client disconnects. - */ -struct client_disconnected_signal -{ - client_t *client; -}; - /** * The IPC server is a singleton object accessed via shared_data::ref_ptr_t. * It represents the IPC socket used for communication with clients. */ -class server_t : public wf::signal::provider_t +class server_t { public: server_t(); void init(std::string socket_path); ~server_t(); - /** - * While a method call is being executed, this function may be called to determine the client which - * called it. - */ - client_t *get_current_request_client() - { - return current_client; - } - private: friend class client_t; wf::shared_data::ref_ptr_t method_repository; - // Valid only during a method call! - client_t *current_client = nullptr; void handle_incoming_message(client_t *client, nlohmann::json message); void client_disappeared(client_t *client); diff --git a/plugins/ipc/meson.build b/plugins/ipc/meson.build index c4f0501e8..a33f56b2c 100644 --- a/plugins/ipc/meson.build +++ b/plugins/ipc/meson.build @@ -23,4 +23,4 @@ demoipc = shared_module('demo-ipc', install: true, install_dir: conf_data.get('PLUGIN_PATH')) -install_headers(['ipc-method-repository.hpp', 'ipc.hpp', 'ipc-helpers.hpp', 'ipc-activator.hpp'], subdir: 'wayfire/plugins/ipc') +install_headers(['ipc-method-repository.hpp', 'ipc-helpers.hpp', 'ipc-activator.hpp'], subdir: 'wayfire/plugins/ipc') diff --git a/plugins/ipc/stipc.cpp b/plugins/ipc/stipc.cpp index e47b0dac4..2d54ebd34 100644 --- a/plugins/ipc/stipc.cpp +++ b/plugins/ipc/stipc.cpp @@ -2,21 +2,17 @@ #include "wayfire/plugin.hpp" #include "wayfire/plugins/common/shared-core-data.hpp" #include "wayfire/toplevel-view.hpp" -#include "wayfire/unstable/wlr-surface-node.hpp" #include "wayfire/util.hpp" -#include "wayfire/view-helpers.hpp" #include #include #include #include #include #include "src/view/view-impl.hpp" +#include #define WAYFIRE_PLUGIN #include - -#include "ipc.hpp" -#include "ipc-helpers.hpp" #include extern "C" { diff --git a/plugins/single_plugins/ipc-rules.cpp b/plugins/single_plugins/ipc-rules.cpp index 7001634cd..adf642c5b 100644 --- a/plugins/single_plugins/ipc-rules.cpp +++ b/plugins/single_plugins/ipc-rules.cpp @@ -8,10 +8,8 @@ #include #include "plugins/ipc/ipc-helpers.hpp" -#include "plugins/ipc/ipc.hpp" #include "plugins/ipc/ipc-method-repository.hpp" #include "wayfire/core.hpp" -#include "wayfire/object.hpp" #include "wayfire/plugins/common/util.hpp" #include "wayfire/unstable/wlr-surface-node.hpp" #include "wayfire/plugins/common/shared-core-data.hpp" @@ -20,7 +18,6 @@ #include "wayfire/view-helpers.hpp" #include "wayfire/window-manager.hpp" #include "wayfire/workarea.hpp" -#include "wayfire/workspace-set.hpp" #include "config.h" #include @@ -141,7 +138,7 @@ class ipc_rules_t : public wf::plugin_interface_t, public wf::per_output_tracker method_repository->register_method("window-rules/configure-view", configure_view); method_repository->register_method("window-rules/focus-view", focus_view); method_repository->register_method("window-rules/get-focused-view", get_focused_view); - ipc_server->connect(&on_client_disconnected); + method_repository->connect(&on_client_disconnected); wf::get_core().connect(&on_view_mapped); wf::get_core().connect(&on_kbfocus_changed); init_output_tracking(); @@ -346,14 +343,14 @@ class ipc_rules_t : public wf::plugin_interface_t, public wf::per_output_tracker private: wf::shared_data::ref_ptr_t method_repository; - wf::shared_data::ref_ptr_t ipc_server; // Track a list of clients which have requested watch - std::set clients; + std::set clients; - wf::ipc::method_callback on_client_watch = [=] (nlohmann::json data) + wf::ipc::method_callback_full on_client_watch = + [=] (nlohmann::json data, wf::ipc::client_interface_t *client) { - clients.insert(ipc_server->get_current_request_client()); + clients.insert(client); return wf::ipc::json_ok(); };