[AT-SPI] Add Socket::SetOffset() and related APIs 87/275887/9
authorArtur Świgoń <a.swigon@samsung.com>
Fri, 3 Jun 2022 15:19:39 +0000 (17:19 +0200)
committerArtur Świgoń <a.swigon@samsung.com>
Thu, 7 Jul 2022 15:59:08 +0000 (17:59 +0200)
These APIs allow to set an offset that is added to every GetExtents()
result. The parent process calls Bridge::SetSocketOffset() which makes a
D-Bus call resulting in Bridge::SetExtentsOffset() being called in the
child process (widget). The widget needs this information to report its
screen coordinates correctly to AT-SPI clients, and for navigation to
work.

BridgeComponent::GetExtents adds the value of mExtentsOffset to
Component::GetExtents when reporting back to AT clients. So, in the
reverse operation of GetNavigableAtPoint, the value of mExtentsOffset
has to be subtracted.

Change-Id: I4e563c8be1267101c355e27f6e2782f62655347f

dali/devel-api/adaptor-framework/accessibility-bridge.h
dali/devel-api/atspi-interfaces/socket.h
dali/internal/accessibility/bridge/bridge-accessible.cpp
dali/internal/accessibility/bridge/bridge-base.cpp
dali/internal/accessibility/bridge/bridge-base.h
dali/internal/accessibility/bridge/bridge-component.cpp
dali/internal/accessibility/bridge/bridge-impl.cpp
dali/internal/accessibility/bridge/bridge-socket.cpp
dali/internal/accessibility/bridge/bridge-socket.h
dali/internal/accessibility/bridge/dummy-atspi.h

index e35d9a5..43d2a55 100644 (file)
@@ -36,6 +36,7 @@ namespace Dali
 namespace Accessibility
 {
 class Accessible;
+class ProxyAccessible;
 
 /**
  * @brief Base class for different accessibility bridges.
@@ -401,6 +402,36 @@ struct DALI_ADAPTOR_API Bridge
   virtual void UnembedSocket(const Address& plug, const Address& socket) = 0;
 
   /**
+   * @brief Calls socket.SetOffset(x, y) via D-Bus.
+   *
+   * The "SetOffset" D-Bus method is a DALi extension. It can be used to inform a DALi widget about
+   * its position on the screen.
+   *
+   * @param[in] socket The socket
+   * @param[in] x Horizontal offset
+   * @param[in] y Vertical offset
+   *
+   * @note Remote object pointed to by 'socket' must implement 'org.a11y.atspi.Socket'.
+   * @see EmbedSocket()
+   * @see SetExtentsOffset()
+   */
+  virtual void SetSocketOffset(ProxyAccessible* socket, std::int32_t x, std::int32_t y) = 0;
+
+  /**
+   * @brief Sets the global extents offset.
+   *
+   * This offset will be added during serialization of GetExtents() return value to D-Bus.
+   * Local calls to GetExtents() are unaffected.
+   *
+   * @param[in] x Horizontal offset
+   * @param[in] y Vertical offset
+   *
+   * @see SetSocketOffset()
+   * @see Dali::Accessibility::Component::GetExtents()
+   */
+  virtual void SetExtentsOffset(std::int32_t x, std::int32_t y) = 0;
+
+  /**
    * @brief Sets the preferred bus name.
    *
    * If the Bridge is enabled, it will immediately release the previous name and request the new one.
@@ -485,6 +516,7 @@ protected:
     Bridge*                               mBridge = nullptr;
     Actor                                 mHighlightActor;
     Actor                                 mCurrentlyHighlightedActor;
+    std::pair<std::int32_t, std::int32_t> mExtentsOffset{0, 0};
   };
   std::shared_ptr<Data> mData;
   friend class Accessible;
index 0e74694..34bd45e 100644 (file)
@@ -48,6 +48,14 @@ public:
   virtual void Unembed(Address plug) = 0;
 
   /**
+   * @brief Set the offset (position information).
+   *
+   * @param[in] x Horizontal offset
+   * @param[in] y Vertical offset
+   */
+  virtual void SetOffset(std::int32_t x, std::int32_t y) = 0;
+
+  /**
    * @brief Downcasts an Accessible to a Socket.
    *
    * @param obj The Accessible
index a7ecf8e..8545240 100644 (file)
@@ -627,6 +627,10 @@ DBus::ValueOrError<Accessible*, uint8_t, Accessible*> BridgeAccessible::GetNavig
   Accessible* deputy     = nullptr;
   auto        accessible = FindSelf();
   auto        cType      = static_cast<CoordinateType>(coordinateType);
+
+  x -= mData->mExtentsOffset.first;
+  y -= mData->mExtentsOffset.second;
+
   LOG() << "GetNavigableAtPoint: " << x << ", " << y << " type: " << coordinateType;
   auto component = CalculateNavigableAccessibleAtPoint(accessible, {x, y}, cType, GET_NAVIGABLE_AT_POINT_MAX_RECURSION_DEPTH);
   bool recurse   = false;
index 9b920d8..803390d 100644 (file)
@@ -62,6 +62,11 @@ void BridgeBase::AddFilteredEvent(FilteredEvents kind, Dali::Accessibility::Acce
     tickTimer = Dali::Timer::New(100);
     tickTimer.TickSignal().Connect(this, &BridgeBase::TickFilteredEvents);
   }
+
+  if(!tickTimer.IsRunning())
+  {
+    tickTimer.Start();
+  }
 }
 
 bool BridgeBase::TickFilteredEvents()
index 066c107..51c5a63 100644 (file)
@@ -193,9 +193,20 @@ public:
     {
       mIsEmbedded = false;
       mParent.SetAddress({});
+      Dali::Accessibility::Bridge::GetCurrentBridge()->SetExtentsOffset(0, 0);
     }
   }
 
+  void SetOffset(std::int32_t x, std::int32_t y) override
+  {
+    if(!mIsEmbedded)
+    {
+      return;
+    }
+
+    Dali::Accessibility::Bridge::GetCurrentBridge()->SetExtentsOffset(x, y);
+  }
+
   // Component
 
   Dali::Rect<> GetExtents(Dali::Accessibility::CoordinateType type) const override
@@ -267,7 +278,8 @@ public:
  */
 enum class FilteredEvents
 {
-  BOUNDS_CHANGED ///< Bounds changed
+  BOUNDS_CHANGED, ///< Bounds changed
+  SET_OFFSET, ///< Set offset
 };
 
 // Custom specialization of std::hash
index 2a297f5..ef0ff0f 100644 (file)
@@ -65,12 +65,20 @@ DBus::ValueOrError<Accessible*> BridgeComponent::GetAccessibleAtPoint(int32_t x,
 DBus::ValueOrError<std::tuple<int32_t, int32_t, int32_t, int32_t> > BridgeComponent::GetExtents(uint32_t coordType)
 {
   auto rect = FindSelf()->GetExtents(static_cast<CoordinateType>(coordType));
+
+  rect.x += mData->mExtentsOffset.first;
+  rect.y += mData->mExtentsOffset.second;
+
   return std::tuple<int32_t, int32_t, int32_t, int32_t>{rect.x, rect.y, rect.width, rect.height};
 }
 
 DBus::ValueOrError<int32_t, int32_t> BridgeComponent::GetPosition(uint32_t coordType)
 {
   auto rect = FindSelf()->GetExtents(static_cast<CoordinateType>(coordType));
+
+  rect.x += mData->mExtentsOffset.first;
+  rect.y += mData->mExtentsOffset.second;
+
   return {static_cast<int32_t>(rect.x), static_cast<int32_t>(rect.y)};
 }
 
index f5fa4d1..644aca4 100644 (file)
@@ -717,6 +717,23 @@ public:
     client.method<void(Address)>("Unembed").call(plug);
   }
 
+  void SetSocketOffset(ProxyAccessible* socket, std::int32_t x, std::int32_t y) override
+  {
+    AddFilteredEvent(FilteredEvents::SET_OFFSET, socket, 1.0f, [=]() {
+      auto client = CreateSocketClient(socket->GetAddress());
+
+      client.method<void(std::int32_t, std::int32_t)>("SetOffset").asyncCall([](DBus::ValueOrError<void>) {}, x, y);
+    });
+  }
+
+  void SetExtentsOffset(std::int32_t x, std::int32_t y) override
+  {
+    if(mData)
+    {
+      mData->mExtentsOffset = {x, y};
+    }
+  }
+
   void SetPreferredBusName(std::string_view preferredBusName) override
   {
     if(preferredBusName == mPreferredBusName)
index fdbae8c..621a433 100644 (file)
@@ -26,6 +26,7 @@ void BridgeSocket::RegisterInterfaces()
 
   AddFunctionToInterface(desc, "Embed", &BridgeSocket::Embed);
   AddFunctionToInterface(desc, "Unembed", &BridgeSocket::Unembed);
+  AddFunctionToInterface(desc, "SetOffset", &BridgeSocket::SetOffset);
 
   mDbusServer.addInterface("/", desc, true);
 }
@@ -45,3 +46,9 @@ DBus::ValueOrError<void> BridgeSocket::Unembed(Address plug)
   FindSelf()->Unembed(plug);
   return {};
 }
+
+DBus::ValueOrError<void> BridgeSocket::SetOffset(std::int32_t x, std::int32_t y)
+{
+  FindSelf()->SetOffset(x, y);
+  return {};
+}
index 6034700..f39671c 100644 (file)
@@ -52,6 +52,11 @@ public:
    * @copydoc Dali::Accessibility::Socket::Unembed()
    */
   DBus::ValueOrError<void> Unembed(Dali::Accessibility::Address plug);
+
+  /**
+   * @copydoc Dali::Accessibility::Socket::SetOffset()
+   */
+  DBus::ValueOrError<void> SetOffset(std::int32_t x, std::int32_t y);
 };
 
 #endif // DALI_INTERNAL_ACCESSIBILITY_BRIDGE_SOCKET_H
index 57db35d..81caf8e 100644 (file)
@@ -194,6 +194,14 @@ struct DummyBridge : Dali::Accessibility::Bridge
   {
   }
 
+  void SetSocketOffset(ProxyAccessible* socket, std::int32_t x, std::int32_t y) override
+  {
+  }
+
+  void SetExtentsOffset(std::int32_t x, std::int32_t y) override
+  {
+  }
+
   void SetPreferredBusName(std::string_view preferredBusName) override
   {
   }