meow 1.1.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,15 @@
1
+ === 2.0.0
2
+
3
+ * 1 Major enhancement
4
+
5
+ * Run and stop methods have been removed (Thanks David Billskog!)
6
+
7
+ * 3 Bugfixes
8
+
9
+ * Updated Ruby/Cocoa syntax conventions
10
+ * Fixed a typo with "sticky" options
11
+ * Updated copyright
12
+
1
13
  === 1.1.0 / 2008-06-13
2
14
 
3
15
  * 3 major enhancements
@@ -29,12 +29,20 @@ Send Growl notifications via Ruby.
29
29
  == THANKS:
30
30
 
31
31
  Thanks to the Growl team! This code is heavily based on their ruby example.
32
+ Thanks to Satoshi for the click code from Lime Chat.
32
33
 
33
34
  == LICENSE:
34
35
 
35
36
  (The MIT License)
36
37
 
37
- Copyright (c) 2008 Aaron Patterson, Evan Phoenix, Eric Hodel
38
+ Copyright (c) 2008:
39
+
40
+ * {Aaron Patterson}[http://tenderlovemaking.com]
41
+ * Evan Phoenix
42
+ * Eric Hodel
43
+ * Justin Palmer
44
+ * Satoshi Nakagawa
45
+ * David Billskog
38
46
 
39
47
  Permission is hereby granted, free of charge, to any person obtaining
40
48
  a copy of this software and associated documentation files (the
@@ -2,7 +2,7 @@ require 'osx/cocoa'
2
2
  require 'meow/notifier'
3
3
 
4
4
  class Meow
5
- VERSION = '1.1.0'
5
+ VERSION = '2.0.0'
6
6
  PRIORITIES = { :very_low => -2,
7
7
  :moderate => -1,
8
8
  :normal => 0,
@@ -22,6 +22,9 @@ class Meow
22
22
  @@callbacks = Notifier.new
23
23
  @@callbacks.setup
24
24
 
25
+ # The thread that is responsible for catching native callbacks.
26
+ @@background_runner = nil
27
+
25
28
  class << self
26
29
  ###
27
30
  # Send a message in one call.
@@ -53,19 +56,6 @@ class Meow
53
56
 
54
57
  return new_image
55
58
  end
56
-
57
- ##
58
- # Call this if you have passed blocks to #notify. This blocks forever, but
59
- # it's the only way to properly get events.
60
- def run
61
- OSX::NSApp.run
62
- end
63
-
64
- ##
65
- # Call this to cause Meow to stop running.
66
- def stop
67
- OSX::NSApp.stop(nil)
68
- end
69
59
  end
70
60
 
71
61
  attr_accessor :name, :note_type, :icon
@@ -79,7 +69,7 @@ class Meow
79
69
  #
80
70
  # Example:
81
71
  # note = Meow.new('My Application')
82
- def initialize(name, note_type = 'Note', icon = OSX::NSWorkspace.sharedWorkspace().iconForFileType_('rb'))
72
+ def initialize(name, note_type = 'Note', icon = OSX::NSWorkspace.sharedWorkspace.iconForFileType('rb'))
83
73
  @name = name
84
74
  @icon = icon
85
75
  @note_type = note_type
@@ -87,14 +77,22 @@ class Meow
87
77
 
88
78
  @pid = OSX::NSProcessInfo.processInfo.processIdentifier
89
79
 
90
- # The notification name to look for when someone clicks on a notify bubble.
91
- @clicked_name = "#{name}-#{@pid}-GrowlClicked!"
80
+ # The notification name to look for when someone clicks on a notify bubble
81
+ # or the bubble is timed out.
82
+ @clicked_name = "#{name}-#{@pid}-#{GROWL_NOTIFICATION_CLICKED}"
83
+ @timeout_name = "#{name}-#{@pid}-#{GROWL_NOTIFICATION_TIMED_OUT}"
92
84
 
93
85
  notify_center = OSX::NSDistributedNotificationCenter.defaultCenter
94
- notify_center.addObserver_selector_name_object_ @@callbacks,
95
- "clicked:",
96
- @clicked_name,
97
- nil
86
+ notify_center.objc_send(:addObserver, @@callbacks,
87
+ :selector, "clicked:",
88
+ :name, @clicked_name,
89
+ :object, nil)
90
+ notify_center.objc_send(:addObserver, @@callbacks,
91
+ :selector, "timeout:",
92
+ :name, @timeout_name,
93
+ :object, nil)
94
+
95
+ start_runner unless @@background_runner
98
96
  end
99
97
 
100
98
  ###
@@ -136,7 +134,7 @@ class Meow
136
134
  }
137
135
 
138
136
  notification[:NotificationAppIcon] = opts[:app_icon].TIFFRepresentation if opts[:app_icon]
139
- notification[:NotificationSticky] = OSX::NSNumber.numberWithBool_(true) if opts[:stick]
137
+ notification[:NotificationSticky] = OSX::NSNumber.numberWithBool(true) if opts[:sticky]
140
138
 
141
139
  notify_center = OSX::NSDistributedNotificationCenter.defaultCenter
142
140
 
@@ -144,8 +142,7 @@ class Meow
144
142
  notification[:NotificationClickContext] = @@callbacks.add(block)
145
143
  end
146
144
 
147
- d = OSX::NSDictionary.dictionaryWithDictionary_(notification)
148
- notify_center.postNotificationName_object_userInfo_deliverImmediately_('GrowlNotification', nil, d, true)
145
+ notify_center.postNotificationName_object_userInfo_deliverImmediately('GrowlNotification', nil, notification, true)
149
146
  end
150
147
 
151
148
  private
@@ -156,14 +153,30 @@ class Meow
156
153
 
157
154
  @registered = [@registered, types, default_types].flatten.uniq
158
155
 
159
- dictionary = OSX::NSDictionary.dictionaryWithDictionary({
160
- 'ApplicationName' => name,
161
- 'AllNotifications' => OSX::NSArray.arrayWithArray(types),
162
- 'DefaultNotifications' => OSX::NSArray.arrayWithArray(default_types),
163
- 'ApplicationIcon' => icon.TIFFRepresentation
164
- })
156
+ dictionary = {
157
+ :ApplicationName => name,
158
+ :AllNotifications => types,
159
+ :DefaultNotifications => default_types,
160
+ :ApplicationIcon => icon.TIFFRepresentation
161
+ }
162
+
165
163
  notify_center = OSX::NSDistributedNotificationCenter.defaultCenter
166
164
  notify_center.postNotificationName_object_userInfo_deliverImmediately_('GrowlApplicationRegistrationNotification', nil, dictionary, true)
167
165
  end
168
166
 
167
+ # Hides the infinite callback loop in the background so that it will not
168
+ # stop the flow of the application.
169
+ def start_runner
170
+ @@background_runner = Thread.new do
171
+ sleep 0.1
172
+ OSX::NSApp.run
173
+ end
174
+ at_exit do
175
+ loop do
176
+ sleep 1
177
+ OSX::NSApplication.sharedApplication.terminate(@@application) if @@callbacks.empty?
178
+ end
179
+ end
180
+ end
181
+
169
182
  end
@@ -6,6 +6,10 @@ class Meow
6
6
  @callbacks = {}
7
7
  end
8
8
 
9
+ def empty?
10
+ @callbacks.empty?
11
+ end
12
+
9
13
  def add(prc)
10
14
  pos = prc.object_id
11
15
  @callbacks[pos] = prc
@@ -13,14 +17,20 @@ class Meow
13
17
  end
14
18
 
15
19
  def clicked(notification)
16
- idx = notification.userInfo[GROWL_KEY_CLICKED_CONTEXT].to_i
17
- begin
18
- if block = @callbacks[idx]
19
- block.call
20
- end
21
- ensure
22
- @callbacks.delete idx
20
+ if block = remove_callback(notification)
21
+ block.call
23
22
  end
24
23
  end
24
+
25
+ def timeout(notification)
26
+ remove_callback(notification)
27
+ end
28
+
29
+ private
30
+
31
+ def remove_callback(notification)
32
+ idx = notification.userInfo[GROWL_KEY_CLICKED_CONTEXT].to_i
33
+ @callbacks.delete idx
34
+ end
25
35
  end
26
36
  end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = %q{meow}
3
- s.version = "1.0.0"
3
+ s.version = "1.1.0"
4
4
 
5
5
  s.specification_version = 2 if s.respond_to? :specification_version=
6
6
 
@@ -1,4 +1,5 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), "helper"))
2
+ require "timeout"
2
3
 
3
4
  class MeowTest < Test::Unit::TestCase
4
5
  ASSETS = File.expand_path(File.join(File.dirname(__FILE__), "assets"))
@@ -51,17 +52,34 @@ class MeowTest < Test::Unit::TestCase
51
52
  }
52
53
  end
53
54
 
55
+ def test_stickyness
56
+ block_called = false
57
+ meep = Meow.new('Meow Test')
58
+ meep.notify('Sticky Test', my_method_name + "\n(you should not close this by clicking the 'x')", :sticky => true) do
59
+ block_called = true
60
+ end
61
+ while !block_called do
62
+ sleep 1
63
+ end
64
+ end
65
+
54
66
  def test_clicks_work
55
- $RUBYCOCOA_SUPPRESS_EXCEPTION_LOGGING = true
56
67
  block_called = false
57
- assert_raises(RuntimeError) {
68
+ meep = Meow.new('Meow Test')
69
+ meep.notify('Click Here', my_method_name + "\n(you should not close this by clicking the 'x')", :sticky => true) do
70
+ block_called = true
71
+ end
72
+ while !block_called do
73
+ sleep 1
74
+ end
75
+ end
76
+
77
+ def test_run_should_not_block
78
+ Timeout::timeout(1) do
58
79
  meep = Meow.new('Meow Test')
59
- meep.notify('Click Here', my_method_name) do
60
- block_called = true
61
- raise 'I do not know how to get run to stop blocking!'
80
+ meep.notify('Non blocking test', my_method_name) do
81
+ #callback block
62
82
  end
63
- Meow.run
64
- }
65
- assert block_called
83
+ end
66
84
  end
67
85
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: meow
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Patterson
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-06-17 00:00:00 -07:00
12
+ date: 2008-08-13 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -57,7 +57,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
57
57
  requirements: []
58
58
 
59
59
  rubyforge_project: meow
60
- rubygems_version: 1.1.1
60
+ rubygems_version: 1.2.0
61
61
  signing_key:
62
62
  specification_version: 2
63
63
  summary: Send Growl notifications via Ruby.