AXElements 1.0.0.alpha8 → 1.0.0.alpha9

Sign up to get free protection for your applications and to get access to all the features.
data/History.markdown CHANGED
@@ -1,6 +1,13 @@
1
1
  # 1.0.0
2
2
 
3
3
  * Added History.markdown to track notable changes
4
+ * Added `Application.frontmost_application`
5
+ * Added `Application.menu_bar_owner`
6
+ * Added `SystemWide.status_bar_items`
7
+ * Added `SystemWide.desktop`
8
+ * Added `Application.finder`
9
+ * Added `Application.dock`
10
+ * Added `DSL#record` to run a screen recording of the given block
4
11
 
5
12
  * Ported `mouse.rb` to C and moved code to [MRMouse](https://github.com/ferrous26/MRMouse)
6
13
 
data/README.markdown CHANGED
@@ -64,13 +64,10 @@ The code from the demo video is right here:
64
64
 
65
65
  ## Getting Setup
66
66
 
67
- You need to have the OS X command line tools installed in order to
68
- build and install AXElements, but you will also need Xcode if you want
69
- to run the test suite (sorry). Go ahead and install the tools now if you
70
- haven't done that yet, I'll wait. Once you have the developer tools,
71
- you should install MacRuby, version 0.12 or newer is required. If you
72
- are on Snow Leopard, you will also need to install the
73
- [Bridge Support Preview](http://www.macruby.org/blog/2010/10/08/bridgesupport-preview.html).
67
+ You will need a MacRuby nightly build for installation. You can get help setting
68
+ up by referencing the
69
+ [Setup MacRuby](https://github.com/MacRuby/MacRuby/wiki/Setting-up-MacRuby)
70
+ guide on Github.
74
71
 
75
72
  You will also need to make sure you "enable access for assistive devices".
76
73
  This can be done in System Preferences in the Universal Access section:
@@ -914,9 +914,6 @@ class NSArray
914
914
  def to_size; CGSize.new(first, at(1)) end
915
915
  # @return [CGRect]
916
916
  def to_rect; CGRectMake(*self[0..3]) end
917
- ##
918
- # Override `super` to exploit trivial parallelism.
919
- #
920
917
  # @return [Array]
921
918
  def to_ruby
922
919
  map do |obj| obj.to_ruby end
@@ -693,16 +693,17 @@ module Accessibility::DSL
693
693
  alias_method :capture_screen, :screenshot
694
694
 
695
695
  ##
696
- # See {Accessibility::ScreenRecorder.record} for details.
696
+ # See (ScreenRecorder)[http://rdoc.info/gems/screen_recorder/frames]
697
+ # for details on the screen recording options
697
698
  #
698
699
  # @param file [String]
699
700
  # @return [String]
700
701
  def record file = nil, &block
701
- require 'accessibility/screen_recorder'
702
+ require 'screen_recorder'
702
703
  if file
703
- Accessibility::ScreenRecorder.record file, &block
704
+ ScreenRecorder.record file, &block
704
705
  else
705
- Accessibility::ScreenRecorder.record &block
706
+ ScreenRecorder.record &block
706
707
  end
707
708
  end
708
709
 
@@ -4,7 +4,7 @@
4
4
  # The main AXElements namespace.
5
5
  module Accessibility
6
6
  # @return [String]
7
- VERSION = '1.0.0.alpha8'
7
+ VERSION = '1.0.0.alpha9'
8
8
 
9
9
  # @return [String]
10
10
  CODE_NAME = 'ルナトーン'
@@ -23,6 +23,55 @@ class AX::Application < AX::Element
23
23
  additionalEventParamDescriptor: nil,
24
24
  launchIdentifier: nil
25
25
  end
26
+
27
+ ##
28
+ # Find and return the dock application
29
+ #
30
+ # @return [AX::Application]
31
+ def dock
32
+ new 'com.apple.dock'
33
+ end
34
+
35
+ ##
36
+ # Find and return the dock application
37
+ #
38
+ # @return [AX::Application]
39
+ def finder
40
+ new 'com.apple.finder'
41
+ end
42
+
43
+ ##
44
+ # Find and return the notification center UI app
45
+ #
46
+ # Obviously, this will only work on OS X 10.8+
47
+ #
48
+ # @return [AX::Application]
49
+ def notification_center
50
+ new 'com.apple.notificationcenterui'
51
+ end
52
+
53
+ ##
54
+ # Find and return the application which is frontmost
55
+ #
56
+ # This is often, but not necessarily, the same as the app that
57
+ # owns the menu bar.
58
+ #
59
+ # @return [AX::Application]
60
+ def frontmost_application
61
+ new NSWorkspace.sharedWorkspace.frontmostApplication
62
+ end
63
+ alias_method :frontmost_app, :frontmost_application
64
+
65
+ ##
66
+ # Find and return the application which owns the menu bar
67
+ #
68
+ # This is often, but not necessarily, the same as the app that
69
+ # is frontmost.
70
+ #
71
+ # @return [AX::Application]
72
+ def menu_bar_owner
73
+ new NSWorkspace.sharedWorkspace.menuBarOwningApplication
74
+ end
26
75
  end
27
76
 
28
77
  ##
data/lib/ax/systemwide.rb CHANGED
@@ -11,6 +11,33 @@ require 'accessibility/string'
11
11
  class AX::SystemWide < AX::Element
12
12
  include Accessibility::String
13
13
 
14
+ class << self
15
+ ##
16
+ # Find and return the group that represents the dock
17
+ #
18
+ # @return [AX::Group]
19
+ def desktop
20
+ AX::Application.finder.scroll_areas.first.groups.first
21
+ end
22
+
23
+ ##
24
+ # @note This currently does not include spotlight or the
25
+ # notification center as they interact oddly with
26
+ # accessibility APIs and how AXElements handle errors
27
+ #
28
+ # Find and return menu bar items for the system
29
+ #
30
+ # That is, menu bar items that do not belong to the current
31
+ # app, but that belong to the system, such as the clock or
32
+ # wi-fi menu.
33
+ #
34
+ # @return [AX::MenuBarItem]
35
+ def status_items
36
+ AX::Application.new('SystemUIServer').menu_bar.children
37
+ end
38
+ end
39
+
40
+
14
41
  ##
15
42
  # Overridden since there is only one way to get the element ref.
16
43
  def initialize
@@ -1,6 +1,6 @@
1
1
  framework 'Cocoa'
2
2
 
3
- MOUNTAIN_LION_APPKIT_VERSION = 1187
3
+ MOUNTAIN_LION_APPKIT_VERSION ||= 1187
4
4
  if NSAppKitVersionNumber >= MOUNTAIN_LION_APPKIT_VERSION
5
5
  framework '/System/Library/Frameworks/CoreGraphics.framework'
6
6
  end
metadata CHANGED
@@ -2,14 +2,14 @@
2
2
  name: AXElements
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease: 6
5
- version: 1.0.0.alpha8
5
+ version: 1.0.0.alpha9
6
6
  platform: ruby
7
7
  authors:
8
8
  - Mark Rada
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-08 00:00:00 Z
12
+ date: 2012-12-11 00:00:00 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: mouse
@@ -19,14 +19,46 @@ dependencies:
19
19
  requirements:
20
20
  - - ~>
21
21
  - !ruby/object:Gem::Version
22
- version: 1.0.1
22
+ version: 1.0.2
23
23
  type: :runtime
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  none: false
26
26
  requirements:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
- version: 1.0.1
29
+ version: 1.0.2
30
+ - !ruby/object:Gem::Dependency
31
+ name: screen_recorder
32
+ prerelease: false
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ~>
37
+ - !ruby/object:Gem::Version
38
+ version: 0.1.3
39
+ type: :runtime
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 0.1.3
46
+ - !ruby/object:Gem::Dependency
47
+ name: minitest
48
+ prerelease: false
49
+ requirement: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: "4.3"
55
+ type: :development
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: "4.3"
30
62
  - !ruby/object:Gem::Dependency
31
63
  name: yard
32
64
  prerelease: false
@@ -81,7 +113,6 @@ files:
81
113
  - lib/accessibility/highlighter.rb
82
114
  - lib/accessibility/pretty_printer.rb
83
115
  - lib/accessibility/qualifier.rb
84
- - lib/accessibility/screen_recorder.rb
85
116
  - lib/accessibility/statistics.rb
86
117
  - lib/accessibility/string.rb
87
118
  - lib/accessibility/translator.rb
@@ -1,217 +0,0 @@
1
- framework 'AVFoundation'
2
- require 'accessibility/version'
3
- require 'ax_elements/core_graphics_workaround'
4
-
5
- ##
6
- # Screen recordings, easy as pie.
7
- #
8
- # Things that you need to be concerned about:
9
- # - screen going to sleep
10
- # - short recordings (~1 second) don't work too well; it looks like
11
- # the last bit of the buffer does not get saved so the last ~0.5
12
- # seconds are not saved to disk (we could add a 0.5 second sleep)
13
- # - small memory leak when a recording starts on Mountain Lion (GC)
14
- # - constantly leaking memory during recording on Lion (GC)
15
- # - run loop hack is not needed if code is already being called from
16
- # in a run loop
17
- # - pausing is not working...not sure why
18
- #
19
- class Accessibility::ScreenRecorder
20
-
21
- ##
22
- # Record the screen while executing the given block. The path to the
23
- # recording will be returned.
24
- #
25
- # The recorder object is yielded.
26
- #
27
- # @yield
28
- # @yieldparam recorder [ScreenRecorder]
29
- # @return [String]
30
- def self.record file_name = nil
31
- raise 'block required' unless block_given?
32
-
33
- recorder = new
34
- file_name ? recorder.start(file_name) : recorder.start
35
- yield recorder
36
- recorder.file
37
-
38
- ensure
39
- recorder.stop
40
- end
41
-
42
- ##
43
- # Path to the screen recording. This is `nil` until the screen
44
- # recording begins.
45
- #
46
- # @return [String]
47
- attr_reader :file
48
-
49
- ##
50
- # @todo Expose configuration options at initialie time
51
- def initialize
52
- @session = AVCaptureSession.alloc.init
53
-
54
- @input = AVCaptureScreenInput.alloc.initWithDisplayID CGMainDisplayID()
55
- @input.capturesMouseClicks = true
56
-
57
- @output = AVCaptureMovieFileOutput.alloc.init
58
- @output.setDelegate self
59
-
60
- @session.addInput @input
61
- @session.addOutput @output
62
-
63
- @sema = Dispatch::Semaphore.new 0
64
- end
65
-
66
- ##
67
- # Synchrnously start recording. You can optionally specify a file
68
- # name for the recording; if you do not then a default name will be
69
- # provided in the form `~/Movies/TestRecording-20121017123230.mov`
70
- # (the timestamp will be different for you).
71
- #
72
- # @param file_name [String]
73
- def start file_name = default_file_name
74
- @file = default_file_name
75
- file_url = NSURL.fileURLWithPath @file, isDirectory: false
76
-
77
- @session.startRunning
78
- @output.startRecordingToOutputFileURL file_url,
79
- recordingDelegate: self
80
-
81
- @sema.wait
82
- end
83
-
84
- ##
85
- # Whether or not the recording has begun. This will be `true`
86
- # after calling {#start} until {#stop} is called. It will be
87
- # `true` while the recording is paused.
88
- def started?
89
- @output.recording?
90
- end
91
-
92
- # ##
93
- # # Whether or not the recording has been paused.
94
- # def paused?
95
- # @output.paused?
96
- # end
97
-
98
- ##
99
- # Duration of the recording, in seconds.
100
- #
101
- # @return [Float]
102
- def length
103
- duration = @output.recordedDuration
104
- (duration.value.to_f / duration.timescale.to_f)
105
- end
106
-
107
- ##
108
- # Size of the recording on disk, in bytes.
109
- #
110
- # @return [Fixnum]
111
- def size
112
- @output.recordedFileSize
113
- end
114
-
115
- # ##
116
- # # Synchronously pause the recording. You can optionally pass a block
117
- # # to this method.
118
- # #
119
- # # If you pass a block, the recording is paused so that the block
120
- # # can execute and recording resumes after the block finishes. If
121
- # # you do not pass a block then the recording is paused until you
122
- # # call {#resume} on the receiver.
123
- # #
124
- # # @yield Optionally pass a block
125
- # def pause
126
- # @output.pauseRecording
127
- # wait_for_callback
128
- # @sema.wait
129
-
130
- # if block_given?
131
- # yield
132
- # resume
133
- # end
134
- # end
135
-
136
- # ##
137
- # # Synchronously resume a {#pause}d recording.
138
- # def resume
139
- # @output.resumeRecording
140
- # wait_for_callback
141
- # @sema.wait
142
- # end
143
-
144
- ##
145
- # Synchronously stop recording and finish up commiting any data to disk.
146
- # A recording cannot be {#start}ed again after it has been stopped; if
147
- # you want to pause a recording then you should use {#pause} instead.
148
- def stop
149
- @session.stopRunning
150
- @output.stopRecording
151
- @sema.wait
152
- wait_for_callback
153
- @sema.wait
154
- end
155
-
156
-
157
- # @!group AVCaptureFileOutputDelegate
158
-
159
- def captureOutput captureOutput, didOutputSampleBuffer:sampleBuffer, fromConnection:connection
160
- # gets called for every chunk of the recording getting committed to disk
161
- end
162
-
163
- def captureOutput captureOutput, didDropSampleBuffer:sampleBuffer, fromConnection:connection
164
- NSLog("Error: dropped same data from recording")
165
- end
166
-
167
-
168
- # @!group AVCaptureFileOutputRecordingDelegate
169
-
170
- def captureOutput captureOutput, didFinishRecordingToOutputFileAtURL:outputFileURL, fromConnections:connections, error:error
171
- NSLog('Finishing')
172
- CFRunLoopStop(CFRunLoopGetCurrent())
173
- @sema.signal
174
- end
175
-
176
- def captureOutput captureOutput, didPauseRecordingToOutputFileAtURL:fileURL, fromConnections:connections
177
- NSLog('Pausing')
178
- CFRunLoopStop(CFRunLoopGetCurrent())
179
- @sema.signal
180
- end
181
-
182
- def captureOutput captureOutput, didResumeRecordingToOutputFileAtURL:fileURL, fromConnections:connections
183
- NSLog('Resuming')
184
- CFRunLoopStop(CFRunLoopGetCurrent())
185
- @sema.signal
186
- end
187
-
188
- def captureOutput captureOutput, didStartRecordingToOutputFileAtURL:fileURL, fromConnections:connections
189
- NSLog('Starting')
190
- @sema.signal
191
- end
192
-
193
- def captureOutput captureOutput, willFinishRecordingToOutputFileAtURL:fileURL, fromConnections:connections, error:error
194
- NSLog('Will Finish')
195
- @sema.signal
196
- end
197
-
198
-
199
- private
200
-
201
- def default_file_name
202
- date = Time.now.strftime '%Y%m%d%H%M%S'
203
- File.expand_path("~/Movies/TestRecording-#{date}.mov")
204
- end
205
-
206
- def wait_for_callback
207
- case CFRunLoopRunInMode(KCFRunLoopDefaultMode, 30, false)
208
- when KCFRunLoopRunStopped
209
- true
210
- when KCFRunLoopRunTimedOut
211
- raise 'did not get callback'
212
- else
213
- raise 'unexpected result from waiting for callback'
214
- end
215
- end
216
-
217
- end