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

📄 qx11embed_x11.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	    }	}	break;    case QEvent::FocusOut: {	// When receiving a FocusOut, we ask our client to remove its	// focus.	if (o == this && d->client) {            if (!d->isEmbedded())                d->moveInputToProxy();	    if (d->clientIsXEmbed) {		QFocusEvent *fe = (QFocusEvent *)event;		if (o == this && d->client && fe->reason() != Qt::ActiveWindowFocusReason)		    sendXEmbedMessage(d->client, x11Info().display(), XEMBED_FOCUS_OUT);	    } else {		d->checkGrab();	    }	}    }	break;    case QEvent::Close: {	if (o == this && d->client) {	    // Unmap the client and reparent it to the root window.	    // Wait until the messages have been processed. Then ask	    // the window manager to delete the window.	    XUnmapWindow(x11Info().display(), d->client);	    XReparentWindow(x11Info().display(), d->client, x11Info().appRootWindow(), 0, 0);	    XSync(x11Info().display(), false);	    XEvent ev;	    memset(&ev, 0, sizeof(ev));	    ev.xclient.type = ClientMessage;	    ev.xclient.window = d->client;	    ev.xclient.message_type = ATOM(WM_PROTOCOLS);	    ev.xclient.format = 32;	    ev.xclient.data.s[0] = ATOM(WM_DELETE_WINDOW);	    XSendEvent(x11Info().display(), d->client, false, NoEventMask, &ev);	    XFlush(x11Info().display());	    d->client = 0;	    d->clientIsXEmbed = false;            d->wmMinimumSizeHint = QSize();            updateGeometry();            setEnabled(false);	    update();	    emit clientClosed();	}    }    default:	break;    }    return QObject::eventFilter(o, event);}/*! \internal    Handles X11 events for the container.*/bool QX11EmbedContainer::x11Event(XEvent *event){    Q_D(QX11EmbedContainer);    switch (event->type) {    case CreateNotify:	// The client created an embedded window.	if (d->client)	    d->rejectClient(event->xcreatewindow.window);	else	    d->acceptClient(event->xcreatewindow.window);      break;    case DestroyNotify:	if (event->xdestroywindow.window == d->client) {	    // The client died.	    d->client = 0;	    d->clientIsXEmbed = false;            d->wmMinimumSizeHint = QSize();            updateGeometry();	    update();            setEnabled(false);	    emit clientClosed();	}        break;    case ReparentNotify:	// The client sends us this if it reparents itself out of our	// widget.	if (event->xreparent.window == d->client && event->xreparent.parent != internalWinId()) {	    d->client = 0;	    d->clientIsXEmbed = false;            d->wmMinimumSizeHint = QSize();            updateGeometry();	    update();            setEnabled(false);	    emit clientClosed();	} else if (event->xreparent.parent == internalWinId()) {	    // The client reparented itself into this window.	    if (d->client)		d->rejectClient(event->xreparent.window);	    else		d->acceptClient(event->xreparent.window);	}	break;    case ClientMessage: {	if (event->xclient.message_type == _XEMBED) {	    // Ignore XEMBED messages not to ourselves	    if (event->xclient.window != internalWinId())		break;	    // Receiving an XEmbed message means the client	    // is an XEmbed client.	    d->clientIsXEmbed = true;	    Time msgtime = (Time) event->xclient.data.l[0];	    if (msgtime > X11->time)		X11->time = msgtime;	    switch (event->xclient.data.l[1]) {	    case XEMBED_REQUEST_FOCUS: {		// This typically happens when the client gets focus		// because of a mouse click.		if (!hasFocus())		    setFocus(Qt::OtherFocusReason);		// The message is passed along to the topmost container		// that eventually responds with a XEMBED_FOCUS_IN		// message. The focus in message is passed all the way		// back until it reaches the original focus		// requestor. In the end, not only the original client		// has focus, but also all its ancestor containers.		if (d->isEmbedded()) {                    // If our window's embedded flag is set, then		    // that suggests that we are part of a client. The		    // parentWinId will then point to an container to whom		    // we must pass this message.		    sendXEmbedMessage(d->topLevelParentWinId(), x11Info().display(), XEMBED_REQUEST_FOCUS);		} else {                    // Our window's embedded flag is not set,		    // so we are the topmost container. We respond to		    // the focus request message with a focus in		    // message. This message will pass on from client		    // to container to client until it reaches the		    // originator of the XEMBED_REQUEST_FOCUS message.		    sendXEmbedMessage(d->client, x11Info().display(), XEMBED_FOCUS_IN, XEMBED_FOCUS_CURRENT);		}		break;	    }	    case XEMBED_FOCUS_NEXT:		// Client sends this event when it received a tab		// forward and was at the end of its focus chain. If		// we are the only widget in the focus chain, we send		// ourselves a FocusIn event.                if (d->focus_next != this) {		    focusNextPrevChild(true);                } else {                    QFocusEvent event(QEvent::FocusIn, Qt::TabFocusReason);                    qApp->sendEvent(this, &event);                }		break;	    case XEMBED_FOCUS_PREV:		// Client sends this event when it received a backtab		// and was at the start of its focus chain. If we are		// the only widget in the focus chain, we send		// ourselves a FocusIn event.                if (d->focus_next != this) {		    focusNextPrevChild(false);                } else {                    QFocusEvent event(QEvent::FocusIn, Qt::BacktabFocusReason);                    qApp->sendEvent(this, &event);                }		break;	    default:		break;	    }	}    }	break;    case XButtonPress:	if (!d->clientIsXEmbed) {            setFocus(Qt::MouseFocusReason);            XAllowEvents(x11Info().display(), ReplayPointer, CurrentTime);            return true;	}	break;    case XButtonRelease:	if (!d->clientIsXEmbed)            XAllowEvents(x11Info().display(), SyncPointer, CurrentTime);	break;    default:	break;    }    return QWidget::x11Event(event);}/*! \internal    Whenever the container is resized, we need to resize our client.*/void QX11EmbedContainer::resizeEvent(QResizeEvent *){    Q_D(QX11EmbedContainer);    if (d->client)	XResizeWindow(x11Info().display(), d->client, width(), height());}/*! \internal    We use the QShowEvent to signal to our client that we want it to    map itself. We do this by changing its window property    XEMBED_INFO. The client will get an X11 PropertyNotify.*/void QX11EmbedContainer::showEvent(QShowEvent *){    Q_D(QX11EmbedContainer);    if (d->client) {	unsigned int data[] = {XEMBED_VERSION, XEMBED_MAPPED};	XChangeProperty(x11Info().display(), d->client, _XEMBED_INFO, _XEMBED_INFO, 32,			PropModeReplace, (unsigned char *) data, 2);    }}/*! \internal    We use the QHideEvent to signal to our client that we want it to    unmap itself. We do this by changing its window property    XEMBED_INFO. The client will get an X11 PropertyNotify.*/void QX11EmbedContainer::hideEvent(QHideEvent *){    Q_D(QX11EmbedContainer);    if (d->client) {	unsigned int data[] = {XEMBED_VERSION, XEMBED_MAPPED};	XChangeProperty(x11Info().display(), d->client, _XEMBED_INFO, _XEMBED_INFO, 32,			PropModeReplace, (unsigned char *) data, 2);    }}/*!    \reimp*/bool QX11EmbedContainer::event(QEvent *event){    if (event->type() == QEvent::ParentChange) {        XSelectInput(x11Info().display(), internalWinId(),                     KeyPressMask | KeyReleaseMask                     | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask                     | KeymapStateMask                     | PointerMotionMask                     | EnterWindowMask | LeaveWindowMask                     | FocusChangeMask                     | ExposureMask                     | StructureNotifyMask                     | SubstructureNotifyMask);    }    return QWidget::event(event);}/*! \internal    Rejects a client window by reparenting it to the root window.  The    client will receive a reparentnotify, and will most likely assume    that the container has shut down. The XEmbed protocol does not    define any way to reject a client window, but this is a clean way    to do it.*/void QX11EmbedContainerPrivate::rejectClient(WId window){    Q_Q(QX11EmbedContainer);    q->setEnabled(false);    XRemoveFromSaveSet(q->x11Info().display(), client);    XReparentWindow(q->x11Info().display(), window, q->x11Info().appRootWindow(), 0, 0);}/*! \internal    Accepts a client by mapping it, resizing it and optionally    activating and giving it logical focusing through XEMBED messages.*/void QX11EmbedContainerPrivate::acceptClient(WId window){    Q_Q(QX11EmbedContainer);    client = window;    q->setEnabled(true);    // This tells Qt that we wish to forward DnD messages to    // our client.    if (!extra)        createExtra();    extraData()->xDndProxy = client;    unsigned int version = XEmbedVersion();    Atom actual_type_return;    int actual_format_return;    unsigned long nitems_return = 0;    unsigned long bytes_after_return;    unsigned char *prop_return = 0;    unsigned int clientversion = 0;    // Add this client to our saveset, so if we crash, the client window    // doesn't get destroyed. This is useful for containers that restart    // automatically after a crash, because it can simply reembed its clients    // without having to restart them (KDE panel).    XAddToSaveSet(q->x11Info().display(), client);    // XEmbed clients have an _XEMBED_INFO property in which we can    // fetch the version    if (XGetWindowProperty(q->x11Info().display(), client, _XEMBED_INFO, 0, 2, false, _XEMBED_INFO,			   &actual_type_return, &actual_format_return, &nitems_return,			   &bytes_after_return, &prop_return) == Success) {	if (actual_type_return != None && actual_format_return != 0) {	    // Clients with the _XEMBED_INFO property are XEMBED clients.	    clientIsXEmbed = true;	    unsigned int *p = (unsigned int *)prop_return;	    if (nitems_return >= 2)		clientversion = p[0];	}	XFree(prop_return);    }    // Store client window's original size and placement.    Window root;    int x_return, y_return;    unsigned int width_return, height_return, border_width_return, depth_return;    XGetGeometry(q->x11Info().display(), client, &root, &x_return, &y_return,		 &width_return, &height_return, &border_width_return, &depth_return);    clientOriginalRect.setCoords(x_return, y_return,				 x_return + width_return - 1,				 y_return + height_return - 1);    // Ask the client for its minimum size.    XSizeHints size;    long msize;    if (XGetWMNormalHints(q->x11Info().display(), client, &size, &msize) && (size.flags & PMinSize)) {	wmMinimumSizeHint = QSize(size.min_width, size.min_height);        q->updateGeometry();    }    // The container should set the data2 field to the lowest of its    // supported version number and that of the client (from    // _XEMBED_INFO property).    unsigned int minversion = version > clientversion ? clientversion : version;    sendXEmbedMessage(client, q->x11Info().display(), XEMBED_EMBEDDED_NOTIFY, q->internalWinId(), minversion);    XMapWindow(q->x11Info().display(), client);    // Resize it, but no smaller than its minimum size hint.    XResizeWindow(q->x11Info().display(),                  client,                  qMax(q->width(), wmMinimumSizeHint.width()),                  qMax(q->height(), wmMinimumSizeHint.height()));    q->update();    // Not mentioned in the protocol is that if the container    // is already active, the client must be activated to work    // properly.    if (q->window()->isActiveWindow())	sendXEmbedMessage(client, q->x11Info().display(), XEMBED_WINDOW_ACTIVATE);    // Also, if the container already has focus, then it must    // send a focus in message to its new client; otherwise we ask    // it to remove focus.    if (q->focusWidget() == q && q->hasFocus())	sendXEmbedMessage(client, q->x11Info().display(), XEMBED_FOCUS_IN, XEMBED_FOCUS_FIRST);    else	sendXEmbedMessage(client, q->x11Info().display(), XEMBED_FOCUS_OUT);    if (!clientIsXEmbed) {        checkGrab();        if (q->hasFocus()) {            XSetInputFocus(q->x11Info().display(), client, XRevertToParent, x11Time());        } else {            if (!isEmbedded())                moveInputToProxy();        }    }    emit q->clientIsEmbedded();}/*! \internal    Moves X11 keyboard input focus to the focusProxy, unless the focus    is there already. When X11 keyboard input focus is on the    focusProxy, which is a child of the container and a sibling of the    client, X11 keypresses and keyreleases will always go to the proxy    and not to the client.*/void QX11EmbedContainerPrivate::moveInputToProxy(){    Q_Q(QX11EmbedContainer);    WId focus;    int revert_to;    XGetInputFocus(q->x11Info().display(), &focus, &revert_to);    if (focus != focusProxy->internalWinId())	XSetInputFocus(q->x11Info().display(), focusProxy->internalWinId(), XRevertToParent, x11Time());}/*! \internal    Ask the window manager to give us a default minimum size.*/QSize QX11EmbedContainer::minimumSizeHint() const{    Q_D(const QX11EmbedContainer);    if (!d->client || !d->wmMinimumSizeHint.isValid())	return QWidget::minimumSizeHint();    return d->wmMinimumSizeHint;}/*! \internal*/void QX11EmbedContainerPrivate::checkGrab(){    Q_Q(QX11EmbedContainer);    if (!clientIsXEmbed && q->isActiveWindow() && !q->hasFocus()) {        if (!xgrab) {            XGrabButton(q->x11Info().display(), AnyButton, AnyModifier, q->internalWinId(),                        true, ButtonPressMask, GrabModeSync, GrabModeAsync,                        None, None);        }        xgrab = true;    } else {	if (xgrab)	    XUngrabButton(q->x11Info().display(), AnyButton, AnyModifier, q->internalWinId());        xgrab = false;    }}/*!    Detaches the client from the embedder. The client will appear as a    standalone window on the desktop.*/void QX11EmbedContainer::discardClient(){    Q_D(QX11EmbedContainer);    if (d->client) {	XResizeWindow(x11Info().display(), d->client, d->clientOriginalRect.width(),		      d->clientOriginalRect.height());	d->rejectClient(d->client);    }}

⌨️ 快捷键说明

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