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