File: extra-gestures.cpp

package info (click to toggle)
wayfire 0.10.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,764 kB
  • sloc: cpp: 52,464; xml: 2,987; ansic: 699; makefile: 161
file content (118 lines) | stat: -rw-r--r-- 3,724 bytes parent folder | download | duplicates (2)
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>);