comparison mac/dw.m @ 2067:3ccd0da07514

Mac: Initial notification support for the Mac.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Thu, 14 May 2020 13:13:45 +0000
parents 19fb7f72051b
children 370baf78abdc
comparison
equal deleted inserted replaced
2066:2c2530f8cbef 2067:3ccd0da07514
1 /* 1 /*
2 * Dynamic Windows: 2 * Dynamic Windows:
3 * A GTK like implementation of the MacOS GUI using Cocoa 3 * A GTK like implementation of the MacOS GUI using Cocoa
4 * 4 *
5 * (C) 2011-2019 Brian Smith <brian@dbsoft.org> 5 * (C) 2011-2020 Brian Smith <brian@dbsoft.org>
6 * (C) 2011-2018 Mark Hessling <mark@rexx.org> 6 * (C) 2011-2018 Mark Hessling <mark@rexx.org>
7 * 7 *
8 * Requires 10.5 or later. 8 * Requires 10.5 or later.
9 * clang -std=c99 -g -o dwtest -D__MAC__ -I. dwtest.c mac/dw.m -framework Cocoa -framework WebKit 9 * clang -std=c99 -g -o dwtest -D__MAC__ -I. dwtest.c mac/dw.m -framework Cocoa -framework WebKit
10 */ 10 */
28 #endif 28 #endif
29 29
30 /* Create a define to let us know to include Lion specific features */ 30 /* Create a define to let us know to include Lion specific features */
31 #if defined(MAC_OS_X_VERSION_10_7) && ((defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7) || !defined(MAC_OS_X_VERSION_MAX_ALLOWED)) 31 #if defined(MAC_OS_X_VERSION_10_7) && ((defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7) || !defined(MAC_OS_X_VERSION_MAX_ALLOWED))
32 #define BUILDING_FOR_LION 32 #define BUILDING_FOR_LION
33 #endif
34
35 /* Create a define to let us know to include Mountain Lion specific features */
36 #if defined(MAC_OS_X_VERSION_10_8) && ((defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8) || !defined(MAC_OS_X_VERSION_MAX_ALLOWED))
37 #define BUILDING_FOR_MOUNTAIN_LION
33 #endif 38 #endif
34 39
35 /* Macros to handle local auto-release pools */ 40 /* Macros to handle local auto-release pools */
36 #define DW_LOCAL_POOL_IN NSAutoreleasePool *localpool = nil; \ 41 #define DW_LOCAL_POOL_IN NSAutoreleasePool *localpool = nil; \
37 if(DWThread != (DWTID)-1 && pthread_self() != DWThread) \ 42 if(DWThread != (DWTID)-1 && pthread_self() != DWThread) \
144 * the replacements are not available in earlier versions. 149 * the replacements are not available in earlier versions.
145 */ 150 */
146 #if defined(MAC_OS_X_VERSION_10_14) && ((defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_14) || !defined(MAC_OS_X_VERSION_MAX_ALLOWED)) 151 #if defined(MAC_OS_X_VERSION_10_14) && ((defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_14) || !defined(MAC_OS_X_VERSION_MAX_ALLOWED))
147 #define DWProgressIndicatorStyleBar NSProgressIndicatorStyleBar 152 #define DWProgressIndicatorStyleBar NSProgressIndicatorStyleBar
148 #define BUILDING_FOR_MOJAVE 153 #define BUILDING_FOR_MOJAVE
154 #import <UserNotifications/UserNotifications.h>
149 #else 155 #else
150 #define DWProgressIndicatorStyleBar NSProgressIndicatorBarStyle 156 #define DWProgressIndicatorStyleBar NSProgressIndicatorBarStyle
151 #endif 157 #endif
152 158
153 /* Handle deprecation of constants in 10.15... */ 159 /* Handle deprecation of constants in 10.15... */
10688 NSWindowDepth screenDepth = [[NSScreen mainScreen] depth]; 10694 NSWindowDepth screenDepth = [[NSScreen mainScreen] depth];
10689 return NSBitsPerPixelFromDepth(screenDepth); 10695 return NSBitsPerPixelFromDepth(screenDepth);
10690 } 10696 }
10691 10697
10692 /* 10698 /*
10699 * Creates a new system notification if possible.
10700 * Parameters:
10701 * title: The short title of the notification.
10702 * pixmap: Handle to an image to display or NULL if none.
10703 * description: A longer description of the notification,
10704 * or NULL if none is necessary.
10705 * Returns:
10706 * A handle to the notification which can be used to attach a "clicked" event if desired,
10707 * or NULL if it fails or notifications are not supported by the system.
10708 * Remarks:
10709 * This will create a system notification that will show in the notifaction panel
10710 * on supported systems, which may be clicked to perform another task.
10711 */
10712 HWND dw_notification_new(const char *title, HPIXMAP pixmap, const char *description, ...)
10713 {
10714 #ifdef BUILDING_FOR_MOUNTAIN_LION
10715 char outbuf[1025] = {0};
10716 HWND retval = NULL;
10717
10718 if(description)
10719 {
10720 va_list args;
10721
10722 va_start(args, description);
10723 vsnprintf(outbuf, 1024, description, args);
10724 va_end(args);
10725 }
10726
10727 #ifdef BUILDING_FOR_MOJAVE
10728 // Configure the notification's payload.
10729 if (@available(macOS 10.14, *))
10730 {
10731 UNMutableNotificationContent* notification = [[UNMutableNotificationContent alloc] init];
10732
10733 if(notification)
10734 {
10735 notification.title = [NSString stringWithUTF8String:title];
10736 if(description)
10737 notification.body = [NSString stringWithUTF8String:outbuf];
10738 retval = notification;
10739 }
10740 }
10741 else
10742 #endif
10743 {
10744 // Fallback on earlier versions
10745 NSUserNotification *notification = [[NSUserNotification alloc] init];
10746
10747 if(notification)
10748 {
10749 notification.title = [NSString stringWithUTF8String:title];
10750 notification.informativeText = [NSString stringWithUTF8String:outbuf];
10751 if(pixmap && pixmap->image)
10752 notification.contentImage = pixmap->image;
10753 retval = notification;
10754 }
10755 }
10756 return retval;
10757 #else
10758 return NULL;
10759 #endif
10760 }
10761
10762 /*
10763 * Sends a notification created by dw_notification_new() after attaching signal handler.
10764 * Parameters:
10765 * notification: The handle to the notification returned by dw_notification_new().
10766 * Returns:
10767 * DW_ERROR_NONE on success, DW_ERROR_UNKNOWN on error or not supported.
10768 */
10769 int dw_notification_send(HWND notification)
10770 {
10771 #ifdef BUILDING_FOR_MOUNTAIN_LION
10772 if(notification)
10773 {
10774 #ifdef BUILDING_FOR_MOJAVE
10775 // Schedule the notification.
10776 if (@available(macOS 10.14, *))
10777 {
10778 UNMutableNotificationContent *content = (UNMutableNotificationContent *)notification;
10779 NSString *notid = [NSString stringWithFormat:@"dw-notification-%llu", (unsigned long long)notification];
10780 UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:notid
10781 content:content trigger:nil];
10782
10783 UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
10784 [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
10785 _event_handler(notification, nil, 8);
10786 }];
10787 }
10788 else
10789 #endif
10790 {
10791 // Fallback on earlier versions
10792 [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
10793 }
10794 return DW_ERROR_NONE;
10795 }
10796 #endif
10797 return DW_ERROR_UNKNOWN;
10798 }
10799
10800
10801 /*
10693 * Returns some information about the current operating environment. 10802 * Returns some information about the current operating environment.
10694 * Parameters: 10803 * Parameters:
10695 * env: Pointer to a DWEnv struct. 10804 * env: Pointer to a DWEnv struct.
10696 */ 10805 */
10697 void dw_environment_query(DWEnv *env) 10806 void dw_environment_query(DWEnv *env)
11945 [DWMainMenu retain]; 12054 [DWMainMenu retain];
11946 [DWApp setMainMenu:DWMainMenu]; 12055 [DWApp setMainMenu:DWMainMenu];
11947 DWObj = [[DWObject alloc] init]; 12056 DWObj = [[DWObject alloc] init];
11948 DWDefaultFont = nil; 12057 DWDefaultFont = nil;
11949 #ifdef BUILDING_FOR_MOJAVE 12058 #ifdef BUILDING_FOR_MOJAVE
12059 if (@available(macOS 10.14, *))
12060 {
12061 [[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:UNAuthorizationOptionAlert
12062 completionHandler:^(BOOL granted, NSError * _Nullable error) {
12063 if (!granted) {
12064 NSLog(@"Unable to get notification permission.");
12065 }
12066 }];
12067 }
11950 _DWDirtyDrawables = [[NSMutableArray alloc] init]; 12068 _DWDirtyDrawables = [[NSMutableArray alloc] init];
11951 #else 12069 #else
11952 /* Create mutexes for thread safety */ 12070 /* Create mutexes for thread safety */
11953 DWRunMutex = dw_mutex_new(); 12071 DWRunMutex = dw_mutex_new();
11954 DWThreadMutex = dw_mutex_new(); 12072 DWThreadMutex = dw_mutex_new();