osxhotkey 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG ADDED
@@ -0,0 +1,5 @@
1
+
2
+ == 0.0.1 / 2006-11-13
3
+
4
+ * initial release
5
+
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
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'mkmf'
4
+ $CFLAGS << " -framework Carbon "
5
+ $LDFLAGS << " -framework Carbon "
6
+ create_makefile 'osxhotkey'
7
+
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
@@ -0,0 +1,3 @@
1
+ require 'test/unit'
2
+ require File.dirname(__FILE__) + '/../lib/osx/hotkey'
3
+
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: []