Logo Search packages:      
Sourcecode: qt4-x11 version File versions

bool QX11EmbedWidget::x11Event ( XEvent *  event  )  [protected]

For internal use only.

Handles some notification events and client messages. Client side XEmbed message receiving is also handled here.

Definition at line 712 of file qx11embed_x11.cpp.

References containerClosed(), embedded(), QCoreApplication::instance(), QWidget::internalWinId(), and QWidget::window().

{
    Q_D(QX11EmbedWidget);
    switch (event->type) {
    case DestroyNotify:
        // If the container window is destroyed, we signal this to the user.
        emit containerClosed();
        break;
    case ReparentNotify:
        // If the container shuts down, we will be reparented to the
        // root window. We must also consider the case that we may be
        // reparented from one container to another.
        if (event->xreparent.parent == x11Info().appRootWindow()) {
            emit containerClosed();
            return true;
        } else {
            d->container = event->xreparent.parent;
        }
        break;
    case UnmapNotify:
        // Mapping and unmapping are handled by changes to the
        // _XEMBED_INFO property. Any default map/unmap requests are
        // ignored.
        return true;
    case PropertyNotify:
        // The container sends us map/unmap messages through the
        // _XEMBED_INFO property. We adhere to the XEMBED_MAPPED bit in
        // data2.
        if (event->xproperty.atom == _XEMBED_INFO) {
            Atom actual_type_return;
            int actual_format_return;
            unsigned long nitems_return;
            unsigned long bytes_after_return;
            unsigned char *prop_return = 0;
            if (XGetWindowProperty(x11Info().display(), internalWinId(), _XEMBED_INFO, 0, 2,
                                   false, XA_CARDINAL, &actual_type_return,
                                   &actual_format_return, &nitems_return,
                                   &bytes_after_return, &prop_return) == Success) {
                if (nitems_return > 1) {
                    if (((int * )prop_return)[1] & XEMBED_MAPPED) {
                        XMapWindow(x11Info().display(), internalWinId());
                    } else {
                        XUnmapWindow(x11Info().display(), internalWinId());
                    }
                }
            }
        }

        break;
    case ClientMessage:
        // XEMBED messages have message_type _XEMBED
        if (event->xclient.message_type == _XEMBED) {
            // Discard XEMBED messages not to ourselves. (### dead code?)
            if (event->xclient.window != internalWinId())
                break;

            // Update qt_x_time if necessary
            Time msgtime = (Time) event->xclient.data.l[0];
            if (msgtime > X11->time)
                X11->time = msgtime;

            switch (event->xclient.data.l[1]) {
            case XEMBED_WINDOW_ACTIVATE: {
                // When we receive an XEMBED_WINDOW_ACTIVATE, we need
                // to send ourselves a synthetic FocusIn X11 event for
                // Qt to activate us.
                XEvent ev;
                memset(&ev, 0, sizeof(ev));
                ev.xfocus.display = x11Info().display();
                ev.xfocus.type = XFocusIn;
                ev.xfocus.window = internalWinId();
                ev.xfocus.mode = NotifyNormal;
                ev.xfocus.detail = NotifyNonlinear;
                ((QApplication *)QApplication::instance())->x11ProcessEvent(&ev);
            }
                break;
            case XEMBED_WINDOW_DEACTIVATE: {
                // When we receive an XEMBED_WINDOW_DEACTIVATE, we
                // need to send ourselves a synthetic FocusOut event
                // for Qt to deativate us.
                XEvent ev;
                memset(&ev, 0, sizeof(ev));
                ev.xfocus.display = x11Info().display();
                ev.xfocus.type = XFocusOut;
                ev.xfocus.window = internalWinId();
                ev.xfocus.mode = NotifyNormal;
                ev.xfocus.detail = NotifyNonlinear;
                ((QApplication *)QApplication::instance())->x11ProcessEvent(&ev);
            }
                break;
            case XEMBED_EMBEDDED_NOTIFY: {
                // In this message's l[2] we have the max version
                // supported by both the client and the
                // container. QX11EmbedWidget does not use this field.

                // We have been embedded, so we set our
                // client's embedded flag.
                d->setEmbedded();
                emit embedded();
            }
                break;
            case XEMBED_FOCUS_IN:
                // in case we embed more than one topLevel window inside the same
                // host window.
                if (window() != qApp->activeWindow())
                    qApp->setActiveWindow(this);

                switch (event->xclient.data.l[2]) {
                case XEMBED_FOCUS_CURRENT:
                    // The container sends us this message if it wants
                    // us to focus on the widget that last had focus.
                    // This is the reply when XEMBED_REQUEST_FOCUS is
                    // sent to the container.
                    if (!d->currentFocus.isNull()) {
                        if (!d->currentFocus->hasFocus())
                            d->currentFocus->setFocus(Qt::OtherFocusReason);
                    } else {
                        // No widget currently has focus. We set focus
                        // on the first widget next to the
                        // client widget. Since the setFocus will not work
                        // if the window is disabled, set the currentFocus
                        // directly so that it's set on window activate.
                        d->currentFocus = d->getFocusWidget(QX11EmbedWidgetPrivate::FirstFocusWidget);
                        d->currentFocus->setFocus(Qt::OtherFocusReason);
                    }
                    break;
                case XEMBED_FOCUS_FIRST:
                    // The container sends this message when it wants
                    // us to focus on the first widget in our focus
                    // chain (typically because of a tab).
                    d->currentFocus = d->getFocusWidget(QX11EmbedWidgetPrivate::FirstFocusWidget);
                    d->currentFocus->setFocus(Qt::TabFocusReason);
                    break;
                case XEMBED_FOCUS_LAST:
                    // The container sends this message when it wants
                    // us to focus on the last widget in our focus
                    // chain (typically because of a backtab).
                    d->currentFocus = d->getFocusWidget(QX11EmbedWidgetPrivate::LastFocusWidget);
                    d->currentFocus->setFocus(Qt::BacktabFocusReason);
                    break;
                default:
                    // Ignore any other XEMBED_FOCUS_IN details.
                    break;
                }
                break;
            case XEMBED_FOCUS_OUT:
                // The container sends us this message when it wants us
                // to lose focus and forget about the widget that last
                // had focus. Typically sent by the container when it
                // loses focus because of mouse or tab activity. We do
                // then not want to set focus on anything if we're
                // activated.
                d->clearFocus();

                break;
            default:
                // Ignore any other XEMBED messages.
                break;
            };
        } else {
            // Non-XEMBED client messages are not interesting.
        }

        break;
    default:
        // Ignore all other x11 events.
        break;
    }

    // Allow default handling.
    return QWidget::x11Event(event);
}


Generated by  Doxygen 1.6.0   Back to index