Opened 5 years ago

Closed 4 years ago

#44 closed task (fixed)

Port QSystemTrayIcon

Reported by: dmik Owned by: dmik
Priority: major Milestone: Qt Beta 4
Component: QtGui Version: 4.5.1 Beta 1
Severity: Keywords:
Cc:

Description

Provide the OS/2 version of the QSystemTrayIcon class.

Change History (21)

comment:1 Changed 5 years ago by diver

is this class hard to port? i just ask because smplayer needs it. right now i added some ifdef to build it.

comment:2 Changed 5 years ago by dmik

If you surrounded the places with #ifndef QT_NO_SYSTEMTRAY, this is entirely correct (I did the same when I tried to build smplayer). QSystemTrayIcon isn't very difficult but there are more important things so it's low priority.

comment:3 Changed 5 years ago by diver

yes i agree we have mor important things to do. i surrounded it with #ifndef QT_OS_OS2 but will change it to QT_NO_SYSTEMTRAY. so i don't have to think about it when QT get's it later.

comment:4 Changed 5 years ago by diver

  • Milestone changed from Qt Enhanced to Qt GA

comment:5 Changed 5 years ago by diver

  • Milestone changed from Qt GA to Qt Beta4

comment:6 Changed 5 years ago by dmik

  • Owner set to dmik
  • Status changed from new to accepted

comment:7 Changed 5 years ago by dmik

There is a Systray API, http://www.eros2.info/systray_widget_en.shtml. The toolikt is available here http://ecomstation.ru/personal/eros2/downloads/trayapi.zip.

I checked it and recalled the limitation I encountered back then when looked at it during the Qt3 port: Systray API always uses the icon of the frame window and there is no opportunity to change that. In Qt4, the developer can set any icon as the tray icon regardless of the application's main window icon (which I find reasonable). I talked to eros2 and the reason for doing that is that he though there is no way to share pointer handles between processes (although there is).

I will try to get the sources from eros2 and see if they will suit our needs. My idea is to enhance the Systray API so that it's possible to set any icon and still maintain the backward compatibility so that all exiting applications that use Systray API will also work.

Note that if we fail with using the Systray API sources, we will stii be able to provide backward compatibility by implementing the same DDE protocol (systray uses DDE for communication between processes).

comment:8 Changed 5 years ago by dmik

Another important question is whether we need standalone systray support or XCenter is enough. I think the latter. This simplifies things in case if we implement it on our own (i.e. not using Systray/WPS).

comment:9 Changed 5 years ago by diver

yes i agree, xworkplace/ecenter is enough

comment:10 Changed 5 years ago by dmik

The mentioned system tray XCenter plug-in relies on the SysTray?/WPS daemon, systrayd.exe. I would like to avoid such a dependency. Taking into account that we would need to extend the existing implementation anyway, I decided to create a new XCenter plug-in from scratch which will work both ways.

Committed the initial sketch of the XCenter widget plugin in r252. It is part of the normal build process; xsystray.dll is built and placed to /plugins/xcenter/.

comment:11 Changed 5 years ago by dmik

The extended system tray widget will provide the following API:

  • winhAddSysTrayIcon(HWND, ULONG ulID, HPOINTER, ULONG ulFlags)

Adds a new icon to the system tray with the specified ID for the given HWND. The given HWND will become a receiver of the notification messages from the system tray for the given icon. If an icon with this ID is already present in the system tray, it will be replaced with the new one.

  • winhRemoveSysTrayIcon (HWND, ULONG ulID)

Removes the previously added icon with the given HWND and ID.

  • winhSetSysTrayIconToolTip (HWND, ULONG ulID, PSZ)

Sets the tooltip string that will be shown when the mouse pointer is held over the specified icon for some time. A NULL string will reset the tooltip.

  • winhShowSysTrayIconBalloon (HWND, ULONG ulID, PSZ pszTitle, PSZ pszText, ULONG ulFlags, ULONG ulTimeout)

Shows the notification balloon over the specified icon with the given title and containing the given text message. The balloon is automatically hidden after ulTimeout milliseconds.

  • winhHideSysTrayIcon (HWND, ULONG ulID)

Hides the balloon of the given icon if it is shown.

comment:12 Changed 5 years ago by dmik

Did more stuff in r255. You can review the improved API (3rdparty/os2/xsystray/xsystray_api.h, it's close to the final version now.

Note that although QT_NO_SYSTEMTRAYICON is no more defined, QSystemTrayIcon isn't usable yet.

comment:13 Changed 4 years ago by dmik

They changed QPixmap code a lot in Qt4. The main consequence is that QPixmap isn't directly backed up by the native pixmap resource (HBITMAP in case of Win32 and OS/2) any more. This is probably because they do all widget rendering themselves (using the double buffered technique to reduce flicker and then simply flushing the buffer to the top-level window space). The system engine isn't used to blit pixmaps any more, so that it doesn't make sense to maintain handles for them. I need some more time to adopt to the new scheme.

The good news is that it will also move #53, #55 and #73 on.

comment:14 Changed 4 years ago by dmik

Ah, and HICON is basically a number of HBITMAPs packed together and this is how it influences this task -- we need to convert from a QPixmap associated with the QSystemTrayIcon to HBITMAP to HICON.

comment:15 Changed 4 years ago by dmik

By HICON above I mean HPOINTER of course. Conversion functions are done in r260, let's see how they work.

comment:16 Changed 4 years ago by dmik

WinCreatePointerIndirect?() has this silly bug so that it always ignores hbmMiniPointer and hbmMiniColor fields of the POINTERINFO structure and badly scales the normal icon to the mini one when it's needed (and vice versa if a mini icon is supplied) which looks ugly of course.

I think I will have to paint icons myself (not through WinDrawPointer?) in the system tray widget.

comment:17 Changed 4 years ago by dmik

And there is also a vendor bug in the QIcon's best size match algorithm (the behavior is opposite to the documentation).

I also like code like this :)

    if (actualSize.isNull())
        return actualSize;

    // dmik: actualSize is guaranteed to be !isNull() at this point
    // but they still check for isNull()

    if (!actualSize.isNull() && (actualSize.width() > size.width() || actualSize.height() > size.height()))
        actualSize.scale(size, Qt::KeepAspectRatio);

All fixed in r261.

comment:18 Changed 4 years ago by dmik

Implemented a lot of new stuff including:

  • better shared memory management;
  • detection of crashed applications and cleaning up icons remaining after them;
  • broadcasting a special message at system tray startup to let applications re-add their icons after a WPS crash;
  • better spacing between icons in the tray;
  • notifications from the system tray that deliver WM_BUTTONxyyy, WM_HSCROLL/WM_VSCROLL and WM_CONTEXTMENU messages in the icon area to the associated client window.

Things to do are:

  1. Use HMQ array in the client-side API code to memorize which threads we HK_INPUT hooked (necessary for proper multi-thread support).
  2. Optimize server-side memory pool performance by organizing free blocks in a one-way linked list (this makes sense when there are many allocations in the pool which currently may lead to full scan when searching for a free block).
  3. Icon tooltips.
  4. Qt-drawn notification balloons.
  5. Alpha blend icons in the tray.
  6. Native-drawn notification balloons.
  7. Support SysTray?/WPS API (DDE).

First two are minor improvements which I want to have before the plugin gets widely distributed, so Beta4. 3 and 4 is IMHO worth it too. The rest will most likely go to a separate defect (Qt Enhanced).

comment:19 Changed 4 years ago by dmik

3, 4 and 5.

comment:20 Changed 4 years ago by dmik

I also relicensed the whole xsystray code under GPL v2 to be fully compatible with the rest of xworkplace where we should eventually integrate.

comment:21 Changed 4 years ago by dmik

  • Resolution set to fixed
  • Status changed from accepted to closed

Done with 1, 3 and 4. The rest is moved to #99; enough for Beta4. We've done a really big amount of work already regarding the system tray thing: the xsystray plugin has the same functionality as in Windows 95. We only lack native balloons comparing to modern system tray implementations on other platforms which isn't a problem for Qt4 applications on OS/2 because Qt4 will draw it's own balloons until we implement native ones in XCenter style.

Note: See TracTickets for help on using tickets.