1 #ifndef SEAT_HPP
2 #define SEAT_HPP
3 
4 #include <wayfire/signal-definitions.hpp>
5 #include <wayfire/nonstd/wlroots-full.hpp>
6 
7 #include "../../view/surface-impl.hpp"
8 #include "wayfire/output.hpp"
9 #include "wayfire/input-device.hpp"
10 
11 namespace wf
12 {
13 struct cursor_t;
14 class keyboard_t;
15 
16 struct drag_icon_t : public wlr_child_surface_base_t
17 {
18     wlr_drag_icon *icon;
19     wl_listener_wrapper on_map, on_unmap, on_destroy;
20 
21     drag_icon_t(wlr_drag_icon *icon);
22     point_t get_offset() override;
23 
24     /** Called each time the DnD icon position changes. */
25     void damage();
26     void damage_surface_box(const wlr_box& rect) override;
27 
28     /* Force map without receiving a wlroots event */
force_mapwf::drag_icon_t29     void force_map()
30     {
31         this->map(icon->surface);
32     }
33 
34   private:
35     /** Last icon box. */
36     wf::geometry_t last_box = {0, 0, 0, 0};
37 
38     /** Damage surface box in global coordinates. */
39     void damage_surface_box_global(const wlr_box& rect);
40 };
41 
42 class input_device_impl_t : public wf::input_device_t
43 {
44   public:
45     input_device_impl_t(wlr_input_device *dev);
46     virtual ~input_device_impl_t() = default;
47 
48     wf::wl_listener_wrapper on_destroy;
update_options()49     virtual void update_options()
50     {}
51 };
52 
53 class pointer_t;
54 class touch_interface_t;
55 
56 /**
57  * A seat is a collection of input devices which work together, and have a
58  * keyboard focus, etc.
59  *
60  * The seat is the place where a bit of the shared state of separate input devices
61  * resides, and also contains:
62  *
63  * 1. Keyboards
64  * 2. Logical pointer
65  * 3. Touch interface
66  * 4. Tablets
67  *
68  * In addition, each seat has its own clipboard, primary selection and DnD state.
69  * Currently, Wayfire supports just a single seat.
70  */
71 class seat_t
72 {
73   public:
74     seat_t();
75 
76     uint32_t get_modifiers();
77 
78     void break_mod_bindings();
79 
80     void set_keyboard_focus(wayfire_view view);
81     wayfire_view keyboard_focus;
82 
83     /**
84      * Set the currently active keyboard on the seat.
85      */
86     void set_keyboard(wf::keyboard_t *kbd);
87 
88     wlr_seat *seat = nullptr;
89     std::unique_ptr<cursor_t> cursor;
90     std::unique_ptr<pointer_t> lpointer;
91     std::unique_ptr<touch_interface_t> touch;
92 
93     // Current drag icon
94     std::unique_ptr<wf::drag_icon_t> drag_icon;
95     // Is dragging active. Note we can have a drag without a drag icon.
96     bool drag_active = false;
97 
98     /** Update the position of the drag icon, if it exists */
99     void update_drag_icon();
100 
101     /**
102      * Make sure that the surface can receive input focus.
103      * If it is a xwayland surface, it will be restacked to the top.
104      */
105     void ensure_input_surface(wf::surface_interface_t *surface);
106 
107   private:
108     wf::wl_listener_wrapper request_start_drag, start_drag, end_drag,
109         request_set_selection, request_set_primary_selection;
110 
111     wf::signal_connection_t on_new_device, on_remove_device;
112 
113     /** The currently active keyboard device on the seat */
114     wf::keyboard_t *current_keyboard = nullptr;
115 
116     /** A list of all keyboards in this seat */
117     std::vector<std::unique_ptr<wf::keyboard_t>> keyboards;
118 
119     /**
120      * Check if the drag request is valid, and if yes, start the drag operation.
121      */
122     void validate_drag_request(wlr_seat_request_start_drag_event *ev);
123 
124     /** Send updated capabilities to clients */
125     void update_capabilities();
126 
127     // The surface which has last received input focus
128     wlr_surface *last_focus_surface = NULL;
129 };
130 }
131 
132 /** Convert the given point to a surface-local point */
133 wf::pointf_t get_surface_relative_coords(wf::surface_interface_t *surface,
134     const wf::pointf_t& point);
135 
136 #endif /* end of include guard: SEAT_HPP */
137