Skip to content

Commit d0033c9

Browse files
authored
Merge pull request #152 from horriblename/fix/send-cancel
Re-implement send_cancel
2 parents ebb3794 + 13cfe38 commit d0033c9

File tree

9 files changed

+138
-38
lines changed

9 files changed

+138
-38
lines changed

flake.lock

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

flake.nix

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
{
22
description = "Hyprland plugin for touch gestures";
33

4-
inputs.hyprland.url = "git+https://github.com/hyprwm/Hyprland?submodules=1";
4+
inputs.hyprland.url = "git+https://github.com/hyprwm/Hyprland?submodules=1&tag=v0.42.0";
55

66
outputs = {
77
self,
88
hyprland,
9-
}: let
9+
} @ inputs: let
1010
inherit (hyprland.inputs) nixpkgs;
1111
withPkgsFor = fn: nixpkgs.lib.genAttrs (builtins.attrNames hyprland.packages) (system: fn system nixpkgs.legacyPackages.${system});
1212
in {
@@ -16,6 +16,7 @@
1616
inherit (self.packages.${system}) wf-touch;
1717
};
1818
in {
19+
inherit inputs;
1920
default = hyprgrassPackage;
2021
hyprgrass = hyprgrassPackage;
2122
hyprgrassWithTests = hyprgrassPackage.override {runTests = true;};

src/GestureManager.cpp

Lines changed: 53 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@
1111
#include <hyprland/src/devices/ITouch.hpp>
1212
#include <hyprland/src/managers/KeybindManager.hpp>
1313
#include <hyprland/src/managers/LayoutManager.hpp>
14+
#include <hyprland/src/managers/SeatManager.hpp>
1415
#include <hyprland/src/managers/input/InputManager.hpp>
16+
#include <hyprland/src/protocols/core/Compositor.hpp>
17+
#include <hyprland/src/protocols/core/Seat.hpp>
1518
#undef private
1619

1720
#include <algorithm>
@@ -267,23 +270,12 @@ void GestureManager::sendCancelEventsToWindows() {
267270
return;
268271
}
269272

270-
for (const auto& surface : this->touchedSurfaces) {
271-
if (!surface)
272-
continue;
273-
274-
// Retrieve the client from the surface
275-
// wl_client* client = wl_resource_get_client(surface->resource);
276-
// if (!client)
277-
// continue;
278-
279-
// FIXME: couldn't find replacement for g_pCompositor->m_sSeat
280-
// wlr_seat_client* seat_client = wlr_seat_client_for_wl_client(g_pCompositor->m_sSeat.seat, client);
281-
//
282-
// if (seat_client) {
283-
// wlr_seat_touch_notify_cancel(g_pCompositor->m_sSeat.seat, seat_client);
284-
// }
273+
for (const auto& touch : this->touchedResources.all()) {
274+
const auto t = touch.lock();
275+
if (t.impl_) { // FIXME: idk how to check weak pointer validity
276+
t->sendCancel();
277+
}
285278
}
286-
this->touchedSurfaces.clear();
287279
}
288280

289281
// @return whether or not to inhibit further actions
@@ -295,23 +287,43 @@ bool GestureManager::onTouchDown(ITouch::SDownEvent ev) {
295287
// if (g_pCompositor->m_sSeat.exclusiveClient) // lock screen, I think
296288
// return false;
297289

298-
if (!eventForwardingInhibited() && **SEND_CANCEL && g_pInputManager->m_sTouchData.touchFocusSurface) {
299-
// remember which surfaces were touched, to later send cancel events
300-
const auto surface = g_pInputManager->m_sTouchData.touchFocusSurface;
301-
const auto TOUCHED = std::find(touchedSurfaces.begin(), touchedSurfaces.end(), surface);
302-
if (TOUCHED == touchedSurfaces.end()) {
303-
touchedSurfaces.push_back(surface);
304-
}
305-
}
306290
this->m_pLastTouchedMonitor =
307291
g_pCompositor->getMonitorFromName(!ev.device->boundOutput.empty() ? ev.device->boundOutput : "");
308292

309293
this->m_pLastTouchedMonitor =
310294
this->m_pLastTouchedMonitor ? this->m_pLastTouchedMonitor : g_pCompositor->m_pLastMonitor.get();
311295

312-
const auto& position = m_pLastTouchedMonitor->vecPosition;
313-
const auto& geometry = m_pLastTouchedMonitor->vecSize;
314-
this->m_sMonitorArea = {position.x, position.y, geometry.x, geometry.y};
296+
const auto& monitorPos = m_pLastTouchedMonitor->vecPosition;
297+
const auto& monitorSize = m_pLastTouchedMonitor->vecSize;
298+
this->m_sMonitorArea = {monitorPos.x, monitorPos.y, monitorSize.x, monitorSize.y};
299+
300+
g_pCompositor->warpCursorTo({
301+
monitorPos.x + ev.pos.x * monitorSize.x,
302+
monitorPos.y + ev.pos.y * monitorSize.y,
303+
});
304+
305+
g_pInputManager->refocus();
306+
307+
if (!eventForwardingInhibited() && **SEND_CANCEL && g_pInputManager->m_sTouchData.touchFocusSurface) {
308+
// remember which surfaces were touched, to later send cancel events
309+
const auto surface = g_pInputManager->m_sTouchData.touchFocusSurface;
310+
311+
if (this->m_sGestureState.fingers.size() == 0) {
312+
this->touchedResources.clear();
313+
}
314+
315+
wl_client* client = surface.get()->client();
316+
if (client) {
317+
SP<CWLSeatResource> seat = g_pSeatManager->seatResourceForClient(client);
318+
319+
if (seat) {
320+
auto touches = seat.get()->touches;
321+
for (const auto& touch : touches) {
322+
this->touchedResources.insert(touch);
323+
}
324+
}
325+
}
326+
}
315327

316328
// NOTE @wlr_touch_down_event.x and y uses a number between 0 and 1 to
317329
// represent "how many percent of screen" whereas
@@ -352,6 +364,20 @@ bool GestureManager::onTouchUp(ITouch::SUpEvent ev) {
352364

353365
const auto BLOCK = IGestureManager::onTouchUp(gesture_event);
354366
if (**SEND_CANCEL) {
367+
const auto surface = g_pInputManager->m_sTouchData.touchFocusSurface;
368+
369+
wl_client* client = surface.get()->client();
370+
if (client) {
371+
SP<CWLSeatResource> seat = g_pSeatManager->seatResourceForClient(client);
372+
373+
if (seat) {
374+
auto touches = seat.get()->touches;
375+
for (const auto& touch : touches) {
376+
this->touchedResources.remove(touch);
377+
}
378+
}
379+
}
380+
355381
return BLOCK;
356382
} else {
357383
// send_cancel is turned off; we need to rely on touchup events

src/GestureManager.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22
#include "./gestures/Gestures.hpp"
33
#include "HyprLogger.hpp"
4+
#include "VecSet.hpp"
45
#include "gestures/Shared.hpp"
56
#include <memory>
67

@@ -9,6 +10,7 @@
910
#include <hyprland/src/helpers/Monitor.hpp>
1011
#include <hyprland/src/includes.hpp>
1112
#include <hyprland/src/managers/KeybindManager.hpp>
13+
#include <hyprland/src/protocols/core/Seat.hpp>
1214
#undef private
1315

1416
#include <list>
@@ -46,7 +48,7 @@ class GestureManager : public IGestureManager {
4648
void handleCancelledGesture() override;
4749

4850
private:
49-
std::vector<CWeakPointer<CWLSurfaceResource>> touchedSurfaces;
51+
VecSet<CWeakPointer<CWLTouchResource>> touchedResources;
5052
CMonitor* m_pLastTouchedMonitor;
5153
SMonitorArea m_sMonitorArea;
5254
wl_event_source* long_press_timer;

src/HyprLogger.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44
class HyprLogger : public Logger {
55
public:
66
void debug(std::string s) {
7-
Debug::log(INFO, s);
7+
Debug::log(INFO, "[hyprgrass] {}", s);
88
}
99
};

src/VecSet.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#include "VecSet.hpp"
2+
3+
template <class T> bool VecSet<T>::has(const T x) {
4+
for (const auto& i : this->set) {
5+
if (i == x) {
6+
return true;
7+
}
8+
}
9+
10+
return false;
11+
}
12+
13+
template <class T> bool VecSet<T>::insert(const T x) {
14+
if (this->has(x)) {
15+
return true;
16+
}
17+
18+
this->set.push_back(x);
19+
return false;
20+
}
21+
22+
template <class T> bool VecSet<T>::remove(const T x) {
23+
for (int i = 0; i < this->set.size(); i++) {
24+
if (this->set[i] == x) {
25+
if (i != this->set.size() - 1) {
26+
this->set[i] = this->set.back();
27+
}
28+
29+
this->set.pop_back();
30+
return true;
31+
}
32+
}
33+
34+
return false;
35+
}
36+
37+
template <class T> void VecSet<T>::clear() {
38+
this->set.clear();
39+
}
40+
41+
template <class T> const std::vector<T>& VecSet<T>::all() const {
42+
return this->set;
43+
}

src/VecSet.hpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#include <vector>
2+
3+
#include <hyprland/src/helpers/memory/Memory.hpp>
4+
#include <hyprland/src/protocols/core/Seat.hpp>
5+
6+
// Probably not compatible with move semantics, I really don't know
7+
template <class T> class VecSet {
8+
public:
9+
bool has(const T x);
10+
11+
// returns whether or not it already exists prior to insert
12+
bool insert(const T x);
13+
14+
// returns whether or not x was found in the set
15+
bool remove(const T x);
16+
17+
void clear();
18+
19+
const std::vector<T>& all() const;
20+
21+
private:
22+
std::vector<T> set;
23+
};
24+
25+
// For some reason if I put this anywhere else the symbols don't get compiled in.
26+
// C++ is a beauty
27+
template class VecSet<Hyprutils::Memory::CWeakPointer<CWLTouchResource>>;

src/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
101101
HyprlandAPI::addConfigValue(PHANDLE, "plugin:touch_gestures:edge_margin",
102102
Hyprlang::CConfigValue((Hyprlang::INT)10));
103103
HyprlandAPI::addConfigValue(PHANDLE, "plugin:touch_gestures:experimental:send_cancel",
104-
Hyprlang::CConfigValue((Hyprlang::INT)0));
104+
Hyprlang::CConfigValue((Hyprlang::INT)1));
105105
#pragma GCC diagnostic pop
106106

107107
HyprlandAPI::addConfigKeyword(PHANDLE, "hyprgrass-bind", onNewBind, Hyprlang::SHandlerOptions{});

src/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ subdir('gestures')
33
shared_module('hyprgrass',
44
'main.cpp',
55
'GestureManager.cpp',
6+
'VecSet.cpp',
67
cpp_args: ['-DWLR_USE_UNSTABLE'],
78
link_with: [gestures],
89
dependencies: [

0 commit comments

Comments
 (0)