42 #include "qplatformdefs.h" 54 #include <private/qt_x11_p.h> 55 #include <private/qwidget_p.h> 61 #include <X11/Xatom.h> 62 #include <X11/Xutil.h> 63 #include <X11/keysymdef.h> 66 #ifndef XK_ISO_Left_Tab 67 #define XK_ISO_Left_Tab 0xFE20 71 #ifdef QX11EMBED_DEBUG 371 long detail = 0,
long data1 = 0,
long data2 = 0)
373 XClientMessageEvent
c;
374 memset(&c, 0,
sizeof(c));
375 c.type = ClientMessage;
382 c.data.l[1] = message;
383 c.data.l[2] = detail;
387 XSendEvent(display, window,
false, NoEventMask, (
XEvent *) &c);
402 lastKeyEvent =
event->xkey;
423 && event->xreparent.window == data->
id 424 && event->xreparent.parent == data->
rootWindow) {
430 && event->type == PropertyNotify
431 && event->xproperty.window == data->
id 433 if (event->xproperty.state == PropertyDelete) {
440 unsigned char *retval;
441 unsigned long nitems, after;
443 &ret, &format, &nitems, &after, &retval );
445 long state = *(
long *)retval;
447 if (state == WithdrawnState) {
473 emit q->error(error);
483 void checkActivateWindow(
QObject *o);
506 KeyPressMask | KeyReleaseMask | ButtonPressMask
508 | KeymapStateMask | ButtonMotionMask | PointerMotionMask
510 | ExposureMask | StructureNotifyMask
511 | SubstructureNotifyMask | PropertyChangeMask);
516 (
unsigned char*) data, 2);
522 #ifdef QX11EMBED_DEBUG 523 qDebug() <<
"QX11EmbedWidget::QX11EmbedWidget: constructed client" 524 << (
void *)
this <<
"with winId" <<
winId();
537 #ifdef QX11EMBED_DEBUG 538 qDebug() <<
"QX11EmbedWidget::~QX11EmbedWidget: unmapping" 539 << (
void *)
this <<
"with winId" <<
winId()
540 <<
"from container with winId" <<
d->container;
546 #ifdef QX11EMBED_DEBUG 547 qDebug() <<
"QX11EmbedWidget::~QX11EmbedWidget: destructed client" 548 << (
void *)
this <<
"with winId" <<
winId();
560 return d_func()->lastError;
573 #ifdef QX11EMBED_DEBUG 574 qDebug() <<
"QX11EmbedWidget::embedInto: embedding client" 575 << (
void *)
this <<
"with winId" <<
winId() <<
"into container" 594 d->data.fstrut_dirty =
false;
617 if (((w->
focusPolicy() & focus_flag) == focus_flag)
621 if (fw == FirstFocusWidget)
641 if ((xec = qobject_cast<QX11EmbedWidget *>(o)))
643 }
while ((o = o->
parent()));
666 if (!(w &&
qApp->activeWindow()))
693 if (!q->window()->hasFocus())
709 ((
QHackWidget *)q->window())->topData()->embedded = 1;
722 switch (event->
type()) {
729 if (
d->xEmbedWidget(o) ==
this) {
730 if (
d->currentFocus.isNull())
749 if (
d->xEmbedWidget(o) ==
this)
750 d->currentFocus = qobject_cast<QWidget *>(o);
768 if (
d->xEmbedWidget(o) ==
this)
769 d->currentFocus = qobject_cast<QWidget *>(o);
774 if (!
d->currentFocus.isNull()) {
775 if (!
d->currentFocus->hasFocus())
790 if (
d->xEmbedWidget(o) ==
this) {
801 d->checkActivateWindow(o);
821 switch (event->type) {
823 #ifdef QX11EMBED_DEBUG 824 qDebug() <<
"QX11EmbedWidget::x11Event: client" 825 << (
void *)
this <<
"with winId" <<
winId()
826 <<
"received a DestroyNotify";
833 #ifdef QX11EMBED_DEBUG 834 qDebug() <<
"QX11EmbedWidget::x11Event: client" 835 << (
void *)
this <<
"with winId" <<
winId()
836 <<
"received a ReparentNotify to" 850 d->container =
event->xreparent.parent;
863 Atom actual_type_return;
864 int actual_format_return;
865 unsigned long nitems_return;
866 unsigned long bytes_after_return;
867 unsigned char *prop_return = 0;
870 &actual_format_return, &nitems_return,
871 &bytes_after_return, &prop_return) ==
Success) {
872 if (nitems_return > 1) {
887 if (event->xclient.message_type ==
ATOM(
_XEMBED)) {
893 Time msgtime = (Time) event->xclient.data.l[0];
894 if (msgtime >
X11->time)
897 switch (event->xclient.data.l[1]) {
913 if (!
qApp->activePopupWidget())
922 #ifdef QX11EMBED_DEBUG 923 qDebug() <<
"QX11EmbedWidget::x11Event: client" 924 << (
void *)
this <<
"with winId" <<
winId()
925 <<
"received an XEMBED EMBEDDED NOTIFY message";
939 if (
qApp->activeModalWidget())
945 qApp->setActiveWindow(
this);
947 switch (event->xclient.data.l[2]) {
953 if (!
d->currentFocus.isNull()) {
954 if (!
d->currentFocus->hasFocus())
1021 KeyPressMask | KeyReleaseMask | ButtonPressMask
1023 | KeymapStateMask | ButtonMotionMask | PointerMotionMask
1025 | ExposureMask | StructureNotifyMask
1026 | SubstructureNotifyMask | PropertyChangeMask);
1048 return d->container;
1060 clientIsXEmbed =
false;
1064 bool isEmbedded()
const;
1065 void moveInputToProxy();
1068 void rejectClient(
WId window);
1072 WId topLevelParentWinId()
const;
1077 emit q->error(error);
1118 d->focusProxy->createWinId();
1119 d->focusProxy->setGeometry(-1, -1, 1, 1);
1123 qApp->installEventFilter(
this);
1126 if (!oldX11EventFilter)
1130 KeyPressMask | KeyReleaseMask
1131 | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask
1134 | EnterWindowMask | LeaveWindowMask
1137 | StructureNotifyMask
1138 | SubstructureNotifyMask);
1146 if (
qApp->activeWindow() ==
window() && !
d->isEmbedded())
1147 d->moveInputToProxy();
1149 #ifdef QX11EMBED_DEBUG 1150 qDebug() <<
"QX11EmbedContainer::QX11EmbedContainer: constructed container" 1151 << (
void *)
this <<
"with winId" <<
winId();
1172 return d_func()->lastError;
1192 return ((
QHackWidget *)q->window())->topData()->embedded == 1;
1205 return ((
QHackWidget *)q->window())->topData()->parentWinId;
1242 Window *childrenReturn = 0;
1243 unsigned int nchildrenReturn;
1246 &parentReturn, &childrenReturn, &nchildrenReturn) == 0) {
1250 if (childrenReturn) {
1251 XFree(childrenReturn);
1255 thisId = parentReturn;
1260 }
while (thisId != rootReturn);
1264 XWindowAttributes attrib;
1270 XSelectInput(
x11Info().
display(),
id, attrib.your_event_mask | PropertyChangeMask | StructureNotifyMask);
1306 qApp->x11ProcessEvent(&event);
1332 switch (event->
type()) {
1335 if (o ==
this &&
d->client) {
1336 lastKeyEvent.window =
d->client;
1343 if (o ==
this &&
d->client) {
1344 lastKeyEvent.window =
d->client;
1355 if (o ==
window() &&
d->client) {
1356 if (
d->clientIsXEmbed) {
1363 if (!
d->isEmbedded())
1364 d->moveInputToProxy();
1370 if (o ==
window() &&
d->client) {
1371 if (
d->clientIsXEmbed)
1382 if (o ==
this &&
d->client) {
1383 if (!
d->isEmbedded())
1384 d->activeContainer =
this;
1386 if (
d->clientIsXEmbed) {
1387 if (!
d->isEmbedded())
1388 d->moveInputToProxy();
1412 if (o ==
this &&
d->client) {
1413 if (!
d->isEmbedded()) {
1414 d->activeContainer = 0;
1416 d->moveInputToProxy();
1419 if (
d->clientIsXEmbed) {
1431 if (o ==
this &&
d->client) {
1440 memset(&ev, 0,
sizeof(ev));
1441 ev.xclient.type = ClientMessage;
1442 ev.xclient.window =
d->client;
1444 ev.xclient.format = 32;
1450 d->clientIsXEmbed =
false;
1451 d->wmMinimumSizeHint =
QSize();
1477 switch (event->type) {
1481 d->rejectClient(event->xcreatewindow.window);
1483 d->acceptClient(event->xcreatewindow.window);
1486 if (event->xdestroywindow.window ==
d->client) {
1489 d->clientIsXEmbed =
false;
1490 d->wmMinimumSizeHint =
QSize();
1497 case ReparentNotify:
1500 if (event->xreparent.window ==
d->client && event->xreparent.parent !=
internalWinId()) {
1502 d->clientIsXEmbed =
false;
1503 d->wmMinimumSizeHint =
QSize();
1511 d->rejectClient(event->xreparent.window);
1513 d->acceptClient(event->xreparent.window);
1516 case ClientMessage: {
1517 if (event->xclient.message_type ==
ATOM(
_XEMBED)) {
1524 d->clientIsXEmbed =
true;
1526 Time msgtime = (Time) event->xclient.data.l[0];
1527 if (msgtime >
X11->time)
1528 X11->time = msgtime;
1530 switch (event->xclient.data.l[1]) {
1543 if (
d->isEmbedded()) {
1566 if (
d->focus_next !=
this) {
1570 qApp->sendEvent(
this, &event);
1579 if (
d->focus_next !=
this) {
1583 qApp->sendEvent(
this, &event);
1594 if (!
d->clientIsXEmbed) {
1601 if (!
d->clientIsXEmbed)
1640 PropModeReplace, (
unsigned char *) data, 2);
1659 PropModeReplace, (
unsigned char *) data, 2);
1670 KeyPressMask | KeyReleaseMask
1671 | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask
1674 | EnterWindowMask | LeaveWindowMask
1677 | StructureNotifyMask
1678 | SubstructureNotifyMask);
1697 q->setEnabled(
false);
1698 XRemoveFromSaveSet(q->x11Info().display(), client);
1720 extraData()->xDndProxy = client;
1724 Atom actual_type_return;
1725 int actual_format_return;
1726 unsigned long nitems_return = 0;
1727 unsigned long bytes_after_return;
1728 unsigned char *prop_return = 0;
1729 unsigned int clientversion = 0;
1735 XAddToSaveSet(q->x11Info().display(), client);
1739 if (XGetWindowProperty(q->x11Info().display(), client,
ATOM(
_XEMBED_INFO), 0, 2,
false,
1741 &nitems_return, &bytes_after_return, &prop_return) ==
Success) {
1743 if (actual_type_return !=
None && actual_format_return != 0) {
1745 clientIsXEmbed =
true;
1747 long *p = (
long *)prop_return;
1748 if (nitems_return >= 2)
1749 clientversion = (
unsigned int)p[0];
1757 int x_return, y_return;
1758 unsigned int width_return, height_return, border_width_return, depth_return;
1759 XGetGeometry(q->x11Info().display(), client, &root, &x_return, &y_return,
1760 &width_return, &height_return, &border_width_return, &depth_return);
1761 clientOriginalRect.setCoords(x_return, y_return,
1762 x_return + width_return - 1,
1763 y_return + height_return - 1);
1768 if (XGetWMNormalHints(q->x11Info().display(), client, &
size, &msize) && (size.flags & PMinSize)) {
1769 wmMinimumSizeHint =
QSize(size.min_width, size.min_height);
1770 q->updateGeometry();
1776 unsigned int minversion = version > clientversion ? clientversion : version;
1778 XMapWindow(q->x11Info().display(), client);
1781 XResizeWindow(q->x11Info().display(),
1783 qMax(q->width(), wmMinimumSizeHint.width()),
1784 qMax(q->height(), wmMinimumSizeHint.height()));
1790 if (q->window()->isActiveWindow())
1796 if (q->focusWidget() == q && q->hasFocus())
1801 if (!clientIsXEmbed) {
1803 if (q->hasFocus()) {
1811 emit q->clientIsEmbedded();
1843 if (!
d->client || !
d->wmMinimumSizeHint.isValid())
1845 return d->wmMinimumSizeHint;
1854 if (!clientIsXEmbed && q->isActiveWindow() && !q->hasFocus()) {
1856 XGrabButton(q->x11Info().display(),
AnyButton, AnyModifier, q->internalWinId(),
1857 true, ButtonPressMask, GrabModeSync, GrabModeAsync,
1863 XUngrabButton(q->x11Info().display(),
AnyButton, AnyModifier, q->internalWinId());
1876 XResizeWindow(
x11Info().
display(),
d->client,
d->clientOriginalRect.width(),
1877 d->clientOriginalRect.height());
1879 d->rejectClient(
d->client);
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
void paintEvent(QPaintEvent *e)
Reimplemented Function
bool x11Event(XEvent *)
Handles X11 events for the container.
static XKeyEvent lastKeyEvent
QX11EmbedContainerPrivate()
#define QT_END_NAMESPACE
This macro expands to.
static QX11EmbedContainer * activeContainer
static Qt::HANDLE appRootWindow(int screen=-1)
Returns a handle for the applications root window on the given screen.
static QCoreApplication::EventFilter oldX11EventFilter
static LibLoadStatus status
EventFilter setEventFilter(EventFilter filter)
Replaces the event filter function for the QCoreApplication with filter and returns the pointer to th...
T * qobject_cast(QObject *object)
static unsigned int XEMBED_VERSION
The QObject class is the base class of all Qt objects.
void acceptClient(WId window)
Accepts a client by mapping it, resizing it and optionally activating and giving it logical focusing ...
The QElapsedTimer class provides a fast way to calculate elapsed times.
qint64 elapsed() const
Returns the number of milliseconds since this QElapsedTimer was last started.
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Error error() const
Returns the last error that occurred.
void emitError(QX11EmbedContainer::Error error)
Q_CORE_EXPORT void qDebug(const char *,...)
~QX11EmbedContainer()
Destructs a QX11EmbedContainer.
void showEvent(QShowEvent *)
We use the QShowEvent to signal to our client that we want it to map itself.
#define QT_BEGIN_NAMESPACE
This macro expands to.
Q_GUI_EXPORT EGLDisplay display()
void update()
Updates the layout for parentWidget().
The QHideEvent class provides an event which is sent after a widget is hidden.
Q_GUI_EXPORT QX11Data * qt_x11Data
The QResizeEvent class contains event parameters for resize events.
static void sendXEmbedMessage(WId window, Display *display, long message, long detail=0, long data1=0, long data2=0)
bool eventFilter(QObject *, QEvent *)
Handles key, activation and focus events for the container.
static bool sendEvent(QObject *receiver, QEvent *event)
Sends event event directly to receiver receiver, using the notify() function.
void setCoords(int x1, int y1, int x2, int y2)
Sets the coordinates of the rectangle's top-left corner to (x1, y1), and the coordinates of its botto...
static int x11ErrorHandler(Display *, XErrorEvent *)
The QShowEvent class provides an event that is sent when a widget is shown.
static void setActiveWindow(QWidget *act)
Sets the active window to the active widget in response to a system event.
virtual bool eventFilter(QObject *, QEvent *)
Filters events if this object has been installed as an event filter for the watched object...
#define Q_DECLARE_PUBLIC(Class)
void discardClient()
Detaches the client from the embedder.
static QCoreApplication * instance()
Returns a pointer to the application's QCoreApplication (or QApplication) instance.
static QString fromLatin1(const char *, int size=-1)
Returns a QString initialized with the first size characters of the Latin-1 string str...
void clientClosed()
This signal is emitted by the container when the client widget closes.
static bool x11EventFilter(void *message, long *result)
static const int AnyButton
QObject * parent() const
Returns a pointer to the parent object.
bool event(QEvent *)
Reimplemented Function
WId clientWinId() const
If the container has an embedded widget, this function returns the X11 window ID of the client; other...
void installEventFilter(QObject *)
Installs an event filter filterObj on this object.
bool(* EventFilter)(void *message, long *result)
A function with the following signature that can be used as an event filter:
void moveInputToProxy()
Moves X11 keyboard input focus to the focusProxy, unless the focus is there already.
if(void) toggleToolbarShown
The QRect class defines a rectangle in the plane using integer precision.
bool isEmbedded() const
Returns whether or not the windows' embedded flag is set.
static Bool functor(Display *display, XEvent *event, XPointer arg)
The QSize class defines the size of a two-dimensional object using integer point precision.
#define Q_DECLARE_PRIVATE(Class)
void embedClient(WId id)
Instructs the container to embed the X11 window with window ID id.
QSize minimumSizeHint() const
Ask the window manager to give us a default minimum size.
The QPaintEvent class contains event parameters for paint events.
QX11EmbedContainer::Error lastError
The QEvent class is the base class of all event classes.
Type type() const
Returns the event type.
QX11EmbedContainer(QWidget *parent=0)
Creates a QX11EmbedContainer object with the given parent.
void rejectClient(WId window)
Rejects a client window by reparenting it to the root window.
WId topLevelParentWinId() const
Returns the parentWinId of the window.
void start()
Starts this timer.
The QX11EmbedContainer class provides an XEmbed container widget.
void hideEvent(QHideEvent *)
We use the QHideEvent to signal to our client that we want it to unmap itself.
The QFocusEvent class contains event parameters for widget focus events.
static Display * display()
Returns the default display for the application.
static unsigned int XEmbedVersion()
void resizeEvent(QResizeEvent *)
Whenever the container is resized, we need to resize our client.