movewin 1.6 → 1.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/ext/movewin/dispatch/empty.rb +4 -0
- data/ext/movewin/extconf.rb +102 -42
- data/ext/movewin/movewin_ext.c +16 -5
- data/ext/movewin/winutils.c +24 -2
- data/ext/movewin/winutils.h +5 -2
- data/lib/movewin.rb +2 -2
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
NWIxMjcyMDY0MzMxMzkzOTg0ZTI0MzI4ZmMxYmI5NjA0YTg0Mzk1Yg==
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3843c385c582fdeeb83f418b7681e91506fcd9a8e0b645b321e12a3c6e02d120
|
4
|
+
data.tar.gz: 60fe63177a8b4081f64bccdbf36bd824f562a13390b082734337c95c6eba2ae1
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
MjUxODk1ODhkZTljODNhOGUyNzZmNzIxNDJiZmE4ZDI5ODRmYmQ0MDQ3ZDdl
|
11
|
-
YTI5MjE5ZDNmZDM0M2Y3ZTE3YmRiOGQzYWQwMTEyZDQ0NDZkNmY=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
YWJmNjUyNWM0ODc0MTMwMGRlNWYzNzY4NGNkMmNlNjI1ZDQ0MzY0YmQ1YTMy
|
14
|
-
ZDBjZWE4MWNkNWM1MWIwOWU2ZjAzYjhkNjZmYjg4ODg3NDMwN2FkMjc3OWE1
|
15
|
-
ZWExN2JlNmY5MzhiZDYwZGMwNGYzODVlZjYwMWUxMTc1MGQzNDI=
|
6
|
+
metadata.gz: acb032ac21110ad0b3d142966a3e43e1c7f2be28780eb90e2f655d2b10a3f2850169757bc9ce01aef87c43cc4ae435f82cc6129883c8471a2c8f23000f4efe86
|
7
|
+
data.tar.gz: 3701ad4547eec20f8a4604250a82a23c778cfc596e0fdc561af70e1485103505ae1565e17de707307c0b4c513c76ec923e0a3dc42806b1e8d4e93c157ee2acbd
|
data/ext/movewin/extconf.rb
CHANGED
@@ -7,12 +7,7 @@ def main(argv = [])
|
|
7
7
|
$CFLAGS = '-Wall'
|
8
8
|
$LDFLAGS = '-Wall -framework Carbon'
|
9
9
|
|
10
|
-
|
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
|
25
|
+
# Return true if our compiler is GCC (not Clang), as for RVM installed Ruby
|
36
26
|
def using_gcc?
|
37
|
-
|
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
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
File.
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
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
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
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
|
-
|
64
|
+
status = 'skipped'
|
64
65
|
end
|
65
|
-
|
66
|
+
ensure
|
67
|
+
File.unlink(tmpfile) if File.exists?(tmpfile)
|
66
68
|
end
|
67
|
-
|
68
|
-
|
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 <
|
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
|
-
|
75
|
-
|
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
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
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
|
data/ext/movewin/movewin_ext.c
CHANGED
@@ -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
|
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, "
|
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
|
109
|
-
return
|
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 */
|
data/ext/movewin/winutils.c
CHANGED
@@ -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
|
212
|
+
bool isAuthorizedForAccessibility() {
|
191
213
|
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1090
|
192
214
|
return AXAPIEnabled() || AXIsProcessTrusted();
|
193
215
|
#else
|
data/ext/movewin/winutils.h
CHANGED
@@ -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
|
70
|
+
bool isAuthorizedForAccessibility();
|
68
71
|
|
69
72
|
/* Given window dictionary from CGWindowList, return accessibility object */
|
70
73
|
AXUIElementRef AXWindowFromCGWindow(CFDictionaryRef window);
|
data/lib/movewin.rb
CHANGED
@@ -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.
|
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.
|
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:
|
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
|
-
|
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
|