changeset 28:fac2b2d242d3

animone: add preliminary AT-SPI stuff anime_list: finish the regular singular right click menu
author Paper <paper@tflc.us>
date Sun, 17 Nov 2024 19:56:01 -0500
parents 13b647714159
children 40fd3776ce9b
files CMakeLists.txt include/animone/a11y.h include/animone/a11y/atspi.h include/animone/a11y/win32.h include/animone/types.h src/a11y.cc src/a11y/atspi.cc src/a11y/win32.cc src/strategist.cc
diffstat 9 files changed, 114 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Wed Oct 02 23:06:43 2024 -0400
+++ b/CMakeLists.txt	Sun Nov 17 19:56:01 2024 -0500
@@ -87,6 +87,14 @@
 		list(APPEND INCLUDE_DIRS ${XCB_INCLUDE_DIRS})
 		list(APPEND SRC_FILES src/win/x11.cc)
 	endif() # XCB_FOUND
+
+	pkg_check_modules(ATSPI atspi-2)
+	if (ATSPI_FOUND)
+		list(APPEND DEFINES USE_ATSPI)
+		list(APPEND LIBRARIES ${ATSPI_LINK_LIBRARIES})
+		list(APPEND INCLUDE_DIRS ${ATSPI_INCLUDE_DIRS})
+		list(APPEND SRC_FILES src/a11y/atspi.cc)
+	endif() # ATSPI_FOUND
 endif() # PKG_CONFIG_FOUND
 
 add_library(animia SHARED ${SRC_FILES})
--- a/include/animone/a11y.h	Wed Oct 02 23:06:43 2024 -0400
+++ b/include/animone/a11y.h	Sun Nov 17 19:56:01 2024 -0500
@@ -22,7 +22,7 @@
 
 using web_browser_proc_t = std::function<void(const WebBrowserInformation&)>;
 
-bool GetWebBrowserInformation(const Window& window, web_browser_proc_t web_browser_proc);
+bool GetWebBrowserInformation(const Result& result, web_browser_proc_t web_browser_proc);
 
 } // namespace internal
 } // namespace animone
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/animone/a11y/atspi.h	Sun Nov 17 19:56:01 2024 -0500
@@ -0,0 +1,13 @@
+#ifndef ANIMONE_ANIMONE_A11Y_ATSPI_H_
+#define ANIMONE_ANIMONE_A11Y_ATSPI_H_
+
+#include "animone.h"
+#include "animone/a11y.h"
+
+namespace animone::internal::atspi {
+
+bool GetWebBrowserInformation(const Result& result, web_browser_proc_t web_browser_proc);
+
+} // namespace animone::internal::atspi
+
+#endif // ANIMONE_ANIMONE_A11Y_ATSPI_H_
--- a/include/animone/a11y/win32.h	Wed Oct 02 23:06:43 2024 -0400
+++ b/include/animone/a11y/win32.h	Sun Nov 17 19:56:01 2024 -0500
@@ -7,7 +7,7 @@
 
 namespace animone::internal::win32 {
 
-bool GetWebBrowserInformation(const Window& window, web_browser_proc_t web_browser_proc);
+bool GetWebBrowserInformation(const Result& result, web_browser_proc_t web_browser_proc);
 
 } // namespace animone::internal::win32
 
--- a/include/animone/types.h	Wed Oct 02 23:06:43 2024 -0400
+++ b/include/animone/types.h	Sun Nov 17 19:56:01 2024 -0500
@@ -29,7 +29,7 @@
 
 /* different window systems have different sized IDs */
 union ANIMONE_API wid_t {
-	std::uintptr_t win32;
+	std::uintptr_t win32; // XXX this ought to be a `void *`
 	std::int64_t quartz; // FIXME is this correct?
 	std::uint32_t x11;
 };
--- a/src/a11y.cc	Wed Oct 02 23:06:43 2024 -0400
+++ b/src/a11y.cc	Sun Nov 17 19:56:01 2024 -0500
@@ -4,13 +4,21 @@
 #	include "animone/a11y/win32.h"
 #endif
 
+#ifdef USE_ATSPI
+#	include "animone/a11y/atspi.h"
+#endif
+
 namespace animone::internal {
 
-bool GetWebBrowserInformation(const Window& window, web_browser_proc_t web_browser_proc) {
+bool GetWebBrowserInformation(const Result& result, web_browser_proc_t web_browser_proc) {
 	bool success = false;
 
 #ifdef USE_WIN32
-	success ^= win32::GetWebBrowserInformation(window, web_browser_proc);
+	success ^= win32::GetWebBrowserInformation(result, web_browser_proc);
+#endif
+
+#ifdef USE_ATSPI
+	success ^= atspi::GetWebBrowserInformation(result, web_browser_proc);
 #endif
 
 	return success;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/a11y/atspi.cc	Sun Nov 17 19:56:01 2024 -0500
@@ -0,0 +1,77 @@
+#include <functional>
+#include <string>
+#include <vector>
+#include <memory>
+
+#include "animone.h"
+#include "animone/a11y/atspi.h"
+
+#include <atspi/atspi.h>
+
+namespace animone::internal::atspi {
+
+/* deleters */
+template<typename T>
+struct g_object_del {
+    void operator()(T* p) const { ::g_object_unref(p); };
+};
+
+template<typename T>
+using GObjectPtr = std::unique_ptr<T, g_object_del<T>>;
+
+/* ----------------------------------------------------------------- */
+
+// FIXME | atspi_exit()
+bool GetWebBrowserInformation(const Result& result, web_browser_proc_t web_browser_proc) {
+	GObjectPtr<AtspiAccessible> desktop;
+	GObjectPtr<AtspiAccessible> application;
+
+	{
+		int err = atspi_init();
+		if (err != 0 && err != 1)
+			return false;
+	}
+
+	// Currently only one desktop is supported, so this is equivalent to doing
+	// just atspi_get_desktop(0). However it's nice to futureproof where possible.
+	for (gint i = 0; i < atspi_get_desktop_count(); i++) {
+		desktop.reset(atspi_get_desktop(i));
+		if (!desktop)
+			return false;
+
+		for (gint j = 0; j < atspi_accessible_get_child_count(application.get(), nullptr); j++) {
+			application.reset(atspi_accessible_get_child_at_index(desktop.get(), j, nullptr));
+			if (!application)
+				return false;
+
+			GError *error = NULL;
+
+			std::uint32_t pid = atspi_accessible_get_process_id(application.get(), &error);
+			if (error) {
+				::g_error_free(error);
+				return false;
+			}
+
+			if (pid == result.process.pid)
+				goto found; // found it
+		}
+	}
+
+	// didn't get anything... lol
+	return false;
+
+found:
+	// found a matching application
+
+	gchar *title = atspi_accessible_get_name(application.get(), NULL);
+	if (title) {
+		web_browser_proc({WebBrowserInformationType::Title, title});
+		::g_free(title);
+	}
+
+	// TODO need to find address and tab? idk
+
+	return true;
+}
+
+}
--- a/src/a11y/win32.cc	Wed Oct 02 23:06:43 2024 -0400
+++ b/src/a11y/win32.cc	Sun Nov 17 19:56:01 2024 -0500
@@ -235,14 +235,14 @@
 
 /* ------------------------------------------------------------------------------------ */
 
-bool GetWebBrowserInformation(const Window& window, web_browser_proc_t web_browser_proc) {
+bool GetWebBrowserInformation(const Result& result, web_browser_proc_t web_browser_proc) {
 	if (!web_browser_proc)
 		return false;
 
 	if (!InitializeUIAutomation())
 		return false;
 
-	ComInterface<Element> parent(GetElementFromHandle(reinterpret_cast<HWND>(window.id.win32)));
+	ComInterface<Element> parent(GetElementFromHandle(reinterpret_cast<HWND>(result.window.id.win32)));
 	if (!parent)
 		return false;
 
--- a/src/strategist.cc	Wed Oct 02 23:06:43 2024 -0400
+++ b/src/strategist.cc	Sun Nov 17 19:56:01 2024 -0500
@@ -122,7 +122,7 @@
 			}
 		};
 
-		success |= GetWebBrowserInformation(result.window, web_browser_proc);
+		success |= GetWebBrowserInformation(result, web_browser_proc);
 	}
 
 	return success;