Qt 4.8
qx11embed_x11.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qplatformdefs.h"
43 #include "qx11embed_x11.h"
44 #include <qapplication.h>
45 #include <qevent.h>
46 #include <qpainter.h>
47 #include <qlayout.h>
48 #include <qstyle.h>
49 #include <qstyleoption.h>
50 #include <qelapsedtimer.h>
51 #include <qpointer.h>
52 #include <qdebug.h>
53 #include <qx11info_x11.h>
54 #include <private/qt_x11_p.h>
55 #include <private/qwidget_p.h>
56 
57 #define XK_MISCELLANY
58 #define XK_LATIN1
59 #define None 0
60 #include <X11/Xlib.h>
61 #include <X11/Xatom.h>
62 #include <X11/Xutil.h>
63 #include <X11/keysymdef.h>
64 #include <X11/X.h>
65 
66 #ifndef XK_ISO_Left_Tab
67 #define XK_ISO_Left_Tab 0xFE20
68 #endif
69 
70 //#define QX11EMBED_DEBUG
71 #ifdef QX11EMBED_DEBUG
72 #include <qdebug.h>
73 #endif
74 
76 
291 const int XButtonPress = ButtonPress;
292 const int XButtonRelease = ButtonRelease;
293 #undef ButtonPress
294 #undef ButtonRelease
295 
296 // This is a hack to move topData() out from QWidgetPrivate to public. We
297 // need to to inspect window()'s embedded state.
298 class QHackWidget : public QWidget
299 {
301 public:
302  QTLWExtra* topData() { return d_func()->topData(); }
303 };
304 
305 static unsigned int XEMBED_VERSION = 0;
306 
321 };
322 
327 };
328 
330  XEMBED_FOCUS_OTHER = (0 << 0),
332 };
333 
335  XEMBED_MAPPED = (1 << 0)
336 };
337 
344 };
345 
348 };
349 
350 // Silence the default X11 error handler.
351 static int x11ErrorHandler(Display *, XErrorEvent *)
352 {
353  return 0;
354 }
355 
356 // Returns the X11 timestamp. Maintained mainly by qapplication
357 // internals, but also updated by the XEmbed widgets.
358 static Time x11Time()
359 {
360  return qt_x11Data->time;
361 }
362 
363 // Gives the version and flags of the supported XEmbed protocol.
364 static unsigned int XEmbedVersion()
365 {
366  return 0;
367 }
368 
369 // Sends an XEmbed message.
370 static void sendXEmbedMessage(WId window, Display *display, long message,
371  long detail = 0, long data1 = 0, long data2 = 0)
372 {
373  XClientMessageEvent c;
374  memset(&c, 0, sizeof(c));
375  c.type = ClientMessage;
376  c.message_type = ATOM(_XEMBED);
377  c.format = 32;
378  c.display = display;
379  c.window = window;
380 
381  c.data.l[0] = x11Time();
382  c.data.l[1] = message;
383  c.data.l[2] = detail;
384  c.data.l[3] = data1;
385  c.data.l[4] = data2;
386 
387  XSendEvent(display, window, false, NoEventMask, (XEvent *) &c);
388 }
389 
390 // From qapplication_x11.cpp
391 static XKeyEvent lastKeyEvent;
392 
394 
395 // The purpose of this global x11 filter is for one to capture the key
396 // events in their original state, but most importantly this is the
397 // only way to get the WM_TAKE_FOCUS message from WM_PROTOCOLS.
398 static bool x11EventFilter(void *message, long *result)
399 {
400  XEvent *event = reinterpret_cast<XEvent *>(message);
401  if (event->type == XKeyPress || event->type == XKeyRelease)
402  lastKeyEvent = event->xkey;
403 
404  if (oldX11EventFilter && oldX11EventFilter != &x11EventFilter)
405  return oldX11EventFilter(message, result);
406  else
407  return false;
408 }
409 
410 //
412 {
416 };
417 
419 {
420  functorData *data = (functorData *) arg;
421 
422  if (!data->reparentedToRoot && event->type == ReparentNotify
423  && event->xreparent.window == data->id
424  && event->xreparent.parent == data->rootWindow) {
425  data->reparentedToRoot = true;
426  return true;
427  }
428 
429  if (!data->clearedWmState
430  && event->type == PropertyNotify
431  && event->xproperty.window == data->id
432  && event->xproperty.atom == ATOM(WM_STATE)) {
433  if (event->xproperty.state == PropertyDelete) {
434  data->clearedWmState = true;
435  return true;
436  }
437 
438  Atom ret;
439  int format, status;
440  unsigned char *retval;
441  unsigned long nitems, after;
442  status = XGetWindowProperty(display, data->id, ATOM(WM_STATE), 0, 2, False, ATOM(WM_STATE),
443  &ret, &format, &nitems, &after, &retval );
444  if (status == Success && ret == ATOM(WM_STATE) && format == 32 && nitems > 0) {
445  long state = *(long *)retval;
446  XFree(retval);
447  if (state == WithdrawnState) {
448  data->clearedWmState = true;
449  return true;
450  }
451  }
452  }
453 
454  return false;
455 }
456 
458 {
460 public:
462  {
463  lastError = QX11EmbedWidget::Unknown;
464  container = 0;
465  }
466 
467  void setEmbedded();
468 
471 
472  lastError = error;
473  emit q->error(error);
474  }
475 
478  LastFocusWidget
479  };
480 
482  QWidget *getFocusWidget(FocusWidgets fw);
483  void checkActivateWindow(QObject *o);
484  QX11EmbedWidget *xEmbedWidget(QObject *o) const;
485  void clearFocus();
486 
489 
491 
492 };
493 
498  : QWidget(*new QX11EmbedWidgetPrivate, parent, 0)
499 {
500  XSetErrorHandler(x11ErrorHandler);
501 
504  createWinId();
505  XSelectInput(x11Info().display(), internalWinId(),
506  KeyPressMask | KeyReleaseMask | ButtonPressMask
507  | ButtonReleaseMask
508  | KeymapStateMask | ButtonMotionMask | PointerMotionMask
509  | FocusChangeMask
510  | ExposureMask | StructureNotifyMask
511  | SubstructureNotifyMask | PropertyChangeMask);
512 
513  long data[] = {XEMBED_VERSION, XEMBED_MAPPED};
514  XChangeProperty(x11Info().display(), internalWinId(), ATOM(_XEMBED_INFO),
515  ATOM(_XEMBED_INFO), 32, PropModeReplace,
516  (unsigned char*) data, 2);
517 
521 
522 #ifdef QX11EMBED_DEBUG
523  qDebug() << "QX11EmbedWidget::QX11EmbedWidget: constructed client"
524  << (void *)this << "with winId" << winId();
525 #endif
526 }
527 
534 {
536  if (d->container) {
537 #ifdef QX11EMBED_DEBUG
538  qDebug() << "QX11EmbedWidget::~QX11EmbedWidget: unmapping"
539  << (void *)this << "with winId" << winId()
540  << "from container with winId" << d->container;
541 #endif
542  XUnmapWindow(x11Info().display(), internalWinId());
543  XReparentWindow(x11Info().display(), internalWinId(), x11Info().appRootWindow(x11Info().screen()), 0, 0);
544  }
545 
546 #ifdef QX11EMBED_DEBUG
547  qDebug() << "QX11EmbedWidget::~QX11EmbedWidget: destructed client"
548  << (void *)this << "with winId" << winId();
549 #endif
550 }
551 
559 {
560  return d_func()->lastError;
561 }
562 
571 {
573 #ifdef QX11EMBED_DEBUG
574  qDebug() << "QX11EmbedWidget::embedInto: embedding client"
575  << (void *)this << "with winId" << winId() << "into container"
576  << id;
577 #endif
578 
579  d->container = id;
580  switch (XReparentWindow(x11Info().display(), internalWinId(), d->container, 0, 0)) {
581  case BadWindow:
582  d->emitError(InvalidWindowID);
583  break;
584  case BadMatch:
585  d->emitError(Internal);
586  break;
587  case Success:
588  default:
589  break;
590  }
591  QTLWExtra* x = d->extra ? d->extra->topextra : 0;
592  if (x)
593  x->frameStrut.setCoords(0, 0, 0, 0);
594  d->data.fstrut_dirty = false;
595 }
596 
605 {
607  QWidget *tlw = q;
608  QWidget *w = tlw->nextInFocusChain();
609 
610  QWidget *last = tlw;
611 
612  extern bool qt_tab_all_widgets;
613  uint focus_flag = qt_tab_all_widgets ? Qt::TabFocus : Qt::StrongFocus;
614 
615  while (w != tlw)
616  {
617  if (((w->focusPolicy() & focus_flag) == focus_flag)
618  && w->isVisibleTo(q) && w->isEnabled())
619  {
620  last = w;
621  if (fw == FirstFocusWidget)
622  break;
623  }
624  w = w->nextInFocusChain();
625  }
626 
627  return last;
628 }
629 
635 {
636  QX11EmbedWidget *xec = 0;
637 
638  // Check the widget itself, then its parents, and find the first
639  // QX11EmbedWidget.
640  do {
641  if ((xec = qobject_cast<QX11EmbedWidget *>(o)))
642  return xec;
643  } while ((o = o->parent()));
644  return 0;
645 }
646 
655 {
657  QX11EmbedWidget *xec = xEmbedWidget(o);
658 
659  // check if we are in the right xembed client
660  if (q != xec)
661  return;
662 
663  QWidget *w = qobject_cast<QWidget *>(o);
664 
665  // if it is no active window, then don't do the change
666  if (!(w && qApp->activeWindow()))
667  return;
668 
669  // if it already is the active window, don't do anything
670  if (w->window() != qApp->activeWindow())
671  {
672  qApp->setActiveWindow(w->window());
673  currentFocus = w;
674 
675  sendXEmbedMessage(xec->containerWinId(), q->x11Info().display(), XEMBED_REQUEST_FOCUS);
676  }
677 }
678 
684 {
686  // Setting focus on the client itself removes Qt's
687  // logical focus rectangle. We can't just do a
688  // clearFocus here, because when we send the synthetic
689  // FocusIn to ourselves on activation, Qt will set
690  // focus on focusWidget() again. This way, we "hide"
691  // focus rather than clearing it.
692 
693  if (!q->window()->hasFocus())
694  q->window()->setFocus(Qt::OtherFocusReason);
695 
696  currentFocus = 0;
697 }
698 
707 {
709  ((QHackWidget *)q->window())->topData()->embedded = 1;
710 }
711 
720 {
722  switch (event->type()) {
723  case QEvent::FocusIn:
724  switch (((QFocusEvent *)event)->reason()) {
726  // If the user clicks into one of the client widget's
727  // children and we didn't have focus already, we request
728  // focus from our container.
729  if (d->xEmbedWidget(o) == this) {
730  if (d->currentFocus.isNull())
732 
733  d->currentFocus = qobject_cast<QWidget *>(o);
734  }
735  break;
736  case Qt::TabFocusReason:
737  // If the xembed client receives a focus event because of
738  // a Tab, then we are at the end of our focus chain and we
739  // ask the container to move to its next focus widget.
740  if (o == this) {
741  d->clearFocus();
743  return true;
744  } else {
745  // We're listening on events from qApp, so in order
746  // for us to know who to set focus on if we receive an
747  // activation event, we note the widget that got the
748  // focusin last.
749  if (d->xEmbedWidget(o) == this)
750  d->currentFocus = qobject_cast<QWidget *>(o);
751  }
752  break;
754  // If the window receives a focus event because of
755  // a Backtab, then we are at the start of our focus chain
756  // and we ask the container to move to its previous focus
757  // widget.
758  if (o == this) {
759  // See comment for Tab.
760  // If we receive a XEMBED_FOCUS_IN
761  // XEMBED_FOCUS_CURRENT, we will set focus in
762  // currentFocus. To avoid that in this case, we reset
763  // currentFocus.
764  d->clearFocus();
766  return true;
767  } else {
768  if (d->xEmbedWidget(o) == this)
769  d->currentFocus = qobject_cast<QWidget *>(o);
770  }
771  break;
773  if (isActiveWindow()) {
774  if (!d->currentFocus.isNull()) {
775  if (!d->currentFocus->hasFocus())
776  d->currentFocus->setFocus(Qt::OtherFocusReason);
777  } else {
778  d->clearFocus();
779  return true;
780  }
781  }
782 
783  break;
787  // If focus is received to any child widget because of any
788  // other reason, remember the widget so that we can give
789  // it focus again if we're activated.
790  if (d->xEmbedWidget(o) == this) {
791  d->currentFocus = qobject_cast<QWidget *>(o);
792  }
793  break;
794  default:
795  break;
796  }
797  break;
799  // If we get a mouse button press event inside a embedded widget
800  // make sure this is the active window in qapp.
801  d->checkActivateWindow(o);
802  break;
803  default:
804  break;
805  }
806 
807  return QWidget::eventFilter(o, event);
808 }
809 
819 {
821  switch (event->type) {
822  case DestroyNotify:
823 #ifdef QX11EMBED_DEBUG
824  qDebug() << "QX11EmbedWidget::x11Event: client"
825  << (void *)this << "with winId" << winId()
826  << "received a DestroyNotify";
827 #endif
828  // If the container window is destroyed, we signal this to the user.
829  d->container = 0;
831  break;
832  case ReparentNotify:
833 #ifdef QX11EMBED_DEBUG
834  qDebug() << "QX11EmbedWidget::x11Event: client"
835  << (void *)this << "with winId" << winId()
836  << "received a ReparentNotify to"
837  << ((event->xreparent.parent == x11Info().appRootWindow(x11Info().screen()))
838  ? QString::fromLatin1("root") : QString::number(event->xreparent.parent));
839 #endif
840  // If the container shuts down, we will be reparented to the
841  // root window. We must also consider the case that we may be
842  // reparented from one container to another.
843  if (event->xreparent.parent == x11Info().appRootWindow(x11Info().screen())) {
844  if (((QHackWidget *)this)->topData()->embedded) {
845  d->container = 0;
847  }
848  return true;
849  } else {
850  d->container = event->xreparent.parent;
851  }
852  break;
853  case UnmapNotify:
854  // Mapping and unmapping are handled by changes to the
855  // _XEMBED_INFO property. Any default map/unmap requests are
856  // ignored.
857  return true;
858  case PropertyNotify:
859  // The container sends us map/unmap messages through the
860  // _XEMBED_INFO property. We adhere to the XEMBED_MAPPED bit in
861  // data2.
862  if (event->xproperty.atom == ATOM(_XEMBED_INFO)) {
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;
868  if (XGetWindowProperty(x11Info().display(), internalWinId(), ATOM(_XEMBED_INFO), 0, 2,
869  false, ATOM(_XEMBED_INFO), &actual_type_return,
870  &actual_format_return, &nitems_return,
871  &bytes_after_return, &prop_return) == Success) {
872  if (nitems_return > 1) {
873  if (((long * )prop_return)[1] & XEMBED_MAPPED) {
874  XMapWindow(x11Info().display(), internalWinId());
875  } else {
876  XUnmapWindow(x11Info().display(), internalWinId());
877  }
878  }
879  if (prop_return)
880  XFree(prop_return);
881  }
882  }
883 
884  break;
885  case ClientMessage:
886  // XEMBED messages have message_type _XEMBED
887  if (event->xclient.message_type == ATOM(_XEMBED)) {
888  // Discard XEMBED messages not to ourselves. (### dead code?)
889  if (event->xclient.window != internalWinId())
890  break;
891 
892  // Update qt_x_time if necessary
893  Time msgtime = (Time) event->xclient.data.l[0];
894  if (msgtime > X11->time)
895  X11->time = msgtime;
896 
897  switch (event->xclient.data.l[1]) {
898  case XEMBED_WINDOW_ACTIVATE: {
899  // When we receive an XEMBED_WINDOW_ACTIVATE, we simply send
900  // ourselves a WindowActivate event. Real activation happens
901  // when receive XEMBED_FOCUS_IN.
902  if (!isActiveWindow()) {
904  QApplication::sendEvent(this, &ev);
905  }
906  }
907  break;
909  // When we receive an XEMBED_WINDOW_DEACTIVATE, we simply send
910  // ourselves a WindowDeactivate event. Real activation happens
911  // when receive XEMBED_FOCUS_IN.
912  if (isActiveWindow()) {
913  if (!qApp->activePopupWidget())
915  } else {
917  QApplication::sendEvent(this, &ev);
918  }
919  }
920  break;
921  case XEMBED_EMBEDDED_NOTIFY: {
922 #ifdef QX11EMBED_DEBUG
923  qDebug() << "QX11EmbedWidget::x11Event: client"
924  << (void *)this << "with winId" << winId()
925  << "received an XEMBED EMBEDDED NOTIFY message";
926 #endif
927  // In this message's l[2] we have the max version
928  // supported by both the client and the
929  // container. QX11EmbedWidget does not use this field.
930 
931  // We have been embedded, so we set our
932  // client's embedded flag.
933  d->setEmbedded();
934  emit embedded();
935  }
936  break;
937  case XEMBED_FOCUS_IN:
938  // don't set the focus if a modal dialog is open
939  if (qApp->activeModalWidget())
940  break;
941 
942  // in case we embed more than one topLevel window inside the same
943  // host window.
944  if (window() != qApp->activeWindow())
945  qApp->setActiveWindow(this);
946 
947  switch (event->xclient.data.l[2]) {
949  // The container sends us this message if it wants
950  // us to focus on the widget that last had focus.
951  // This is the reply when XEMBED_REQUEST_FOCUS is
952  // sent to the container.
953  if (!d->currentFocus.isNull()) {
954  if (!d->currentFocus->hasFocus())
955  d->currentFocus->setFocus(Qt::OtherFocusReason);
956  } else {
957  // No widget currently has focus. We set focus
958  // on the first widget next to the
959  // client widget. Since the setFocus will not work
960  // if the window is disabled, set the currentFocus
961  // directly so that it's set on window activate.
962  d->currentFocus = d->getFocusWidget(QX11EmbedWidgetPrivate::FirstFocusWidget);
963  d->currentFocus->setFocus(Qt::OtherFocusReason);
964  }
965  break;
966  case XEMBED_FOCUS_FIRST:
967  // The container sends this message when it wants
968  // us to focus on the first widget in our focus
969  // chain (typically because of a tab).
970  d->currentFocus = d->getFocusWidget(QX11EmbedWidgetPrivate::FirstFocusWidget);
971  d->currentFocus->setFocus(Qt::TabFocusReason);
972  break;
973  case XEMBED_FOCUS_LAST:
974  // The container sends this message when it wants
975  // us to focus on the last widget in our focus
976  // chain (typically because of a backtab).
977  d->currentFocus = d->getFocusWidget(QX11EmbedWidgetPrivate::LastFocusWidget);
978  d->currentFocus->setFocus(Qt::BacktabFocusReason);
979  break;
980  default:
981  // Ignore any other XEMBED_FOCUS_IN details.
982  break;
983  }
984  break;
985  case XEMBED_FOCUS_OUT:
986  // The container sends us this message when it wants us
987  // to lose focus and forget about the widget that last
988  // had focus. Typically sent by the container when it
989  // loses focus because of mouse or tab activity. We do
990  // then not want to set focus on anything if we're
991  // activated.
992  if (isActiveWindow())
993  d->clearFocus();
994 
995  break;
996  default:
997  // Ignore any other XEMBED messages.
998  break;
999  };
1000  } else {
1001  // Non-XEMBED client messages are not interesting.
1002  }
1003 
1004  break;
1005  default:
1006  // Ignore all other x11 events.
1007  break;
1008  }
1009 
1010  // Allow default handling.
1011  return QWidget::x11Event(event);
1012 }
1013 
1018 {
1019  if (event->type() == QEvent::ParentChange) {
1020  XSelectInput(x11Info().display(), internalWinId(),
1021  KeyPressMask | KeyReleaseMask | ButtonPressMask
1022  | ButtonReleaseMask
1023  | KeymapStateMask | ButtonMotionMask | PointerMotionMask
1024  | FocusChangeMask
1025  | ExposureMask | StructureNotifyMask
1026  | SubstructureNotifyMask | PropertyChangeMask);
1027  }
1028  return QWidget::event(event);
1029 }
1030 
1035 {
1036  if (layout())
1037  layout()->update();
1038  QWidget::resizeEvent(event);
1039 }
1040 
1046 {
1047  Q_D(const QX11EmbedWidget);
1048  return d->container;
1049 }
1050 
1052 {
1054 public:
1056  {
1057  lastError = QX11EmbedContainer::Unknown;
1058  client = 0;
1059  focusProxy = 0;
1060  clientIsXEmbed = false;
1061  xgrab = false;
1062  }
1063 
1064  bool isEmbedded() const;
1065  void moveInputToProxy();
1066 
1067  void acceptClient(WId window);
1068  void rejectClient(WId window);
1069 
1070  void checkGrab();
1071 
1072  WId topLevelParentWinId() const;
1073 
1076  lastError = error;
1077  emit q->error(error);
1078  }
1079 
1083  bool xgrab;
1086 
1088 
1090 };
1091 
1093 
1098  : QWidget(*new QX11EmbedContainerPrivate, parent, 0)
1099 {
1101  XSetErrorHandler(x11ErrorHandler);
1102 
1105  createWinId();
1106 
1109  // ### PORT setKeyCompression(false);
1110  setAcceptDrops(true);
1111  setEnabled(false);
1112 
1113  // Everybody gets a focus proxy, but only one toplevel container's
1114  // focus proxy is actually in use.
1115  d->focusProxy = new QWidget(this);
1116  d->focusProxy->setAttribute(Qt::WA_NativeWindow);
1117  d->focusProxy->setAttribute(Qt::WA_DontCreateNativeAncestors);
1118  d->focusProxy->createWinId();
1119  d->focusProxy->setGeometry(-1, -1, 1, 1);
1120 
1121  // We need events from the window (activation status) and
1122  // from qApp (keypress/release).
1123  qApp->installEventFilter(this);
1124 
1125  // Install X11 event filter.
1126  if (!oldX11EventFilter)
1128 
1129  XSelectInput(x11Info().display(), internalWinId(),
1130  KeyPressMask | KeyReleaseMask
1131  | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask
1132  | KeymapStateMask
1133  | PointerMotionMask
1134  | EnterWindowMask | LeaveWindowMask
1135  | FocusChangeMask
1136  | ExposureMask
1137  | StructureNotifyMask
1138  | SubstructureNotifyMask);
1139 
1140  // Make sure our new event mask takes effect as soon as possible.
1141  XFlush(x11Info().display());
1142 
1143  // Move input to our focusProxy if this widget is active, and not
1144  // shaded by a modal dialog (in which case isActiveWindow() would
1145  // still return true, but where we must not move input focus).
1146  if (qApp->activeWindow() == window() && !d->isEmbedded())
1147  d->moveInputToProxy();
1148 
1149 #ifdef QX11EMBED_DEBUG
1150  qDebug() << "QX11EmbedContainer::QX11EmbedContainer: constructed container"
1151  << (void *)this << "with winId" << winId();
1152 #endif
1153 }
1154 
1159 {
1161  if (d->client) {
1162  XUnmapWindow(x11Info().display(), d->client);
1163  XReparentWindow(x11Info().display(), d->client, x11Info().appRootWindow(x11Info().screen()), 0, 0);
1164  }
1165 
1166  if (d->xgrab)
1167  XUngrabButton(x11Info().display(), AnyButton, AnyModifier, internalWinId());
1168 }
1169 
1170 
1172  return d_func()->lastError;
1173 }
1174 
1175 
1179 {
1180 }
1181 
1190 {
1191  Q_Q(const QX11EmbedContainer);
1192  return ((QHackWidget *)q->window())->topData()->embedded == 1;
1193 }
1194 
1203 {
1204  Q_Q(const QX11EmbedContainer);
1205  return ((QHackWidget *)q->window())->topData()->parentWinId;
1206 }
1207 
1213 {
1214  Q_D(const QX11EmbedContainer);
1215  return d->client;
1216 }
1217 
1230 {
1232 
1233  if (id == 0) {
1234  d->emitError(InvalidWindowID);
1235  return;
1236  }
1237 
1238  // Walk up the tree of parent windows to prevent embedding of ancestors.
1239  WId thisId = internalWinId();
1240  Window rootReturn;
1241  Window parentReturn;
1242  Window *childrenReturn = 0;
1243  unsigned int nchildrenReturn;
1244  do {
1245  if (XQueryTree(x11Info().display(), thisId, &rootReturn,
1246  &parentReturn, &childrenReturn, &nchildrenReturn) == 0) {
1247  d->emitError(InvalidWindowID);
1248  return;
1249  }
1250  if (childrenReturn) {
1251  XFree(childrenReturn);
1252  childrenReturn = 0;
1253  }
1254 
1255  thisId = parentReturn;
1256  if (id == thisId) {
1257  d->emitError(InvalidWindowID);
1258  return;
1259  }
1260  } while (thisId != rootReturn);
1261 
1262  // watch for property notify events (see below)
1263  XGrabServer(x11Info().display());
1264  XWindowAttributes attrib;
1265  if (!XGetWindowAttributes(x11Info().display(), id, &attrib)) {
1266  XUngrabServer(x11Info().display());
1267  d->emitError(InvalidWindowID);
1268  return;
1269  }
1270  XSelectInput(x11Info().display(), id, attrib.your_event_mask | PropertyChangeMask | StructureNotifyMask);
1271  XUngrabServer(x11Info().display());
1272 
1273  // Put the window into WithdrawnState
1274  XUnmapWindow(x11Info().display(), id);
1275  XSync(x11Info().display(), False); // make sure the window is hidden
1276 
1277  /*
1278  Wait for notification from the window manager that the window is
1279  in withdrawn state. According to the ICCCM section 4.1.3.1,
1280  we should wait for the WM_STATE property to either be deleted or
1281  set to WithdrawnState.
1282 
1283  For safety, we will not wait more than 500 ms, so that we can
1284  preemptively workaround buggy window managers.
1285  */
1286  QElapsedTimer t;
1287  t.start();
1288 
1289  functorData data;
1290  data.id = id;
1291  data.rootWindow = attrib.root;
1292  data.clearedWmState = false;
1293  data.reparentedToRoot = false;
1294 
1295  do {
1296  if (t.elapsed() > 500) // time-out after 500 ms
1297  break;
1298 
1299  XEvent event;
1300  if (!XCheckIfEvent(x11Info().display(), &event, functor, (XPointer) &data)) {
1301  XSync(x11Info().display(), False);
1302  usleep(50000);
1303  continue;
1304  }
1305 
1306  qApp->x11ProcessEvent(&event);
1307  } while (!data.clearedWmState || !data.reparentedToRoot);
1308 
1309  // restore the event mask
1310  XSelectInput(x11Info().display(), id, attrib.your_event_mask);
1311 
1312  switch (XReparentWindow(x11Info().display(), id, internalWinId(), 0, 0)) {
1313  case BadWindow:
1314  case BadMatch:
1315  d->emitError(InvalidWindowID);
1316  break;
1317  default:
1318  break;
1319  }
1320 }
1321 
1330 {
1332  switch (event->type()) {
1333  case QEvent::KeyPress:
1334  // Forward any keypresses to our client.
1335  if (o == this && d->client) {
1336  lastKeyEvent.window = d->client;
1337  XSendEvent(x11Info().display(), d->client, false, KeyPressMask, (XEvent *) &lastKeyEvent);
1338  return true;
1339  }
1340  break;
1341  case QEvent::KeyRelease:
1342  // Forward any keyreleases to our client.
1343  if (o == this && d->client) {
1344  lastKeyEvent.window = d->client;
1345  XSendEvent(x11Info().display(), d->client, false, KeyReleaseMask, (XEvent *) &lastKeyEvent);
1346  return true;
1347  }
1348  break;
1349 
1351  // When our container window is activated, we pass the
1352  // activation message on to our client. Note that X input
1353  // focus is set to our focus proxy. We want to intercept all
1354  // keypresses.
1355  if (o == window() && d->client) {
1356  if (d->clientIsXEmbed) {
1358  } else {
1359  d->checkGrab();
1360  if (hasFocus())
1361  XSetInputFocus(x11Info().display(), d->client, XRevertToParent, x11Time());
1362  }
1363  if (!d->isEmbedded())
1364  d->moveInputToProxy();
1365  }
1366  break;
1368  // When our container window is deactivated, we pass the
1369  // deactivation message to our client.
1370  if (o == window() && d->client) {
1371  if (d->clientIsXEmbed)
1373  else
1374  d->checkGrab();
1375  }
1376  break;
1377  case QEvent::FocusIn:
1378  // When receiving FocusIn events generated by Tab or Backtab,
1379  // we pass focus on to our client. Any mouse activity is sent
1380  // directly to the client, and it will ask us for focus with
1381  // XEMBED_REQUEST_FOCUS.
1382  if (o == this && d->client) {
1383  if (!d->isEmbedded())
1384  d->activeContainer = this;
1385 
1386  if (d->clientIsXEmbed) {
1387  if (!d->isEmbedded())
1388  d->moveInputToProxy();
1389 
1390  QFocusEvent *fe = (QFocusEvent *)event;
1391  switch (fe->reason()) {
1392  case Qt::TabFocusReason:
1394  break;
1397  break;
1398  default:
1400  break;
1401  }
1402  } else {
1403  d->checkGrab();
1404  XSetInputFocus(x11Info().display(), d->client, XRevertToParent, x11Time());
1405  }
1406  }
1407 
1408  break;
1409  case QEvent::FocusOut: {
1410  // When receiving a FocusOut, we ask our client to remove its
1411  // focus.
1412  if (o == this && d->client) {
1413  if (!d->isEmbedded()) {
1414  d->activeContainer = 0;
1415  if (isActiveWindow())
1416  d->moveInputToProxy();
1417  }
1418 
1419  if (d->clientIsXEmbed) {
1420  QFocusEvent *fe = (QFocusEvent *)event;
1421  if (o == this && d->client && fe->reason() != Qt::ActiveWindowFocusReason)
1423  } else {
1424  d->checkGrab();
1425  }
1426  }
1427  }
1428  break;
1429 
1430  case QEvent::Close: {
1431  if (o == this && d->client) {
1432  // Unmap the client and reparent it to the root window.
1433  // Wait until the messages have been processed. Then ask
1434  // the window manager to delete the window.
1435  XUnmapWindow(x11Info().display(), d->client);
1436  XReparentWindow(x11Info().display(), d->client, x11Info().appRootWindow(x11Info().screen()), 0, 0);
1437  XSync(x11Info().display(), false);
1438 
1439  XEvent ev;
1440  memset(&ev, 0, sizeof(ev));
1441  ev.xclient.type = ClientMessage;
1442  ev.xclient.window = d->client;
1443  ev.xclient.message_type = ATOM(WM_PROTOCOLS);
1444  ev.xclient.format = 32;
1445  ev.xclient.data.s[0] = ATOM(WM_DELETE_WINDOW);
1446  XSendEvent(x11Info().display(), d->client, false, NoEventMask, &ev);
1447 
1448  XFlush(x11Info().display());
1449  d->client = 0;
1450  d->clientIsXEmbed = false;
1451  d->wmMinimumSizeHint = QSize();
1452  updateGeometry();
1453  setEnabled(false);
1454  update();
1455 
1456  emit clientClosed();
1457  }
1458  }
1459  default:
1460  break;
1461  }
1462 
1463  return QWidget::eventFilter(o, event);
1464 }
1465 
1474 {
1476 
1477  switch (event->type) {
1478  case CreateNotify:
1479  // The client created an embedded window.
1480  if (d->client)
1481  d->rejectClient(event->xcreatewindow.window);
1482  else
1483  d->acceptClient(event->xcreatewindow.window);
1484  break;
1485  case DestroyNotify:
1486  if (event->xdestroywindow.window == d->client) {
1487  // The client died.
1488  d->client = 0;
1489  d->clientIsXEmbed = false;
1490  d->wmMinimumSizeHint = QSize();
1491  updateGeometry();
1492  update();
1493  setEnabled(false);
1494  emit clientClosed();
1495  }
1496  break;
1497  case ReparentNotify:
1498  // The client sends us this if it reparents itself out of our
1499  // widget.
1500  if (event->xreparent.window == d->client && event->xreparent.parent != internalWinId()) {
1501  d->client = 0;
1502  d->clientIsXEmbed = false;
1503  d->wmMinimumSizeHint = QSize();
1504  updateGeometry();
1505  update();
1506  setEnabled(false);
1507  emit clientClosed();
1508  } else if (event->xreparent.parent == internalWinId()) {
1509  // The client reparented itself into this window.
1510  if (d->client)
1511  d->rejectClient(event->xreparent.window);
1512  else
1513  d->acceptClient(event->xreparent.window);
1514  }
1515  break;
1516  case ClientMessage: {
1517  if (event->xclient.message_type == ATOM(_XEMBED)) {
1518  // Ignore XEMBED messages not to ourselves
1519  if (event->xclient.window != internalWinId())
1520  break;
1521 
1522  // Receiving an XEmbed message means the client
1523  // is an XEmbed client.
1524  d->clientIsXEmbed = true;
1525 
1526  Time msgtime = (Time) event->xclient.data.l[0];
1527  if (msgtime > X11->time)
1528  X11->time = msgtime;
1529 
1530  switch (event->xclient.data.l[1]) {
1531  case XEMBED_REQUEST_FOCUS: {
1532  // This typically happens when the client gets focus
1533  // because of a mouse click.
1534  if (!hasFocus())
1536 
1537  // The message is passed along to the topmost container
1538  // that eventually responds with a XEMBED_FOCUS_IN
1539  // message. The focus in message is passed all the way
1540  // back until it reaches the original focus
1541  // requestor. In the end, not only the original client
1542  // has focus, but also all its ancestor containers.
1543  if (d->isEmbedded()) {
1544  // If our window's embedded flag is set, then
1545  // that suggests that we are part of a client. The
1546  // parentWinId will then point to an container to whom
1547  // we must pass this message.
1548  sendXEmbedMessage(d->topLevelParentWinId(), x11Info().display(), XEMBED_REQUEST_FOCUS);
1549  } else {
1550  // Our window's embedded flag is not set,
1551  // so we are the topmost container. We respond to
1552  // the focus request message with a focus in
1553  // message. This message will pass on from client
1554  // to container to client until it reaches the
1555  // originator of the XEMBED_REQUEST_FOCUS message.
1557  }
1558 
1559  break;
1560  }
1561  case XEMBED_FOCUS_NEXT:
1562  // Client sends this event when it received a tab
1563  // forward and was at the end of its focus chain. If
1564  // we are the only widget in the focus chain, we send
1565  // ourselves a FocusIn event.
1566  if (d->focus_next != this) {
1567  focusNextPrevChild(true);
1568  } else {
1570  qApp->sendEvent(this, &event);
1571  }
1572 
1573  break;
1574  case XEMBED_FOCUS_PREV:
1575  // Client sends this event when it received a backtab
1576  // and was at the start of its focus chain. If we are
1577  // the only widget in the focus chain, we send
1578  // ourselves a FocusIn event.
1579  if (d->focus_next != this) {
1580  focusNextPrevChild(false);
1581  } else {
1583  qApp->sendEvent(this, &event);
1584  }
1585 
1586  break;
1587  default:
1588  break;
1589  }
1590  }
1591  }
1592  break;
1593  case XButtonPress:
1594  if (!d->clientIsXEmbed) {
1596  XAllowEvents(x11Info().display(), ReplayPointer, CurrentTime);
1597  return true;
1598  }
1599  break;
1600  case XButtonRelease:
1601  if (!d->clientIsXEmbed)
1602  XAllowEvents(x11Info().display(), SyncPointer, CurrentTime);
1603  break;
1604  default:
1605  break;
1606  }
1607 
1608  return QWidget::x11Event(event);
1609 }
1610 
1619 {
1621  if (d->client)
1622  XResizeWindow(x11Info().display(), d->client, width(), height());
1623 }
1624 
1635 {
1637  if (d->client) {
1638  long data[] = {XEMBED_VERSION, XEMBED_MAPPED};
1639  XChangeProperty(x11Info().display(), d->client, ATOM(_XEMBED_INFO), ATOM(_XEMBED_INFO), 32,
1640  PropModeReplace, (unsigned char *) data, 2);
1641  }
1642 }
1643 
1654 {
1656  if (d->client) {
1657  long data[] = {XEMBED_VERSION, XEMBED_MAPPED};
1658  XChangeProperty(x11Info().display(), d->client, ATOM(_XEMBED_INFO), ATOM(_XEMBED_INFO), 32,
1659  PropModeReplace, (unsigned char *) data, 2);
1660  }
1661 }
1662 
1667 {
1668  if (event->type() == QEvent::ParentChange) {
1669  XSelectInput(x11Info().display(), internalWinId(),
1670  KeyPressMask | KeyReleaseMask
1671  | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask
1672  | KeymapStateMask
1673  | PointerMotionMask
1674  | EnterWindowMask | LeaveWindowMask
1675  | FocusChangeMask
1676  | ExposureMask
1677  | StructureNotifyMask
1678  | SubstructureNotifyMask);
1679  }
1680  return QWidget::event(event);
1681 }
1682 
1695 {
1697  q->setEnabled(false);
1698  XRemoveFromSaveSet(q->x11Info().display(), client);
1699  XReparentWindow(q->x11Info().display(), window, q->x11Info().appRootWindow(q->x11Info().screen()), 0, 0);
1700 }
1701 
1711 {
1713  client = window;
1714  q->setEnabled(true);
1715 
1716  // This tells Qt that we wish to forward DnD messages to
1717  // our client.
1718  if (!extra)
1719  createExtra();
1720  extraData()->xDndProxy = client;
1721 
1722  unsigned int version = XEmbedVersion();
1723 
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;
1730 
1731  // Add this client to our saveset, so if we crash, the client window
1732  // doesn't get destroyed. This is useful for containers that restart
1733  // automatically after a crash, because it can simply reembed its clients
1734  // without having to restart them (KDE panel).
1735  XAddToSaveSet(q->x11Info().display(), client);
1736 
1737  // XEmbed clients have an _XEMBED_INFO property in which we can
1738  // fetch the version
1739  if (XGetWindowProperty(q->x11Info().display(), client, ATOM(_XEMBED_INFO), 0, 2, false,
1740  ATOM(_XEMBED_INFO), &actual_type_return, &actual_format_return,
1741  &nitems_return, &bytes_after_return, &prop_return) == Success) {
1742 
1743  if (actual_type_return != None && actual_format_return != 0) {
1744  // Clients with the _XEMBED_INFO property are XEMBED clients.
1745  clientIsXEmbed = true;
1746 
1747  long *p = (long *)prop_return;
1748  if (nitems_return >= 2)
1749  clientversion = (unsigned int)p[0];
1750  }
1751 
1752  XFree(prop_return);
1753  }
1754 
1755  // Store client window's original size and placement.
1756  Window root;
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);
1764 
1765  // Ask the client for its minimum size.
1766  XSizeHints size;
1767  long msize;
1768  if (XGetWMNormalHints(q->x11Info().display(), client, &size, &msize) && (size.flags & PMinSize)) {
1769  wmMinimumSizeHint = QSize(size.min_width, size.min_height);
1770  q->updateGeometry();
1771  }
1772 
1773  // The container should set the data2 field to the lowest of its
1774  // supported version number and that of the client (from
1775  // _XEMBED_INFO property).
1776  unsigned int minversion = version > clientversion ? clientversion : version;
1777  sendXEmbedMessage(client, q->x11Info().display(), XEMBED_EMBEDDED_NOTIFY, q->internalWinId(), minversion);
1778  XMapWindow(q->x11Info().display(), client);
1779 
1780  // Resize it, but no smaller than its minimum size hint.
1781  XResizeWindow(q->x11Info().display(),
1782  client,
1783  qMax(q->width(), wmMinimumSizeHint.width()),
1784  qMax(q->height(), wmMinimumSizeHint.height()));
1785  q->update();
1786 
1787  // Not mentioned in the protocol is that if the container
1788  // is already active, the client must be activated to work
1789  // properly.
1790  if (q->window()->isActiveWindow())
1791  sendXEmbedMessage(client, q->x11Info().display(), XEMBED_WINDOW_ACTIVATE);
1792 
1793  // Also, if the container already has focus, then it must
1794  // send a focus in message to its new client; otherwise we ask
1795  // it to remove focus.
1796  if (q->focusWidget() == q && q->hasFocus())
1797  sendXEmbedMessage(client, q->x11Info().display(), XEMBED_FOCUS_IN, XEMBED_FOCUS_FIRST);
1798  else
1799  sendXEmbedMessage(client, q->x11Info().display(), XEMBED_FOCUS_OUT);
1800 
1801  if (!clientIsXEmbed) {
1802  checkGrab();
1803  if (q->hasFocus()) {
1804  XSetInputFocus(q->x11Info().display(), client, XRevertToParent, x11Time());
1805  }
1806  } else {
1807  if (!isEmbedded())
1808  moveInputToProxy();
1809  }
1810 
1811  emit q->clientIsEmbedded();
1812 }
1813 
1826 {
1828  // Following Owen Taylor's advice from the XEmbed specification to
1829  // always use CurrentTime when no explicit user action is involved.
1830  XSetInputFocus(q->x11Info().display(), focusProxy->internalWinId(), XRevertToParent, CurrentTime);
1831 }
1832 
1841 {
1842  Q_D(const QX11EmbedContainer);
1843  if (!d->client || !d->wmMinimumSizeHint.isValid())
1844  return QWidget::minimumSizeHint();
1845  return d->wmMinimumSizeHint;
1846 }
1847 
1852 {
1854  if (!clientIsXEmbed && q->isActiveWindow() && !q->hasFocus()) {
1855  if (!xgrab) {
1856  XGrabButton(q->x11Info().display(), AnyButton, AnyModifier, q->internalWinId(),
1857  true, ButtonPressMask, GrabModeSync, GrabModeAsync,
1858  None, None);
1859  }
1860  xgrab = true;
1861  } else {
1862  if (xgrab)
1863  XUngrabButton(q->x11Info().display(), AnyButton, AnyModifier, q->internalWinId());
1864  xgrab = false;
1865  }
1866 }
1867 
1873 {
1875  if (d->client) {
1876  XResizeWindow(x11Info().display(), d->client, d->clientOriginalRect.width(),
1877  d->clientOriginalRect.height());
1878 
1879  d->rejectClient(d->client);
1880  }
1881 }
1882 
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qstring.cpp:6448
QX11EmbedFocusInDetail
void checkActivateWindow(QObject *o)
Checks the active window.
void paintEvent(QPaintEvent *e)
Reimplemented Function
double d
Definition: qnumeric_p.h:62
void containerClosed()
This signal is emitted by the client widget when the container closes the widget. ...
void embedInto(WId id)
When this function is called, the widget embeds itself into the container whose window ID is id...
unsigned long WId
Definition: qwindowdefs.h:119
bool x11Event(XEvent *)
Handles X11 events for the container.
unsigned char c[8]
Definition: qnumeric_p.h:62
static XKeyEvent lastKeyEvent
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
QSize size() const
void emitError(QX11EmbedWidget::Error error)
QRect frameStrut
Definition: qwidget_p.h:180
QX11EmbedWidget * xEmbedWidget(QObject *o) const
virtual QSize minimumSizeHint() const
static QX11EmbedContainer * activeContainer
bool eventFilter(QObject *, QEvent *)
Handles WindowActivate and FocusIn events for the client.
bool isVisibleTo(QWidget *) const
Returns true if this widget would become visible if ancestor is shown; otherwise returns false...
Definition: qwidget.cpp:8371
#define error(msg)
QX11EmbedAccelFlags
static Qt::HANDLE appRootWindow(int screen=-1)
Returns a handle for the applications root window on the given screen.
Time time
Definition: qt_x11_p.h:476
Qt::FocusPolicy focusPolicy
the way the widget accepts keyboard focus
Definition: qwidget.h:187
static QCoreApplication::EventFilter oldX11EventFilter
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
const QX11Info & x11Info() const
Returns information about the configuration of the X display used to display the widget.
virtual void resizeEvent(QResizeEvent *)
This event handler can be reimplemented in a subclass to receive widget resize events which are passe...
Definition: qwidget.cpp:9587
static LibLoadStatus status
Definition: qlocale_icu.cpp:69
QWidget * nextInFocusChain() const
Returns the next widget in this widget&#39;s focus chain.
Definition: qwidget.cpp:6873
EventFilter setEventFilter(EventFilter filter)
Replaces the event filter function for the QCoreApplication with filter and returns the pointer to th...
bool isActiveWindow() const
bool hasFocus() const
Definition: qwidget.cpp:6583
T * qobject_cast(QObject *object)
Definition: qobject.h:375
static unsigned int XEMBED_VERSION
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
#define X11
Definition: qt_x11_p.h:724
void acceptClient(WId window)
Accepts a client by mapping it, resizing it and optionally activating and giving it logical focusing ...
#define Q_D(Class)
Definition: qglobal.h:2482
int height() const
The QElapsedTimer class provides a fast way to calculate elapsed times.
Definition: qelapsedtimer.h:53
QWidget * focusProxy() const
Returns the focus proxy, or 0 if there is no focus proxy.
Definition: qwidget.cpp:6561
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)
Definition: qglobal.h:1217
Error error() const
Returns the last error that occurred.
#define Q_Q(Class)
Definition: qglobal.h:2483
void resizeEvent(QResizeEvent *)
Reimplemented Function
union _XEvent XEvent
Definition: qwindowdefs.h:116
#define ATOM(x)
Definition: qt_x11_p.h:723
void update()
Updates the widget unless updates are disabled or the widget is hidden.
Definition: qwidget.cpp:10883
void clearFocus()
Takes keyboard input focus from the widget.
Definition: qwidget.cpp:6757
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.
QTLWExtra * topData()
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
QX11EmbedInfoFlags
Q_GUI_EXPORT EGLDisplay display()
Definition: qegl.cpp:589
void update()
Updates the layout for parentWidget().
Definition: qlayout.cpp:1225
#define qApp
QWidget(QWidget *parent=0, Qt::WindowFlags f=0)
Constructs a widget which is a child of parent, with widget flags set to f.
Definition: qwidget.cpp:1189
int width() const
#define emit
Definition: qobjectdefs.h:76
The QHideEvent class provides an event which is sent after a widget is hidden.
Definition: qevent.h:388
Q_GUI_EXPORT QX11Data * qt_x11Data
virtual bool x11Event(XEvent *)
This special event handler can be reimplemented in a subclass to receive native X11 events passed in ...
Definition: qwidget.cpp:9969
QWidgetData * data
Definition: qwidget.h:815
The QResizeEvent class contains event parameters for resize events.
Definition: qevent.h:349
static void sendXEmbedMessage(WId window, Display *display, long message, long detail=0, long data1=0, long data2=0)
unsigned int uint
Definition: qglobal.h:996
WId containerWinId() const
If the widget is embedded, returns the window ID of the container; otherwize returns 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&#39;s top-left corner to (x1, y1), and the coordinates of its botto...
Definition: qrect.h:416
static int x11ErrorHandler(Display *, XErrorEvent *)
The QShowEvent class provides an event that is sent when a widget is shown.
Definition: qevent.h:380
Error error() const
Returns the type of error that occurred last.
static void setActiveWindow(QWidget *act)
Sets the active window to the active widget in response to a system event.
void setEnabled(bool)
Definition: qwidget.cpp:3447
bool isEnabled() const
Definition: qwidget.h:948
#define None
virtual bool eventFilter(QObject *, QEvent *)
Filters events if this object has been installed as an event filter for the watched object...
Definition: qobject.cpp:1375
char * XPointer
Definition: qt_x11_p.h:180
QPointer< QWidget > currentFocus
void setFocus()
Gives the keyboard input focus to this widget (or its focus proxy) if this widget or one of its paren...
Definition: qwidget.h:432
QX11EmbedMessageType
struct _XDisplay Display
Definition: qwindowdefs.h:115
#define Q_DECLARE_PUBLIC(Class)
Definition: qglobal.h:2477
void setAcceptDrops(bool on)
Definition: qwidget.cpp:3534
The QX11EmbedWidget class provides an XEmbed client widget.
Definition: qx11embed_x11.h:54
int x() const
void discardClient()
Detaches the client from the embedder.
static QCoreApplication * instance()
Returns a pointer to the application&#39;s QCoreApplication (or QApplication) instance.
bool event(QEvent *)
Reimplemented Function
static QString fromLatin1(const char *, int size=-1)
Returns a QString initialized with the first size characters of the Latin-1 string str...
Definition: qstring.cpp:4188
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.
Definition: qobject.h:273
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.
Definition: qobject.cpp:2070
virtual bool focusNextPrevChild(bool next)
Finds a new widget to give the keyboard focus to, as appropriate for Tab and Shift+Tab, and returns true if it can find a new widget, or false if it can&#39;t.
Definition: qwidget.cpp:6836
bool(* EventFilter)(void *message, long *result)
A function with the following signature that can be used as an event filter:
const int XButtonPress
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.
Definition: qrect.h:58
QWidget * getFocusWidget(FocusWidgets fw)
Gets the first or last child widget that can get focus.
Qt::FocusReason reason()
Definition: qevent.cpp:1197
WId internalWinId() const
Returns the window system identifier of the widget, or 0 if the widget is not created yet...
Definition: qwidget.h:244
QX11EmbedFocusInFlags
void setAttribute(Qt::WidgetAttribute, bool on=true)
Sets the attribute attribute on this widget if on is true; otherwise clears the attribute.
Definition: qwidget.cpp:11087
QX11EmbedWidget::Error lastError
QX11EmbedAccelModifiers
QWidget * window() const
Returns the window for this widget, i.e.
Definition: qwidget.cpp:4492
bool isEmbedded() const
Returns whether or not the windows&#39; embedded flag is set.
static Bool functor(Display *display, XEvent *event, XPointer arg)
const int XButtonRelease
void createWinId()
Definition: qwidget.cpp:2626
QLayout * layout() const
Returns the layout manager that is installed on this widget, or 0 if no layout manager is installed...
Definition: qwidget.cpp:10073
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
#define Q_DECLARE_PRIVATE(Class)
Definition: qglobal.h:2467
QX11EmbedWidget(QWidget *parent=0)
Constructs a QX11EmbedWidget object with the given parent.
WId winId() const
Returns the window system identifier of the widget.
Definition: qwidget.cpp:2557
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.
Q_GUI_EXPORT bool qt_tab_all_widgets
void updateGeometry()
Notifies the layout system that this widget has changed and may need to change geometry.
Definition: qwidget.cpp:10372
bool event(QEvent *)
This is the main event handler; it handles event event.
Definition: qwidget.cpp:8636
void embedded()
This signal is emitted by the widget that has been embedded by an XEmbed container.
The QPaintEvent class contains event parameters for paint events.
Definition: qevent.h:298
void setSizePolicy(QSizePolicy)
Definition: qwidget.cpp:10198
QX11EmbedContainer::Error lastError
~QX11EmbedWidget()
Destructs the QX11EmbedWidget object.
The QEvent class is the base class of all event classes.
Definition: qcoreevent.h:56
Type type() const
Returns the event type.
Definition: qcoreevent.h:303
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.
Definition: qx11embed_x11.h:88
void setEmbedded()
Sets the embedded flag on the client.
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.
Definition: qevent.h:275
static Display * display()
Returns the default display for the application.
static Time x11Time()
void setFocusPolicy(Qt::FocusPolicy policy)
Definition: qwidget.cpp:7631
static unsigned int XEmbedVersion()
void resizeEvent(QResizeEvent *)
Whenever the container is resized, we need to resize our client.
bool x11Event(XEvent *)
Handles some notification events and client messages.