1 #include "bindings-repository.hpp"
2 #include <wayfire/core.hpp>
3 #include <algorithm>
4
handle_key(const wf::keybinding_t & pressed,uint32_t mod_binding_key)5 bool wf::bindings_repository_t::handle_key(const wf::keybinding_t& pressed,
6 uint32_t mod_binding_key)
7 {
8 std::vector<std::function<bool()>> callbacks;
9 for (auto& binding : this->keys)
10 {
11 if (binding->activated_by->get_value() == pressed)
12 {
13 /* We must be careful because the callback might be erased,
14 * so force copy the callback into the lambda */
15 auto callback = binding->callback;
16 callbacks.emplace_back([pressed, callback] ()
17 {
18 return (*callback)(pressed);
19 });
20 }
21 }
22
23 for (auto& binding : this->activators)
24 {
25 if (binding->activated_by->get_value().has_match(pressed))
26 {
27 /* We must be careful because the callback might be erased,
28 * so force copy the callback into the lambda */
29 auto callback = binding->callback;
30 callbacks.emplace_back([pressed, callback, mod_binding_key] ()
31 {
32 wf::activator_data_t ev = {
33 .source = activator_source_t::KEYBINDING,
34 .activation_data = pressed.get_key()
35 };
36
37 if (mod_binding_key)
38 {
39 ev.source = activator_source_t::MODIFIERBINDING;
40 ev.activation_data = mod_binding_key;
41 }
42
43 return (*callback)(ev);
44 });
45 }
46 }
47
48 bool handled = false;
49 for (auto& cb : callbacks)
50 {
51 handled |= cb();
52 }
53
54 return handled;
55 }
56
handle_axis(uint32_t modifiers,wlr_event_pointer_axis * ev)57 bool wf::bindings_repository_t::handle_axis(uint32_t modifiers,
58 wlr_event_pointer_axis *ev)
59 {
60 std::vector<wf::axis_callback*> callbacks;
61
62 for (auto& binding : this->axes)
63 {
64 if (binding->activated_by->get_value() == wf::keybinding_t{modifiers, 0})
65 {
66 callbacks.push_back(binding->callback);
67 }
68 }
69
70 for (auto call : callbacks)
71 {
72 (*call)(ev);
73 }
74
75 return !callbacks.empty();
76 }
77
handle_button(const wf::buttonbinding_t & pressed)78 bool wf::bindings_repository_t::handle_button(const wf::buttonbinding_t& pressed)
79 {
80 std::vector<std::function<bool()>> callbacks;
81 for (auto& binding : this->buttons)
82 {
83 if (binding->activated_by->get_value() == pressed)
84 {
85 /* We must be careful because the callback might be erased,
86 * so force copy the callback into the lambda */
87 auto callback = binding->callback;
88 callbacks.emplace_back([=] ()
89 {
90 return (*callback)(pressed);
91 });
92 }
93 }
94
95 for (auto& binding : this->activators)
96 {
97 if (binding->activated_by->get_value().has_match(pressed))
98 {
99 /* We must be careful because the callback might be erased,
100 * so force copy the callback into the lambda */
101 auto callback = binding->callback;
102 callbacks.emplace_back([=] ()
103 {
104 wf::activator_data_t data = {
105 .source = activator_source_t::BUTTONBINDING,
106 .activation_data = pressed.get_button(),
107 };
108 return (*callback)(data);
109 });
110 }
111 }
112
113 bool binding_handled = false;
114 for (auto call : callbacks)
115 {
116 binding_handled |= call();
117 }
118
119 return binding_handled;
120 }
121
handle_gesture(const wf::touchgesture_t & gesture)122 void wf::bindings_repository_t::handle_gesture(const wf::touchgesture_t& gesture)
123 {
124 std::vector<std::function<void()>> callbacks;
125 for (auto& binding : this->activators)
126 {
127 if (binding->activated_by->get_value().has_match(gesture))
128 {
129 /* We must be careful because the callback might be erased,
130 * so force copy the callback into the lambda */
131 auto callback = binding->callback;
132 callbacks.emplace_back([=] ()
133 {
134 wf::activator_data_t data = {
135 .source = activator_source_t::GESTURE,
136 .activation_data = 0
137 };
138 (*callback)(data);
139 });
140 }
141 }
142
143 for (auto& cb : callbacks)
144 {
145 cb();
146 }
147 }
148
handle_activator(const std::string & activator,const wf::activator_data_t & data)149 bool wf::bindings_repository_t::handle_activator(
150 const std::string& activator, const wf::activator_data_t& data)
151 {
152 auto opt = wf::get_core().config.get_option(activator);
153 for (auto& act : this->activators)
154 {
155 if (act->activated_by == opt)
156 {
157 return (*act->callback)(data);
158 }
159 }
160
161 return false;
162 }
163
rem_binding(void * callback)164 void wf::bindings_repository_t::rem_binding(void *callback)
165 {
166 const auto& erase = [callback] (auto& container)
167 {
168 auto it = std::remove_if(container.begin(), container.end(),
169 [callback] (const auto& ptr)
170 {
171 return ptr->callback == callback;
172 });
173 container.erase(it, container.end());
174 };
175
176 erase(keys);
177 erase(buttons);
178 erase(axes);
179 erase(activators);
180
181 recreate_hotspots();
182 }
183
rem_binding(binding_t * binding)184 void wf::bindings_repository_t::rem_binding(binding_t *binding)
185 {
186 const auto& erase = [binding] (auto& container)
187 {
188 auto it = std::remove_if(container.begin(), container.end(),
189 [binding] (const auto& ptr)
190 {
191 return ptr.get() == binding;
192 });
193 container.erase(it, container.end());
194 };
195
196 erase(keys);
197 erase(buttons);
198 erase(axes);
199 erase(activators);
200
201 recreate_hotspots();
202 }
203
bindings_repository_t(wf::output_t * output)204 wf::bindings_repository_t::bindings_repository_t(wf::output_t *output) :
205 hotspot_mgr(output)
206 {
207 on_config_reload.set_callback([=] (wf::signal_data_t*)
208 {
209 recreate_hotspots();
210 });
211
212 wf::get_core().connect_signal("reload-config", &on_config_reload);
213 }
214
recreate_hotspots()215 void wf::bindings_repository_t::recreate_hotspots()
216 {
217 this->idle_recreate_hotspots.run_once([=] ()
218 {
219 hotspot_mgr.update_hotspots(activators);
220 });
221 }
222