feat(unreal): Support specific button input (#14547) 9323bb804f
* pass through mouse button for sync functions

* update unreal to support specific mouse button input

Co-authored-by: Jonathon Copeland <jcopela4@gmail.com>
diff --git a/.rive_head b/.rive_head
index aabac70..700b2f5 100644
--- a/.rive_head
+++ b/.rive_head
@@ -1 +1 @@
-37aef8611c6082c822b133243b7ef34a2feeea88
+9323bb804febac324538d4b8d8fe11c5e7bdc4b2
diff --git a/include/rive/command_server.hpp b/include/rive/command_server.hpp
index 400fccf..51f1135 100644
--- a/include/rive/command_server.hpp
+++ b/include/rive/command_server.hpp
@@ -48,6 +48,11 @@
                                             const CommandQueue::PointerEvent&);
     rive::HitResult pointerUpSynchronized(StateMachineHandle,
                                           const CommandQueue::PointerEvent&);
+    // Whether a listener under the event's position responds to presses of
+    // its button. Lets a host keep a mouse button for its own use wherever
+    // nothing in the scene wants it.
+    bool listensToButtonAtSynchronized(StateMachineHandle,
+                                       const CommandQueue::PointerEvent&);
 
     File* getFile(FileHandle) const;
     bool getWasDisconnected() const { return m_wasDisconnectReceived; }
diff --git a/src/command_server.cpp b/src/command_server.cpp
index 169f65c..fe68503 100644
--- a/src/command_server.cpp
+++ b/src/command_server.cpp
@@ -569,7 +569,8 @@
             std::unique_lock<std::mutex> lock(stateMachine->m_mutex);
             auto hitResult =
                 stateMachine->instance->pointerDown(pos,
-                                                    pointerEvent.pointerId);
+                                                    pointerEvent.pointerId,
+                                                    pointerEvent.button);
             // Process down-driven state changes before a following pointer up.
             if (hitResult != HitResult::none)
             {
@@ -620,7 +621,9 @@
         {
             std::unique_lock<std::mutex> lock(stateMachine->m_mutex);
             auto hitResult =
-                stateMachine->instance->pointerUp(pos, pointerEvent.pointerId);
+                stateMachine->instance->pointerUp(pos,
+                                                  pointerEvent.pointerId,
+                                                  pointerEvent.button);
             // Process up-driven state changes before any following pointer
             // exit.
             if (hitResult != HitResult::none)
@@ -634,6 +637,29 @@
     return rive::HitResult::none;
 }
 
+bool CommandServer::listensToButtonAtSynchronized(
+    StateMachineHandle handle,
+    const CommandQueue::PointerEvent& pointerEvent)
+{
+    std::unique_lock<std::mutex> accesLock(m_stateMachineAccessMutex);
+    auto it = m_stateMachines.find(handle);
+    if (it != m_stateMachines.end())
+    {
+        auto stateMachine = it->second;
+        accesLock.unlock();
+        auto pos = cursorPosForPointerEvent(stateMachine->instance.get(),
+                                            pointerEvent);
+        {
+            std::unique_lock<std::mutex> lock(stateMachine->m_mutex);
+            return stateMachine->instance->listensToButtonAt(
+                pos,
+                pointerEvent.button);
+        }
+    }
+
+    return false;
+}
+
 File* CommandServer::getFile(FileHandle handle) const
 {
     assert(std::this_thread::get_id() == m_threadID);