From 9f15d609a1388db780f1c355ecaf7a998bd35a43 Mon Sep 17 00:00:00 2001 From: Ilia Bozhinov Date: Tue, 26 Mar 2024 07:57:47 +0200 Subject: [PATCH] view-shot: add ipc support (#235) --- src/view-shot.cpp | 65 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 49 insertions(+), 16 deletions(-) diff --git a/src/view-shot.cpp b/src/view-shot.cpp index f9ea13b..208142c 100644 --- a/src/view-shot.cpp +++ b/src/view-shot.cpp @@ -23,12 +23,15 @@ */ #include +#include +#include #include #include #include #include #include -#include +#include +#include #include @@ -50,17 +53,19 @@ static std::string replaceAll(std::string s, const std::string& from, return s; } -class wayfire_view_shot : public wf::per_output_plugin_instance_t +class wayfire_view_shot : public wf::plugin_interface_t { const std::string transformer_name = "view_shot"; wf::option_wrapper_t capture_binding{"view-shot/capture"}; wf::option_wrapper_t file_name{"view-shot/filename"}; wf::option_wrapper_t command{"view-shot/command"}; + wf::shared_data::ref_ptr_t ipc_repo; public: void init() override { - output->add_activator(capture_binding, &on_capture); + wf::get_core().bindings->add_activator(capture_binding, &on_capture); + ipc_repo->register_method("view-shot/capture", on_ipc_capture); } wf::activator_callback on_capture = [=] (auto) @@ -72,6 +77,42 @@ class wayfire_view_shot : public wf::per_output_plugin_instance_t return false; } + char _file_name[255]; + auto time = std::time(nullptr); + std::strftime(_file_name, sizeof(_file_name), + file_name.value().c_str(), std::localtime(&time)); + std::string formatted_file_name = _file_name; + + if (take_snapshot(view, formatted_file_name)) + { + wf::get_core().run(replaceAll(command, "%f", formatted_file_name)); + return true; + } + + return false; + }; + + wf::ipc::method_callback on_ipc_capture = [=] (nlohmann::json data) + { + WFJSON_EXPECT_FIELD(data, "view-id", number_unsigned); + WFJSON_EXPECT_FIELD(data, "file", string); + + auto view = wf::ipc::find_view_by_id(data["view-id"]); + if (!view) + { + return wf::ipc::json_error("No such view found!"); + } + + if (take_snapshot(view, data["file"])) + { + return wf::ipc::json_ok(); + } + + return wf::ipc::json_error("Failed to capture view."); + }; + + bool take_snapshot(wayfire_view view, std::string filename) + { wf::render_target_t offscreen_buffer; view->take_snapshot(offscreen_buffer); auto width = offscreen_buffer.viewport_width; @@ -91,24 +132,16 @@ class wayfire_view_shot : public wf::per_output_plugin_instance_t offscreen_buffer.release(); // free gpu memory OpenGL::render_end(); - char _file_name[255]; - auto time = std::time(nullptr); - std::strftime(_file_name, sizeof(_file_name), - file_name.value().c_str(), std::localtime(&time)); - std::string formatted_file_name = _file_name; - - image_io::write_to_file(formatted_file_name, pixels, width, height, "png", true); + image_io::write_to_file(filename, pixels, width, height, "png", true); free(pixels); - - wf::get_core().run(replaceAll(command, "%f", formatted_file_name)); - return true; - }; + } void fini() override { - output->rem_binding(&on_capture); + wf::get_core().bindings->rem_binding(&on_capture); + ipc_repo->unregister_method("view-shot/capture"); } }; -DECLARE_WAYFIRE_PLUGIN(wf::per_output_plugin_t); +DECLARE_WAYFIRE_PLUGIN(wayfire_view_shot);