Skip to content

Commit e127a22

Browse files
committed
refactor: implement gesture action interface for modular gesture handling
* Create IGestureAction interface with execute/canExecute/actionName methods * Add EdgeGestureAction and CornerGestureAction base classes for common patterns * Implement concrete action classes for all gesture types: - LeftEdgeGestureAction, RightEdgeGestureAction - TopEdgeGestureAction, BottomEdgeGestureAction - BottomCornerGestureAction * Integrate action objects into CwlGestureManager with proper memory management * Extract all gesture logic from direct implementation to action delegation * Add comprehensive documentation and Qt object hierarchy support This establishes the foundation for gesture-to-action mapping and runtime configuration while achieving loose coupling between gesture detection and action execution as specified in the refactoring plan.
1 parent b8eddd3 commit e127a22

5 files changed

Lines changed: 608 additions & 167 deletions

File tree

src/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ set(CWL_SOURCES
1010
glwindow.cpp
1111
gesture.cpp
1212
gesture-manager.cpp
13+
gesture-action.cpp
1314
process-manager.cpp)
1415

1516
set(CWL_HEADERS
@@ -19,6 +20,7 @@ set(CWL_HEADERS
1920
glwindow.h
2021
gesture.h
2122
gesture-manager.h
23+
gesture-action.h
2224
process-manager.h)
2325

2426
set(QML_RESOURCES)

src/gesture-action.cpp

Lines changed: 307 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,307 @@
1+
#include "gesture-action.h"
2+
#include "cutie-wlc.h"
3+
#include "glwindow.h"
4+
#include "gesture.h"
5+
#include "extensions/input-method-v2.h"
6+
7+
// LeftEdgeGestureAction implementation
8+
LeftEdgeGestureAction::LeftEdgeGestureAction(QObject *parent)
9+
: EdgeGestureAction(parent)
10+
{
11+
}
12+
13+
bool LeftEdgeGestureAction::canExecute(CwlCompositor *compositor) const
14+
{
15+
return (compositor->launcherPosition() == 0.0) &&
16+
(compositor->blur() != 0.0);
17+
}
18+
19+
QString LeftEdgeGestureAction::actionName() const
20+
{
21+
return "LeftEdgeGesture";
22+
}
23+
24+
bool LeftEdgeGestureAction::handleBegin(QPointerEvent *ev,
25+
CwlCompositor *compositor)
26+
{
27+
return canExecute(compositor);
28+
}
29+
30+
bool LeftEdgeGestureAction::handleUpdate(QPointerEvent *ev,
31+
CwlCompositor *compositor)
32+
{
33+
if ((ev->points().first().globalPosition() -
34+
compositor->glWindow()->gesture()->startingPoint())
35+
.x() > GESTURE_MINIMUM_THRESHOLD) {
36+
compositor->glWindow()->gesture()->confirmGesture();
37+
}
38+
compositor->setBlur(1.0 -
39+
1.0 * ev->points().first().globalPosition().x() /
40+
compositor->glWindow()->width());
41+
return true;
42+
}
43+
44+
bool LeftEdgeGestureAction::handleEnd(QPointerEvent *ev,
45+
CwlCompositor *compositor)
46+
{
47+
if (ev->points().first().globalPosition().x() >
48+
GESTURE_ACCEPT_THRESHOLD) {
49+
compositor->raise(compositor->getHomeView());
50+
return true;
51+
}
52+
compositor->startBlurAnimation();
53+
compositor->setHomeOpen(false);
54+
return true;
55+
}
56+
57+
// RightEdgeGestureAction implementation
58+
RightEdgeGestureAction::RightEdgeGestureAction(QObject *parent)
59+
: EdgeGestureAction(parent)
60+
{
61+
}
62+
63+
bool RightEdgeGestureAction::canExecute(CwlCompositor *compositor) const
64+
{
65+
return (compositor->launcherPosition() == 0.0) &&
66+
(compositor->blur() != 0.0);
67+
}
68+
69+
QString RightEdgeGestureAction::actionName() const
70+
{
71+
return "RightEdgeGesture";
72+
}
73+
74+
bool RightEdgeGestureAction::handleBegin(QPointerEvent *ev,
75+
CwlCompositor *compositor)
76+
{
77+
return canExecute(compositor);
78+
}
79+
80+
bool RightEdgeGestureAction::handleUpdate(QPointerEvent *ev,
81+
CwlCompositor *compositor)
82+
{
83+
if ((-ev->points().first().globalPosition() +
84+
compositor->glWindow()->gesture()->startingPoint())
85+
.x() > GESTURE_MINIMUM_THRESHOLD) {
86+
compositor->glWindow()->gesture()->confirmGesture();
87+
}
88+
compositor->setBlur(1.0 * ev->points().first().globalPosition().x() /
89+
compositor->glWindow()->width());
90+
return true;
91+
}
92+
93+
bool RightEdgeGestureAction::handleEnd(QPointerEvent *ev,
94+
CwlCompositor *compositor)
95+
{
96+
if (ev->points().first().globalPosition().x() <
97+
compositor->glWindow()->width() - GESTURE_ACCEPT_THRESHOLD) {
98+
compositor->raise(compositor->getHomeView());
99+
return true;
100+
}
101+
compositor->startBlurAnimation();
102+
compositor->setHomeOpen(false);
103+
return true;
104+
}
105+
106+
// TopEdgeGestureAction implementation
107+
TopEdgeGestureAction::TopEdgeGestureAction(QObject *parent)
108+
: EdgeGestureAction(parent)
109+
{
110+
}
111+
112+
bool TopEdgeGestureAction::canExecute(CwlCompositor *compositor) const
113+
{
114+
return compositor->launcherPosition() > 0.0;
115+
}
116+
117+
QString TopEdgeGestureAction::actionName() const
118+
{
119+
return "TopEdgeGesture";
120+
}
121+
122+
bool TopEdgeGestureAction::handleBegin(QPointerEvent *ev,
123+
CwlCompositor *compositor)
124+
{
125+
return canExecute(compositor);
126+
}
127+
128+
bool TopEdgeGestureAction::handleUpdate(QPointerEvent *ev,
129+
CwlCompositor *compositor)
130+
{
131+
if ((ev->points().first().globalPosition() -
132+
compositor->glWindow()->gesture()->startingPoint())
133+
.y() > GESTURE_MINIMUM_THRESHOLD) {
134+
compositor->glWindow()->gesture()->confirmGesture();
135+
}
136+
compositor->setLauncherPosition(qMin(
137+
1.0, 1.0 - (ev->points().first().globalPosition().y() /
138+
compositor->scaleFactor() -
139+
compositor->m_workspace->outputGeometry().y()) /
140+
compositor->m_workspace->outputGeometry()
141+
.height()));
142+
return true;
143+
}
144+
145+
bool TopEdgeGestureAction::handleEnd(QPointerEvent *ev,
146+
CwlCompositor *compositor)
147+
{
148+
if (ev->points().first().globalPosition().y() <
149+
compositor->glWindow()->height() * 0.2) {
150+
compositor->startLauncherOpenAnimation();
151+
} else {
152+
compositor->startLauncherCloseAnimation();
153+
}
154+
return true;
155+
}
156+
157+
// BottomEdgeGestureAction implementation
158+
BottomEdgeGestureAction::BottomEdgeGestureAction(QObject *parent)
159+
: EdgeGestureAction(parent)
160+
{
161+
}
162+
163+
bool BottomEdgeGestureAction::canExecute(CwlCompositor *compositor) const
164+
{
165+
// Check panel state
166+
if (compositor->getPanelView() != nullptr &&
167+
compositor->getPanelView()->panelState > 1) {
168+
return false;
169+
}
170+
171+
// Check input method state
172+
if (compositor->getInputMethodManager()->getInputMethod() != nullptr &&
173+
!compositor->getInputMethodManager()
174+
->getInputMethod()
175+
->isPanelHidden()) {
176+
return false;
177+
}
178+
179+
return true;
180+
}
181+
182+
QString BottomEdgeGestureAction::actionName() const
183+
{
184+
return "BottomEdgeGesture";
185+
}
186+
187+
bool BottomEdgeGestureAction::handleBegin(QPointerEvent *ev,
188+
CwlCompositor *compositor)
189+
{
190+
return canExecute(compositor);
191+
}
192+
193+
bool BottomEdgeGestureAction::handleUpdate(QPointerEvent *ev,
194+
CwlCompositor *compositor)
195+
{
196+
if (!canExecute(compositor)) {
197+
return false;
198+
}
199+
200+
if ((-ev->points().first().globalPosition() +
201+
compositor->glWindow()->gesture()->startingPoint())
202+
.y() > GESTURE_MINIMUM_THRESHOLD) {
203+
compositor->glWindow()->gesture()->confirmGesture();
204+
compositor->setLauncherPosition(qMin(
205+
1.0,
206+
1.0 - (ev->points().first().globalPosition().y() /
207+
compositor->scaleFactor() -
208+
compositor->m_workspace->outputGeometry().y()) /
209+
compositor->m_workspace
210+
->outputGeometry()
211+
.height()));
212+
}
213+
return true;
214+
}
215+
216+
bool BottomEdgeGestureAction::handleEnd(QPointerEvent *ev,
217+
CwlCompositor *compositor)
218+
{
219+
if (compositor->getPanelView() != nullptr &&
220+
compositor->getPanelView()->panelState > 1) {
221+
return false;
222+
}
223+
224+
if (ev->points().first().globalPosition().y() <
225+
compositor->glWindow()->height() * 0.8) {
226+
compositor->startLauncherOpenAnimation();
227+
} else {
228+
compositor->startLauncherCloseAnimation();
229+
}
230+
return true;
231+
}
232+
233+
// BottomCornerGestureAction implementation
234+
BottomCornerGestureAction::BottomCornerGestureAction(int corner,
235+
QObject *parent)
236+
: CornerGestureAction(corner, parent)
237+
{
238+
}
239+
240+
bool BottomCornerGestureAction::canExecute(CwlCompositor *compositor) const
241+
{
242+
// Only handle bottom corners
243+
if (m_corner != CORNER_BR && m_corner != CORNER_BL) {
244+
return false;
245+
}
246+
247+
// Check launcher position
248+
if (compositor->launcherPosition() > 0.0) {
249+
return false;
250+
}
251+
252+
// Check panel state
253+
if (compositor->getPanelView() != nullptr &&
254+
compositor->getPanelView()->panelState > 1) {
255+
return false;
256+
}
257+
258+
return true;
259+
}
260+
261+
QString BottomCornerGestureAction::actionName() const
262+
{
263+
return QString("BottomCornerGesture_%1")
264+
.arg(m_corner == CORNER_BR ? "BR" : "BL");
265+
}
266+
267+
bool BottomCornerGestureAction::handleBeginUpdate(QPointerEvent *ev,
268+
CwlCompositor *compositor)
269+
{
270+
if (!canExecute(compositor)) {
271+
return false;
272+
}
273+
274+
// Check input method state during begin/update
275+
if (compositor->getInputMethodManager()->getInputMethod() != nullptr &&
276+
!compositor->getInputMethodManager()
277+
->getInputMethod()
278+
->isPanelHidden()) {
279+
return false;
280+
}
281+
282+
if ((-ev->points().first().globalPosition() +
283+
compositor->glWindow()->gesture()->startingPoint())
284+
.y() > GESTURE_MINIMUM_THRESHOLD) {
285+
compositor->glWindow()->gesture()->confirmGesture();
286+
}
287+
return true;
288+
}
289+
290+
bool BottomCornerGestureAction::handleEnd(QPointerEvent *ev,
291+
CwlCompositor *compositor)
292+
{
293+
if (compositor->getPanelView() != nullptr &&
294+
compositor->getPanelView()->panelState > 1) {
295+
return false;
296+
}
297+
298+
if (ev->points().first().globalPosition().y() <
299+
compositor->glWindow()->height() * 0.8) {
300+
compositor->getInputMethodManager()
301+
->getInputMethod()
302+
->showPanel();
303+
return true;
304+
}
305+
306+
return false;
307+
}

0 commit comments

Comments
 (0)