Пример #1
0
QSystemTrayIconSys::QSystemTrayIconSys(QSystemTrayIcon *q)
    : QWidget(0, Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint),
      q(q), colormap(0)
{
    setAttribute(Qt::WA_AlwaysShowToolTips);
    setAttribute(Qt::WA_QuitOnClose, false);
    setAttribute(Qt::WA_NoSystemBackground, true);
    setAttribute(Qt::WA_PaintOnScreen);

    static bool eventFilterAdded = false;
    Display *display = QX11Info::display();
    if (!eventFilterAdded) {
        oldEventFilter = qApp->setEventFilter(sysTrayTracker);
	eventFilterAdded = true;
	Window root = QX11Info::appRootWindow();
        XWindowAttributes attr;
        XGetWindowAttributes(display, root, &attr);
        if ((attr.your_event_mask & StructureNotifyMask) != StructureNotifyMask) {
            (void) QApplication::desktop(); // lame trick to ensure our event mask is not overridden
            XSelectInput(display, root, attr.your_event_mask | StructureNotifyMask); // for MANAGER selection
        }
    }
    if (trayIcons.isEmpty()) {
        sysTrayWindow = locateSystemTray();
	if (sysTrayWindow != XNone)
	    XSelectInput(display, sysTrayWindow, StructureNotifyMask); // track tray events
    }
    trayIcons.append(this);
    setMouseTracking(true);
#ifndef QT_NO_TOOLTIP
    setToolTip(q->toolTip());
#endif
    if (sysTrayWindow != XNone)
        addToTray();
}
Пример #2
0
bool QSystemTrayIconSys::sysTrayTracker(void *message, long *result)
{
    bool retval = false;
    if (QSystemTrayIconSys::oldEventFilter)
        retval = QSystemTrayIconSys::oldEventFilter(message, result);

    if (trayIcons.isEmpty())
        return retval;

    Display *display = QX11Info::display();
    XEvent *ev = (XEvent *)message;
    if  (ev->type == DestroyNotify && ev->xany.window == sysTrayWindow) {
	sysTrayWindow = locateSystemTray();
        memset(&sysTrayVisual, 0, sizeof(sysTrayVisual));
        for (int i = 0; i < trayIcons.count(); i++) {
            if (sysTrayWindow == XNone) {
	        QBalloonTip::hideBalloon();
                trayIcons[i]->hide(); // still no luck
                trayIcons[i]->destroy();
                trayIcons[i]->create();
	    } else
                trayIcons[i]->addToTray(); // add it to the new tray
        }
        retval = true;
    } else if (ev->type == ClientMessage && sysTrayWindow == XNone) {
        static Atom manager_atom = XInternAtom(display, "MANAGER", False);
        XClientMessageEvent *cm = (XClientMessageEvent *)message;
        if ((cm->message_type == manager_atom) && ((Atom)cm->data.l[1] == sysTraySelection)) {
	    sysTrayWindow = cm->data.l[2];
            memset(&sysTrayVisual, 0, sizeof(sysTrayVisual));
	    XSelectInput(display, sysTrayWindow, StructureNotifyMask);
            for (int i = 0; i < trayIcons.count(); i++) {
                trayIcons[i]->addToTray();
            }
            retval = true;
        }
    } else if (ev->type == PropertyNotify && ev->xproperty.atom == ATOM(_NET_SYSTEM_TRAY_VISUAL) &&
               ev->xproperty.window == sysTrayWindow) {
        memset(&sysTrayVisual, 0, sizeof(sysTrayVisual));
        for (int i = 0; i < trayIcons.count(); i++) {
            trayIcons[i]->addToTray();
        }
    }

    return retval;
}
Пример #3
0
XVisualInfo* QSystemTrayIconSys::getSysTrayVisualInfo()
{
    Display *display = QX11Info::display();

    if (!sysTrayVisual.visual) {
        Window win = locateSystemTray();
        if (win != XNone) {
            Atom actual_type;
            int actual_format;
            ulong nitems, bytes_remaining;
            uchar *data = 0;
            int result = XGetWindowProperty(display, win, ATOM(_NET_SYSTEM_TRAY_VISUAL), 0, 1,
                                            False, XA_VISUALID, &actual_type,
                                            &actual_format, &nitems, &bytes_remaining, &data);
            VisualID vid = 0;
            if (result == Success && data && actual_type == XA_VISUALID && actual_format == 32 &&
                nitems == 1 && bytes_remaining == 0)
                vid = *(VisualID*)data;
            if (data)
                XFree(data);
            if (vid == 0)
                return 0;

            uint mask = VisualIDMask;
            XVisualInfo *vi, rvi;
            int count;
            rvi.visualid = vid;
            vi = XGetVisualInfo(display, mask, &rvi, &count);
            if (vi) {
                sysTrayVisual = vi[0];
                XFree((char*)vi);
            }
            if (sysTrayVisual.depth != 32)
                memset(&sysTrayVisual, 0, sizeof(sysTrayVisual));
        }
    }

    return sysTrayVisual.visual ? &sysTrayVisual : 0;
}
bool QXcbNativeInterface::systrayVisualHasAlphaChannel() {
    const QXcbScreen *screen = static_cast<QXcbScreen *>(QGuiApplication::primaryScreen()->handle());

    if (m_systrayVisualId == XCB_NONE) {
        xcb_connection_t *xcb_conn = screen->xcb_connection();
        xcb_atom_t tray_atom = screen->atom(QXcbAtom::_NET_SYSTEM_TRAY_VISUAL);

        xcb_window_t systray_window = locateSystemTray(xcb_conn, screen);
        if (systray_window == XCB_WINDOW_NONE)
            return false;

        // Get the xcb property for the _NET_SYSTEM_TRAY_VISUAL atom
        xcb_get_property_cookie_t systray_atom_cookie;
        xcb_get_property_reply_t *systray_atom_reply;

        systray_atom_cookie = xcb_get_property_unchecked(xcb_conn, false, systray_window,
                                                        tray_atom, XCB_ATOM_VISUALID, 0, 1);
        systray_atom_reply = xcb_get_property_reply(xcb_conn, systray_atom_cookie, 0);

        if (!systray_atom_reply)
            return false;

        if (systray_atom_reply->value_len > 0 && xcb_get_property_value_length(systray_atom_reply) > 0) {
            xcb_visualid_t * vids = (uint32_t *)xcb_get_property_value(systray_atom_reply);
            m_systrayVisualId = vids[0];
        }

        free(systray_atom_reply);
    }

    if (m_systrayVisualId != XCB_NONE) {
        quint8 depth = screen->depthOfVisual(m_systrayVisualId);
        return depth == 32;
    } else {
        return false;
    }
}