mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
fix(input): resync hover after panel relayout
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user