aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/managers
diff options
context:
space:
mode:
authorVaxry <[email protected]>2023-10-29 18:09:05 +0000
committerVaxry <[email protected]>2023-10-29 18:09:05 +0000
commit7a5234a0cca2508b7a5ede1fc60dc3ae8b72a51c (patch)
tree581626c545765a0f797a4f4681100facb0826b0f /src/managers
parentaf9440152e19cee74b675e53087e032b9ccb5459 (diff)
downloadHyprland-7a5234a0cca2508b7a5ede1fc60dc3ae8b72a51c.tar.gz
Hyprland-7a5234a0cca2508b7a5ede1fc60dc3ae8b72a51c.zip
input: better cursor image infrastructure
Improves handling of cursor images/surfaces Fixes an issue with decos and cursors Fixes #3471
Diffstat (limited to 'src/managers')
-rw-r--r--src/managers/input/InputManager.cpp78
-rw-r--r--src/managers/input/InputManager.hpp19
2 files changed, 76 insertions, 21 deletions
diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp
index 1e8760aa..b19a929c 100644
--- a/src/managers/input/InputManager.cpp
+++ b/src/managers/input/InputManager.cpp
@@ -301,9 +301,9 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
if (g_pHyprRenderer->m_bHasARenderedCursor) {
// TODO: maybe wrap?
if (m_ecbClickBehavior == CLICKMODE_KILL)
- g_pHyprRenderer->setCursorFromName("crosshair");
+ setCursorImageOverride("crosshair");
else
- g_pHyprRenderer->setCursorFromName("left_ptr");
+ setCursorImageOverride("left_ptr");
}
m_bEmptyFocusCursorSet = true;
@@ -355,6 +355,14 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
return;
}
+ if (pFoundWindow && foundSurface == pFoundWindow->m_pWLSurface.wlr() && !m_bCursorImageOverridden) {
+ const auto BOX = pFoundWindow->getWindowMainSurfaceBox();
+ if (!VECINRECT(mouseCoords, BOX.x, BOX.y, BOX.x + BOX.width, BOX.y + BOX.height))
+ setCursorImageOverride("left_ptr");
+ else
+ restoreCursorIconToApp();
+ }
+
if (pFoundWindow) {
// change cursor icon if hovering over border
if (*PRESIZEONBORDER && *PRESIZECURSORICON) {
@@ -460,25 +468,65 @@ void CInputManager::processMouseRequest(wlr_seat_pointer_request_set_cursor_even
if (!cursorImageUnlocked() || !g_pHyprRenderer->m_bHasARenderedCursor)
return;
- // cursorSurfaceInfo.pSurface = e->surface;
+ if (e->seat_client == g_pCompositor->m_sSeat.seat->pointer_state.focused_client) {
+ m_sCursorSurfaceInfo.wlSurface.unassign();
+
+ if (e->surface) {
+ m_sCursorSurfaceInfo.wlSurface.assign(e->surface);
+ m_sCursorSurfaceInfo.vHotspot = {e->hotspot_x, e->hotspot_y};
+ m_sCursorSurfaceInfo.hidden = false;
+ } else {
+ m_sCursorSurfaceInfo.vHotspot = {};
+ m_sCursorSurfaceInfo.hidden = true;
+ }
- // if (e->surface) {
- // hyprListener_CursorSurfaceDestroy.removeCallback();
- // hyprListener_CursorSurfaceDestroy.initCallback(
- // &e->surface->events.destroy, [&](void* owner, void* data) { cursorSurfaceInfo.pSurface = nullptr; }, this, "InputManager");
- // cursorSurfaceInfo.vHotspot = {e->hotspot_x, e->hotspot_y};
- // }
+ m_sCursorSurfaceInfo.name = "";
- if (e->seat_client == g_pCompositor->m_sSeat.seat->pointer_state.focused_client)
+ m_sCursorSurfaceInfo.inUse = true;
g_pHyprRenderer->setCursorSurface(e->surface, e->hotspot_x, e->hotspot_y);
+ }
}
void CInputManager::processMouseRequest(wlr_cursor_shape_manager_v1_request_set_shape_event* e) {
if (!g_pHyprRenderer->m_bHasARenderedCursor || !cursorImageUnlocked())
return;
- if (e->seat_client == g_pCompositor->m_sSeat.seat->pointer_state.focused_client)
- g_pHyprRenderer->setCursorFromName(wlr_cursor_shape_v1_name(e->shape));
+ if (e->seat_client == g_pCompositor->m_sSeat.seat->pointer_state.focused_client) {
+ m_sCursorSurfaceInfo.wlSurface.unassign();
+ m_sCursorSurfaceInfo.vHotspot = {};
+ m_sCursorSurfaceInfo.name = wlr_cursor_shape_v1_name(e->shape);
+ m_sCursorSurfaceInfo.hidden = false;
+
+ m_sCursorSurfaceInfo.inUse = true;
+ g_pHyprRenderer->setCursorFromName(m_sCursorSurfaceInfo.name);
+ }
+}
+
+void CInputManager::restoreCursorIconToApp() {
+ if (m_sCursorSurfaceInfo.inUse)
+ return;
+
+ if (m_sCursorSurfaceInfo.hidden) {
+ g_pHyprRenderer->setCursorSurface(nullptr, 0, 0);
+ return;
+ }
+
+ if (m_sCursorSurfaceInfo.name.empty()) {
+ if (m_sCursorSurfaceInfo.wlSurface.exists())
+ g_pHyprRenderer->setCursorSurface(m_sCursorSurfaceInfo.wlSurface.wlr(), m_sCursorSurfaceInfo.vHotspot.x, m_sCursorSurfaceInfo.vHotspot.y);
+ } else {
+ g_pHyprRenderer->setCursorFromName(m_sCursorSurfaceInfo.name);
+ }
+
+ m_sCursorSurfaceInfo.inUse = true;
+}
+
+void CInputManager::setCursorImageOverride(const std::string& name) {
+ if (m_bCursorImageOverridden)
+ return;
+
+ m_sCursorSurfaceInfo.inUse = false;
+ g_pHyprRenderer->setCursorFromName(name);
}
bool CInputManager::cursorImageUnlocked() {
@@ -1487,7 +1535,8 @@ void CInputManager::destroySwitch(SSwitchDevice* pDevice) {
void CInputManager::setCursorImageUntilUnset(std::string name) {
g_pHyprRenderer->setCursorFromName(name.c_str());
- m_bCursorImageOverridden = true;
+ m_bCursorImageOverridden = true;
+ m_sCursorSurfaceInfo.inUse = false;
}
void CInputManager::unsetCursorImage() {
@@ -1495,8 +1544,7 @@ void CInputManager::unsetCursorImage() {
return;
m_bCursorImageOverridden = false;
- if (!g_pHyprRenderer->m_bWindowRequestedCursorHide)
- g_pHyprRenderer->setCursorFromName("left_ptr");
+ restoreCursorIconToApp();
}
std::string CInputManager::deviceNameToInternalString(std::string in) {
diff --git a/src/managers/input/InputManager.hpp b/src/managers/input/InputManager.hpp
index 670bc4da..b4d365ee 100644
--- a/src/managers/input/InputManager.hpp
+++ b/src/managers/input/InputManager.hpp
@@ -229,15 +229,22 @@ class CInputManager {
void setBorderCursorIcon(eBorderIconDirection);
void setCursorIconOnBorder(CWindow* w);
+ // temporary. Obeys setUntilUnset.
+ void setCursorImageOverride(const std::string& name);
+
// cursor surface
- // struct cursorSI {
- // wlr_surface* pSurface = nullptr;
- // Vector2D vHotspot;
- // bool bUsed = false;
- // } cursorSurfaceInfo;
- // DYNLISTENER(CursorSurfaceDestroy);
+ struct cursorSI {
+ bool hidden = false; // null surface = hidden
+ CWLSurface wlSurface;
+ Vector2D vHotspot;
+ std::string name; // if not empty, means set by name.
+ bool inUse = false;
+ } m_sCursorSurfaceInfo;
+
+ void restoreCursorIconToApp(); // no-op if restored
friend class CKeybindManager;
+ friend class CWLSurface;
};
inline std::unique_ptr<CInputManager> g_pInputManager;