Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[platform-swt-dev] System Tray - Proposed addition of the "bubble message" feature...

Hi,

I need the ability to report some low priority, assynchronous messages to the
user in a RCP application that I'm developping which will be required to works
both on Windows XP and MacOS (you can _somewhat_ compare this application to MSN
Messenger).

The exact behaviour may vary on each plateform, based on each plateform UI guidelines: for example, on Windows, we could popup a bubble over the system tray, while on MacOS,
the application's icon, in the dock would bouce, but no message would be shown. Most
XWindow implementations would provide behaviours similar to those of Windows or MacOS.

(this feature as also been requested several times on the mailling list, and a
bugzilla entry can be found at https://bugs.eclipse.org/bugs/show_bug.cgi?id=58009 )

Below is a first working Windows implementation, based on the SWT sources in SWT-3.1-Win32.
The most notable change is to add the code bellow to org.eclipse.swt.widgets.TrayItem .

-------------------------------------------------------------------------------
/**
* Display a low priority, assynchronous and unreliable notification to the
* user, in a plateform dependant way.
* * In most cases, the notification's message will be displayed through some
* kind of pannels near the tray's icon (bubbles on Windows); on MacOS, the
* application's icon in the system dock will bounce, but no message will be
* displayed. In some environment, absolutely no behaviour will take place
* (either because the graphical environment do not offer any notification
* mecanism or because the user as disabled it).
*
* Behaviour when posting a notification while an other notification is already
* posted is system dependant; it is wise to avoid such cases, as it is probable
* that it may yield unexpected results on some plateforms.
* * @param title the notification's title
* @param message the notification's message
* @param severity the notification severity (one of SWT.ICON_*)
* @param timeout the time (in ms) before the notification is dismissed
*
* @exception SWTException <ul>
*    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
*    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
* </ul>
*/
public void postNotification(String title, String message, int severity, int timeout) {
   checkWidget ();
   if (OS.IsWinCE || OS.SHELL32_MAJOR < 5) return;
   if (title == null || message == null) error(SWT.ERROR_NULL_ARGUMENT);

   NOTIFYICONDATA iconData = OS.IsUnicode ? (NOTIFYICONDATA) new NOTIFYICONDATAW () : new NOTIFYICONDATAA ();

   // Copy the title
   TCHAR buffer = new TCHAR (0, title == null ? "" : title, true);
   int length = Math.min (63, buffer.length ());
   if (OS.IsUnicode) {
       char [] szInfoTitle = ((NOTIFYICONDATAW) iconData).szInfoTitle;
       System.arraycopy (buffer.chars, 0, szInfoTitle, 0, length);
   } else {
       byte [] szInfoTitle = ((NOTIFYICONDATAA) iconData).szInfoTitle;
       System.arraycopy (buffer.bytes, 0, szInfoTitle, 0, length);
   }

   // Copy the message
   buffer = new TCHAR (0, message == null ? "" : message, true);
   length = Math.min (255, buffer.length ());
   if (OS.IsUnicode) {
       char [] szInfo = ((NOTIFYICONDATAW) iconData).szInfo;
       System.arraycopy (buffer.chars, 0, szInfo, 0, length);
   } else {
       byte [] szInfo = ((NOTIFYICONDATAA) iconData).szInfo;
       System.arraycopy (buffer.bytes, 0, szInfo, 0, length);
   }

   // Put the severity
   switch (severity) {
   case SWT.ICON_ERROR:
       iconData.dwInfoFlags = OS.NIIF_ERROR;
       break;
   case SWT.ICON_WARNING:
       iconData.dwInfoFlags = OS.NIIF_WARNING;
       break;
   case SWT.ICON_INFORMATION:
       iconData.dwInfoFlags = OS.NIIF_INFO;
       break;
   default:
       iconData.dwInfoFlags = OS.NIIF_NONE;
       break;
   }
// The uTimeout field is union with uVersion
   iconData.uVersion = timeout;

   iconData.cbSize = NOTIFYICONDATA.sizeof;
   iconData.uID = id;
   iconData.hWnd = display.hwndMessage;
   iconData.uFlags = OS.NIF_INFO;
   OS.Shell_NotifyIcon (OS.NIM_MODIFY, iconData);
}
===============================================================================


There is also the appending of one line inside the 'messageProc' method in
this file, to handle the case where the user click in the bubble. The change
is the addition of the third line bellow:

--- (around lines 222 to 225): ------------------------------------------------

	case OS.WM_LBUTTONDBLCLK:
	case OS.WM_RBUTTONDBLCLK:
+       case OS.WM_USER + 5:        // OS.NIN_BALLOONUSERCLICK
		if (hooks (SWT.DefaultSelection)) {
			OS.SetForegroundWindow (hwnd);
===============================================================================


Finally, a demo for this feature can be added to Snippet143.java:

--- (around line 58, right after the loop for creation of the items): ---------

           MenuItem mi = new MenuItem(menu, SWT.PUSH);
           mi.setText("Show notification");
           mi.addListener(SWT.Selection, new Listener() {
               public void handleEvent(Event event) {
                   item.postNotification(
                           "Title of the message",
                           "This message may get displayed when you " +
                           "choose \"Show notification\" from the menu.",
                           SWT.ICON_INFORMATION,
                           20000);
               };
           });
===============================================================================


I intend to write the MacOS version of the postNotification() method in the
following weeks; for now, an empty method would be sufficient, since it is
declared that this method is for posting _unreliable_ information to the user.



Well, any comment, worries, suggestion, love letter, or anything else ?


James



Back to the top