movewin 1.6 → 1.11

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.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- YmU4MmIyMzIxZGZiYjY4ODQ2NTQ4NDIxYWQ4ZjJlNTIwMjJhNmQyZA==
5
- data.tar.gz: !binary |-
6
- NWIxMjcyMDY0MzMxMzkzOTg0ZTI0MzI4ZmMxYmI5NjA0YTg0Mzk1Yg==
2
+ SHA256:
3
+ metadata.gz: 3843c385c582fdeeb83f418b7681e91506fcd9a8e0b645b321e12a3c6e02d120
4
+ data.tar.gz: 60fe63177a8b4081f64bccdbf36bd824f562a13390b082734337c95c6eba2ae1
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- NmNkNmNhMWRiYmM2YTBhYTNhZTYwMGE2ZTZlYWU1YTJkMmRhNjY1MTljMDhh
10
- MjUxODk1ODhkZTljODNhOGUyNzZmNzIxNDJiZmE4ZDI5ODRmYmQ0MDQ3ZDdl
11
- YTI5MjE5ZDNmZDM0M2Y3ZTE3YmRiOGQzYWQwMTEyZDQ0NDZkNmY=
12
- data.tar.gz: !binary |-
13
- YWJmNjUyNWM0ODc0MTMwMGRlNWYzNzY4NGNkMmNlNjI1ZDQ0MzY0YmQ1YTMy
14
- ZDBjZWE4MWNkNWM1MWIwOWU2ZjAzYjhkNjZmYjg4ODg3NDMwN2FkMjc3OWE1
15
- ZWExN2JlNmY5MzhiZDYwZGMwNGYzODVlZjYwMWUxMTc1MGQzNDI=
6
+ metadata.gz: acb032ac21110ad0b3d142966a3e43e1c7f2be28780eb90e2f655d2b10a3f2850169757bc9ce01aef87c43cc4ae435f82cc6129883c8471a2c8f23000f4efe86
7
+ data.tar.gz: 3701ad4547eec20f8a4604250a82a23c778cfc596e0fdc561af70e1485103505ae1565e17de707307c0b4c513c76ec923e0a3dc42806b1e8d4e93c157ee2acbd
@@ -0,0 +1,4 @@
1
+ # This empty Ruby file exists to make sure the ext/movewin/dispatch
2
+ # directory is copied into the "movewin-#{VERSION}.gem" file, so that
3
+ # building this RubyGem will work under Yosemite (OS X 10.10), as per:
4
+ # https://github.com/andrewgho/movewin-ruby/issues/1
@@ -7,12 +7,7 @@ def main(argv = [])
7
7
  $CFLAGS = '-Wall'
8
8
  $LDFLAGS = '-Wall -framework Carbon'
9
9
 
10
- # No have_framework() in mkmf that ships with Ruby versions earlier than 1.9
11
- if ruby_older_than?('1.9')
12
- have_header('Carbon/Carbon.h')
13
- else
14
- have_framework('Carbon')
15
- end
10
+ have_header('Carbon/Carbon.h')
16
11
 
17
12
  # On Yosemite or newer, fix bug in Carbon header that breaks under gcc
18
13
  if yosemite_or_newer? && using_gcc?
@@ -22,66 +17,131 @@ def main(argv = [])
22
17
  create_makefile('movewin/movewin_ext')
23
18
  end
24
19
 
25
- # Return true if current Ruby version is older than given version
26
- def ruby_older_than?(version)
27
- Gem::Version.new(RUBY_VERSION) < Gem::Version.new(version)
28
- end
29
-
30
20
  # Return true if this is OS X 10.10 (Yosemite) or newer
31
21
  def yosemite_or_newer?
32
22
  Gem::Version.new(`sw_vers -productVersion`) >= Gem::Version.new('10.10')
33
23
  end
34
24
 
35
- # Return true if our compiler is GCC (not clang), as for RVM installed Ruby
25
+ # Return true if our compiler is GCC (not Clang), as for RVM installed Ruby
36
26
  def using_gcc?
37
- true # TODO: make this really work
27
+ # Match gcc, /usr/local/bin/gcc-4.2, etc. (Clang is "xcrun cc")
28
+ File.basename(RbConfig::MAKEFILE_CONFIG["CC"]).match(/\Agcc\b/)
38
29
  end
39
30
 
40
31
  # Building with GCC on Yosemite (OS X 10.10) results in an error
41
32
  # (https://github.com/andrewgho/movewin-ruby/issues/1).
42
33
  # Patch header file to work around this issue.
43
34
  def fix_dispatch_object_header!
44
- srcfile = find_header_file('dispatch/object.h')
45
- tmpfile = "#{File.dirname(__FILE__)}/dispatch/object.h.tmp.#{$$}"
46
- begin
47
- patched = false
48
- File.open(tmpfile, 'w') do |tmpfh|
49
- File.open(srcfile, 'r').each do |srcline|
50
- patched ||= srcline.sub!(
51
- /\Atypedef void \(\^dispatch_block_t\)\(void\);/,
52
- 'typedef void* dispatch_block_t;'
53
- )
54
- tmpfh.print(srcline)
35
+ $stdout.print 'Creating patched copy of dispatch/object.h... '
36
+ $stdout.flush
37
+ status = 'failed'
38
+ if (srcfile = find_header_file('dispatch/object.h'))
39
+ tmpfile = "#{File.dirname(__FILE__)}/dispatch/object.h.tmp.#{$$}"
40
+ begin
41
+ patched = false
42
+ File.open(tmpfile, 'w') do |tmpfh|
43
+ File.open(srcfile, 'r').each do |srcline|
44
+ patched ||= srcline.sub!(
45
+ /\Atypedef void \(\^dispatch_block_t\)\(void\);/,
46
+ 'typedef void* dispatch_block_t;'
47
+ )
48
+ tmpfh.print(srcline)
49
+ end
55
50
  end
56
- end
57
- if patched
58
- destfile = "#{File.dirname(__FILE__)}/dispatch/object.h"
59
- File.rename(tmpfile, destfile)
60
- if $CFLAGS.nil? || $CFLAGS.empty?
61
- $CFLAGS = "-I#{File.dirname(__FILE__)}"
51
+ if patched
52
+ destfile = "#{File.dirname(__FILE__)}/dispatch/object.h"
53
+ File.rename(tmpfile, destfile)
54
+ if $CFLAGS.nil? || $CFLAGS.empty?
55
+ $CFLAGS = "-I#{File.dirname(__FILE__)}"
56
+ else
57
+ $CFLAGS += " -I#{File.dirname(__FILE__)}"
58
+ end
59
+ # TODO: Ruby 2.2 mkmf doesn't seem to actually use CLEANINGS any more
60
+ set_constant! :CLEANINGS,
61
+ "DISTCLEANFILES += dispatch/object.h\n" + CLEANINGS
62
+ status = "patched #{destfile}"
62
63
  else
63
- $CFLAGS += " -I#{File.dirname(__FILE__)}"
64
+ status = 'skipped'
64
65
  end
65
- set_constant!(:CLEANINGS, "CLEANFILES += dispatch/object.h\n" + CLEANINGS)
66
+ ensure
67
+ File.unlink(tmpfile) if File.exists?(tmpfile)
66
68
  end
67
- ensure
68
- File.unlink(tmpfile) if File.exists?(tmpfile)
69
+ else
70
+ status = 'header not found'
69
71
  end
72
+ $stdout.puts status
73
+ $stdout.flush
70
74
  end
71
75
 
72
- # Given an #include <foo/bar.h>, return actual filename /path/to/foo/bar.h
76
+ # Given an #include <dispatch/object.h>, return actual filename
77
+ # /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include/dispatch/object.h
73
78
  def find_header_file(header)
74
- # TODO: really crawl through cpp include path to find this
75
- "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include/#{header}"
79
+ filename = nil
80
+ header_include_paths.each do |path|
81
+ maybe_filename = "#{path}/#{header}"
82
+ if File.exists?(maybe_filename)
83
+ filename = maybe_filename
84
+ break
85
+ end
86
+ end
87
+ filename
88
+ end
89
+
90
+ # Return GCC header include path
91
+ # (http://stackoverflow.com/a/19839946, http://stackoverflow.com/a/19852298)
92
+ # gcc -Wp,-v -xc /dev/null -fsyntax-only 2>&1
93
+ def header_include_paths
94
+ cmd = RbConfig::MAKEFILE_CONFIG["CC"]
95
+ args = %w{-Wp,-v -xc /dev/null -fsyntax-only}
96
+ paths = []
97
+ reading_paths = false
98
+ run_command(cmd, *args) do |line|
99
+ line.chomp!
100
+ if reading_paths
101
+ if line == 'End of search list.'
102
+ reading_paths = false
103
+ elsif line.match(/\A /)
104
+ line.strip!
105
+ line.sub!(/\s+\(framework directory\)\Z/, '')
106
+ paths << line
107
+ end
108
+ elsif line == '#include <...> search starts here:'
109
+ reading_paths = true
110
+ end
111
+ end
112
+ paths
113
+ end
114
+
115
+ # Safely run a command with no shell escapes, pass output lines to callback
116
+ def run_command(cmd, *args)
117
+ raise ArgumentError.new('missing required cmd to run') if cmd.nil?
118
+ rd, wr = IO.pipe
119
+ if fork
120
+ wr.close
121
+ if block_given?
122
+ rd.each { |line| yield(line) }
123
+ else
124
+ rd.read
125
+ end
126
+ rd.close
127
+ Process.wait
128
+ else
129
+ rd.close
130
+ $stdout.reopen(wr)
131
+ $stderr.reopen(wr)
132
+ exec cmd, *args
133
+ raise "exec #{cmd} failed"
134
+ end
135
+ $? == 0 # return a bool indicating a successful exit
76
136
  end
77
137
 
78
138
  # Redefine constant without warning (http://stackoverflow.com/q/3375360)
79
- class Object
80
- def set_constant!(const, value)
81
- mod = self.is_a?(Module) ? self : self.class
82
- mod.send(:remove_const, const) if mod.const_defined?(const)
83
- mod.const_set(const, value)
139
+ def set_constant!(const, value)
140
+ unless Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.0')
141
+ # Ruby 2.0.0 and newer no longer warn when const_set() redefines constant
142
+ Object::send(:remove_const, const) if Object::const_defined?(const)
84
143
  end
144
+ Object::send(:const_set, const, value)
85
145
  end
86
146
 
87
147
  # Run main loop and exit
@@ -2,7 +2,7 @@
2
2
  * movewin_ext.c - Ruby extension to list and move OS X windows
3
3
  * Andrew Ho (andrew@zeuscat.com)
4
4
  *
5
- * Copyright (c) 2014, Andrew Ho.
5
+ * Copyright (c) 2014-2020, Andrew Ho.
6
6
  * All rights reserved.
7
7
  *
8
8
  * Redistribution and use in source and binary forms, with or without
@@ -44,7 +44,10 @@ static VALUE MW_WindowClass;
44
44
  void Init_movewin_ext();
45
45
 
46
46
  /* Ruby method implementations */
47
- VALUE MW_is_authorized(VALUE module); /* MoveWin.authorized? */
47
+ VALUE MW_is_recording_authorized(VALUE module);
48
+ /* MoveWin.recording_authorized? */
49
+ VALUE MW_is_accessibility_authorized(VALUE module);
50
+ /* MoveWin.accessibility_authorized? */
48
51
  VALUE MW_display_size(VALUE module); /* MoveWin.display_size */
49
52
  VALUE MW_windows(VALUE module); /* MoveWin.windows */
50
53
  VALUE MW_Window_id(VALUE self); /* MoveWin::Window.id */
@@ -86,7 +89,10 @@ void Init_movewin_ext() {
86
89
 
87
90
  /* Define module MoveWin and its methods */
88
91
  MW_Module = rb_define_module("MoveWin");
89
- rb_define_singleton_method(MW_Module, "authorized?", MW_is_authorized, 0);
92
+ rb_define_singleton_method(MW_Module, "recording_authorized?",
93
+ MW_is_recording_authorized, 0);
94
+ rb_define_singleton_method(MW_Module, "accessibility_authorized?",
95
+ MW_is_accessibility_authorized, 0);
90
96
  rb_define_singleton_method(MW_Module, "display_size", MW_display_size, 0);
91
97
  rb_define_singleton_method(MW_Module, "windows", MW_windows, 0);
92
98
 
@@ -104,9 +110,14 @@ void Init_movewin_ext() {
104
110
  rb_define_method(MW_WindowClass, "to_s", MW_Window_to_string, 0);
105
111
  }
106
112
 
113
+ /* Return true if we are authorized to do screen recording */
114
+ VALUE MW_is_recording_authorized(VALUE module) {
115
+ return isAuthorizedForScreenRecording() ? Qtrue : Qfalse;
116
+ }
117
+
107
118
  /* Return true if we are authorized to use OS X accessibility APIs */
108
- VALUE MW_is_authorized(VALUE module) {
109
- return isAuthorized() ? Qtrue : Qfalse;
119
+ VALUE MW_is_accessibility_authorized(VALUE module) {
120
+ return isAuthorizedForAccessibility() ? Qtrue : Qfalse;
110
121
  }
111
122
 
112
123
  /* Return dimensions of current main display as an array of two integers */
@@ -2,7 +2,7 @@
2
2
  * winutils.c - utility functions for listing and moving windows
3
3
  * Andrew Ho (andrew@zeuscat.com)
4
4
  *
5
- * Copyright (c) 2014, Andrew Ho.
5
+ * Copyright (c) 2014-2020, Andrew Ho.
6
6
  * All rights reserved.
7
7
  *
8
8
  * Redistribution and use in source and binary forms, with or without
@@ -186,8 +186,30 @@ CGSize CGWindowGetSize(CFDictionaryRef window) {
186
186
  return CGSizeMake(width, height);
187
187
  }
188
188
 
189
+ /* Return true if and only if we are authorized to do screen recording */
190
+ bool isAuthorizedForScreenRecording() {
191
+ if (MAC_OS_X_VERSION_MIN_REQUIRED < 101500) {
192
+ /* OS X prior to Catalina does not require separate permissions */
193
+ return 1;
194
+ } else {
195
+ CGDisplayStreamFrameAvailableHandler handler =
196
+ ^(CGDisplayStreamFrameStatus status,
197
+ uint64_t display_time,
198
+ IOSurfaceRef frame_surface,
199
+ CGDisplayStreamUpdateRef updateRef) { return; };
200
+ CGDisplayStreamRef stream =
201
+ CGDisplayStreamCreate(CGMainDisplayID(), 1, 1, 'BGRA', NULL, handler);
202
+ if (stream == NULL) {
203
+ return 0;
204
+ } else {
205
+ CFRelease(stream);
206
+ return 1;
207
+ }
208
+ }
209
+ }
210
+
189
211
  /* Return true if and only if we are authorized to call accessibility APIs */
190
- bool isAuthorized() {
212
+ bool isAuthorizedForAccessibility() {
191
213
  #if MAC_OS_X_VERSION_MIN_REQUIRED < 1090
192
214
  return AXAPIEnabled() || AXIsProcessTrusted();
193
215
  #else
@@ -2,7 +2,7 @@
2
2
  * winutils.h - utility functions for listing and moving windows
3
3
  * Andrew Ho (andrew@zeuscat.com)
4
4
  *
5
- * Copyright (c) 2014, Andrew Ho.
5
+ * Copyright (c) 2014-2020, Andrew Ho.
6
6
  * All rights reserved.
7
7
  *
8
8
  * Redistribution and use in source and binary forms, with or without
@@ -63,8 +63,11 @@ char *windowTitle(char *appName, char *windowName);
63
63
  CGPoint CGWindowGetPosition(CFDictionaryRef window);
64
64
  CGSize CGWindowGetSize(CFDictionaryRef window);
65
65
 
66
+ /* Return true if and only if we are authorized to do screen recording */
67
+ bool isAuthorizedForScreenRecording();
68
+
66
69
  /* Return true if and only if we are authorized to call accessibility APIs */
67
- bool isAuthorized();
70
+ bool isAuthorizedForAccessibility();
68
71
 
69
72
  /* Given window dictionary from CGWindowList, return accessibility object */
70
73
  AXUIElementRef AXWindowFromCGWindow(CFDictionaryRef window);
@@ -2,7 +2,7 @@
2
2
  # movewin.rb - Ruby native code that augments movewin_ext Ruby extension
3
3
  # Andrew Ho (andrew@zeuscat.com)
4
4
  #
5
- # Copyright (c) 2014, Andrew Ho.
5
+ # Copyright (c) 2014-2020, Andrew Ho.
6
6
  # All rights reserved.
7
7
  #
8
8
  # Redistribution and use in source and binary forms, with or without
@@ -36,7 +36,7 @@
36
36
  require 'movewin/movewin_ext'
37
37
 
38
38
  module MoveWin
39
- VERSION = '1.6'
39
+ VERSION = '1.11'
40
40
 
41
41
  # Individual accessors for display size components
42
42
  def self.display_width; MoveWin.display_size[0]; end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: movewin
3
3
  version: !ruby/object:Gem::Version
4
- version: '1.6'
4
+ version: '1.11'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Ho
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-01 00:00:00.000000000 Z
11
+ date: 2020-07-03 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: List and move OS X windows from Ruby via the OS X accessibility APIs.
14
14
  email: andrew@zeuscat.com
@@ -17,6 +17,7 @@ extensions:
17
17
  - ext/movewin/extconf.rb
18
18
  extra_rdoc_files: []
19
19
  files:
20
+ - ext/movewin/dispatch/empty.rb
20
21
  - ext/movewin/extconf.rb
21
22
  - ext/movewin/movewin_ext.c
22
23
  - ext/movewin/winutils.c
@@ -32,17 +33,16 @@ require_paths:
32
33
  - lib
33
34
  required_ruby_version: !ruby/object:Gem::Requirement
34
35
  requirements:
35
- - - ! '>='
36
+ - - ">="
36
37
  - !ruby/object:Gem::Version
37
38
  version: '0'
38
39
  required_rubygems_version: !ruby/object:Gem::Requirement
39
40
  requirements:
40
- - - ! '>='
41
+ - - ">="
41
42
  - !ruby/object:Gem::Version
42
43
  version: '0'
43
44
  requirements: []
44
- rubyforge_project:
45
- rubygems_version: 2.4.2
45
+ rubygems_version: 3.0.3
46
46
  signing_key:
47
47
  specification_version: 4
48
48
  summary: List and move OS X windows from Ruby