diff options
Diffstat (limited to 'src/widgets/kernel')
-rw-r--r-- | src/widgets/kernel/kernel.pri | 6 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget.cpp | 9 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget.h | 2 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget_qpa.cpp | 10 | ||||
-rw-r--r-- | src/widgets/kernel/qwidgetwindow.cpp | 18 | ||||
-rw-r--r-- | src/widgets/kernel/qwindowcontainer.cpp | 218 | ||||
-rw-r--r-- | src/widgets/kernel/qwindowcontainer_p.h | 73 |
7 files changed, 327 insertions, 9 deletions
diff --git a/src/widgets/kernel/kernel.pri b/src/widgets/kernel/kernel.pri index 4d3d7c4e0a..533b696faa 100644 --- a/src/widgets/kernel/kernel.pri +++ b/src/widgets/kernel/kernel.pri @@ -34,7 +34,8 @@ HEADERS += \ kernel/qgesturerecognizer.h \ kernel/qgesturemanager_p.h \ kernel/qdesktopwidget_qpa_p.h \ - kernel/qwidgetwindow_qpa_p.h + kernel/qwidgetwindow_qpa_p.h \ + kernel/qwindowcontainer_p.h SOURCES += \ kernel/qaction.cpp \ @@ -62,7 +63,8 @@ SOURCES += \ kernel/qapplication_qpa.cpp \ kernel/qdesktopwidget_qpa.cpp \ kernel/qwidget_qpa.cpp \ - kernel/qwidgetwindow.cpp + kernel/qwidgetwindow.cpp \ + kernel/qwindowcontainer.cpp # TODO diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 3b9e889a9c..31f6af5dce 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -6908,14 +6908,15 @@ void QWidget::setUpdatesEnabled(bool enable) Shows the widget and its child widgets. This function is equivalent to setVisible(true) in the normal case, and equivalent to showFullScreen() if the QStyleHints::showIsFullScreen() hint - is true. + is true and the window is not a popup. \sa raise(), showEvent(), hide(), setVisible(), showMinimized(), showMaximized(), - showNormal(), isVisible() + showNormal(), isVisible(), windowFlags() */ void QWidget::show() { - if (isWindow() && qApp->styleHints()->showIsFullScreen()) + bool isPopup = data->window_flags & Qt::Popup & ~Qt::Window; + if (isWindow() && !isPopup && qApp->styleHints()->showIsFullScreen()) showFullScreen(); else setVisible(true); @@ -9088,7 +9089,7 @@ QLayout *QWidget::layout() const existing layout manager (returned by layout()) before you can call setLayout() with the new layout. - If \a layout is the layout manger on a different widget, setLayout() + If \a layout is the layout manager on a different widget, setLayout() will reparent the layout and make it the layout manager for this widget. Example: diff --git a/src/widgets/kernel/qwidget.h b/src/widgets/kernel/qwidget.h index 25dac1ed5e..d24258e742 100644 --- a/src/widgets/kernel/qwidget.h +++ b/src/widgets/kernel/qwidget.h @@ -593,6 +593,8 @@ public: QWindow *windowHandle() const; + static QWidget *createWindowContainer(QWindow *window, QWidget *parent=0, Qt::WindowFlags flags=0); + friend class QDesktopScreenWidget; Q_SIGNALS: diff --git a/src/widgets/kernel/qwidget_qpa.cpp b/src/widgets/kernel/qwidget_qpa.cpp index 84693d02a5..554148675e 100644 --- a/src/widgets/kernel/qwidget_qpa.cpp +++ b/src/widgets/kernel/qwidget_qpa.cpp @@ -999,6 +999,12 @@ static inline void applyCursor(QWidget *w, QCursor c) window->setCursor(c); } +static inline void unsetCursor(QWidget *w) +{ + if (QWindow *window = w->windowHandle()) + window->unsetCursor(); +} + void qt_qpa_set_cursor(QWidget *w, bool force) { if (!w->testAttribute(Qt::WA_WState_Created)) @@ -1032,9 +1038,9 @@ void qt_qpa_set_cursor(QWidget *w, bool force) else // Enforce the windows behavior of clearing the cursor on // disabled widgets. - applyCursor(nativeParent, Qt::ArrowCursor); + unsetCursor(nativeParent); } else { - applyCursor(nativeParent, Qt::ArrowCursor); + unsetCursor(nativeParent); } } #endif //QT_NO_CURSOR diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 462ebc605b..50b61beb05 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -39,6 +39,7 @@ ** ****************************************************************************/ +#include "private/qwindow_p.h" #include "qwidgetwindow_qpa_p.h" #include "private/qwidget_p.h" @@ -60,8 +61,23 @@ extern int openPopupCount; bool qt_replay_popup_mouse_event = false; extern bool qt_try_modal(QWidget *widget, QEvent::Type type); +class QWidgetWindowPrivate : public QWindowPrivate +{ + Q_DECLARE_PUBLIC(QWidgetWindow) +public: + QWindow *eventReceiver() { + Q_Q(QWidgetWindow); + QWindow *w = q; + while (w->parent() && qobject_cast<QWidgetWindow *>(w) && qobject_cast<QWidgetWindow *>(w->parent())) { + w = w->parent(); + } + return w; + } +}; + QWidgetWindow::QWidgetWindow(QWidget *widget) - : m_widget(widget) + : QWindow(*new QWidgetWindowPrivate(), 0) + , m_widget(widget) { updateObjectName(); connect(m_widget, &QObject::objectNameChanged, this, &QWidgetWindow::updateObjectName); diff --git a/src/widgets/kernel/qwindowcontainer.cpp b/src/widgets/kernel/qwindowcontainer.cpp new file mode 100644 index 0000000000..81322f49b4 --- /dev/null +++ b/src/widgets/kernel/qwindowcontainer.cpp @@ -0,0 +1,218 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwindowcontainer_p.h" +#include "qwidget_p.h" +#include <QtGui/qwindow.h> + +QT_BEGIN_NAMESPACE + +class QWindowContainerPrivate : public QWidgetPrivate +{ +public: + Q_DECLARE_PUBLIC(QWindowContainer) + + QWindowContainerPrivate() : window(0), oldFocusWindow(0) { } + ~QWindowContainerPrivate() { } + + QPointer<QWindow> window; + QWindow *oldFocusWindow; +}; + + + +/*! + \fn QWidget *QWidget::createWindowContainer(QWindow *window, QWidget *parent, Qt::WindowFlags flags); + + Creates a QWidget that makes it possible to embed \a window into + a QWidget-based application. + + The window container is created as a child of \a parent and with + window flags \a flags. + + Once the window has been embedded into the container, the + container will control the window's geometry and + visibility. Explicit calls to QWindow::setGeometry(), + QWindow::show() or QWindow::hide() on an embedded window is not + recommended. + + The container takes over ownership of \a window. The window can + be removed from the window container with a call to + QWindow::setParent(). + + The window container has a number of known limitations: + + \list + + \li Stacking order; The embedded window will stack on top of the + widget hierarchy as an opaque box. The stacking order of multiple + overlapping window container instances is undefined. + + \li Window Handles; The window container will explicitly invoke + winId() which will force the use of native window handles + inside the application. See \l {Native Widgets vs Alien Widgets} + {QWidget documentation} for more details. + + \li Rendering Integration; The window container does not interoperate + with QGraphicsProxyWidget, QWidget::render() or similar functionality. + + \li Focus Handling; It is possible to let the window container + instance have any focus policy and it will delegate focus to the + window via a call to QWindow::requestActivate(). However, + returning to the normal focus chain from the QWindow instance will + be up to the QWindow instance implementation itself. For instance, + when entering a Qt Quick based window with tab focus, it is quite + likely that further tab presses will only cycle inside the QML + application. Also, whether QWindow::requestActivate() actually + gives the window focus, is platform dependent. + + \li Using many window container instances in a QWidget-based + application can greatly hurt the overall performance of the + application. + + \endlist + */ + +QWidget *QWidget::createWindowContainer(QWindow *window, QWidget *parent, Qt::WindowFlags flags) +{ + return new QWindowContainer(window, parent, flags); +} + + + +/*! + \internal + */ + +QWindowContainer::QWindowContainer(QWindow *embeddedWindow, QWidget *parent, Qt::WindowFlags flags) + : QWidget(*new QWindowContainerPrivate, parent, flags) +{ + Q_D(QWindowContainer); + if (!embeddedWindow) { + qWarning("QWindowContainer: embedded window cannot be null"); + return; + } + + d->window = embeddedWindow; + + // We force this window to become a native window and reparent the + // window directly to it. This is done so that the order in which + // the QWindowContainer is added to a QWidget tree and when it + // gets a window does not matter. + winId(); + d->window->setParent(windowHandle()); + + connect(QGuiApplication::instance(), SIGNAL(focusWindowChanged(QWindow *)), this, SLOT(focusWindowChanged(QWindow *))); +} + + + +/*! + \internal + */ + +QWindowContainer::~QWindowContainer() +{ + Q_D(QWindowContainer); + delete d->window; +} + + + +/*! + \internal + */ + +void QWindowContainer::focusWindowChanged(QWindow *focusWindow) +{ + Q_D(QWindowContainer); + d->oldFocusWindow = focusWindow; +} + + + +/*! + \internal + */ + +bool QWindowContainer::event(QEvent *e) +{ + Q_D(QWindowContainer); + if (!d->window) + return QWidget::event(e); + + QEvent::Type type = e->type(); + switch (type) { + case QEvent::ChildRemoved: { + QChildEvent *ce = static_cast<QChildEvent *>(e); + if (ce->child() == d->window) + d->window = 0; + break; + } + // The only thing we are interested in is making sure our sizes stay + // in sync, so do a catch-all case. + case QEvent::Resize: + case QEvent::Move: + case QEvent::PolishRequest: + d->window->setGeometry(0, 0, width(), height()); + break; + case QEvent::Show: + d->window->show(); + break; + case QEvent::Hide: + d->window->hide(); + break; + case QEvent::FocusIn: + if (d->oldFocusWindow != d->window) { + d->window->requestActivate(); + } else { + QWidget *next = nextInFocusChain(); + next->setFocus(); + } + break; + default: + break; + } + + return QWidget::event(e); +} + +QT_END_NAMESPACE diff --git a/src/widgets/kernel/qwindowcontainer_p.h b/src/widgets/kernel/qwindowcontainer_p.h new file mode 100644 index 0000000000..3e2eddd83c --- /dev/null +++ b/src/widgets/kernel/qwindowcontainer_p.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWINDOWCONTAINER_H +#define QWINDOWCONTAINER_H + +#include <QtWidgets/qwidget.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QWindowContainerPrivate; + +class QWindowContainer : public QWidget +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QWindowContainer) + +public: + explicit QWindowContainer(QWindow *embeddedWindow, QWidget *parent = 0, Qt::WindowFlags f = 0); + ~QWindowContainer(); + +protected: + bool event(QEvent *ev); + +private slots: + void focusWindowChanged(QWindow *focusWindow); +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QWINDOWCONTAINER_H |