atspi 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.yardopts +2 -0
  4. data/Gemfile +3 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +69 -0
  7. data/Rakefile +2 -0
  8. data/atspi.gemspec +23 -0
  9. data/bin/console +7 -0
  10. data/lib/atspi/accessible/action.rb +45 -0
  11. data/lib/atspi/accessible/children/selected.rb +32 -0
  12. data/lib/atspi/accessible/children.rb +72 -0
  13. data/lib/atspi/accessible/descendants/attribute_filter.rb +32 -0
  14. data/lib/atspi/accessible/descendants/interface_filter.rb +24 -0
  15. data/lib/atspi/accessible/descendants/name_filter.rb +18 -0
  16. data/lib/atspi/accessible/descendants/options.rb +49 -0
  17. data/lib/atspi/accessible/descendants/role_filter.rb +23 -0
  18. data/lib/atspi/accessible/descendants/state_filter.rb +23 -0
  19. data/lib/atspi/accessible/descendants.rb +278 -0
  20. data/lib/atspi/accessible/document.rb +26 -0
  21. data/lib/atspi/accessible/extents.rb +129 -0
  22. data/lib/atspi/accessible/hyperlink/anchor.rb +30 -0
  23. data/lib/atspi/accessible/hyperlink.rb +31 -0
  24. data/lib/atspi/accessible/image.rb +35 -0
  25. data/lib/atspi/accessible/selectable.rb +47 -0
  26. data/lib/atspi/accessible/table/cell/columns.rb +44 -0
  27. data/lib/atspi/accessible/table/cell/rows.rb +44 -0
  28. data/lib/atspi/accessible/table/cell.rb +18 -0
  29. data/lib/atspi/accessible/table/cells.rb +37 -0
  30. data/lib/atspi/accessible/table/column.rb +59 -0
  31. data/lib/atspi/accessible/table/columns/selected.rb +42 -0
  32. data/lib/atspi/accessible/table/columns.rb +34 -0
  33. data/lib/atspi/accessible/table/row.rb +59 -0
  34. data/lib/atspi/accessible/table/rows/selected.rb +42 -0
  35. data/lib/atspi/accessible/table/rows.rb +31 -0
  36. data/lib/atspi/accessible/table.rb +50 -0
  37. data/lib/atspi/accessible/text/caret.rb +31 -0
  38. data/lib/atspi/accessible/text/character.rb +45 -0
  39. data/lib/atspi/accessible/text/editable.rb +90 -0
  40. data/lib/atspi/accessible/text/hyperlink.rb +19 -0
  41. data/lib/atspi/accessible/text/hypertext.rb +29 -0
  42. data/lib/atspi/accessible/text/offset.rb +59 -0
  43. data/lib/atspi/accessible/text/range.rb +66 -0
  44. data/lib/atspi/accessible/text/selection.rb +48 -0
  45. data/lib/atspi/accessible/text.rb +120 -0
  46. data/lib/atspi/accessible/value.rb +47 -0
  47. data/lib/atspi/accessible.rb +267 -0
  48. data/lib/atspi/application.rb +46 -0
  49. data/lib/atspi/collection.rb +60 -0
  50. data/lib/atspi/desktop.rb +52 -0
  51. data/lib/atspi/extents.rb +28 -0
  52. data/lib/atspi/libatspi.rb +7 -0
  53. data/lib/atspi/requires.rb +76 -0
  54. data/lib/atspi/selectable_collection/selected.rb +23 -0
  55. data/lib/atspi/selectable_collection.rb +32 -0
  56. data/lib/atspi/state_set.rb +141 -0
  57. data/lib/atspi/version.rb +4 -0
  58. data/lib/atspi/window.rb +33 -0
  59. data/lib/atspi.rb +58 -0
  60. metadata +132 -0
@@ -0,0 +1,278 @@
1
+ Libatspi.load_class :MatchRule
2
+
3
+ module ATSPI
4
+ # A collection of all descendants in the tree below the accessible it belongs
5
+ # to. It can be filtered by state, attribute, role, interface and name using
6
+ # {#where}. The number of descendants to return can be set by {#limit_to}.
7
+ # Recursive search of the tree can be turned on and off by {#recursive}.
8
+ #
9
+ # All methods can be chained together:
10
+ #
11
+ # descendants = ATSPI.applications.first.descendants
12
+ # descendants.where(role: :page_tab, state: :selected).recursive(false).limit_to(1)
13
+ # # => #<ATSPI::Accessible::Descendants:0x101c51014 @state=all:[:selected] @role=any:[:page_tab] @limit=1 @recursive?=false … >
14
+ #
15
+ # To get the actual collection as an array call {#to_a}. Methods not defined
16
+ # here are automatically delegated to {#to_a}, so instances of this class can
17
+ # be directly treated like an array.
18
+ #
19
+ # descendants.where(interface: :Action).map{ |d| d.actions.map(&:name) }
20
+ # # => [["click"], [], ["click"], [], …]
21
+ #
22
+ # In essence, it wraps libatspi's AtspiCollection[https://developer.gnome.org/libatspi/stable/libatspi-atspi-collection.html] and
23
+ # AtspiMatchRule[https://developer.gnome.org/libatspi/stable/AtspiMatchRule.html]
24
+ class Accessible::Descendants
25
+ # @api private
26
+ def initialize(native)
27
+ @native = native
28
+ @filters = {
29
+ state: StateFilter.new,
30
+ attributes: AttributeFilter.new,
31
+ role: RoleFilter.new,
32
+ interface: InterfaceFilter.new,
33
+ name: NameFilter.new,
34
+ }
35
+ @options = Options.new(nil, inverted?: false, order: :canonical, limit: 0, recursive?: true)
36
+ end
37
+
38
+ # @!group Filter
39
+ # @note Filtering sometimes felt rocky on libatspi's side during testing.
40
+ # See the notes in the following sections for details.
41
+ #
42
+ # @see https://developer.gnome.org/libatspi/stable/AtspiMatchRule.html#atspi-match-rule-new atspi_match_rule_new
43
+ #
44
+ # @return [Descendants] a copy of this instance with the modified filters.
45
+ #
46
+ # @overload where(state:)
47
+ # Filters by state(s)
48
+ #
49
+ # @param state [Symbol,Array<Symbol[, mode: :all]>] the states filter.
50
+ # States are given as symbol derived from libatspi's {https://developer.gnome.org/libatspi/stable/libatspi-atspi-constants.html#AtspiStateType AtspiStateType enum}
51
+ # by removing the +ATSPI_STATE_+ prefix and making it lowercase.
52
+ #
53
+ # When given an array, the last item can be set to a hash configuring
54
+ # the filter mode. The mode has to be one of +:all+, +:any+, +:none+,
55
+ # +:empty+. It corresponds to the match type in {https://developer.gnome.org/libatspi/stable/AtspiMatchRule.html#atspi-match-rule-new atspi_match_rule_new} and
56
+ # {https://developer.gnome.org/libatspi/stable/libatspi-atspi-constants.html#AtspiCollectionMatchType AtspiCollectionMatchType}, accordingly.
57
+ #
58
+ # @example
59
+ # # Selects accessibles in state :selected
60
+ # where(state: :selected)
61
+ #
62
+ # # Selects accessibles in both states :selectable *and* :selected
63
+ # where(state: [:selectable, :selected])
64
+ #
65
+ # # Selects accessibles in either state :selectable *or* :selected (or both)
66
+ # where(state: [:selectable, :selected, mode: :any])
67
+ #
68
+ # @overload where(attributes:)
69
+ # Filters by attribute(s)
70
+ #
71
+ # @param attributes [Hash<String => String[, mode: :any]>] the attributes
72
+ # filter. Attributes are given as a Hash as returned by
73
+ # {Accessible#attributes}.
74
+ #
75
+ # The +:mode+ key of the hash can be used to configuring the filter
76
+ # mode. The mode has to be one of +:all+, +:any+, +:none+, +:empty+. It
77
+ # corresponds to the match type in {https://developer.gnome.org/libatspi/stable/AtspiMatchRule.html#atspi-match-rule-new atspi_match_rule_new} and
78
+ # {https://developer.gnome.org/libatspi/stable/libatspi-atspi-constants.html#AtspiCollectionMatchType AtspiCollectionMatchType}, accordingly.
79
+ #
80
+ # @note Filtering attributes in mode +:all+ effectively disables the filter
81
+ # and returns all descendants. It does not narrow down the result set as
82
+ # one would expect.
83
+ #
84
+ # @example
85
+ # # Selects accessibles with value "button" for attribute "tag"
86
+ # where(attributes: { "tag" => "button" })
87
+ #
88
+ # # Selects accessibles with value "button" *or* "input" for attribute "tag"
89
+ # where(attributes: { "tag" => ["button", "input"] })
90
+ #
91
+ # # Selects accessibles with value "button" for attribute "tag" *or* value "block" for attribute "display"
92
+ # where(attributes: { "tag" => "button", "display" => "block" })
93
+ #
94
+ # @overload where(role:)
95
+ # Filters by role
96
+ #
97
+ # @param role [Symbol,Array<Symbol[, mode: :any]>] the roles filter.
98
+ # Roles are given as symbols derived from libatspi's {https://developer.gnome.org/libatspi/stable/libatspi-atspi-constants.html#AtspiRole AtspiRole enum}
99
+ # by removing the +ATSPI_ROLE_+ prefix and making it lowercase.
100
+ #
101
+ # When given an array, the last item can be set to a hash configuring
102
+ # the filter mode. The mode has to be one of +:all+, +:any+, +:none+,
103
+ # +:empty+. It corresponds to the match type in {https://developer.gnome.org/libatspi/stable/AtspiMatchRule.html#atspi-match-rule-new atspi_match_rule_new} and
104
+ # {https://developer.gnome.org/libatspi/stable/libatspi-atspi-constants.html#AtspiCollectionMatchType AtspiCollectionMatchType}, accordingly.
105
+ #
106
+ # @note Setting the mode to a value different from +:any+ for role filters
107
+ # effectively disables the filter and returns all descendants. Since an
108
+ # accessible has only exactly one role, one would expect that it does return an
109
+ # empty set, but it does not.
110
+ #
111
+ # @example
112
+ # # Selects accessibles with role :frame
113
+ # where(role: :frame)
114
+ #
115
+ # # Selects accessibles with role :page_tab_list *or* :page_tab
116
+ # where(role: [:page_tab_list, :page_tab])
117
+ #
118
+ # @overload where(interface:)
119
+ # Filters by interface(s)
120
+ #
121
+ # @param role [Symbol,Array<Symbol[, mode: :all]>] the role filter.
122
+ # Interfaces are given as symbols derived from their name returned by
123
+ # {Accessible#interfaces}
124
+ #
125
+ # When given an array, the last item can be set to a hash configuring
126
+ # the filter mode. The mode has to be one of +:all+, +:any+, +:none+,
127
+ # +:empty+. It corresponds to the match type in {https://developer.gnome.org/libatspi/stable/AtspiMatchRule.html#atspi-match-rule-new atspi_match_rule_new} and
128
+ # {https://developer.gnome.org/libatspi/stable/libatspi-atspi-constants.html#AtspiCollectionMatchType AtspiCollectionMatchType}, accordingly.
129
+ #
130
+ # @note Filtering by multiple interfaces and including +:Accessible+ or
131
+ # +:Collection+ in mode +:all+ does not work. Instead it always returns
132
+ # an empty set.
133
+ #
134
+ # @note Filtering interfaces in mode +:none+ effectively disables the filter
135
+ # and returns the entire set of descendants. Since an accessible always
136
+ # has at least the accessible interfaces it implements one would expect
137
+ # that it does return an empty set, but it does not.
138
+ #
139
+ # @example
140
+ # # Selects accessibles implementing Action
141
+ # where(interface: :Action)
142
+ #
143
+ # # Selects accessibles implementing Action+ *and* Selection
144
+ # where(interface: [:Action, :Selection])
145
+ #
146
+ # # Selects accessibles implementing Action *or* +Selection or both
147
+ # where(interface: [:Action, :Selection, mode: :any])
148
+ #
149
+ # @overload where(name:)
150
+ # Filters by name
151
+ #
152
+ # @param name [String,RegExp] the name filter. When given a string it is
153
+ # matched against the entire name from start to end like +/^name$/+.
154
+ #
155
+ # @example
156
+ # # Selects accessibles with name exactly "Accessibles Name"
157
+ # where(name: "Accessible Name")
158
+ #
159
+ # # Selects accessibles with a name matching /a.{11}y/
160
+ # where(name: /a.{11}y/)
161
+ #
162
+ # @overload where(filters)
163
+ # Combines all or a subset of filters in a single call.
164
+ #
165
+ # @example
166
+ # where(name: /a.{11}y/, state: [:selectable, :selected], role: :page_tab)
167
+ #
168
+ # @param filters [Hash]
169
+ # @option filters [Symbol, Array] :states
170
+ # @option filters [Symbol, Array] :role
171
+ # @option filters [String, RegExp] :name
172
+ # @option filters [Hash] :attributes
173
+ # @option filters [Symbol, Array] :interface
174
+ def where(filters)
175
+ dup(filters: @filters.map do |name, filter|
176
+ extended_filter = filters[name] ? filter.extend(*filters[name]) : filter
177
+ [name, extended_filter]
178
+ end.to_h)
179
+ end
180
+
181
+ # Inverts the conditions set by {#where}.
182
+ #
183
+ # @note Seems to be not considered by libatspi?!
184
+ #
185
+ # @param invert [true, false]
186
+ #
187
+ # @return [Descendants] a copy of the current descendants with the modified
188
+ # _inverted_ option.
189
+ #
190
+ # @see https://developer.gnome.org/libatspi/stable/AtspiMatchRule.html#atspi-match-rule-new invert parameter of atspi_match_rule_new
191
+ def invert(invert = true)
192
+ dup(options: @options.invert(invert))
193
+ end
194
+ # @!endgroup
195
+
196
+ # @!group Options
197
+ # Sorts the collection of descendants.
198
+ #
199
+ # @param order [Symbol] derived from libatspi's {https://developer.gnome.org/libatspi/stable/libatspi-atspi-constants.html#AtspiCollectionSortOrder AtspiCollectionSortOrder enum}
200
+ # by removing the prefix +ATSPI_Collection_SORT_ORDER_+ and making it lowercase.
201
+ #
202
+ # @return [Descendants] a copy of the current descendants with the modified
203
+ # _order_ option.
204
+ #
205
+ # @example
206
+ # descendants.sort_by(:flow) # => #<ATSPI::Accessible::Descendants:0x101c51014 … >
207
+ #
208
+ # @see https://developer.gnome.org/libatspi/stable/libatspi-atspi-collection.html#atspi-collection-get-matches sortby parameter of atspi_collection_get_matches
209
+ def sort_by(order)
210
+ dup(options: @options.order_by(order))
211
+ end
212
+
213
+ # Limits the number of descendants to return.
214
+ #
215
+ # @param limit [Integer] A value of +0+ disables the limit.
216
+ #
217
+ # @return [Descendants] a copy of the current descendants with the modified
218
+ # _limit_ option.
219
+ #
220
+ # @see https://developer.gnome.org/libatspi/stable/libatspi-atspi-collection.html#atspi-collection-get-matches count parameter of atspi_collection_get_matches
221
+ def limit_to(limit)
222
+ dup(options: @options.limit_to(limit))
223
+ end
224
+
225
+ # Turns recursive search on and off.
226
+ #
227
+ # @param recursive [true, false] To limit the descendants to the direct
228
+ # children of the accessible only, set +recursive+ to +false+. By setting
229
+ # +recursive+ to +true+, all descendants in the tree below the accessible
230
+ # the descendants are considered.
231
+ #
232
+ # @return [Descendants] a copy of the current descendants with the modified
233
+ # _recursive_ option.
234
+ #
235
+ # @see https://developer.gnome.org/libatspi/stable/libatspi-atspi-collection.html#atspi-collection-get-matches traverse parameter of atspi_collection_get_matches
236
+ def recursive(recursive = true)
237
+ dup(options: @options.recursive(recursive))
238
+ end
239
+ # @!endgroup
240
+
241
+ # @!group Access
242
+ # @return [Array<Accessible>] the descendants according to the configured
243
+ # filters and options.
244
+ def to_a
245
+ match_rule = Libatspi::MatchRule.new(*@filters[:state], *@filters[:attributes],
246
+ *@filters[:role], *@filters[:interface], @options.inverted?)
247
+ matches = @native.matches(match_rule, *@options).to_a
248
+ matches = matches.select{ |native| native.name =~ @filters[:name].match } if @filters[:name].match
249
+ matches.map{ |native| Accessible.new(native) }
250
+ end
251
+
252
+ # Delegates missing methods to #to_a
253
+ # @return [Object] whatever Array#__send__(m, *args, &block) returns
254
+ def method_missing(m, *args, &block)
255
+ to_a.__send__(m, *args, &block)
256
+ end
257
+ # @!endgroup
258
+
259
+ # @!group Representations
260
+ # @return [String] itself as an inspectable string
261
+ def inspect
262
+ filter_inspect = @filters.map{ |n,f| "@#{n}=#{f.inspect}" }.join(' ')
263
+ "#<#{self.class.name}:0x#{'%x14' % __id__} #{filter_inspect} #{@options.inspect}>"
264
+ end
265
+ # @!endgroup
266
+
267
+ private
268
+
269
+ def dup(values)
270
+ clone = self.class.new(@native)
271
+ instance_variables.each do |name|
272
+ value = values[name.to_s.delete('@').to_sym] || instance_variable_get(name)
273
+ clone.instance_variable_set(name, value)
274
+ end
275
+ clone
276
+ end
277
+ end
278
+ end
@@ -0,0 +1,26 @@
1
+ class ATSPI::Accessible
2
+ # Wraps libatspi's AtspiDocument[https://developer.gnome.org/libatspi/stable/libatspi-atspi-document.html]
3
+ class Document
4
+ # @api private
5
+ def initialize(native)
6
+ @native = native
7
+ end
8
+
9
+ # @return [String] its locale
10
+ # @see https://developer.gnome.org/libatspi/stable/libatspi-atspi-document.html#atspi-document-get-locale atspi_document_get_locale
11
+ def locale
12
+ @native.locale
13
+ end
14
+
15
+ # @return [Hash<String => String>] its attributes
16
+ # @see https://developer.gnome.org/libatspi/stable/libatspi-atspi-document.html#atspi-document-get-attributes atspi_document_get_attributes
17
+ def attributes
18
+ @native.document_attributes.to_h
19
+ end
20
+
21
+ # @return [String] itself as an inspectable string
22
+ def inspect
23
+ "#<#{self.class.name}:0x#{'%x14' % __id__} #{attributes.map{ |k, v| "@#{k}=#{v.inspect}" }.join(' ')}>"
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,129 @@
1
+ class ATSPI::Accessible
2
+ # Wraps libatspi's AtspiComponent[https://developer.gnome.org/libatspi/stable/libatspi-atspi-component.html]
3
+ module Extents
4
+ # @!group Attributes & States
5
+ # Checks if it is extending, that is it has a position and size.
6
+ # Accessibles implementing the {https://developer.gnome.org/libatspi/stable/AtspiAccessible.html#atspi-accessible-get-component component interface}
7
+ # are extending.
8
+ #
9
+ # @return [true, false]
10
+ def extends?
11
+ not @native.component_iface.nil?
12
+ end
13
+
14
+ # @return [Symbol] its layer derived from libatspi's {AtspiComponentLayer enum}[https://developer.gnome.org/libatspi/stable/libatspi-atspi-constants.html#AtspiComponentLayer]
15
+ # by removing the prefix +ATSPI_LAYER_+ and making it lowercase. +:invalid+
16
+ # if it does not implement the {https://developer.gnome.org/libatspi/stable/AtspiAccessible.html#atspi-accessible-get-component component interface}.
17
+ #
18
+ # @see https://developer.gnome.org/libatspi/stable/libatspi-atspi-component.html#atspi-component-get-layer atspi_component_get_layer
19
+ def layer
20
+ if extends?
21
+ @native.layer
22
+ else
23
+ :invalid
24
+ end
25
+ end
26
+
27
+ # @return [Integer] its mdi_z_order. +-1+ if it does not implement the
28
+ # {https://developer.gnome.org/libatspi/stable/AtspiAccessible.html#atspi-accessible-get-component component interface}.
29
+ #
30
+ # @see https://developer.gnome.org/libatspi/stable/libatspi-atspi-component.html#atspi-component-get-mdi-z-order atspi_component_get_mdi_z_order
31
+ def mdi_z_order
32
+ if extends?
33
+ @native.mdi_z_order
34
+ else
35
+ -1
36
+ end
37
+ end
38
+ # @!endgroup
39
+
40
+ # @!group Actions
41
+ # Sets the input focus to it.
42
+ #
43
+ # @return [true, false] indicating success of the operation. +false+ if it
44
+ # does not implement the {https://developer.gnome.org/libatspi/stable/AtspiAccessible.html#atspi-accessible-get-component component interface}.
45
+ #
46
+ # @see https://developer.gnome.org/libatspi/stable/libatspi-atspi-component.html#atspi-component-grab-focus atspi_component_grab_focus
47
+ def grab_focus
48
+ extends? and @native.grab_focus
49
+ end
50
+ # @!endgroup
51
+
52
+ # @!group Attributes & States
53
+ # @return [Float] its opacity between +0.0+ (transparent) and +1.0+ (opaque). +0.0+
54
+ # if it does not implement the {https://developer.gnome.org/libatspi/stable/AtspiAccessible.html#atspi-accessible-get-component component interface}.
55
+ #
56
+ # @see https://developer.gnome.org/libatspi/stable/libatspi-atspi-component.html#atspi-component-get-alpha atspi_component_get_alpha
57
+ def opacity
58
+ if extends?
59
+ @native.alpha
60
+ else
61
+ 0.0
62
+ end
63
+ end
64
+ alias_method :alpha, :opacity
65
+
66
+ # Checks if the given point lies within its bounds
67
+ #
68
+ # @param x [Integer]
69
+ # @param y [Integer]
70
+ # @param relative_to [Symbol] coordinate system derived from
71
+ # libatspi's {https://developer.gnome.org/libatspi/stable/libatspi-atspi-constants.html#AtspiCoordType AtspiCoordType enum}
72
+ # by removing the prefix +ATSPI_COORD_TYPE+ and making it lowercase
73
+ #
74
+ # @return [true, false]
75
+ #
76
+ # @example
77
+ # accessible.contains?(1243, 323, relative_to: :screen) # => true
78
+ #
79
+ # @see https://developer.gnome.org/libatspi/stable/libatspi-atspi-component.html#atspi-component-contains atspi_component_contains
80
+ def contains?(x, y, relative_to:)
81
+ extends? and @native.contains(x, y, relative_to)
82
+ end
83
+ # @!endgroup
84
+
85
+ # @!group Tree & Traversal
86
+ # @param x [Integer]
87
+ # @param y [Integer]
88
+ # @param relative_to [Symbol] coordinate system derived from
89
+ # libatspi's {https://developer.gnome.org/libatspi/stable/libatspi-atspi-constants.html#AtspiCoordType AtspiCoordType enum}
90
+ # by removing the prefix +ATSPI_COORD_TYPE+ and making it lowercase
91
+ #
92
+ # @return [Accessible, nil] the descendant at the given coordinates. +nil+
93
+ # if it does not implement the {https://developer.gnome.org/libatspi/stable/AtspiAccessible.html#atspi-accessible-get-component component interface}.
94
+ #
95
+ # @example
96
+ # accessible.descendant_at(1243, 323, relative_to: :screen) # => #<ATSPI::Accessible:0x140839014 …>
97
+ #
98
+ # @see https://developer.gnome.org/libatspi/stable/libatspi-atspi-component.html#atspi-component-get-accessible-at-point atspi_component_get_accessible_at_point
99
+ def descendant_at(x, y, relative_to:)
100
+ if extends?
101
+ ATSPI::Accessible.new(@native.accessible_at_point(x, y, relative_to))
102
+ else
103
+ nil
104
+ end
105
+ end
106
+ # @!endgroup
107
+
108
+ # @!group Attributes & States
109
+ # @param relative_to [Symbol] coordinate system derived from
110
+ # libatspi's {https://developer.gnome.org/libatspi/stable/libatspi-atspi-constants.html#AtspiCoordType AtspiCoordType enum}
111
+ # by removing the prefix +ATSPI_COORD_TYPE_+ and making it lowercase
112
+ #
113
+ # @return [ATSPI::Extents] its extents. Will have a (0,0) position and a
114
+ # 0x0 size if it does not implement the {https://developer.gnome.org/libatspi/stable/AtspiAccessible.html#atspi-accessible-get-component component interface}.
115
+ #
116
+ # @example
117
+ # accessible.extents(relative_to: :screen) # => #<ATSPI::Extents:0x10b62c814 @x=2192 @y=187 @width=655 @height=492>
118
+ #
119
+ # @see https://developer.gnome.org/libatspi/stable/libatspi-atspi-component.html#atspi-component-get-extents atspi_component_get_extents
120
+ def extents(relative_to:)
121
+ if extends?
122
+ ATSPI::Extents.new(@native.extents(relative_to))
123
+ else
124
+ ATSPI::Extents.new(Struct.new(:x, :y, :width, :height).new(0, 0, 0, 0))
125
+ end
126
+ end
127
+ # @!endgroup
128
+ end
129
+ end
@@ -0,0 +1,30 @@
1
+ module ATSPI
2
+ # Wraps libatspi's AtspiHyperlink[https://developer.gnome.org/libatspi/stable/AtspiHyperlink.html]
3
+ # together with {Hyperlink}.
4
+ class Accessible::Hyperlink::Anchor
5
+ # @api private
6
+ def initialize(native, idx)
7
+ @native = native
8
+ @idx = idx
9
+ end
10
+
11
+ # @return [String] its uri
12
+ # @see https://developer.gnome.org/libatspi/stable/AtspiHyperlink.html#atspi-hyperlink-get-uri atspi_hyperlink_get_uri
13
+ def uri
14
+ @native.uri(@idx)
15
+ end
16
+
17
+ # @return [Accessible,nil] its object or nil if it has none
18
+ # @see https://developer.gnome.org/libatspi/stable/AtspiHyperlink.html#atspi-hyperlink-get-object atspi_hyperlink_get_object
19
+ def object
20
+ if object = @native.object(@idx)
21
+ Accessible.new(object)
22
+ end
23
+ end
24
+
25
+ # @return [String] itself as an inspectable string
26
+ def inspect
27
+ "#<#{self.class.name}:0x#{'%x14' % __id__} @uri=#{uri.inspect}>"
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,31 @@
1
+ class ATSPI::Accessible
2
+ # Wraps libatspi's AtspiHyperlink[https://developer.gnome.org/libatspi/stable/AtspiHyperlink.html]
3
+ # together with {Anchor}
4
+ class Hyperlink
5
+ extend Forwardable
6
+ # @api private
7
+ def initialize(native)
8
+ @native = native
9
+ end
10
+
11
+ # @return [Array<Anchor>] its anchors
12
+ # @see https://developer.gnome.org/libatspi/stable/AtspiHyperlink.html#atspi-hyperlink-get-n-anchors atspi_hyperlink_get_n_anchors
13
+ def anchors
14
+ @native.n_anchors.times.map do |idx|
15
+ Anchor.new(@native, idx)
16
+ end
17
+ end
18
+
19
+ # Checks if it's valid
20
+ # @return [true,false]
21
+ # @see https://developer.gnome.org/libatspi/stable/AtspiHyperlink.html#atspi-hyperlink-is-valid atspi_hyperlink_is_valid
22
+ def valid?
23
+ @native.is_valid
24
+ end
25
+
26
+ # @return [String] itself as an inspectable string
27
+ def inspect
28
+ "#<#{self.class.name}:0x#{'%x14' % __id__} @anchors=#{anchors.inspect}>"
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,35 @@
1
+ module ATSPI
2
+ # Wraps libatspi's AtspiImage[https://developer.gnome.org/libatspi/stable/libatspi-atspi-image.html]
3
+ class Accessible::Image
4
+ # @api private
5
+ def initialize(native)
6
+ @native = native
7
+ end
8
+
9
+ # @return [String] its description
10
+ # @see https://developer.gnome.org/libatspi/stable/libatspi-atspi-image.html#atspi-image-get-image-description atspi_image_get_image_description
11
+ def description
12
+ @native.image_description
13
+ end
14
+
15
+ # @param (see Accessible::Extents#extents)
16
+ # @return [Extents] its extents
17
+ # @example (see Accessible::Extents#extents)
18
+ # @see https://developer.gnome.org/libatspi/stable/libatspi-atspi-image.html#atspi-image-get-image-extents atspi_image_get_image_extents
19
+ def extents(relative_to:)
20
+ Extents.new(@native.image_extents(relative_to))
21
+ end
22
+
23
+ # @return [String] its locale
24
+ # @see https://developer.gnome.org/libatspi/stable/libatspi-atspi-image.html#atspi-image-get-image-locale atspi_image_get_image_locale
25
+ def locale
26
+ @native.image_locale
27
+ end
28
+
29
+ # @return [String] itself as an inspectable string
30
+ def inspect
31
+ "#<#{self.class.name}:0x#{'%x14' % __id__} @description=#{description.inspect} " <<
32
+ "@extents=#{extents(relative_to: :screen).inspect}>"
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,47 @@
1
+ class ATSPI::Accessible
2
+ # Wraps libatspi's AtspiSelection[https://developer.gnome.org/libatspi/stable/libatspi-atspi-selection.html]
3
+ # together with parts of {Children} and {Children::Selected}
4
+ module Selectable
5
+ # @!group Attributes & States
6
+ # Checks if it can be selected. Accessibles which parent's native
7
+ # implements the {https://developer.gnome.org/libatspi/stable/AtspiAccessible.html#atspi-accessible-get-selection selection interface}
8
+ # are selectable.
9
+ #
10
+ # @return [true, false]
11
+ def selectable?
12
+ parent.children.selectable?
13
+ end
14
+ # @!endgroup
15
+
16
+ # @!group Actions
17
+ # Selects it
18
+ # @return [true, false] indicating success of the operation. +false+ if its
19
+ # parent does not implement the {https://developer.gnome.org/libatspi/stable/AtspiAccessible.html#atspi-accessible-get-selection selection interface}.
20
+ #
21
+ # @see https://developer.gnome.org/libatspi/stable/libatspi-atspi-selection.html#atspi-selection-select-child atspi_selection_select_child
22
+ def select
23
+ selectable? and parent.__send__(:native).select_child(index_in_parent)
24
+ end
25
+
26
+ # Deselects it
27
+ # @return [true, false] indicating success of the operation. +false+ if its
28
+ # parent does not implement the {https://developer.gnome.org/libatspi/stable/AtspiAccessible.html#atspi-accessible-get-selection selection interface}.
29
+ #
30
+ # @see https://developer.gnome.org/libatspi/stable/libatspi-atspi-selection.html#atspi-selection-deselect-child atspi_selection_deselect_child
31
+ def deselect
32
+ selectable? and parent.__send__(:native).deselect_child(index_in_parent)
33
+ end
34
+ # @!endgroup
35
+
36
+ # @!group Attributes & States
37
+ # Checks if it currently is selected
38
+ # @return [true, false] +false+ if its
39
+ # parent does not implement the {https://developer.gnome.org/libatspi/stable/AtspiAccessible.html#atspi-accessible-get-selection selection interface}.
40
+ #
41
+ # @see https://developer.gnome.org/libatspi/stable/libatspi-atspi-selection.html#atspi-selection-is-child-selected atspi_selection_is_child_selected
42
+ def selected?
43
+ selectable? and parent.__send__(:native).is_child_selected(index_in_parent)
44
+ end
45
+ # @!endgroup
46
+ end
47
+ end
@@ -0,0 +1,44 @@
1
+ module ATSPI
2
+ class Accessible::Table
3
+ # Represents the columns a table {Cell} spans.
4
+ class Cell::Columns
5
+ include SelectableCollection::Selected
6
+
7
+ # @api private
8
+ INDEX_METHOD = :index
9
+
10
+ # @api private
11
+ def initialize(native)
12
+ @native = native
13
+ @first_idx = row_col_span[2]
14
+ end
15
+
16
+ # @!group Enumerable interface
17
+ # @param n [Integer] the index in the collection of the cell's columns
18
+ # and not the index in the collection of all the table's columns.
19
+ #
20
+ # @return [Column] the n'th column of the cell
21
+ #
22
+ # @see https://developer.gnome.org/libatspi/stable/libatspi-atspi-table.html#atspi-table-get-row-column-extents-at-index atspi_table_get_row_column_extents_at_index
23
+ def at(n)
24
+ super do |mapped_idx|
25
+ Column.new(@native.get_parent, @first_idx+mapped_idx)
26
+ end
27
+ end
28
+
29
+ # @return [Integer] the number of columns the cell spans
30
+ #
31
+ # @see https://developer.gnome.org/libatspi/stable/libatspi-atspi-table.html#atspi-table-get-row-column-extents-at-index atspi_table_get_row_column_extents_at_index
32
+ def count
33
+ row_col_span[4]
34
+ end
35
+ # @!endgroup
36
+
37
+ private
38
+
39
+ def row_col_span
40
+ @native.get_parent.row_column_extents_at_index(@native.index_in_parent)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,44 @@
1
+ module ATSPI
2
+ class Accessible::Table
3
+ # Represents the rows a table {Cell} spans.
4
+ class Cell::Rows
5
+ include SelectableCollection::Selected
6
+
7
+ # @api private
8
+ INDEX_METHOD = :index
9
+
10
+ # @api private
11
+ def initialize(native)
12
+ @native = native
13
+ @first_idx = row_col_span[1]
14
+ end
15
+
16
+ # @!group Enumerable interface
17
+ # @param n [Integer] the index in the collection of the cell's rows and
18
+ # not the index in the collection of all the table's rows.
19
+ #
20
+ # @return [Row] the n'th row of the cell
21
+ #
22
+ # @see https://developer.gnome.org/libatspi/stable/libatspi-atspi-table.html#atspi-table-get-row-column-extents-at-index atspi_table_get_row_column_extents_at_index
23
+ def at(n)
24
+ super do |mapped_idx|
25
+ Row.new(@native.get_parent, @first_idx+mapped_idx)
26
+ end
27
+ end
28
+
29
+ # @return [Integer] the number of rows the cell spans
30
+ #
31
+ # @see https://developer.gnome.org/libatspi/stable/libatspi-atspi-table.html#atspi-table-get-row-column-extents-at-index atspi_table_get_row_column_extents_at_index
32
+ def count
33
+ row_col_span[3]
34
+ end
35
+ # @!endgroup
36
+
37
+ private
38
+
39
+ def row_col_span
40
+ @native.get_parent.row_column_extents_at_index(@native.index_in_parent)
41
+ end
42
+ end
43
+ end
44
+ end