fix(input): resync hover after panel relayout

This commit is contained in:
Ly-sec
2026-05-03 21:01:38 +02:00
parent 25ded7541a
commit cc5d81e99e
3 changed files with 32 additions and 0 deletions
+25
View File
@@ -71,8 +71,20 @@ void InputDispatcher::pointerMotion(float x, float y, std::uint32_t serial) {
}
bool InputDispatcher::pointerButton(float x, float y, std::uint32_t button, bool pressed) {
m_lastPointerX = x;
m_lastPointerY = y;
m_hasPointerPosition = true;
pruneDetachedAreas();
InputArea* target = m_capturedArea != nullptr ? m_capturedArea : m_hoveredArea;
// Press with no hover target: subtree may have been rebuilt (same global coords, new InputArea*).
if (target == nullptr && m_capturedArea == nullptr && pressed && m_hasPointerPosition) {
updateHover(x, y, m_lastSerial);
target = m_hoveredArea;
}
if (target != nullptr) {
float localX = 0.0f;
float localY = 0.0f;
@@ -89,12 +101,25 @@ bool InputDispatcher::pointerButton(float x, float y, std::uint32_t button, bool
}
return true;
}
// Release lost its capture (e.g. onClick rebuilt the scene); restore hover without mis-delivering the release.
if (!pressed && m_capturedArea == nullptr && m_hasPointerPosition) {
updateHover(x, y, m_lastSerial);
}
if (pressed) {
setFocus(nullptr);
}
return false;
}
void InputDispatcher::syncPointerHover() {
if (!m_hasPointerPosition || m_capturedArea != nullptr) {
return;
}
updateHover(m_lastPointerX, m_lastPointerY, m_lastSerial);
}
bool InputDispatcher::pointerAxis(float x, float y, std::uint32_t axis, std::uint32_t axisSource, double value,
std::int32_t discrete, std::int32_t value120, float lines) {
pruneDetachedAreas();
+1
View File
@@ -19,6 +19,7 @@ public:
void pointerEnter(float x, float y, std::uint32_t serial);
void pointerLeave();
void pointerMotion(float x, float y, std::uint32_t serial);
void syncPointerHover();
// Returns true if the event was consumed by a scene widget
bool pointerButton(float x, float y, std::uint32_t button, bool pressed);
bool pointerAxis(float x, float y, std::uint32_t axis, std::uint32_t axisSource, double value, std::int32_t discrete,
+6
View File
@@ -1352,6 +1352,9 @@ void PanelManager::buildScene(std::uint32_t width, std::uint32_t height) {
m_contentNode->setPosition(panelX + kPadding, panelY + kPadding);
m_contentNode->setSize(panelW - kPadding * 2.0f, panelH - kPadding * 2.0f);
}
if (m_pointerInside) {
m_inputDispatcher.syncPointerHover();
}
}
void PanelManager::prepareFrame(bool needsUpdate, bool needsLayout) {
@@ -1384,6 +1387,9 @@ void PanelManager::prepareFrame(bool needsUpdate, bool needsLayout) {
if (m_activePanel != nullptr) {
m_activePanel->layout(*m_renderContext, m_contentWidth, m_contentHeight);
}
if (m_pointerInside) {
m_inputDispatcher.syncPointerHover();
}
}
}