atspi 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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