Jorricks / macos-notifications

Create interactable notifications in the Notification Centre on any Mac using Python
https://jorricks.github.io/macos-notifications/
MIT License
69 stars 4 forks source link

Missing from the documentation? How to create a persistent notification #16

Closed dstromberg closed 10 months ago

dstromberg commented 10 months ago

I have a program I want to use mac_notifications in.

I need the notification to stay visible until clicked though - timing out after a handful of seconds doesn't work well for this application.

I don't see anything about this in the documentation. The closest seems to be: :param delay: Delay before showing the message.

Am I missing something?

Thanks!

dstromberg commented 10 months ago

I figured out that I probably need to use action_button_str and action_callback.

But now I'm finding that the only way I can get out of client.create_notification is to use action_callback=functools.partial(sys.exit, 0)

That seems a bit heavy handed; I don't really (necessarily) want my program to exit yet.

Here's a little sample program:

#!/usr/bin/env python3

import functools
import sys

from mac_notifications import client

def noop(*args, **kwargs):
    """No operation: do nothing."""
    pass

if __name__ == '__main__':
    client.create_notification(
        title="title",
        subtitle="subtitle",
        icon=None,
        action_button_str="Acknowledge",
        action_callback=functools.partial(sys.exit, 0),
    )
    print('hello')

I also tried action_callback=noop - that didn't appear to exit client.create_notification

How can I make this test program execute the print('hello') ?

I must be missing something. But what?

Thanks!

dstromberg commented 10 months ago

OK, making progress, but there's a third problem now:

#!/usr/bin/env python3

import sys
import time

from mac_notifications import client

def noop(*args, **kwargs):
    """No operation: do nothing."""
    pass

class Callback:
    def __init__(self):
        self.called_back = False

    def callback(self, *args, **kwargs):
        print(f'args: {args}')
        print(f'kwargs: {kwargs}')
        self.called_back = True

if __name__ == '__main__':
    cb = Callback()
    client.create_notification(
        title="title",
        subtitle="subtitle",
        icon=None,
        action_button_str="Acknowledge",
        action_callback=cb.callback,
    )
    while not cb.called_back:
        print('waiting...')
        sys.stdout.flush()
        time.sleep(1)
    print('hello!')

This one does print('hello!'), but it never exits. What do I need to do to persuade the program to "fall of the end"?

dstromberg commented 10 months ago

Is it normal for such processes to linger? I wonder if there's a wait*() somewhere?

| | -+= 85765 dstromberg /usr/local/Cellar/python@3.11/3.11.4_1/Frameworks/Python.framework/Versions/3.11/Resources/Python.app/Contents/MacOS/Python ./tst2 | | |--- 85766 dstromberg /usr/local/Cellar/python@3.11/3.11.4_1/Frameworks/Python.framework/Versions/3.11/Resources/Python.app/Contents/MacOS/Python -c from multiprocessing.resource_tracker import main;main(6) | | --- 85767 dstromberg /usr/local/Cellar/python@3.11/3.11.4_1/Frameworks/Python.framework/Versions/3.11/Resources/Python.app/Contents/MacOS/Python -c from multiprocessing.spawn import spawn_main; spawn_main(tracker_fd=7, pipe_handle=10) --multiprocessing-fork

Normally I'd approach such a problem with strace, but not on a MacOS system.

khurshid-alam commented 1 week ago

why not force exit inside callback ?

def fp():
    print ("ack")
    sys.exit(0)

#....
action_callback=functools.partial(fp)