meow 1.1.0 → 2.0.0

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.
@@ -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.