Skip to content

Commit

Permalink
Add pin-view plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
soreau committed Aug 13, 2024
1 parent f60d50b commit 248b9a5
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 0 deletions.
1 change: 1 addition & 0 deletions metadata/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ install_data('join-views.xml', install_dir: wayfire.get_variable(pkgconfig: 'met
install_data('keycolor.xml', install_dir: wayfire.get_variable(pkgconfig: 'metadatadir'))
install_data('mag.xml', install_dir: wayfire.get_variable(pkgconfig: 'metadatadir'))
install_data('obs.xml', install_dir: wayfire.get_variable(pkgconfig: 'metadatadir'))
install_data('pin-view.xml', install_dir: wayfire.get_variable(pkgconfig: 'metadatadir'))
install_data('showrepaint.xml', install_dir: wayfire.get_variable(pkgconfig: 'metadatadir'))
install_data('view-shot.xml', install_dir: wayfire.get_variable(pkgconfig: 'metadatadir'))
install_data('water.xml', install_dir: wayfire.get_variable(pkgconfig: 'metadatadir'))
Expand Down
8 changes: 8 additions & 0 deletions metadata/pin-view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0"?>
<wayfire>
<plugin name="pin-view">
<_short>Pin View</_short>
<_long>Set a view layer, role and workspace</_long>
<category>Window Management</category>
</plugin>
</wayfire>
3 changes: 3 additions & 0 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ if json.found()
obs = shared_module('obs', 'obs.cpp',
dependencies: [wayfire, json],
install: true, install_dir: join_paths(get_option('libdir'), 'wayfire'))
pin_view = shared_module('pin-view', 'pin-view.cpp',
dependencies: [wayfire, json],
install: true, install_dir: join_paths(get_option('libdir'), 'wayfire'))
endif

showrepaint = shared_module('showrepaint', 'showrepaint.cpp',
Expand Down
166 changes: 166 additions & 0 deletions src/pin-view.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2024 Scott Moreau <[email protected]>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

#include <wayfire/core.hpp>
#include <wayfire/view.hpp>
#include <wayfire/plugin.hpp>
#include <wayfire/output.hpp>
#include <wayfire/view-helpers.hpp>
#include <wayfire/util/duration.hpp>
#include <wayfire/render-manager.hpp>
#include <wayfire/view-transform.hpp>
#include <wayfire/scene-operations.hpp>
#include <wayfire/per-output-plugin.hpp>
#include <wayfire/signal-definitions.hpp>
#include <wayfire/plugins/ipc/ipc-helpers.hpp>
#include <wayfire/plugins/common/shared-core-data.hpp>
#include <wayfire/plugins/ipc/ipc-method-repository.hpp>
namespace wf
{
namespace pin_view
{
class pin_view_data : public wf::custom_data_t
{
public:
wf::scene::layer layer;
wf::view_role_t role;
};
class wayfire_pin_view : public wf::plugin_interface_t
{
wf::shared_data::ref_ptr_t<wf::ipc::method_repository_t> ipc_repo;

public:
void init() override
{
ipc_repo->register_method("pin-view/pin", ipc_pin_view);
ipc_repo->register_method("pin-view/unpin", ipc_unpin_view);
}

wf::ipc::method_callback ipc_pin_view = [=] (nlohmann::json data) -> nlohmann::json
{
WFJSON_EXPECT_FIELD(data, "view-id", number_unsigned);
WFJSON_EXPECT_FIELD(data, "layer", string);
/* workspace x,y */
WFJSON_OPTIONAL_FIELD(data, "x", number_unsigned);
WFJSON_OPTIONAL_FIELD(data, "y", number_unsigned);

auto view = wf::ipc::find_view_by_id(data["view-id"]);
if (view)
{
if (!view->get_data<pin_view_data>())
{
pin_view_data pv_data;
pv_data.layer = *wf::get_view_layer(view);
pv_data.role = view->role;
view->store_data(std::make_unique<pin_view_data>(pv_data));
}

auto output = view->get_output();
int x = 0, y = 0;
if (data.contains("x"))
{
x = data["x"].get<int>();
if (data.contains("y"))
{
y = data["y"].get<int>();
}

auto og = output->get_relative_geometry();
auto cws = output->wset()->get_current_workspace();
wf::point_t nws{x, y};
if (auto toplevel = toplevel_cast(view))
{
auto vg = toplevel->get_geometry();
toplevel->move(vg.x + (nws.x - cws.x) * og.width, vg.y + (nws.y - cws.y) * og.height);
}
} else
{
view->role = wf::VIEW_ROLE_DESKTOP_ENVIRONMENT;
}

wf::scene::layer layer;
if (data["layer"] == "background")
{
layer = wf::scene::layer::BACKGROUND;
} else if (data["layer"] == "bottom")
{
layer = wf::scene::layer::BOTTOM;
} else if (data["layer"] == "workspace")
{
layer = wf::scene::layer::WORKSPACE;
} else if (data["layer"] == "top")
{
layer = wf::scene::layer::TOP;
} else if (data["layer"] == "unmanaged")
{
layer = wf::scene::layer::UNMANAGED;
} else if (data["layer"] == "overlay")
{
layer = wf::scene::layer::OVERLAY;
} else if (data["layer"] == "lock")
{
layer = wf::scene::layer::LOCK;
} else
{
layer = wf::scene::layer::TOP;
}

wf::scene::readd_front(output->node_for_layer(layer), view->get_root_node());
} else
{
return wf::ipc::json_error("Failed to find view with given id. Maybe it was closed?");
}

return wf::ipc::json_ok();
};

wf::ipc::method_callback ipc_unpin_view = [=] (nlohmann::json data) -> nlohmann::json
{
WFJSON_EXPECT_FIELD(data, "view-id", number_unsigned);

auto view = wf::ipc::find_view_by_id(data["view-id"]);
if (view && view->get_data<pin_view_data>())
{
auto pvd = view->get_data<pin_view_data>();
view->role = pvd->role;
wf::scene::readd_front(view->get_output()->node_for_layer(pvd->layer), view->get_root_node());
} else
{
LOGE("Failed to find view with given id. Perhaps it is not pinned.");
return wf::ipc::json_error("Failed to find view with given id. Perhaps it is not pinned.");
}

return wf::ipc::json_ok();
};

void fini() override
{
ipc_repo->unregister_method("pin-view/pin");
ipc_repo->unregister_method("pin-view/unpin");
}
};
}
}

DECLARE_WAYFIRE_PLUGIN(wf::pin_view::wayfire_pin_view);

0 comments on commit 248b9a5

Please sign in to comment.