osxhotkey 0.0.1
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.
- data/CHANGELOG +5 -0
- data/README +29 -0
- data/Rakefile +120 -0
- data/ext/extconf.rb +7 -0
- data/ext/osxhotkey.c +85 -0
- data/lib/osx/hotkey.rb +75 -0
- data/test/osxhotkey_test.rb +46 -0
- data/test/test_helper.rb +3 -0
- metadata +63 -0
data/README
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
osx/hotkey
|
3
|
+
by cho45 <cho45@lowreal.net>
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
Enable Hotkey integraion with Ruby/Cocoa
|
7
|
+
|
8
|
+
== FEATURES/PROBLEMS:
|
9
|
+
|
10
|
+
* Add a new NSApplication subclass named NSApplicationWithHotKey
|
11
|
+
|
12
|
+
== SYNOPSYS:
|
13
|
+
|
14
|
+
require 'osx/cocoa'
|
15
|
+
require 'osx/hotkey'
|
16
|
+
|
17
|
+
app = NSApplicationWithHotKey.sharedApplication
|
18
|
+
ref = app.register_hotkey("Command+Shift+J") do
|
19
|
+
puts 'hello'
|
20
|
+
end
|
21
|
+
|
22
|
+
app.run
|
23
|
+
|
24
|
+
Yes. Run this script, and press Command+Shift+J, and see 'hello' on stdout.
|
25
|
+
|
26
|
+
== LICENSE:
|
27
|
+
|
28
|
+
Ruby's
|
29
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'rake/packagetask'
|
6
|
+
require 'rake/gempackagetask'
|
7
|
+
require 'rake/rdoctask'
|
8
|
+
require 'rake/contrib/rubyforgepublisher'
|
9
|
+
require 'fileutils'
|
10
|
+
include FileUtils
|
11
|
+
|
12
|
+
AUTHOR = "cho45"
|
13
|
+
EMAIL = "cho45@lowreal.net"
|
14
|
+
DESCRIPTION = "HotKey integration with Ruby/Cocoa"
|
15
|
+
RUBYFORGE_PROJECT = "osxhotkey"
|
16
|
+
HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
|
17
|
+
BIN_FILES = %w( )
|
18
|
+
VERS = "0.0.1"
|
19
|
+
|
20
|
+
|
21
|
+
NAME = "osxhotkey"
|
22
|
+
REV = File.read(".svn/entries")[/committed-rev="(d+)"/, 1] rescue nil
|
23
|
+
CLEAN.include ['**/.*.sw?', '*.gem', '.config']
|
24
|
+
RDOC_OPTS = ['--quiet', '--title', "osxhotkey documentation",
|
25
|
+
"--opname", "index.html",
|
26
|
+
"--line-numbers",
|
27
|
+
"--main", "README",
|
28
|
+
"--inline-source"]
|
29
|
+
|
30
|
+
desc "Packages up osxhotkey gem."
|
31
|
+
task :default => [:test]
|
32
|
+
task :package => [:clean]
|
33
|
+
|
34
|
+
Rake::TestTask.new("test") { |t|
|
35
|
+
sh %{ruby setup.rb config}
|
36
|
+
sh %{ruby setup.rb setup}
|
37
|
+
t.libs << "test"
|
38
|
+
t.libs << "ext"
|
39
|
+
t.pattern = "test/**/*_test.rb"
|
40
|
+
t.verbose = true
|
41
|
+
}
|
42
|
+
|
43
|
+
spec = Gem::Specification.new do |s|
|
44
|
+
s.name = NAME
|
45
|
+
s.version = VERS
|
46
|
+
s.platform = Gem::Platform::RUBY
|
47
|
+
s.has_rdoc = true
|
48
|
+
s.extra_rdoc_files = ["README", "CHANGELOG"]
|
49
|
+
s.rdoc_options += RDOC_OPTS + ['--exclude', '^(examples|extras)/']
|
50
|
+
s.summary = DESCRIPTION
|
51
|
+
s.description = DESCRIPTION
|
52
|
+
s.author = AUTHOR
|
53
|
+
s.email = EMAIL
|
54
|
+
s.homepage = HOMEPATH
|
55
|
+
s.executables = BIN_FILES
|
56
|
+
s.rubyforge_project = RUBYFORGE_PROJECT
|
57
|
+
s.bindir = "bin"
|
58
|
+
s.require_path = "lib"
|
59
|
+
s.autorequire = "osx/hotkey"
|
60
|
+
s.test_files = Dir["test/test_*.rb"]
|
61
|
+
|
62
|
+
#s.add_dependency('activesupport', '>=1.3.1')
|
63
|
+
#s.required_ruby_version = '>= 1.8.2'
|
64
|
+
|
65
|
+
s.files = %w(README CHANGELOG Rakefile) +
|
66
|
+
Dir.glob("{bin,doc,test,lib,templates,generator,extras,website,script}/**/*") +
|
67
|
+
Dir.glob("ext/**/*.{h,c,rb}") +
|
68
|
+
Dir.glob("examples/**/*.rb") +
|
69
|
+
Dir.glob("tools/*.rb")
|
70
|
+
|
71
|
+
s.extensions = FileList["ext/**/extconf.rb"].to_a
|
72
|
+
end
|
73
|
+
|
74
|
+
Rake::GemPackageTask.new(spec) do |p|
|
75
|
+
p.need_tar = true
|
76
|
+
p.gem_spec = spec
|
77
|
+
end
|
78
|
+
|
79
|
+
task :install do
|
80
|
+
name = "#{NAME}-#{VERS}.gem"
|
81
|
+
sh %{rake package}
|
82
|
+
sh %{sudo gem install pkg/#{name}}
|
83
|
+
end
|
84
|
+
|
85
|
+
task :uninstall => [:clean] do
|
86
|
+
sh %{sudo gem uninstall #{NAME}}
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
Rake::RDocTask.new do |rdoc|
|
91
|
+
rdoc.rdoc_dir = 'html'
|
92
|
+
rdoc.options += RDOC_OPTS
|
93
|
+
rdoc.template = "#{ENV['template']}.rb" if ENV['template']
|
94
|
+
if ENV['DOC_FILES']
|
95
|
+
rdoc.rdoc_files.include(ENV['DOC_FILES'].split(/,\s*/))
|
96
|
+
else
|
97
|
+
rdoc.rdoc_files.include('README', 'CHANGELOG')
|
98
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
desc "Publish to RubyForge"
|
103
|
+
task :rubyforge => [:rdoc, :package] do
|
104
|
+
Rake::RubyForgePublisher.new(RUBYFORGE_PROJECT, 'cho45').upload
|
105
|
+
end
|
106
|
+
|
107
|
+
desc "Publish to lab"
|
108
|
+
task :publab do
|
109
|
+
require 'rake/contrib/sshpublisher'
|
110
|
+
|
111
|
+
path = File.expand_path(File.dirname(__FILE__))
|
112
|
+
|
113
|
+
Rake::SshDirPublisher.new(
|
114
|
+
"cho45@lab.lowreal.net",
|
115
|
+
"/srv/www/lab.lowreal.net/public/site-ruby",
|
116
|
+
path + "/pkg"
|
117
|
+
).upload
|
118
|
+
end
|
119
|
+
|
120
|
+
|
data/ext/extconf.rb
ADDED
data/ext/osxhotkey.c
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
|
2
|
+
#include <Carbon/Carbon.h>
|
3
|
+
#include <ruby.h>
|
4
|
+
|
5
|
+
struct rhk {
|
6
|
+
EventHotKeyRef hotkeyref;
|
7
|
+
};
|
8
|
+
|
9
|
+
static VALUE
|
10
|
+
rhk_alloc(VALUE klass) {
|
11
|
+
struct rhk* ptr = ALLOC(struct rhk);
|
12
|
+
|
13
|
+
return Data_Wrap_Struct(klass, 0, -1, ptr);
|
14
|
+
}
|
15
|
+
|
16
|
+
static VALUE
|
17
|
+
rhk_initialize(VALUE self, VALUE keyCode, VALUE modifiers) {
|
18
|
+
rb_ivar_set(self, rb_intern("@keyCode"), keyCode);
|
19
|
+
rb_ivar_set(self, rb_intern("@modifiers"), modifiers);
|
20
|
+
|
21
|
+
return Qnil;
|
22
|
+
}
|
23
|
+
|
24
|
+
static VALUE
|
25
|
+
rhk_register(VALUE self) {
|
26
|
+
static UInt32 _id = 0;
|
27
|
+
VALUE modifiers, keyCode;
|
28
|
+
|
29
|
+
keyCode = rb_ivar_get(self, rb_intern("@keyCode"));
|
30
|
+
modifiers = rb_ivar_get(self, rb_intern("@modifiers"));
|
31
|
+
|
32
|
+
UInt32 modifier = NUM2INT(modifiers);
|
33
|
+
|
34
|
+
EventHotKeyID keyId;
|
35
|
+
keyId.signature = 'HtKe';
|
36
|
+
keyId.id = _id++;
|
37
|
+
|
38
|
+
EventHotKeyRef hotKeyRef;
|
39
|
+
OSStatus status = RegisterEventHotKey(
|
40
|
+
NUM2INT(keyCode),
|
41
|
+
modifier,
|
42
|
+
keyId,
|
43
|
+
GetApplicationEventTarget(),
|
44
|
+
0,
|
45
|
+
&hotKeyRef
|
46
|
+
);
|
47
|
+
|
48
|
+
if (status != noErr) rb_raise(rb_eStandardError, "RegisterEventHotKey returned Error status");
|
49
|
+
|
50
|
+
struct rhk* ptr;
|
51
|
+
Data_Get_Struct(self, struct rhk, ptr);
|
52
|
+
ptr->hotkeyref = hotKeyRef;
|
53
|
+
|
54
|
+
return INT2NUM((unsigned int)hotKeyRef);
|
55
|
+
}
|
56
|
+
|
57
|
+
static VALUE
|
58
|
+
rhk_unregister(VALUE self) {
|
59
|
+
struct rhk* ptr;
|
60
|
+
Data_Get_Struct(self, struct rhk, ptr);
|
61
|
+
UnregisterEventHotKey(ptr->hotkeyref);
|
62
|
+
return Qtrue;
|
63
|
+
}
|
64
|
+
|
65
|
+
void
|
66
|
+
Init_osxhotkey () {
|
67
|
+
VALUE HotKey;
|
68
|
+
VALUE module;
|
69
|
+
|
70
|
+
rb_eval_string("require 'osx/cocoa'");
|
71
|
+
module = rb_eval_string("OSX");
|
72
|
+
|
73
|
+
HotKey = rb_define_class_under(module, "HotKey", rb_cObject);
|
74
|
+
rb_define_const(HotKey, "SHIFT", INT2NUM(shiftKey));
|
75
|
+
rb_define_const(HotKey, "CONTROL", INT2NUM(controlKey));
|
76
|
+
rb_define_const(HotKey, "COMMAND", INT2NUM(cmdKey));
|
77
|
+
rb_define_const(HotKey, "OPTION", INT2NUM(optionKey));
|
78
|
+
|
79
|
+
rb_define_alloc_func(HotKey, rhk_alloc);
|
80
|
+
rb_define_private_method(HotKey, "initialize", rhk_initialize, 2);
|
81
|
+
rb_define_method(HotKey, "register", rhk_register, 0);
|
82
|
+
rb_define_method(HotKey, "unregister", rhk_unregister, 0);
|
83
|
+
}
|
84
|
+
|
85
|
+
|
data/lib/osx/hotkey.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#
|
3
|
+
|
4
|
+
require 'osx/cocoa'
|
5
|
+
require 'osxhotkey.so'
|
6
|
+
|
7
|
+
include OSX
|
8
|
+
|
9
|
+
class OSX::NSApplicationWithHotKey < NSApplication
|
10
|
+
|
11
|
+
ns_override 'sendEvent:'
|
12
|
+
|
13
|
+
KEYMAP = {
|
14
|
+
"0" => 0x1D, "1" => 0x12, "2" => 0x13, "3" => 0x14,
|
15
|
+
"4" => 0x15, "5" => 0x17, "6" => 0x16, "7" => 0x1A,
|
16
|
+
"8" => 0x1C, "9" => 0x19, "A" => 0x00, "B" => 0x0B,
|
17
|
+
"C" => 0x08, "D" => 0x02, "E" => 0x0E, "F" => 0x03,
|
18
|
+
"G" => 0x05, "H" => 0x04, "I" => 0x22, "J" => 0x26,
|
19
|
+
"K" => 0x28, "L" => 0x25, "M" => 0x2E, "N" => 0x2D,
|
20
|
+
"O" => 0x1F, "P" => 0x23, "Q" => 0x0C, "R" => 0x0F,
|
21
|
+
"S" => 0x01, "T" => 0x11, "U" => 0x20, "V" => 0x09,
|
22
|
+
"W" => 0x0D, "X" => 0x07, "Y" => 0x10, "Z" => 0x06,
|
23
|
+
}
|
24
|
+
|
25
|
+
def sendEvent(event) # :nodoc:
|
26
|
+
if event.oc_type == 14 &&
|
27
|
+
event.subtype == 6
|
28
|
+
@hotkey_procs ||= {}
|
29
|
+
if @hotkey_procs[event.data1]
|
30
|
+
@hotkey_procs[event.data1].call
|
31
|
+
end
|
32
|
+
end
|
33
|
+
super_sendEvent(event)
|
34
|
+
end
|
35
|
+
|
36
|
+
# This method register the _keys_ as global hotkey.
|
37
|
+
# And when the key is pressed, call the _block_.
|
38
|
+
#
|
39
|
+
# _keys_ is caseinsensitive
|
40
|
+
def register_hotkey(keys, &block)
|
41
|
+
raise ArgumentError, "Require block." unless block_given?
|
42
|
+
mod = 0
|
43
|
+
key = nil
|
44
|
+
keys.split('+').each do |k|
|
45
|
+
k = k.upcase
|
46
|
+
case k
|
47
|
+
when 'SHIFT', 'CONTROL', 'COMMAND', 'OPTION'
|
48
|
+
mod |= HotKey.const_get(k)
|
49
|
+
else
|
50
|
+
if KEYMAP[k]
|
51
|
+
key = KEYMAP[k]
|
52
|
+
else
|
53
|
+
raise ArgumentError, "The Key #{k} is not in Map"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
raise ArgumentError, "The Key is invalid" unless key
|
58
|
+
ref = HotKey.new(key, mod)
|
59
|
+
id = ref.register
|
60
|
+
@hotkey_procs ||= {}
|
61
|
+
@hotkey_procs[id] = block
|
62
|
+
ref
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
if $0 == __FILE__
|
68
|
+
app = NSApplicationWithHotKey.sharedApplication
|
69
|
+
ref = app.register_hotkey("command+shift+j") do
|
70
|
+
puts 'hello'
|
71
|
+
end
|
72
|
+
|
73
|
+
app.run
|
74
|
+
end
|
75
|
+
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
|
3
|
+
class OsxhotkeyTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
end
|
6
|
+
|
7
|
+
def test_load
|
8
|
+
assert true
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_keys
|
12
|
+
require 'thread'
|
13
|
+
|
14
|
+
q = SizedQueue.new(1)
|
15
|
+
|
16
|
+
app = NSApplicationWithHotKey.sharedApplication
|
17
|
+
assert_raise(ArgumentError) do
|
18
|
+
app.register_hotkey("") do
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
keytest = %w(
|
23
|
+
Command+Shift+T
|
24
|
+
Control+Option+T
|
25
|
+
)
|
26
|
+
|
27
|
+
keytest.each_with_index do |k,i|
|
28
|
+
app.register_hotkey(k) do
|
29
|
+
q << "OK#{i}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
Thread.start do
|
34
|
+
Thread.current.abort_on_exception = true
|
35
|
+
|
36
|
+
keytest.each_with_index do |k,i|
|
37
|
+
puts "Press #{k}"
|
38
|
+
assert_equal "OK#{i}", q.pop
|
39
|
+
end
|
40
|
+
|
41
|
+
app.stop(nil)
|
42
|
+
end
|
43
|
+
|
44
|
+
app.run
|
45
|
+
end
|
46
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.0
|
3
|
+
specification_version: 1
|
4
|
+
name: osxhotkey
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.0.1
|
7
|
+
date: 2006-11-14 00:00:00 +09:00
|
8
|
+
summary: HotKey integration with Ruby/Cocoa
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: cho45@lowreal.net
|
12
|
+
homepage: http://osxhotkey.rubyforge.org
|
13
|
+
rubyforge_project: osxhotkey
|
14
|
+
description: HotKey integration with Ruby/Cocoa
|
15
|
+
autorequire: osx/hotkey
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
-
|
22
|
+
- ">"
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 0.0.0
|
25
|
+
version:
|
26
|
+
platform: ruby
|
27
|
+
signing_key:
|
28
|
+
cert_chain:
|
29
|
+
post_install_message:
|
30
|
+
authors:
|
31
|
+
- cho45
|
32
|
+
files:
|
33
|
+
- README
|
34
|
+
- CHANGELOG
|
35
|
+
- Rakefile
|
36
|
+
- test/osxhotkey_test.rb
|
37
|
+
- test/test_helper.rb
|
38
|
+
- lib/osx
|
39
|
+
- lib/osx/hotkey.rb
|
40
|
+
- ext/osxhotkey.c
|
41
|
+
- ext/extconf.rb
|
42
|
+
test_files:
|
43
|
+
- test/test_helper.rb
|
44
|
+
rdoc_options:
|
45
|
+
- "--quiet"
|
46
|
+
- "--title"
|
47
|
+
- osxhotkey documentation
|
48
|
+
- "--opname"
|
49
|
+
- index.html
|
50
|
+
- "--line-numbers"
|
51
|
+
- "--main"
|
52
|
+
- README
|
53
|
+
- "--inline-source"
|
54
|
+
- "--exclude"
|
55
|
+
- "^(examples|extras)/"
|
56
|
+
extra_rdoc_files:
|
57
|
+
- README
|
58
|
+
- CHANGELOG
|
59
|
+
executables: []
|
60
|
+
extensions:
|
61
|
+
- ext/extconf.rb
|
62
|
+
requirements: []
|
63
|
+
dependencies: []
|