Commit 0e8f4ce7cf2f17e26880da3096a0fd56e310640e

Authored by samuel thibault
1 parent 4fd3d566

Cherry-pick at-spi2 initialization fix

debian/changelog
... ... @@ -2,6 +2,7 @@ brltty (5.6-4) UNRELEASED; urgency=medium
2 2  
3 3 * Cherry-pick python brlapi close fix, to avoid orca accumulating brlapi
4 4 connections.
  5 + * Cherry-pick at-spi2 initialization fix.
5 6  
6 7 -- Samuel Thibault <sthibault@debian.org> Tue, 03 Apr 2018 17:38:28 +0200
7 8  
... ...
debian/patches/git-atspi2-init 0 → 100644
... ... @@ -0,0 +1,114 @@
  1 +commit 6afc25d4c15a37c5adaadc3c9296dbe82fc0e106
  2 +Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
  3 +Date: Fri Apr 6 11:22:58 2018 +0200
  4 +
  5 + atspi2: Fix looking for currently active widget
  6 +
  7 + The current code was actually not working at all because the initial
  8 + sender is SPI2_DBUS_INTERFACE_REG with path SPI2_DBUS_PATH_ROOT, and its
  9 + children are applications with SPI2_DBUS_PATH_ROOT too, so when deciding
  10 + to recurse, we need to check for both the path and the sender, not only
  11 + the path, which may be the same for two sender and make use believe than
  12 + we have a loop right from the beginning between SPI2_DBUS_INTERFACE_REG
  13 + and applications.
  14 +
  15 + It is however noticeable that some applications do not actually always
  16 + expose their widgets as tree, but sometimes as a clique! We thus need to
  17 + take care not only of direct loops, but also loops to further ancestors,
  18 + and just stop recursing completely in that case, to avoid an exponential
  19 + number of lookups.
  20 +
  21 +diff --git a/Drivers/Screen/AtSpi2/screen.c b/Drivers/Screen/AtSpi2/screen.c
  22 +index c550b9d58..e9d770057 100644
  23 +--- a/Drivers/Screen/AtSpi2/screen.c
  24 ++++ b/Drivers/Screen/AtSpi2/screen.c
  25 +@@ -693,8 +693,17 @@ static int reinitTerm(const char *sender, const char *path) {
  26 + }
  27 +
  28 + /* Try to find an active object among children of the given object */
  29 +-static int findTerm(const char *sender, const char *path, int active, int depth);
  30 +-static int recurseFindTerm(const char *sender, const char *path, int active, int depth) {
  31 ++
  32 ++/* We need to take care of bogus applications which have children loops, so we
  33 ++ * need to compare newly found children with the list of ancestors */
  34 ++struct pathList {
  35 ++ const char *sender;
  36 ++ const char *path;
  37 ++ struct pathList *prev;
  38 ++ int loop;
  39 ++};
  40 ++static int findTerm(const char *sender, const char *path, int active, int depth, struct pathList *list);
  41 ++static int recurseFindTerm(const char *sender, const char *path, int active, int depth, struct pathList *list) {
  42 + DBusMessage *msg, *reply;
  43 + DBusMessageIter iter, iter_array, iter_struct;
  44 + int res = 0;
  45 +@@ -717,19 +726,42 @@ static int recurseFindTerm(const char *sender, const char *path, int active, int
  46 + while (dbus_message_iter_get_arg_type (&iter_array) != DBUS_TYPE_INVALID)
  47 + {
  48 + const char *childsender, *childpath;
  49 ++ struct pathList *cur;
  50 ++
  51 + dbus_message_iter_recurse (&iter_array, &iter_struct);
  52 + dbus_message_iter_get_basic (&iter_struct, &childsender);
  53 + dbus_message_iter_next (&iter_struct);
  54 + dbus_message_iter_get_basic (&iter_struct, &childpath);
  55 +- /* Make sure that the child is not the same as the parent, to avoid recursing indefinitely. */
  56 +- if (strcmp(path, childpath))
  57 ++
  58 ++ /* Make sure that the child is not the same as an ancestor, to avoid
  59 ++ * recursing indefinitely. */
  60 ++ for (cur = list; cur; cur = cur->prev)
  61 ++ if (!strcmp(childsender, cur->sender) && !strcmp(childpath, cur->path))
  62 ++ {
  63 ++ /* Loop detected, avoid continuing looking at this part of the tree
  64 ++ which is not actually a tree! */
  65 ++ cur->loop = 1;
  66 ++ break;
  67 ++ }
  68 ++ if (! cur)
  69 + {
  70 +- if (findTerm(childsender, childpath, active, depth))
  71 ++ struct pathList me = {
  72 ++ .sender = sender,
  73 ++ .path = path,
  74 ++ .prev = list,
  75 ++ };
  76 ++ if (findTerm(childsender, childpath, active, depth, &me))
  77 + {
  78 + res = 1;
  79 + goto out;
  80 + }
  81 ++ if (me.loop) {
  82 ++ /* There is a loop up to us. Avoid continuing looking here which may
  83 ++ * entail an exponential number of lookups. */
  84 ++ break;
  85 ++ }
  86 + }
  87 ++
  88 + dbus_message_iter_next (&iter_array);
  89 + }
  90 +
  91 +@@ -739,7 +771,7 @@ out:
  92 + }
  93 +
  94 + /* Test whether this object is active, and if not recurse in its children */
  95 +-static int findTerm(const char *sender, const char *path, int active, int depth) {
  96 ++static int findTerm(const char *sender, const char *path, int active, int depth, struct pathList *list) {
  97 + dbus_uint32_t *states = getState(sender, path);
  98 +
  99 + if (!states)
  100 +@@ -760,12 +792,12 @@ static int findTerm(const char *sender, const char *path, int active, int depth)
  101 + }
  102 +
  103 + free(states);
  104 +- return recurseFindTerm(sender, path, active, depth+1);
  105 ++ return recurseFindTerm(sender, path, active, depth+1, list);
  106 + }
  107 +
  108 + /* Find out currently focused terminal, starting from registry */
  109 + static void initTerm(void) {
  110 +- recurseFindTerm(SPI2_DBUS_INTERFACE_REG, SPI2_DBUS_PATH_ROOT, 0, 0);
  111 ++ recurseFindTerm(SPI2_DBUS_INTERFACE_REG, SPI2_DBUS_PATH_ROOT, 0, 0, NULL);
  112 + }
  113 +
  114 + /* Handle incoming events */
... ...
debian/patches/series
... ... @@ -4,3 +4,4 @@
4 4 50-constants.patch
5 5 disable-synth-callback.patch
6 6 git-pythonclose
  7 +git-atspi2-init
... ...