diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi index 1591cbd7be0..585ae678842 100644 --- a/doc/lispref/os.texi +++ b/doc/lispref/os.texi @@ -3255,9 +3255,10 @@ Note that versions of Windows before W2K support only @code{:icon} and @code{:tip}. The other parameters can be passed, but they will be ignored on those old systems. -There can be at most one active notification at any given time. An -active notification must be removed by calling -@code{w32-notification-close} before a new one can be shown. +There can be at most one active notification at any given time for each +Emacs frame. An active notification must be removed by calling +@code{w32-notification-close} before a new one can be shown for the same +frame. @end defun To remove the notification and its icon from the taskbar, use the @@ -3265,7 +3266,12 @@ following function: @defun w32-notification-close id This function removes the tray notification given by its unique -@var{id}. +@var{id}. The same Emacs frame which was the selected frame when the +notification was created must be selected when removing the +notification. A Lisp program which shows notifications must track which +frame corresponds to which notification @var{id}, and select that frame +when removing the notification. (When a frame is deleted, a +notification it created, if any, will be removed by MS-Windows.) @end defun @cindex desktop notifications, Haiku diff --git a/src/w32fns.c b/src/w32fns.c index 4aaafdd85d3..3fc0f55244f 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -10337,8 +10337,8 @@ typedef struct MY_NOTIFYICONDATAW { #endif -#define EMACS_TRAY_NOTIFICATION_ID 42 /* arbitrary */ -#define EMACS_NOTIFICATION_MSG (WM_APP + 1) +#define EMACS_TRAY_NOTIFICATION_ID_INIT 42 /* arbitrary */ +#define EMACS_NOTIFICATION_MSG (WM_APP + 1) enum NI_Severity { Ni_None, @@ -10403,14 +10403,16 @@ utf8_mbslen_lim (const char *str, int lim) return mblen; } +static unsigned short last_tray_notification_id; + /* Low-level subroutine to show tray notifications. All strings are supposed to be unibyte UTF-8 encoded by the caller. */ -static EMACS_INT +static int add_tray_notification (struct frame *f, const char *icon, const char *tip, enum NI_Severity severity, unsigned timeout, const char *title, const char *msg) { - EMACS_INT retval = EMACS_TRAY_NOTIFICATION_ID; + int retval = -1; if (FRAME_W32_P (f)) { @@ -10437,7 +10439,12 @@ add_tray_notification (struct frame *f, const char *icon, const char *tip, else nidw.cbSize = MYNOTIFYICONDATAW_V1_SIZE; /* < W2K */ nidw.hWnd = FRAME_W32_WINDOW (f); - nidw.uID = EMACS_TRAY_NOTIFICATION_ID; + if (!last_tray_notification_id) + last_tray_notification_id = EMACS_TRAY_NOTIFICATION_ID_INIT; + else + last_tray_notification_id++; + retval = last_tray_notification_id; + nidw.uID = last_tray_notification_id; nidw.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP | NIF_INFO; nidw.uCallbackMessage = EMACS_NOTIFICATION_MSG; if (!*icon) @@ -10660,16 +10667,19 @@ Note that versions of Windows before W2K support only `:icon' and `:tip'. You can pass the other parameters, but they will be ignored on those old systems. -There can be at most one active notification at any given time. An -active notification must be removed by calling `w32-notification-close' -before a new one can be shown. +There can be at most one active notification at any given time per each +Emacs frame. An active notification must be removed by calling the +function `w32-notification-close', with the same frame selected as the +one which was selected when the notification was created, before a new +one can be shown for the same frame. The caller must track which +notification was created from which frame, using the returned ID value. usage: (w32-notification-notify &rest PARAMS) */) (ptrdiff_t nargs, Lisp_Object *args) { struct frame *f = SELECTED_FRAME (); Lisp_Object arg_plist, lres; - EMACS_INT retval; + int retval; char *icon, *tip, *title, *msg; enum NI_Severity severity; unsigned timeout = 0; @@ -10732,7 +10742,9 @@ usage: (w32-notification-notify &rest PARAMS) */) DEFUN ("w32-notification-close", Fw32_notification_close, Sw32_notification_close, 1, 1, 0, - doc: /* Remove the MS-Windows tray notification specified by its ID. */) + doc: /* Remove the MS-Windows tray notification specified by its ID. +The frame which was selected when the notification was created must +be selected when removing the notification. */) (Lisp_Object id) { struct frame *f = SELECTED_FRAME ();