diff --git a/metadata/ghost.xml b/metadata/ghost.xml new file mode 100644 index 0000000..0f043af --- /dev/null +++ b/metadata/ghost.xml @@ -0,0 +1,17 @@ + + + + <_short>Ghost Windows + Window Management + + + + diff --git a/metadata/meson.build b/metadata/meson.build index 081949b..17bea4b 100644 --- a/metadata/meson.build +++ b/metadata/meson.build @@ -7,6 +7,7 @@ install_data('focus-change.xml', install_dir: wayfire.get_variable(pkgconfig: 'm install_data('focus-steal-prevent.xml', install_dir: wayfire.get_variable(pkgconfig: 'metadatadir')) install_data('follow-focus.xml', install_dir: wayfire.get_variable(pkgconfig: 'metadatadir')) install_data('force-fullscreen.xml', install_dir: wayfire.get_variable(pkgconfig: 'metadatadir')) +install_data('ghost.xml', install_dir: wayfire.get_variable(pkgconfig: 'metadatadir')) install_data('hide-cursor.xml', install_dir: wayfire.get_variable(pkgconfig: 'metadatadir')) install_data('join-views.xml', install_dir: wayfire.get_variable(pkgconfig: 'metadatadir')) install_data('keycolor.xml', install_dir: wayfire.get_variable(pkgconfig: 'metadatadir')) diff --git a/src/ghost.cpp b/src/ghost.cpp new file mode 100644 index 0000000..82b185d --- /dev/null +++ b/src/ghost.cpp @@ -0,0 +1,117 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const std::string shade_transformer_name = "ghost_transformer"; + +namespace wf +{ +namespace ghost +{ +using namespace wf::scene; +class ghost_view : public wf::scene::view_2d_transformer_t +{ + wayfire_view view; + + public: + + ghost_view(wayfire_view view) : wf::scene::view_2d_transformer_t(view) + { + this->view = view; + } + + std::optional find_node_at(const wf::pointf_t& at) override + { + return {}; + } + + virtual ~ghost_view() + {} +}; + +class ghost_plugin : public wf::plugin_interface_t +{ + wf::ipc_activator_t ghost_window{"ghost/ghost_window"}; + wf::view_matcher_t ghost_match{"ghost/ghost_match"}; + + void pop_transformer(wayfire_view view) + { + if (view->get_transformed_node()->get_transformer(shade_transformer_name)) + { + view->get_transformed_node()->rem_transformer(shade_transformer_name); + } + } + + void remove_shade_transformers() + { + for (auto& view : wf::get_core().get_all_views()) + { + pop_transformer(view); + } + } + + std::shared_ptr ensure_transformer(wayfire_view view) + { + auto tmgr = view->get_transformed_node(); + if (auto tr = tmgr->get_transformer(shade_transformer_name)) + { + return tr; + } + + auto node = std::make_shared(view); + tmgr->add_transformer(node, wf::TRANSFORMER_2D, shade_transformer_name); + auto tr = tmgr->get_transformer(shade_transformer_name); + + return tr; + } + + public: + + void init() override + { + for (auto& view : wf::get_core().get_all_views()) + { + if (ghost_match.matches(view)) + { + ensure_transformer(view); + } + } + + ghost_window.set_handler(ghost_view_cb); + wf::get_core().connect(&on_view_map); + } + + wf::ipc_activator_t::handler_t ghost_view_cb = [=] (wf::output_t *output, wayfire_view view) + { + ensure_transformer(view); + return true; + }; + + wf::signal::connection_t on_view_map = [=] (wf::view_mapped_signal *ev) + { + if (ghost_match.matches(ev->view)) + { + ensure_transformer(ev->view); + } + }; + + void fini() override + { + remove_shade_transformers(); + on_view_map.disconnect(); + } +}; +} +} + +DECLARE_WAYFIRE_PLUGIN(wf::ghost::ghost_plugin); diff --git a/src/meson.build b/src/meson.build index 952b678..e02c334 100644 --- a/src/meson.build +++ b/src/meson.build @@ -36,6 +36,10 @@ force_fullscreen = shared_module('force-fullscreen', 'force-fullscreen.cpp', dependencies: [wayfire], install: true, install_dir: join_paths(get_option('libdir'), 'wayfire')) +ghost = shared_module('ghost', 'ghost.cpp', + dependencies: [wayfire], + install: true, install_dir: join_paths(get_option('libdir'), 'wayfire')) + if giomm.found() glib_main_loop = shared_module('glib-main-loop', 'glib-main-loop.cpp', dependencies: [wayfire, giomm],