1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
|
#include <wayfire/per-output-plugin.hpp>
#include <wayfire/core.hpp>
#include <wayfire/touch/touch.hpp>
#include <wayfire/view.hpp>
#include <wayfire/option-wrapper.hpp>
#include <wayfire/output-layout.hpp>
#include <wayfire/output.hpp>
#include <wayfire/toplevel-view.hpp>
#include <wayfire/window-manager.hpp>
#include <wayfire/util/log.hpp>
namespace wf
{
using namespace touch;
class extra_gestures_plugin_t : public per_output_plugin_instance_t
{
gesture_t touch_and_hold_move;
gesture_t tap_to_close;
wf::option_wrapper_t<int> move_fingers{"extra-gestures/move_fingers"};
wf::option_wrapper_t<int> move_delay{"extra-gestures/move_delay"};
wf::option_wrapper_t<int> close_fingers{"extra-gestures/close_fingers"};
wf::plugin_activation_data_t grab_interface = {
.capabilities = CAPABILITY_MANAGE_COMPOSITOR,
};
public:
void init() override
{
build_touch_and_hold_move();
move_fingers.set_callback([=] () { build_touch_and_hold_move(); });
move_delay.set_callback([=] () { build_touch_and_hold_move(); });
build_tap_to_close();
close_fingers.set_callback([=] () { build_tap_to_close(); });
}
/**
* Run an action on the view under the touch points, if the touch points
* are on the current output and the view is toplevel.
*/
void execute_view_action(std::function<void(wayfire_view)> action)
{
auto& core = wf::get_core();
auto state = core.get_touch_state();
auto center_touch_point = state.get_center().current;
wf::pointf_t center = {center_touch_point.x, center_touch_point.y};
if (core.output_layout->get_output_at(center.x, center.y) != this->output)
{
return;
}
/** Make sure we don't interfere with already activated plugins */
if (!output->can_activate_plugin(&this->grab_interface))
{
return;
}
auto view = core.get_view_at({center.x, center.y});
if (view && (view->role == VIEW_ROLE_TOPLEVEL))
{
action(view);
}
}
void build_touch_and_hold_move()
{
wf::get_core().rem_touch_gesture(&touch_and_hold_move);
touch_and_hold_move = wf::touch::gesture_builder_t()
.action(touch_action_t(move_fingers, true)
.set_move_tolerance(50)
.set_duration(100))
.action(hold_action_t(move_delay)
.set_move_tolerance(100))
.on_completed([=] ()
{
execute_view_action([] (wayfire_view view)
{
if (auto toplevel = wf::toplevel_cast(view))
{
wf::get_core().default_wm->move_request(toplevel);
}
});
}).build();
wf::get_core().add_touch_gesture(&touch_and_hold_move);
}
void build_tap_to_close()
{
wf::get_core().rem_touch_gesture(&tap_to_close);
tap_to_close = wf::touch::gesture_builder_t()
.action(touch_action_t(close_fingers, true)
.set_move_tolerance(50)
.set_duration(150))
.action(touch_action_t(close_fingers, false)
.set_move_tolerance(50)
.set_duration(150))
.on_completed([=] () { execute_view_action([] (wayfire_view view) { view->close(); }); })
.build();
wf::get_core().add_touch_gesture(&tap_to_close);
}
void fini() override
{
wf::get_core().rem_touch_gesture(&touch_and_hold_move);
wf::get_core().rem_touch_gesture(&tap_to_close);
}
};
}
DECLARE_WAYFIRE_PLUGIN(wf::per_output_plugin_t<wf::extra_gestures_plugin_t>);
|