GError *error = nullptr; \
auto v = atspi_accessible_get_unique_id(ATSPI_ACCESSIBLE(obj.get()), &error); \
PRINT_ERROR_AND_FREE(error); \
- if (!error) return "(failed)"; \
+ if (error) return "(failed)"; \
auto z = std::string { v }; \
g_free(v); \
return std::move(z); \
namespace detail
{
- template <typename T> struct AsyncCallbackHelper {
+ template <typename T>
+ struct AsyncCallbackHelper {
using type = std::function<void(Optional<T>)>;
};
- template <> struct AsyncCallbackHelper<void> {
+
+ template <>
+ struct AsyncCallbackHelper<void> {
using type = std::function<void(bool)>;
};
}
class Atspi
{
+ template <typename T> using AsyncCallback = typename detail::AsyncCallbackHelper<T>::type;
+
public:
using StateSet = std::bitset<ATSPI_STATE_LAST_DEFINED>;
sig = '{';
free(t);
std::pair<A, B> a;
- while (signature<std::pair<A, B>>::get(s, a))
+ while (signature<std::pair<A, B>>::get(s, a, sig))
v.push_back(std::move(a));
return true;
}
v.clear();
if (!eldbus_message_iter_get_and_next(iter, 'a', &s)) return false;
std::pair<A, B> a;
- while (signature<std::pair<A, B>>::get(s, a))
+ while (signature<std::pair<A, B>>::get(s, a, '{'))
v.insert(std::move(a));
return true;
}
v.clear();
if (!eldbus_message_iter_get_and_next(iter, 'a', &s)) return false;
std::pair<A, B> a;
- while (signature<A>::get(s, a))
+ while (signature<std::pair<A, B>>::get(s, a, '{'))
v.insert(std::move(a));
return true;
}
return;
#define LISTEN(n) \
- do { navProxy.listen<void()>(#n).add([=]() { emitCallback(CallbackType::n); }); } while (0)
+ do { navProxy.listen<void()>(#n).add([=]() { emitCallback<NavigationCallbackType::n>(); }); } while (0)
LISTEN(FirstRow);
LISTEN(LastRow);
LISTEN(FirstElementInRow);
#undef LISTEN
#define LISTEN(n, SignalName) \
- do { navProxy.listen<void()>(SignalName).add([=]() { emitCallback(CallbackType::n); }); } while (0)
+ do { navProxy.listen<void()>(SignalName).add([=]() { emitCallback<NavigationCallbackType::n>(); }); } while (0)
LISTEN(DashedRow, "SpecialRow");
LISTEN(DashedElementInRow, "SpecialElementInRow");
#undef LISTEN
- navProxy.listen<void(AtspiAccessiblePtr)>("ContextChanged").add(
- [ = ](AtspiAccessiblePtr obj) {
- emitCallback(CallbackType::ContextChanged, std::make_shared<UIElement>(obj));
+ navProxy.listen<void(AtspiAccessiblePtr, int, int, int, int)>("ContextChanged").add(
+ [ = ](AtspiAccessiblePtr obj, int x, int y, int w, int h) {
+ emitCallback<NavigationCallbackType::ContextChanged>(std::make_shared<UIElement>(obj), x, y, w, h);
DEBUG("got element %s", Singleton<Atspi>::instance().getUniqueId(obj).c_str());
});
navProxy.listen<void(int, int, int, int, BoxPositionMode)>("BoxMoved").add(
[ = ](int x, int y, int w, int h, BoxPositionMode mode) {
- emitCallback(CallbackType::BoxMoved, x, y, w, h, mode);
+ emitCallback<NavigationCallbackType::BoxMoved>(x, y, w, h, mode);
});
navProxy.listen<void(AtspiAccessiblePtr, std::vector<std::pair<std::string, std::string>>)>("HackAttributesForRootAfterContextChanged").add(
[ = ](AtspiAccessiblePtr root, std::vector<std::pair<std::string, std::string>> attrs) {
}
private:
- template <typename ... ARGS>
- void emitCallback(CallbackType type, ARGS ... args)
+ template <NavigationCallbackType type, typename ... ARGS>
+ void emitCallback(ARGS ... args)
{
for (auto a : callbacks) {
if (a->type == type) {
- auto b = static_cast<typename NavigationInterface::CallbackHandleImpl<void(ARGS...)>*>(a);
+ using CallbackType = typename NavigationCallbackTraits<type>::CallbackFunctionType;
+ auto b = static_cast<typename NavigationInterface::CallbackHandleImpl<CallbackType>*>(a);
b->callback(args...);
}
}
#include <vector>
#include <memory>
+enum class NavigationCallbackType {
+ FirstRow, LastRow, DashedRow,
+ FirstElementInRow, LastElementInRow, DashedElementInRow,
+ ContextChanged,
+ BoxMoved
+};
+
+template <NavigationCallbackType>
+struct NavigationCallbackTraits {
+ using CallbackFunctionType = void();
+};
+
+
class NavigationInterface
{
public:
DASHED
};
- enum class CallbackType {
- FirstRow, LastRow, DashedRow,
- FirstElementInRow, LastElementInRow, DashedElementInRow,
- ContextChanged,
- BoxMoved
- };
-
- template <CallbackType>
- struct CallbackTraits {
- using CallbackFunctionType = void();
- };
-
struct CallbackHandleBase {
- CallbackType type;
+ NavigationCallbackType type;
bool registered = false;
- CallbackHandleBase(CallbackType type)
+ CallbackHandleBase(NavigationCallbackType type)
: type(type)
{}
virtual std::shared_ptr<UIElement> getCurrentElement() = 0;
virtual std::shared_ptr<UIElement> getElementAtPoint(int x, int y) = 0;
- template <CallbackType type>
- CallbackHandle registerCb(std::function<typename CallbackTraits<type>::CallbackFunctionType> callback)
+ template <NavigationCallbackType type>
+ CallbackHandle registerCb(std::function<typename NavigationCallbackTraits<type>::CallbackFunctionType> callback)
{
- using T = typename CallbackTraits<type>::CallbackFunctionType;
+ using T = typename NavigationCallbackTraits<type>::CallbackFunctionType;
std::unique_ptr<CallbackHandleImpl<T>> ptr{new CallbackHandleImpl<T>(type, std::move(callback))};
callbacks.push_back(ptr.get());
ptr->registered = true;
struct CallbackHandleImpl : public CallbackHandleBase {
std::function<T> callback;
- CallbackHandleImpl(CallbackType type, std::function<T> c)
+ CallbackHandleImpl(NavigationCallbackType type, std::function<T> c)
: CallbackHandleBase(type), callback(std::move(c))
{}
};
#define SPECIALIZE_CALLBACK_TRAITS(Item, FunctionType) \
template <> \
- struct NavigationInterface::CallbackTraits<NavigationInterface::CallbackType::Item> \
+ struct NavigationCallbackTraits<NavigationCallbackType::Item> \
{ \
using CallbackFunctionType = FunctionType; \
};
SPECIALIZE_CALLBACK_TRAITS(ContextChanged, void(std::shared_ptr<UIElement>, int, int, int, int));
-SPECIALIZE_CALLBACK_TRAITS(BoxMoved, void(int, int, int, int, BoxPositionMode));
+SPECIALIZE_CALLBACK_TRAITS(BoxMoved, void(int, int, int, int, NavigationInterface::BoxPositionMode));
#undef SPECIALIZE_CALLBACK_TRAITS
#endif
auto &navigation = Singleton<NavigationInterface>::instance();
navigation.resetPosition();
- using CT = NavigationInterface::CallbackType;
+ using CT = NavigationCallbackType;
navigationHandles.push_back(navigation.registerCb<CT::DashedRow>([ this ]() {
countInactivityAfterCompletedLoop();
}));
scanningMethod = properties.getMethod();
//TODO: register for screen orientation change (probably better to do it in class Window)
- contextChangedHandle = Singleton<NavigationInterface>::instance().registerCb<NavigationInterface::CallbackType::ContextChanged>(
+ contextChangedHandle = Singleton<NavigationInterface>::instance().registerCb<NavigationCallbackType::ContextChanged>(
[this](std::shared_ptr<UIElement> obj, int x, int y, int width, int height) {
auto rect = Rectangle {{x, y}, {width, height}};
properties.setScanningField(rect);
void ScreenScannerManager::acceptAutoscanning()
{
Optional<std::shared_ptr<UIElement>> element;
- if (!properties.isAutoScanEnabled() && properties.getMethod() == ScanningMethod::ROW)
+ if (!properties.isAutoScanEnabled() && properties.getMethod() == ScanningMethod::ROW) {
element = Singleton<NavigationInterface>::instance().getCurrentElement();
- else {
+ } else {
if (!screenScanner) {
ERROR("scanner type not selected");
return;
Rectangle Window::getDimensions() const
{
- return {{0, 0}, {screenWidth, screenHeight}};;
+ return {{0, 0}, {screenWidth, screenHeight}};
}