Skip to content

Commit 5e6cec9

Browse files
authored
cursor: refactor override handling (#12166)
much cleaner and more reliable. Should fix #12088
1 parent 6ade4d5 commit 5e6cec9

File tree

6 files changed

+152
-102
lines changed

6 files changed

+152
-102
lines changed

src/layout/IHyprLayout.cpp

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "../managers/LayoutManager.hpp"
1313
#include "../managers/EventManager.hpp"
1414
#include "../managers/HookSystemManager.hpp"
15+
#include "../managers/cursor/CursorShapeOverrideController.hpp"
1516

1617
void IHyprLayout::onWindowCreated(PHLWINDOW pWindow, eDirection direction) {
1718
CBox desiredGeometry = g_pXWaylandManager->getGeometryForWindow(pWindow);
@@ -243,7 +244,7 @@ void IHyprLayout::onBeginDragWindow() {
243244
// Window will be floating. Let's check if it's valid. It should be, but I don't like crashing.
244245
if (!validMapped(DRAGGINGWINDOW)) {
245246
Debug::log(ERR, "Dragging attempted on an invalid window!");
246-
g_pKeybindManager->changeMouseBindMode(MBIND_INVALID);
247+
CKeybindManager::changeMouseBindMode(MBIND_INVALID);
247248
return;
248249
}
249250

@@ -259,41 +260,41 @@ void IHyprLayout::onBeginDragWindow() {
259260
switch (*RESIZECORNER) {
260261
case 1:
261262
m_grabbedCorner = CORNER_TOPLEFT;
262-
g_pInputManager->setCursorImageUntilUnset("nw-resize");
263+
Cursor::overrideController->setOverride("nw-resize", Cursor::CURSOR_OVERRIDE_SPECIAL_ACTION);
263264
break;
264265
case 2:
265266
m_grabbedCorner = CORNER_TOPRIGHT;
266-
g_pInputManager->setCursorImageUntilUnset("ne-resize");
267+
Cursor::overrideController->setOverride("ne-resize", Cursor::CURSOR_OVERRIDE_SPECIAL_ACTION);
267268
break;
268269
case 3:
269270
m_grabbedCorner = CORNER_BOTTOMRIGHT;
270-
g_pInputManager->setCursorImageUntilUnset("se-resize");
271+
Cursor::overrideController->setOverride("se-resize", Cursor::CURSOR_OVERRIDE_SPECIAL_ACTION);
271272
break;
272273
case 4:
273274
m_grabbedCorner = CORNER_BOTTOMLEFT;
274-
g_pInputManager->setCursorImageUntilUnset("sw-resize");
275+
Cursor::overrideController->setOverride("sw-resize", Cursor::CURSOR_OVERRIDE_SPECIAL_ACTION);
275276
break;
276277
}
277278
} else if (m_beginDragXY.x < m_beginDragPositionXY.x + m_beginDragSizeXY.x / 2.0) {
278279
if (m_beginDragXY.y < m_beginDragPositionXY.y + m_beginDragSizeXY.y / 2.0) {
279280
m_grabbedCorner = CORNER_TOPLEFT;
280-
g_pInputManager->setCursorImageUntilUnset("nw-resize");
281+
Cursor::overrideController->setOverride("nw-resize", Cursor::CURSOR_OVERRIDE_SPECIAL_ACTION);
281282
} else {
282283
m_grabbedCorner = CORNER_BOTTOMLEFT;
283-
g_pInputManager->setCursorImageUntilUnset("sw-resize");
284+
Cursor::overrideController->setOverride("sw-resize", Cursor::CURSOR_OVERRIDE_SPECIAL_ACTION);
284285
}
285286
} else {
286287
if (m_beginDragXY.y < m_beginDragPositionXY.y + m_beginDragSizeXY.y / 2.0) {
287288
m_grabbedCorner = CORNER_TOPRIGHT;
288-
g_pInputManager->setCursorImageUntilUnset("ne-resize");
289+
Cursor::overrideController->setOverride("ne-resize", Cursor::CURSOR_OVERRIDE_SPECIAL_ACTION);
289290
} else {
290291
m_grabbedCorner = CORNER_BOTTOMRIGHT;
291-
g_pInputManager->setCursorImageUntilUnset("se-resize");
292+
Cursor::overrideController->setOverride("se-resize", Cursor::CURSOR_OVERRIDE_SPECIAL_ACTION);
292293
}
293294
}
294295

295296
if (g_pInputManager->m_dragMode != MBIND_RESIZE && g_pInputManager->m_dragMode != MBIND_RESIZE_FORCE_RATIO && g_pInputManager->m_dragMode != MBIND_RESIZE_BLOCK_RATIO)
296-
g_pInputManager->setCursorImageUntilUnset("grabbing");
297+
Cursor::overrideController->setOverride("grabbing", Cursor::CURSOR_OVERRIDE_SPECIAL_ACTION);
297298

298299
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
299300

@@ -310,13 +311,13 @@ void IHyprLayout::onEndDragWindow() {
310311

311312
if (!validMapped(DRAGGINGWINDOW)) {
312313
if (DRAGGINGWINDOW) {
313-
g_pInputManager->unsetCursorImage();
314+
Cursor::overrideController->unsetOverride(Cursor::CURSOR_OVERRIDE_SPECIAL_ACTION);
314315
g_pInputManager->m_currentlyDraggedWindow.reset();
315316
}
316317
return;
317318
}
318319

319-
g_pInputManager->unsetCursorImage();
320+
Cursor::overrideController->unsetOverride(Cursor::CURSOR_OVERRIDE_SPECIAL_ACTION);
320321
g_pInputManager->m_currentlyDraggedWindow.reset();
321322
g_pInputManager->m_wasDraggingWindow = true;
322323

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#include "CursorShapeOverrideController.hpp"
2+
3+
#include <ranges>
4+
5+
using namespace Cursor;
6+
7+
void CShapeOverrideController::setOverride(const std::string& name, eCursorShapeOverrideGroup group) {
8+
if (m_overrides[group] == name)
9+
return;
10+
11+
m_overrides[group] = name;
12+
13+
recheckOverridesResendIfChanged();
14+
}
15+
16+
void CShapeOverrideController::unsetOverride(eCursorShapeOverrideGroup group) {
17+
if (m_overrides[group].empty())
18+
return;
19+
20+
m_overrides[group] = "";
21+
22+
recheckOverridesResendIfChanged();
23+
}
24+
25+
void CShapeOverrideController::recheckOverridesResendIfChanged() {
26+
for (const auto& s : m_overrides | std::views::reverse) {
27+
if (s.empty())
28+
continue;
29+
30+
if (s == m_overrideShape)
31+
return;
32+
33+
m_overrideShape = s;
34+
m_events.overrideChanged.emit(s);
35+
return;
36+
}
37+
38+
if (m_overrideShape.empty())
39+
return;
40+
41+
m_overrideShape = "";
42+
m_events.overrideChanged.emit("");
43+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#pragma once
2+
3+
#include "../../helpers/memory/Memory.hpp"
4+
#include "../../helpers/signal/Signal.hpp"
5+
6+
#include <array>
7+
#include <string>
8+
9+
namespace Cursor {
10+
enum eCursorShapeOverrideGroup : uint8_t {
11+
// unknown group - lowest priority
12+
CURSOR_OVERRIDE_UNKNOWN = 0,
13+
// window edges for resizing from edge
14+
CURSOR_OVERRIDE_WINDOW_EDGE,
15+
// Drag and drop
16+
CURSOR_OVERRIDE_DND,
17+
// special action: Interactive::CDrag, kill, etc.
18+
CURSOR_OVERRIDE_SPECIAL_ACTION,
19+
20+
//
21+
CURSOR_OVERRIDE_END,
22+
};
23+
24+
class CShapeOverrideController {
25+
public:
26+
CShapeOverrideController() = default;
27+
~CShapeOverrideController() = default;
28+
29+
CShapeOverrideController(const CShapeOverrideController&) = delete;
30+
CShapeOverrideController(CShapeOverrideController&) = delete;
31+
CShapeOverrideController(CShapeOverrideController&&) = delete;
32+
33+
void setOverride(const std::string& name, eCursorShapeOverrideGroup group);
34+
void unsetOverride(eCursorShapeOverrideGroup group);
35+
36+
struct {
37+
// if string is empty, override was cleared
38+
CSignalT<const std::string&> overrideChanged;
39+
} m_events;
40+
41+
private:
42+
void recheckOverridesResendIfChanged();
43+
44+
std::array<std::string, CURSOR_OVERRIDE_END> m_overrides;
45+
std::string m_overrideShape;
46+
};
47+
48+
inline UP<CShapeOverrideController> overrideController = makeUnique<CShapeOverrideController>();
49+
};

0 commit comments

Comments
 (0)