Skip to content

Commit

Permalink
add event hooks (#140)
Browse files Browse the repository at this point in the history
Add event hooks, enable multiple event handlers
  • Loading branch information
jaredks committed Jul 5, 2021
1 parent a91ea6f commit e300fe0
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 21 deletions.
1 change: 1 addition & 0 deletions CHANGES.rst
Expand Up @@ -4,6 +4,7 @@ Changes
0.3.0.dev
---------

- Add event hooks, enable multiple event handlers #140
- Allow menu items to be hidden #138
- Fix dark mode alert style #137
- Notifications: fixes, cleanup, and tests #131
Expand Down
6 changes: 3 additions & 3 deletions rumps/_internal.py
Expand Up @@ -27,7 +27,7 @@ def require_string_or_none(*objs):
)


def call_as_function_or_method(func, event):
def call_as_function_or_method(func, *args, **kwargs):
# The idea here is that when using decorators in a class, the functions passed are not bound so we have to
# determine later if the functions we have (those saved as callbacks) for particular events need to be passed
# 'self'.
Expand All @@ -42,8 +42,8 @@ def call_as_function_or_method(func, event):
else:
for name, method in inspect.getmembers(app, predicate=inspect.ismethod):
if method.__func__ is func:
return method(event)
return func(event)
return method(*args, **kwargs)
return func(*args, **kwargs)


def guard_unexpected_errors(func):
Expand Down
40 changes: 40 additions & 0 deletions rumps/events.py
@@ -0,0 +1,40 @@
# -*- coding: utf-8 -*-

import traceback

from . import _internal


class EventEmitter(object):
def __init__(self, name):
self.name = name
self.callbacks = set()
self._executor = _internal.call_as_function_or_method

def register(self, func):
self.callbacks.add(func)
return func

def unregister(self, func):
try:
self.callbacks.remove(func)
return True
except KeyError:
return False

def emit(self, *args, **kwargs):
#print('EventEmitter("%s").emit called' % self.name)
for callback in self.callbacks:
try:
self._executor(callback, *args, **kwargs)
except Exception:
traceback.print_exc()

__call__ = register


before_start = EventEmitter('before_start')
on_notification = EventEmitter('on_notification')
on_sleep = EventEmitter('on_sleep')
on_wake = EventEmitter('on_wake')
before_quit = EventEmitter('before_quit')
15 changes: 5 additions & 10 deletions rumps/notifications.py
Expand Up @@ -15,6 +15,7 @@

from . import _internal
from . import compat
from . import events


def on_notification(f):
Expand All @@ -32,8 +33,7 @@ def notification_center(info):
print 'i know this'
"""
on_notification.__dict__['*'] = f
return f
return events.on_notification.register(f)


def _gather_info_issue_9(): # pragma: no cover
Expand Down Expand Up @@ -116,20 +116,15 @@ def _clicked(ns_user_notification_center, ns_user_notification):
traceback.print_exc()
return

try:
notification_handler = getattr(on_notification, '*')
except AttributeError:
# notification center function not specified, no error but log warning
# notification center function not specified => no error but log warning
if not events.on_notification.callbacks:
rumps._log(
'WARNING: notification received but no function specified for '
'answering it; use @notifications decorator to register a function.'
)
else:
notification = Notification(ns_user_notification, data)
try:
_internal.call_as_function_or_method(notification_handler, notification)
except Exception:
traceback.print_exc()
events.on_notification.emit(notification)


def notify(title, subtitle, message, data=None, sound=True,
Expand Down
20 changes: 12 additions & 8 deletions rumps/rumps.py
Expand Up @@ -24,6 +24,7 @@
from .compat import text_type, string_types, iteritems, collections_abc

from . import _internal
from . import events
from . import notifications

_TIMERS = weakref.WeakKeyDictionary()
Expand Down Expand Up @@ -965,15 +966,17 @@ def applicationDidFinishLaunching_(self, notification):
None
)

def receiveSleepNotification_(self, notification):
_log("receiveSleepNotification")
app = getattr(App, '*app_instance')
return app.sleep()
def receiveSleepNotification_(self, ns_notification):
_log('receiveSleepNotification')
events.on_sleep.emit()

def receiveWakeNotification_(self, notification):
_log("receiveWakeNotification")
app = getattr(App, '*app_instance')
return app.wake()
def receiveWakeNotification_(self, ns_notification):
_log('receiveWakeNotification')
events.on_wake.emit()

def applicationWillTerminate_(self, ns_notification):
_log('applicationWillTerminate')
events.before_quit.emit()

@classmethod
def callback_(cls, nsmenuitem):
Expand Down Expand Up @@ -1183,4 +1186,5 @@ def run(self, **options):
self._nsapp.initializeStatusBar()

AppHelper.installMachInterrupt()
events.before_start.emit()
AppHelper.runEventLoop()

0 comments on commit e300fe0

Please sign in to comment.