366
|
1 #include <functional>
|
|
2 #include <string>
|
|
3 #include <vector>
|
|
4 #include <memory>
|
|
5
|
|
6 #include "animone.h"
|
|
7 #include "animone/a11y/atspi.h"
|
|
8
|
|
9 #include <atspi/atspi.h>
|
|
10
|
|
11 namespace animone::internal::atspi {
|
|
12
|
|
13 /* deleters */
|
|
14 template<typename T>
|
|
15 struct g_object_del {
|
|
16 void operator()(T* p) const { ::g_object_unref(p); };
|
|
17 };
|
|
18
|
|
19 template<typename T>
|
|
20 using GObjectPtr = std::unique_ptr<T, g_object_del<T>>;
|
|
21
|
|
22 /* ----------------------------------------------------------------- */
|
|
23
|
|
24 // FIXME | atspi_exit()
|
|
25 bool GetWebBrowserInformation(const Result& result, web_browser_proc_t web_browser_proc) {
|
|
26 GObjectPtr<AtspiAccessible> desktop;
|
|
27 GObjectPtr<AtspiAccessible> application;
|
|
28
|
|
29 {
|
|
30 int err = atspi_init();
|
|
31 if (err != 0 && err != 1)
|
|
32 return false;
|
|
33 }
|
|
34
|
|
35 // Currently only one desktop is supported, so this is equivalent to doing
|
|
36 // just atspi_get_desktop(0). However it's nice to futureproof where possible.
|
|
37 for (gint i = 0; i < atspi_get_desktop_count(); i++) {
|
|
38 desktop.reset(atspi_get_desktop(i));
|
|
39 if (!desktop)
|
|
40 return false;
|
|
41
|
|
42 for (gint j = 0; j < atspi_accessible_get_child_count(application.get(), nullptr); j++) {
|
|
43 application.reset(atspi_accessible_get_child_at_index(desktop.get(), j, nullptr));
|
|
44 if (!application)
|
|
45 return false;
|
|
46
|
|
47 GError *error = NULL;
|
|
48
|
|
49 std::uint32_t pid = atspi_accessible_get_process_id(application.get(), &error);
|
|
50 if (error) {
|
|
51 ::g_error_free(error);
|
|
52 return false;
|
|
53 }
|
|
54
|
|
55 if (pid == result.process.pid)
|
|
56 goto found; // found it
|
|
57 }
|
|
58 }
|
|
59
|
|
60 // didn't get anything... lol
|
|
61 return false;
|
|
62
|
|
63 found:
|
|
64 // found a matching application
|
|
65
|
|
66 gchar *title = atspi_accessible_get_name(application.get(), NULL);
|
|
67 if (title) {
|
|
68 web_browser_proc({WebBrowserInformationType::Title, title});
|
|
69 ::g_free(title);
|
|
70 }
|
|
71
|
|
72 // TODO need to find address and tab? idk
|
|
73
|
|
74 return true;
|
|
75 }
|
|
76
|
|
77 }
|