xpra icon
Bug tracker and wiki

This bug tracker and wiki are being discontinued
please use https://github.com/Xpra-org/xpra instead.


Ticket #1305: osx-notifications.patch

File osx-notifications.patch, 5.3 KB (added by Antoine Martin, 4 years ago)

try to use native code for notifications

  • xpra/platform/darwin/gui.py

     
    1717from Quartz import CGWindowListCopyWindowInfo, kCGWindowListOptionOnScreenOnly, kCGNullWindowID, kCGWindowListOptionAll #@UnresolvedImport
    1818from AppKit import NSAppleEventManager, NSScreen, NSObject, NSBeep   #@UnresolvedImport
    1919from AppKit import NSApplication, NSWorkspace, NSWorkspaceActiveSpaceDidChangeNotification, NSWorkspaceWillSleepNotification, NSWorkspaceDidWakeNotification     #@UnresolvedImport
     20from Foundation import NSUserNotification, NSUserNotificationCenter, NSUserNotificationDefaultSoundName #@UnresolvedImport
    2021
    2122from xpra.util import envbool
     23from xpra.client.notifications.notifier_base import NotifierBase
    2224from xpra.log import Logger
     25
    2326log = Logger("osx", "events")
    2427workspacelog = Logger("osx", "events", "workspace")
    2528scrolllog = Logger("osx", "events", "scroll")
     29notifylog = Logger("osx", "notify")
    2630
    2731
    2832SLEEP_HANDLER = envbool("XPRA_OSX_SLEEP_HANDLER", True)
     
    9195    osxapp.ready()
    9296
    9397
     98notification_center = None
     99class OSX_Notifier(NotifierBase):
     100    def show_notify(self, dbus_id, tray, nid, app_name, replaces_nid, app_icon, summary, body, expire_timeout):
     101        global notification_center
     102        notification = NSUserNotification.alloc().init()
     103        notification.setTitle_(summary)
     104        notification.setInformativeText_(body)
     105        notification.setIdentifier_("%s" % nid)
     106        #enable sound:
     107        notification.setSoundName_(NSUserNotificationDefaultSoundName)
     108        notifylog("show_notify(..) %s(%s)", notification_center.deliverNotification_, notification)
     109        notification_center.deliverNotification_(notification)
     110
     111    def close_notify(self, nid):
     112        pass
     113
     114class OSX_Subprocess_Notifier(NotifierBase):
     115    def show_notify(self, dbus_id, tray, nid, app_name, replaces_nid, app_icon, summary, body, expire_timeout):
     116        from xpra.platform.darwin import osx_notifier
     117        osx_notifier_file = osx_notifier.__file__
     118        if osx_notifier_file.endswith("pyc"):
     119            os.unlink(osx_notifier_file)
     120            osx_notifier_file = osx_notifier_file[:-1]
     121        import time
     122        cmd = ["python", osx_notifier_file, "%s-%s" % (int(time.time()), nid), summary, body]
     123        from xpra.child_reaper import getChildReaper
     124        import subprocess
     125        env = os.environ.copy()
     126        for x in ("DYLD_LIBRARY_PATH", "XDG_CONFIG_DIRS", "XDG_DATA_DIRS",
     127                  "GTK_DATA_PREFIX", "GTK_EXE_PREFIX", "GTK_PATH",
     128                  "GTK2_RC_FILES", "GTK_IM_MODULE_FILE", "GDK_PIXBUF_MODULE_FILE",
     129                  "PANGO_RC_FILE", "PANGO_LIBDIR", "PANGO_SYSCONFDIR",
     130                  "CHARSETALIASDIR",
     131                  "GST_BUNDLE_CONTENTS", "PYTHON", "PYTHONHOME",
     132                  "PYTHONPATH"):
     133            if x in env:
     134                del env[x]
     135        notifylog("running %s with env=%s", cmd, env)
     136        proc = subprocess.Popen(cmd, env=env)
     137        proc.wait()
     138        notifylog("returned %i", proc.poll())
     139        getChildReaper().add_process(proc, "notifier-%s" % nid, cmd, True, True)
     140
     141    def close_notify(self, nid):
     142        pass
     143   
     144
     145def get_native_notifier_classes():
     146    global notification_center
     147    if notification_center is None:
     148        notification_center = NSUserNotificationCenter.defaultUserNotificationCenter() or False
     149        notifylog("notification_center=%s", notification_center)
     150    v = []
     151    if notification_center:
     152        v = [OSX_Notifier]
     153    v.append(OSX_Subprocess_Notifier)
     154    notifylog("get_native_notifier_classes()=%s", v)
     155    return v
     156
    94157def get_native_tray_menu_helper_classes():
    95158    from xpra.platform.darwin.osx_menu import getOSXMenuHelper
    96159    return [getOSXMenuHelper]
  • xpra/platform/darwin/osx_notifier.py

     
     1#!/usr/bin/env python
     2# This file is part of Xpra.
     3# Copyright (C) 2017 Antoine Martin <antoine@devloop.org.uk>
     4# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
     5# later version. See the file COPYING for details.
     6
     7import sys
     8
     9from Foundation import NSUserNotification, NSUserNotificationCenter, NSUserNotificationDefaultSoundName #@UnresolvedImport
     10
     11
     12notification_center = None
     13
     14
     15def show_notify(nid, summary, body):
     16    notification = NSUserNotification.alloc().init()
     17    notification.setTitle_(summary)
     18    notification.setInformativeText_(body)
     19    notification.setIdentifier_("%s" % nid)
     20    #enable sound:
     21    notification.setSoundName_(NSUserNotificationDefaultSoundName)
     22    notification_center.deliverNotification_(notification)
     23
     24
     25def main():
     26    if len(sys.argv)<4:
     27        print("Error: not enough arguments")
     28        return 1
     29    global notification_center
     30    notification_center = NSUserNotificationCenter.defaultUserNotificationCenter()
     31    if not notification_center:
     32        print("Error: cannot access notification center")
     33        return 2
     34    nid = sys.argv[1]
     35    summary = sys.argv[2]
     36    body = sys.argv[3]
     37    show_notify(nid, summary, body)
     38    return 0
     39
     40
     41if __name__ == "__main__":
     42    v = main()
     43    sys.exit(v)