diff dep/animone/src/a11y/atspi.cc @ 366:886f66775f31

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
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dep/animone/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;
+}
+
+}