aboutsummaryrefslogtreecommitdiffstats
path: root/src/androidselect.c
diff options
context:
space:
mode:
authorPo Lu2024-03-13 10:59:39 +0800
committerPo Lu2024-03-13 11:01:39 +0800
commit6b40d557c4a9a4152565c1a1b0da49a1aaaec84f (patch)
treeac82dd76319ccc7df22a9d70923ec28f97c4f41a /src/androidselect.c
parent4afafa03704aab0c21e4cb4f028256ecead5f795 (diff)
downloademacs-6b40d557c4a9a4152565c1a1b0da49a1aaaec84f.tar.gz
emacs-6b40d557c4a9a4152565c1a1b0da49a1aaaec84f.zip
Port more notification senders to non-XDG systems
* doc/lispref/os.texi (Desktop Notifications): Document that `:timeout' is now implemented. * java/org/gnu/emacs/EmacsDesktopNotification.java (EmacsDesktopNotification): New field delay. (display1): Set delay on Android 8.0 and up. * lisp/erc/erc-desktop-notifications.el (erc-notifications-notify): Call Android or Haiku notification functions on those systems. * lisp/gnus/gnus-notifications.el (gnus-notifications-action) (gnus-notification-close): Remove dismissed notifications from the notification to message map. (gnus-notifications-notify): Call android-notifications-notify if possible. * src/androidselect.c (android_init_emacs_desktop_notification): Update accordingly. (android_notifications_notify_1): New argument TIMEOUT. (Fandroid_notifications_notify): New argument QCtimeout. (syms_of_androidselect) <QCtimeout>: New symbol.
Diffstat (limited to 'src/androidselect.c')
-rw-r--r--src/androidselect.c86
1 files changed, 59 insertions, 27 deletions
diff --git a/src/androidselect.c b/src/androidselect.c
index 521133976a7..87dd2c3d079 100644
--- a/src/androidselect.c
+++ b/src/androidselect.c
@@ -526,7 +526,7 @@ android_init_emacs_desktop_notification (void)
526 FIND_METHOD (init, "<init>", "(Ljava/lang/String;" 526 FIND_METHOD (init, "<init>", "(Ljava/lang/String;"
527 "Ljava/lang/String;Ljava/lang/String;" 527 "Ljava/lang/String;Ljava/lang/String;"
528 "Ljava/lang/String;II[Ljava/lang/String;" 528 "Ljava/lang/String;II[Ljava/lang/String;"
529 "[Ljava/lang/String;)V"); 529 "[Ljava/lang/String;J)V");
530 FIND_METHOD (display, "display", "()V"); 530 FIND_METHOD (display, "display", "()V");
531#undef FIND_METHOD 531#undef FIND_METHOD
532} 532}
@@ -567,16 +567,17 @@ android_locate_icon (const char *name)
567} 567}
568 568
569/* Display a desktop notification with the provided TITLE, BODY, 569/* Display a desktop notification with the provided TITLE, BODY,
570 REPLACES_ID, GROUP, ICON, URGENCY, ACTIONS, RESIDENT, ACTION_CB and 570 REPLACES_ID, GROUP, ICON, URGENCY, ACTIONS, TIMEOUT, RESIDENT,
571 CLOSE_CB. Return an identifier for the resulting notification. */ 571 ACTION_CB and CLOSE_CB. Return an identifier for the resulting
572 notification. */
572 573
573static intmax_t 574static intmax_t
574android_notifications_notify_1 (Lisp_Object title, Lisp_Object body, 575android_notifications_notify_1 (Lisp_Object title, Lisp_Object body,
575 Lisp_Object replaces_id, 576 Lisp_Object replaces_id,
576 Lisp_Object group, Lisp_Object icon, 577 Lisp_Object group, Lisp_Object icon,
577 Lisp_Object urgency, Lisp_Object actions, 578 Lisp_Object urgency, Lisp_Object actions,
578 Lisp_Object resident, Lisp_Object action_cb, 579 Lisp_Object timeout, Lisp_Object resident,
579 Lisp_Object close_cb) 580 Lisp_Object action_cb, Lisp_Object close_cb)
580{ 581{
581 static intmax_t counter; 582 static intmax_t counter;
582 intmax_t id; 583 intmax_t id;
@@ -593,6 +594,7 @@ android_notifications_notify_1 (Lisp_Object title, Lisp_Object body,
593 jint nitems, i; 594 jint nitems, i;
594 jstring item; 595 jstring item;
595 Lisp_Object length; 596 Lisp_Object length;
597 jlong timeout_val;
596 598
597 if (EQ (urgency, Qlow)) 599 if (EQ (urgency, Qlow))
598 type = 2; /* IMPORTANCE_LOW */ 600 type = 2; /* IMPORTANCE_LOW */
@@ -603,6 +605,23 @@ android_notifications_notify_1 (Lisp_Object title, Lisp_Object body,
603 else 605 else
604 signal_error ("Invalid notification importance given", urgency); 606 signal_error ("Invalid notification importance given", urgency);
605 607
608 /* Decode the timeout. */
609
610 timeout_val = 0;
611
612 if (!NILP (timeout))
613 {
614 CHECK_INTEGER (timeout);
615
616 if (!integer_to_intmax (timeout, &id)
617 || id > TYPE_MAXIMUM (jlong)
618 || id < TYPE_MINIMUM (jlong))
619 signal_error ("Invalid timeout", timeout);
620
621 if (id > 0)
622 timeout_val = id;
623 }
624
606 nitems = 0; 625 nitems = 0;
607 626
608 /* If ACTIONS is provided, split it into two arrays of Java strings 627 /* If ACTIONS is provided, split it into two arrays of Java strings
@@ -714,7 +733,8 @@ android_notifications_notify_1 (Lisp_Object title, Lisp_Object body,
714 notification_class.init, 733 notification_class.init,
715 title1, body1, group1, 734 title1, body1, group1,
716 identifier1, icon1, type, 735 identifier1, icon1, type,
717 action_keys, action_titles); 736 action_keys, action_titles,
737 timeout_val);
718 android_exception_check_6 (title1, body1, group1, identifier1, 738 android_exception_check_6 (title1, body1, group1, identifier1,
719 action_titles, action_keys); 739 action_titles, action_keys);
720 740
@@ -723,12 +743,8 @@ android_notifications_notify_1 (Lisp_Object title, Lisp_Object body,
723 ANDROID_DELETE_LOCAL_REF (body1); 743 ANDROID_DELETE_LOCAL_REF (body1);
724 ANDROID_DELETE_LOCAL_REF (group1); 744 ANDROID_DELETE_LOCAL_REF (group1);
725 ANDROID_DELETE_LOCAL_REF (identifier1); 745 ANDROID_DELETE_LOCAL_REF (identifier1);
726 746 ANDROID_DELETE_LOCAL_REF (action_keys);
727 if (action_keys) 747 ANDROID_DELETE_LOCAL_REF (action_titles);
728 ANDROID_DELETE_LOCAL_REF (action_keys);
729
730 if (action_titles)
731 ANDROID_DELETE_LOCAL_REF (action_titles);
732 748
733 /* Display the notification. */ 749 /* Display the notification. */
734 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, 750 (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
@@ -769,8 +785,14 @@ keywords is understood:
769 The action for which CALLBACK is called when the 785 The action for which CALLBACK is called when the
770 notification itself is selected is named "default", 786 notification itself is selected is named "default",
771 its existence is implied, and its TITLE is ignored. 787 its existence is implied, and its TITLE is ignored.
772 No more than three actions can be defined, not 788 No more than three actions defined here will be
773 counting any action with "default" as its key. 789 displayed, not counting any with "default" as its
790 key.
791 :timeout Number of miliseconds from the display of the
792 notification at which it will be automatically
793 dismissed, or a value of zero or smaller if it
794 is to remain until user action is taken to dismiss
795 it.
774 :resident When set the notification will not be automatically 796 :resident When set the notification will not be automatically
775 dismissed when it or an action is selected. 797 dismissed when it or an action is selected.
776 :on-action Function to call when an action is invoked. 798 :on-action Function to call when an action is invoked.
@@ -780,12 +802,15 @@ keywords is understood:
780 with the notification id and the symbol `undefined' 802 with the notification id and the symbol `undefined'
781 for arguments. 803 for arguments.
782 804
783The notification group is ignored on Android 7.1 and earlier versions 805The notification group and timeout are ignored on Android 7.1 and
784of Android. Outside such older systems, it identifies a category that 806earlier versions of Android. On more recent versions, the urgency
785will be displayed in the system Settings menu, and the urgency 807identifies a category that will be displayed in the system Settings
786provided always extends to affect all notifications displayed within 808menu, and the urgency provided always extends to affect all
787that category. If the group is not provided, it defaults to the 809notifications displayed within that category, though it may be ignored
788string "Desktop Notifications". 810if higher than any previously-specified urgency or if the user have
811already configured a different urgency for this category from Settings.
812If the group is not provided, it defaults to the string "Desktop
813Notifications" with the urgency suffixed.
789 814
790Each caller should strive to provide one unchanging combination of 815Each caller should strive to provide one unchanging combination of
791notification group and urgency for each kind of notification it sends, 816notification group and urgency for each kind of notification it sends,
@@ -795,8 +820,8 @@ first notification sent to its notification group.
795 820
796The provided icon should be the name of a "drawable resource" present 821The provided icon should be the name of a "drawable resource" present
797within the "android.R.drawable" class designating an icon with a 822within the "android.R.drawable" class designating an icon with a
798transparent background. If no icon is provided (or the icon is absent 823transparent background. Should no icon be provided (or the icon is
799from this system), it defaults to "ic_dialog_alert". 824absent from this system), it defaults to "ic_dialog_alert".
800 825
801Actions specified with :actions cannot be displayed on Android 4.0 and 826Actions specified with :actions cannot be displayed on Android 4.0 and
802earlier versions of the system. 827earlier versions of the system.
@@ -814,17 +839,18 @@ this function.
814usage: (android-notifications-notify &rest ARGS) */) 839usage: (android-notifications-notify &rest ARGS) */)
815 (ptrdiff_t nargs, Lisp_Object *args) 840 (ptrdiff_t nargs, Lisp_Object *args)
816{ 841{
817 Lisp_Object title, body, replaces_id, group, urgency, resident; 842 Lisp_Object title, body, replaces_id, group, urgency, timeout, resident;
818 Lisp_Object icon; 843 Lisp_Object icon;
819 Lisp_Object key, value, actions, action_cb, close_cb; 844 Lisp_Object key, value, actions, action_cb, close_cb;
820 ptrdiff_t i; 845 ptrdiff_t i;
846 AUTO_STRING (default_icon, "ic_dialog_alert");
821 847
822 if (!android_init_gui) 848 if (!android_init_gui)
823 error ("No Android display connection!"); 849 error ("No Android display connection!");
824 850
825 /* Clear each variable above. */ 851 /* Clear each variable above. */
826 title = body = replaces_id = group = icon = urgency = actions = Qnil; 852 title = body = replaces_id = group = icon = urgency = actions = Qnil;
827 resident = action_cb = close_cb = Qnil; 853 timeout = resident = action_cb = close_cb = Qnil;
828 854
829 /* If NARGS is odd, error. */ 855 /* If NARGS is odd, error. */
830 856
@@ -852,6 +878,8 @@ usage: (android-notifications-notify &rest ARGS) */)
852 icon = value; 878 icon = value;
853 else if (EQ (key, QCactions)) 879 else if (EQ (key, QCactions))
854 actions = value; 880 actions = value;
881 else if (EQ (key, QCtimeout))
882 timeout = value;
855 else if (EQ (key, QCresident)) 883 else if (EQ (key, QCresident))
856 resident = value; 884 resident = value;
857 else if (EQ (key, QCon_action)) 885 else if (EQ (key, QCon_action))
@@ -874,16 +902,19 @@ usage: (android-notifications-notify &rest ARGS) */)
874 urgency = Qlow; 902 urgency = Qlow;
875 903
876 if (NILP (group)) 904 if (NILP (group))
877 group = build_string ("Desktop Notifications"); 905 {
906 AUTO_STRING (format, "Desktop Notifications (%s importance)");
907 group = CALLN (Fformat, format, urgency);
908 }
878 909
879 if (NILP (icon)) 910 if (NILP (icon))
880 icon = build_string ("ic_dialog_alert"); 911 icon = default_icon;
881 else 912 else
882 CHECK_STRING (icon); 913 CHECK_STRING (icon);
883 914
884 return make_int (android_notifications_notify_1 (title, body, replaces_id, 915 return make_int (android_notifications_notify_1 (title, body, replaces_id,
885 group, icon, urgency, 916 group, icon, urgency,
886 actions, resident, 917 actions, timeout, resident,
887 action_cb, close_cb)); 918 action_cb, close_cb));
888} 919}
889 920
@@ -1001,6 +1032,7 @@ syms_of_androidselect (void)
1001 DEFSYM (QCurgency, ":urgency"); 1032 DEFSYM (QCurgency, ":urgency");
1002 DEFSYM (QCicon, ":icon"); 1033 DEFSYM (QCicon, ":icon");
1003 DEFSYM (QCactions, ":actions"); 1034 DEFSYM (QCactions, ":actions");
1035 DEFSYM (QCtimeout, ":timeout");
1004 DEFSYM (QCresident, ":resident"); 1036 DEFSYM (QCresident, ":resident");
1005 DEFSYM (QCon_action, ":on-action"); 1037 DEFSYM (QCon_action, ":on-action");
1006 DEFSYM (QCon_close, ":on-close"); 1038 DEFSYM (QCon_close, ":on-close");