Skip to content

Commit

Permalink
Lots of fixes make it work better
Browse files Browse the repository at this point in the history
  • Loading branch information
soreau committed Aug 14, 2024
1 parent f1d3972 commit 60172c0
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 27 deletions.
2 changes: 1 addition & 1 deletion src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ 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],
dependencies: [wayfire, json, wf_protos],
install: true, install_dir: join_paths(get_option('libdir'), 'wayfire'))
endif

Expand Down
117 changes: 91 additions & 26 deletions src/pin-view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,21 @@
#include <wayfire/per-output-plugin.hpp>
#include <wayfire/signal-definitions.hpp>
#include <wayfire/plugins/ipc/ipc-helpers.hpp>
#include <wayfire/unstable/translation-node.hpp>
#include <wayfire/unstable/xdg-toplevel-base.hpp>
#include <wayfire/plugins/common/shared-core-data.hpp>
#include <wayfire/plugins/ipc/ipc-method-repository.hpp>
#include <wayfire/unstable/wlr-view-keyboard-interaction.hpp>

namespace wf
{
namespace pin_view
{
class pin_view_data : public wf::custom_data_t
{
public:
wf::scene::layer layer;
wf::geometry_t geometry;
wf::point_t workspace;
wf::view_role_t role;
};
class wayfire_pin_view : public wf::plugin_interface_t
Expand All @@ -68,35 +73,19 @@ class wayfire_pin_view : public wf::plugin_interface_t
auto view = wf::ipc::find_view_by_id(data["view-id"]);
if (view)
{
auto output = view->get_output();
output->connect(&on_workspace_changed);
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};
pv_data.role = view->role;
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);
pv_data.workspace = output->wset()->get_view_main_workspace(toplevel);
pv_data.geometry = toplevel->get_geometry();
}
} else
{
view->role = wf::VIEW_ROLE_DESKTOP_ENVIRONMENT;

view->store_data(std::make_unique<pin_view_data>(pv_data));
}

wf::scene::layer layer;
Expand Down Expand Up @@ -126,10 +115,43 @@ class wayfire_pin_view : public wf::plugin_interface_t
layer = wf::scene::layer::TOP;
}

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

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

view->role = wf::VIEW_ROLE_DESKTOP_ENVIRONMENT;
wf::scene::readd_front(view->get_output()->node_for_layer(layer), view->get_root_node());
return wf::ipc::json_ok();
}

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_error("Failed to find view with given id.");
}

return wf::ipc::json_ok();
Expand All @@ -144,7 +166,19 @@ class wayfire_pin_view : public wf::plugin_interface_t
{
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());
wf::scene::readd_front(view->get_output()->wset()->get_node(), view->get_root_node());
if (auto toplevel = toplevel_cast(view))
{
auto output = view->get_output();
auto og = output->get_relative_geometry();
auto cws = output->wset()->get_view_main_workspace(toplevel);
auto vg = toplevel->get_geometry();
toplevel->move(vg.x + (pvd->workspace.x - cws.x) * og.width,
vg.y + (pvd->workspace.y - cws.y) * og.height);
toplevel->set_geometry(pvd->geometry);
}

view->release_data<pin_view_data>();
} else
{
LOGE("Failed to find view with given id. Perhaps it is not pinned.");
Expand All @@ -154,10 +188,41 @@ class wayfire_pin_view : public wf::plugin_interface_t
return wf::ipc::json_ok();
};

wf::signal::connection_t<wf::workspace_changed_signal> on_workspace_changed =
[=] (wf::workspace_changed_signal *ev)
{
auto nws = ev->new_viewport;
auto output = ev->output;
auto og = output->get_relative_geometry();
for (auto & view : wf::get_core().get_all_views())
{
if (!view->get_data<pin_view_data>())
{
continue;
}

if (auto toplevel = toplevel_cast(view))
{
auto cws = output->wset()->get_view_main_workspace(toplevel);
auto vg = toplevel->get_geometry();
toplevel->move(vg.x + (nws.x - cws.x) * og.width, vg.y + (nws.y - cws.y) * og.height);
}
}
};

void fini() override
{
for (auto & view : wf::get_core().get_all_views())
{
if (view->get_data<pin_view_data>())
{
view->release_data<pin_view_data>();
}
}

ipc_repo->unregister_method("pin-view/pin");
ipc_repo->unregister_method("pin-view/unpin");
on_workspace_changed.disconnect();
}
};
}
Expand Down

0 comments on commit 60172c0

Please sign in to comment.