Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add event hooks #140

Merged
merged 4 commits into from Jul 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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()