⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qx11embed_x11.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
}class QX11EmbedWidgetPrivate : public QWidgetPrivate{    Q_DECLARE_PUBLIC(QX11EmbedWidget)public:    inline QX11EmbedWidgetPrivate()    {        container = 0;    }    void setEmbedded();    enum FocusWidgets {        FirstFocusWidget,        LastFocusWidget    };    int focusOriginator;    QWidget *getFocusWidget(FocusWidgets fw);    void checkActivateWindow(QObject *o);    QX11EmbedWidget *xEmbedWidget(QObject *o) const;    void clearFocus();    WId container;    QPointer<QWidget> currentFocus;};/*!    Constructs a QX11EmbedWidget object with the given \a parent.*/QX11EmbedWidget::QX11EmbedWidget(QWidget *parent)    : QWidget(*new QX11EmbedWidgetPrivate, parent, 0){    XSetErrorHandler(x11ErrorHandler);    initXEmbedAtoms(x11Info().display());    XSelectInput(x11Info().display(), winId(),                 KeyPressMask | KeyReleaseMask | ButtonPressMask                    | ButtonReleaseMask                    | KeymapStateMask | ButtonMotionMask | PointerMotionMask                    | FocusChangeMask                    | ExposureMask | StructureNotifyMask                    | SubstructureNotifyMask | PropertyChangeMask);    unsigned int data[] = {XEMBED_VERSION, XEMBED_MAPPED};    XChangeProperty(x11Info().display(), winId(), _XEMBED_INFO,                    XA_CARDINAL, 32, PropModeReplace,                    (unsigned char*) data, 2);    setFocusPolicy(Qt::StrongFocus);    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);    QApplication::instance()->installEventFilter(this);}/*!    Destructs the QX11EmbedWidget object. If the widget is embedded    when deleted, it is hidden and then detached from its container,    so that the container is free to embed a new widget.*/QX11EmbedWidget::~QX11EmbedWidget(){    Q_D(QX11EmbedWidget);    if (d->container) {        XUnmapWindow(x11Info().display(), winId());        XReparentWindow(x11Info().display(), winId(), x11Info().appRootWindow(), 0, 0);    }}/*!    When this function is called, the widget embeds itself into the    container whose window ID is \a id.    If \a id is \e not the window ID of a container this function will    behave unpredictably.*/void QX11EmbedWidget::embedInto(WId id){    Q_D(QX11EmbedWidget);    d->container = id;    switch (XReparentWindow(x11Info().display(), winId(), d->container, 0, 0)) {    case BadWindow:        emit error(InvalidWindowID);        break;    case BadMatch:        emit error(Internal);        break;    case Success:    default:        break;    }}/*! \internal    Gets the first or last child widget that can get focus.*/QWidget *QX11EmbedWidgetPrivate::getFocusWidget(FocusWidgets fw){    Q_Q(QX11EmbedWidget);    QWidget *tlw = q;    QWidget *w = tlw->nextInFocusChain();    QWidget *last = tlw;    extern bool qt_tab_all_widgets;    uint focus_flag = qt_tab_all_widgets ? Qt::TabFocus : Qt::StrongFocus;    while (w != tlw)    {        if (((w->focusPolicy() & focus_flag) == focus_flag)            && w->isVisibleTo(q) && w->isEnabled())        {            last = w;            if (fw == FirstFocusWidget)                break;        }        w = w->nextInFocusChain();    }    return last;}/*! \internal    Returns the xembed widget that the widget is a child of*/QX11EmbedWidget *QX11EmbedWidgetPrivate::xEmbedWidget(QObject *o) const{    QX11EmbedWidget *xec = 0;    // Check the widget itself, then its parents, and find the first    // QX11EmbedWidget.    do {        if ((xec = qobject_cast<QX11EmbedWidget *>(o)))            return xec;    } while ((o = o->parent()));    return 0;}/*! \internal    Checks the active window.*/void QX11EmbedWidgetPrivate::checkActivateWindow(QObject *o){    Q_Q(QX11EmbedWidget);    QX11EmbedWidget *xec = xEmbedWidget(o);    // check if we are in the right xembed client    if (q != xec)        return;    QWidget *w = qobject_cast<QWidget *>(o);    // if it is no active window, then don't do the change    if (!(w && qApp->activeWindow()))        return;    // if it already is the active window, don't do anything    if (w->window() != qApp->activeWindow())    {        qApp->setActiveWindow(w->window());        currentFocus = w;        sendXEmbedMessage(xec->containerWinId(), q->x11Info().display(), XEMBED_REQUEST_FOCUS);    }}/*! \internal    Clears the focus*/void QX11EmbedWidgetPrivate::clearFocus(){    Q_Q(QX11EmbedWidget);    // Setting focus on the client itself removes Qt's    // logical focus rectangle. We can't just do a    // clearFocus here, because when we send the synthetic    // FocusIn to ourselves on activation, Qt will set    // focus on focusWidget() again. This way, we "hide"    // focus rather than clearing it.    if (!q->window()->hasFocus())        q->window()->setFocus(Qt::OtherFocusReason);    currentFocus = 0;}/*! \internal    Sets the embedded flag on the client.*/void QX11EmbedWidgetPrivate::setEmbedded(){    Q_Q(QX11EmbedWidget);    ((QHackWidget *)q->window())->topData()->embedded = 1;}/*! \internal    Handles WindowActivate and FocusIn events for the client.*/bool QX11EmbedWidget::eventFilter(QObject *o, QEvent *event){    Q_D(QX11EmbedWidget);    switch (event->type()) {    case QEvent::FocusIn:        switch (((QFocusEvent *)event)->reason()) {        case Qt::MouseFocusReason:            // If the user clicks into one of the client widget's            // children and we didn't have focus already, we request            // focus from our container.            if (d->xEmbedWidget(o) == this) {                if (d->currentFocus.isNull())                    sendXEmbedMessage(d->container, x11Info().display(), XEMBED_REQUEST_FOCUS);                d->currentFocus = qobject_cast<QWidget *>(o);            }            break;        case Qt::TabFocusReason:            // If the xembed client receives a focus event because of            // a Tab, then we are at the end of our focus chain and we            // ask the container to move to its next focus widget.            if (o == this) {                d->clearFocus();                sendXEmbedMessage(d->container, x11Info().display(), XEMBED_FOCUS_NEXT);                return true;            } else {                // We're listening on events from qApp, so in order                // for us to know who to set focus on if we receive an                // activation event, we note the widget that got the                // focusin last.                if (d->xEmbedWidget(o) == this)                    d->currentFocus = qobject_cast<QWidget *>(o);            }            break;        case Qt::BacktabFocusReason:            // If the window receives a focus event because of            // a Backtab, then we are at the start of our focus chain            // and we ask the container to move to its previous focus            // widget.            if (o == this) {                // See comment for Tab.                // If we receive a XEMBED_FOCUS_IN                // XEMBED_FOCUS_CURRENT, we will set focus in                // currentFocus. To avoid that in this case, we reset                // currentFocus.                d->clearFocus();                sendXEmbedMessage(d->container, x11Info().display(), XEMBED_FOCUS_PREV);                return true;            } else {                if (d->xEmbedWidget(o) == this)                    d->currentFocus = qobject_cast<QWidget *>(o);            }            break;        case Qt::ActiveWindowFocusReason:            if (!d->currentFocus.isNull()) {                if (!d->currentFocus->hasFocus())                    d->currentFocus->setFocus(Qt::OtherFocusReason);            } else {                d->clearFocus();                return true;            }            break;        case Qt::PopupFocusReason:        case Qt::ShortcutFocusReason:        case Qt::OtherFocusReason:            // If focus is received to any child widget because of any            // other reason, remember the widget so that we can give            // it focus again if we're activated.            if (d->xEmbedWidget(o) == this) {               d->currentFocus = qobject_cast<QWidget *>(o);            }            break;        default:            break;        }        break;    case QEvent::MouseButtonPress:        // If we get a mouse button press event inside a embedded widget        // make sure this is the active window in qapp.        d->checkActivateWindow(o);        break;    default:        break;    }    return QWidget::eventFilter(o, event);}/*! \internal    Handles some notification events and client messages. Client side    XEmbed message receiving is also handled here.*/bool QX11EmbedWidget::x11Event(XEvent *event){    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(), winId(), _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(), winId());                    } else {                        XUnmapWindow(x11Info().display(), winId());                    }                }            }        }        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 != winId())                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 = winId();                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 = winId();                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:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -