qwidget_qpa.cpp 32.42 KiB
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtWidgets 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 "QtWidgets/qwidget.h"
#include "QtGui/qevent.h"
#include "QtWidgets/qapplication.h"
#include "private/qwidgetbackingstore_p.h"
#include "private/qwidget_p.h"
#include "private/qwidgetwindow_qpa_p.h"
#include "private/qapplication_p.h"
#include "QtWidgets/qdesktopwidget.h"
#include <qpa/qplatformwindow.h>
#include "QtGui/qsurfaceformat.h"
#include <qpa/qplatformopenglcontext.h>
#include <qpa/qplatformintegration.h>
#include "QtGui/private/qwindow_p.h"
#include "QtGui/private/qguiapplication_p.h"
#include <qpa/qplatformcursor.h>
#include <QtGui/QGuiApplication>
#include <QtGui/QScreen>
#include <QtCore/QMargins>
QT_BEGIN_NAMESPACE
void q_createNativeChildrenAndSetParent(const QWidget *parentWidget)
    QObjectList children = parentWidget->children();
    for (int i = 0; i < children.size(); i++) {
        if (children.at(i)->isWidgetType()) {
            const QWidget *childWidget = qobject_cast<const QWidget *>(children.at(i));
            if (childWidget) { // should not be necessary
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
if (childWidget->testAttribute(Qt::WA_NativeWindow)) { if (!childWidget->windowHandle()) childWidget->winId(); if (childWidget->windowHandle()) { QWindow *parentWindow = childWidget->nativeParentWidget()->windowHandle(); if (childWidget->isWindow()) childWidget->windowHandle()->setTransientParent(parentWindow); else childWidget->windowHandle()->setParent(parentWindow); } } else { q_createNativeChildrenAndSetParent(childWidget); } } } } } void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow) { Q_Q(QWidget); Q_UNUSED(window); Q_UNUSED(initializeWindow); Q_UNUSED(destroyOldWindow); Qt::WindowFlags flags = data.window_flags; if (!q->testAttribute(Qt::WA_NativeWindow) && !q->isWindow()) return; // we only care about real toplevels QWindow *win = topData()->window; // topData() ensures the extra is created but does not ensure 'window' is non-null // in case the extra was already valid. if (!win) { createTLSysExtra(); win = topData()->window; } win->setFlags(data.window_flags); fixPosIncludesFrame(); if (q->testAttribute(Qt::WA_Moved)) win->setGeometry(q->geometry()); else win->resize(q->size()); win->setScreen(QGuiApplication::screens().value(topData()->screenIndex, 0)); if (q->testAttribute(Qt::WA_TranslucentBackground)) { QSurfaceFormat format; format.setAlphaBufferSize(8); win->setFormat(format); } if (QWidget *nativeParent = q->nativeParentWidget()) { if (nativeParent->windowHandle()) { if (flags & Qt::Window) { win->setTransientParent(nativeParent->windowHandle()); win->setParent(0); } else { win->setTransientParent(0); win->setParent(nativeParent->windowHandle()); } } } qt_window_private(win)->positionPolicy = topData()->posIncludesFrame ? QWindowPrivate::WindowFrameInclusive : QWindowPrivate::WindowFrameExclusive; win->create();
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
data.window_flags = win->flags(); QBackingStore *store = q->backingStore(); if (!store) { if (win && q->windowType() != Qt::Desktop) q->setBackingStore(new QBackingStore(win)); else q->setAttribute(Qt::WA_PaintOnScreen, true); } setWindowModified_helper(); setWinId(win->winId()); // Check children and create windows for them if necessary q_createNativeChildrenAndSetParent(q); if (extra && !extra->mask.isEmpty()) setMask_sys(extra->mask); // If widget is already shown, set window visible, too if (q->isVisible()) win->setVisible(true); } void QWidget::destroy(bool destroyWindow, bool destroySubWindows) { Q_D(QWidget); d->aboutToDestroy(); if (!isWindow() && parentWidget()) parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry())); d->deactivateWidgetCleanup(); if ((windowType() == Qt::Popup) && qApp) qApp->d_func()->closePopup(this); if (this == QApplicationPrivate::active_window) QApplication::setActiveWindow(0); if (QWidget::mouseGrabber() == this) releaseMouse(); if (QWidget::keyboardGrabber() == this) releaseKeyboard(); setAttribute(Qt::WA_WState_Created, false); if (windowType() != Qt::Desktop) { if (destroySubWindows) { QObjectList childList(children()); for (int i = 0; i < childList.size(); i++) { QWidget *widget = qobject_cast<QWidget *>(childList.at(i)); if (widget && widget->testAttribute(Qt::WA_NativeWindow)) { if (widget->windowHandle()) { widget->destroy(); } } } } if (destroyWindow) { d->deleteTLSysExtra(); } else { if (parentWidget() && parentWidget()->testAttribute(Qt::WA_WState_Created)) { d->hide_sys(); } } d->setWinId(0); } }
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f) { Q_Q(QWidget); Qt::WindowFlags oldFlags = data.window_flags; bool wasCreated = q->testAttribute(Qt::WA_WState_Created); int targetScreen = -1; // Handle a request to move the widget to a particular screen if (newparent && newparent->windowType() == Qt::Desktop) { // make sure the widget is created on the same screen as the // programmer specified desktop widget // get the desktop's screen number targetScreen = newparent->window()->d_func()->topData()->screenIndex; newparent = 0; } setWinId(0); if (parent != newparent) { QObjectPrivate::setParent_helper(newparent); //### why does this have to be done in the _sys function??? if (q->windowHandle()) { q->windowHandle()->setFlags(f); QWidget *parentWithWindow = newparent ? (newparent->windowHandle() ? newparent : newparent->nativeParentWidget()) : 0; if (parentWithWindow) { if (f & Qt::Window) { q->windowHandle()->setTransientParent(parentWithWindow->windowHandle()); q->windowHandle()->setParent(0); } else { q->windowHandle()->setTransientParent(0); q->windowHandle()->setParent(parentWithWindow->windowHandle()); } } else { q->windowHandle()->setTransientParent(0); q->windowHandle()->setParent(0); } } } if (!newparent) { f |= Qt::Window; if (targetScreen == -1) { if (parent) targetScreen = q->parentWidget()->window()->d_func()->topData()->screenIndex; } } bool explicitlyHidden = q->testAttribute(Qt::WA_WState_Hidden) && q->testAttribute(Qt::WA_WState_ExplicitShowHide); // Reparenting toplevel to child if (!(f&Qt::Window) && (oldFlags&Qt::Window) && !q->testAttribute(Qt::WA_NativeWindow)) { //qDebug() << "setParent_sys() change from toplevel"; q->destroy(); } adjustFlags(f, q); data.window_flags = f; q->setAttribute(Qt::WA_WState_Created, false); q->setAttribute(Qt::WA_WState_Visible, false); q->setAttribute(Qt::WA_WState_Hidden, false); if (newparent && wasCreated && (q->testAttribute(Qt::WA_NativeWindow) || (f & Qt::Window))) q->createWinId(); if (q->isWindow() || (!newparent || newparent->isVisible()) || explicitlyHidden) q->setAttribute(Qt::WA_WState_Hidden); q->setAttribute(Qt::WA_WState_ExplicitShowHide, explicitlyHidden);
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
// move the window to the selected screen if (!newparent && targetScreen != -1) { if (maybeTopData()) maybeTopData()->screenIndex = targetScreen; // only if it is already created if (q->testAttribute(Qt::WA_WState_Created)) { q->windowHandle()->setScreen(QGuiApplication::screens().value(targetScreen, 0)); } } } QPoint QWidget::mapToGlobal(const QPoint &pos) const { int x = pos.x(), y = pos.y(); const QWidget *w = this; while (w) { QWindow *window = w->windowHandle(); if (window && window->handle()) return window->mapToGlobal(QPoint(x, y)); x += w->data->crect.x(); y += w->data->crect.y(); w = w->isWindow() ? 0 : w->parentWidget(); } return QPoint(x, y); } QPoint QWidget::mapFromGlobal(const QPoint &pos) const { int x = pos.x(), y = pos.y(); const QWidget *w = this; while (w) { QWindow *window = w->windowHandle(); if (window && window->handle()) return window->mapFromGlobal(QPoint(x, y)); x -= w->data->crect.x(); y -= w->data->crect.y(); w = w->isWindow() ? 0 : w->parentWidget(); } return QPoint(x, y); } void QWidgetPrivate::updateSystemBackground() {} #ifndef QT_NO_CURSOR void QWidgetPrivate::setCursor_sys(const QCursor &cursor) { Q_UNUSED(cursor); Q_Q(QWidget); qt_qpa_set_cursor(q, false); } void QWidgetPrivate::unsetCursor_sys() { Q_Q(QWidget); qt_qpa_set_cursor(q, false); } #endif //QT_NO_CURSOR void QWidgetPrivate::setWindowTitle_sys(const QString &caption) { Q_Q(QWidget); if (!q->isWindow()) return; if (QWindow *window = q->windowHandle()) window->setTitle(caption);
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
} void QWidgetPrivate::setWindowFilePath_sys(const QString &filePath) { Q_Q(QWidget); if (!q->isWindow()) return; if (QWindow *window = q->windowHandle()) window->setFilePath(filePath); } void QWidgetPrivate::setWindowIcon_sys() { Q_Q(QWidget); if (QWindow *window = q->windowHandle()) window->setIcon(q->windowIcon()); } void QWidgetPrivate::setWindowIconText_sys(const QString &iconText) { Q_UNUSED(iconText); } QWidget *qt_pressGrab = 0; QWidget *qt_mouseGrb = 0; static QWidget *keyboardGrb = 0; static inline QWindow *grabberWindow(const QWidget *w) { QWindow *window = w->windowHandle(); if (!window) if (const QWidget *nativeParent = w->nativeParentWidget()) window = nativeParent->windowHandle(); return window; } void QWidget::grabMouse() { if (qt_mouseGrb) qt_mouseGrb->releaseMouse(); if (QWindow *window = grabberWindow(this)) window->setMouseGrabEnabled(true); qt_mouseGrb = this; qt_pressGrab = 0; } #ifndef QT_NO_CURSOR void QWidget::grabMouse(const QCursor &cursor) { Q_UNUSED(cursor); grabMouse(); } #endif bool QWidgetPrivate::stealMouseGrab(bool grab) { // This is like a combination of grab/releaseMouse() but with error checking // and it has no effect on the result of mouseGrabber(). Q_Q(QWidget); QWindow *window = grabberWindow(q); return window ? window->setMouseGrabEnabled(grab) : false; } void QWidget::releaseMouse() { if (qt_mouseGrb == this) { if (QWindow *window = grabberWindow(this))
421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
window->setMouseGrabEnabled(false); qt_mouseGrb = 0; } } void QWidget::grabKeyboard() { if (keyboardGrb) keyboardGrb->releaseKeyboard(); if (QWindow *window = grabberWindow(this)) window->setKeyboardGrabEnabled(true); keyboardGrb = this; } bool QWidgetPrivate::stealKeyboardGrab(bool grab) { // This is like a combination of grab/releaseKeyboard() but with error // checking and it has no effect on the result of keyboardGrabber(). Q_Q(QWidget); QWindow *window = grabberWindow(q); return window ? window->setKeyboardGrabEnabled(grab) : false; } void QWidget::releaseKeyboard() { if (keyboardGrb == this) { if (QWindow *window = grabberWindow(this)) window->setKeyboardGrabEnabled(false); keyboardGrb = 0; } } QWidget *QWidget::mouseGrabber() { if (qt_mouseGrb) return qt_mouseGrb; return qt_pressGrab; } QWidget *QWidget::keyboardGrabber() { return keyboardGrb; } void QWidget::activateWindow() { QWindow *const wnd = window()->windowHandle(); if (wnd) wnd->requestActivate(); } // move() was invoked with Qt::WA_WState_Created not set (frame geometry // unknown), that is, crect has a position including the frame. // If we can determine the frame strut, fix that and clear the flag. void QWidgetPrivate::fixPosIncludesFrame() { Q_Q(QWidget); if (QTLWExtra *te = maybeTopData()) { if (te->posIncludesFrame) { // For Qt::WA_DontShowOnScreen, assume a frame of 0 (for // example, in QGraphicsProxyWidget). if (q->testAttribute(Qt::WA_DontShowOnScreen)) { te->posIncludesFrame = 0; } else { if (q->windowHandle()) { updateFrameStrut(); if (!q->data->fstrut_dirty) { data.crect.translate(te->frameStrut.x(), te->frameStrut.y()); te->posIncludesFrame = 0;
491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
} } // windowHandle() } // !WA_DontShowOnScreen } // posIncludesFrame } // QTLWExtra } void QWidgetPrivate::show_sys() { Q_Q(QWidget); QWindow *window = q->windowHandle(); if (q->testAttribute(Qt::WA_DontShowOnScreen)) { invalidateBuffer(q->rect()); q->setAttribute(Qt::WA_Mapped); if (q->isWindow() && q->windowModality() != Qt::NonModal && window) { // add our window to the modal window list QGuiApplicationPrivate::showModalWindow(window); } return; } QApplication::postEvent(q, new QUpdateLaterEvent(q->rect())); if (!q->isWindow() && !q->testAttribute(Qt::WA_NativeWindow)) return; if (window) { if (q->isWindow()) fixPosIncludesFrame(); QRect geomRect = q->geometry(); if (!q->isWindow()) { QPoint topLeftOfWindow = q->mapTo(q->nativeParentWidget(),QPoint()); geomRect.moveTopLeft(topLeftOfWindow); } const QRect windowRect = window->geometry(); if (windowRect != geomRect) { if (q->testAttribute(Qt::WA_Moved)) window->setGeometry(geomRect); else window->resize(geomRect.size()); } if (QBackingStore *store = q->backingStore()) { if (store->size() != geomRect.size()) { store->resize(geomRect.size()); } } #ifndef QT_NO_CURSOR qt_qpa_set_cursor(q, false); // Needed in case cursor was set before show #endif invalidateBuffer(q->rect()); window->setVisible(true); // Was the window moved by the Window system or QPlatformWindow::initialGeometry() ? if (window->isTopLevel()) { const QPoint crectTopLeft = q->data->crect.topLeft(); const QPoint windowTopLeft = window->geometry().topLeft(); if (crectTopLeft == QPoint(0, 0) && windowTopLeft != crectTopLeft) q->data->crect.moveTopLeft(windowTopLeft); } } } void QWidgetPrivate::hide_sys() { Q_Q(QWidget);
561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
QWindow *window = q->windowHandle(); if (q->testAttribute(Qt::WA_DontShowOnScreen)) { q->setAttribute(Qt::WA_Mapped, false); if (q->isWindow() && q->windowModality() != Qt::NonModal && window) { // remove our window from the modal window list QGuiApplicationPrivate::hideModalWindow(window); } // do not return here, if window non-zero, we must hide it } deactivateWidgetCleanup(); if (!q->isWindow()) { QWidget *p = q->parentWidget(); if (p &&p->isVisible()) { invalidateBuffer(q->rect()); } } else { invalidateBuffer(q->rect()); } if (window) window->setVisible(false); } Qt::WindowState effectiveState(Qt::WindowStates state) { if (state & Qt::WindowMinimized) return Qt::WindowMinimized; else if (state & Qt::WindowFullScreen) return Qt::WindowFullScreen; else if (state & Qt::WindowMaximized) return Qt::WindowMaximized; return Qt::WindowNoState; } void QWidget::setWindowState(Qt::WindowStates newstate) { Q_D(QWidget); Qt::WindowStates oldstate = windowState(); if (oldstate == newstate) return; if (isWindow() && !testAttribute(Qt::WA_WState_Created)) create(); data->window_state = newstate; data->in_set_window_state = 1; Qt::WindowState newEffectiveState = effectiveState(newstate); Qt::WindowState oldEffectiveState = effectiveState(oldstate); if (isWindow() && newEffectiveState != oldEffectiveState) { // Ensure the initial size is valid, since we store it as normalGeometry below. if (!testAttribute(Qt::WA_Resized) && !isVisible()) adjustSize(); d->createTLExtra(); if (oldEffectiveState == Qt::WindowNoState) d->topData()->normalGeometry = geometry(); Q_ASSERT(windowHandle()); windowHandle()->setWindowState(newEffectiveState); } data->in_set_window_state = 0; if (newstate & Qt::WindowActive) activateWindow(); QWindowStateChangeEvent e(oldstate); QApplication::sendEvent(this, &e); }
631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
void QWidgetPrivate::setFocus_sys() { Q_Q(QWidget); // Embedded native widget may have taken the focus; get it back to toplevel if that is the case const QWidget *topLevel = q->window(); if (topLevel->windowType() != Qt::Popup) { if (QWindow *nativeWindow = q->window()->windowHandle()) { if (nativeWindow != QGuiApplication::focusWindow() && q->testAttribute(Qt::WA_WState_Created)) { nativeWindow->requestActivate(); } } } } void QWidgetPrivate::raise_sys() { Q_Q(QWidget); if (q->isWindow() || q->testAttribute(Qt::WA_NativeWindow)) { q->windowHandle()->raise(); } } void QWidgetPrivate::lower_sys() { Q_Q(QWidget); if (q->isWindow() || q->testAttribute(Qt::WA_NativeWindow)) { Q_ASSERT(q->testAttribute(Qt::WA_WState_Created)); q->windowHandle()->lower(); } else if (QWidget *p = q->parentWidget()) { setDirtyOpaqueRegion(); p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry())); } } void QWidgetPrivate::stackUnder_sys(QWidget*) { Q_Q(QWidget); if (QWidget *p = q->parentWidget()) { setDirtyOpaqueRegion(); p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry())); } } void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) { Q_Q(QWidget); if (extra) { // any size restrictions? w = qMin(w,extra->maxw); h = qMin(h,extra->maxh); w = qMax(w,extra->minw); h = qMax(h,extra->minh); } if (q->isWindow() && q->windowHandle()) { QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration(); if (!integration->hasCapability(QPlatformIntegration::NonFullScreenWindows)) { x = 0; y = 0; w = q->windowHandle()->width(); h = q->windowHandle()->height(); } } QPoint oldp = q->geometry().topLeft(); QSize olds = q->size(); QRect r(x, y, w, h); bool isResize = olds != r.size();
701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
isMove = oldp != r.topLeft(); //### why do we have isMove as a parameter? // We only care about stuff that changes the geometry, or may // cause the window manager to change its state if (r.size() == olds && oldp == r.topLeft()) return; if (!data.in_set_window_state) { q->data->window_state &= ~Qt::WindowMaximized; q->data->window_state &= ~Qt::WindowFullScreen; if (q->isWindow()) topData()->normalGeometry = QRect(0, 0, -1, -1); } QPoint oldPos = q->pos(); data.crect = r; bool needsShow = false; if (!(data.window_state & Qt::WindowFullScreen) && (w == 0 || h == 0)) { q->setAttribute(Qt::WA_OutsideWSRange, true); if (q->isVisible() && q->testAttribute(Qt::WA_Mapped)) hide_sys(); data.crect = QRect(x, y, w, h); } else if (q->isVisible() && q->testAttribute(Qt::WA_OutsideWSRange)) { q->setAttribute(Qt::WA_OutsideWSRange, false); needsShow = true; } if (q->isVisible()) { if (!q->testAttribute(Qt::WA_DontShowOnScreen) && !q->testAttribute(Qt::WA_OutsideWSRange)) { if (q->windowHandle()) { if (q->isWindow()) { q->windowHandle()->setGeometry(q->geometry()); } else { QPoint posInNativeParent = q->mapTo(q->nativeParentWidget(),QPoint()); q->windowHandle()->setGeometry(QRect(posInNativeParent,r.size())); } const QWidgetBackingStore *bs = maybeBackingStore(); if (bs && bs->store) { if (isResize) bs->store->resize(r.size()); } if (needsShow) show_sys(); } if (!q->isWindow()) { if (isMove && !isResize) moveRect(QRect(oldPos, olds), x - oldPos.x(), y - oldPos.y()); else invalidateBuffer_resizeHelper(oldPos, olds); } } if (isMove) { QMoveEvent e(q->pos(), oldPos); QApplication::sendEvent(q, &e); } if (isResize) { QResizeEvent e(r.size(), olds); QApplication::sendEvent(q, &e); if (q->windowHandle()) q->update(); } } else { // not visible if (isMove && q->pos() != oldPos) q->setAttribute(Qt::WA_PendingMoveEvent, true);
771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
if (isResize) q->setAttribute(Qt::WA_PendingResizeEvent, true); } } void QWidgetPrivate::setConstraints_sys() { Q_Q(QWidget); if (extra && q->windowHandle()) { QWindow *win = q->windowHandle(); QWindowPrivate *winp = qt_window_private(win); winp->minimumSize = QSize(extra->minw, extra->minh); winp->maximumSize = QSize(extra->maxw, extra->maxh); if (extra->topextra) { winp->baseSize = QSize(extra->topextra->basew, extra->topextra->baseh); winp->sizeIncrement = QSize(extra->topextra->incw, extra->topextra->inch); } if (winp->platformWindow) { fixPosIncludesFrame(); winp->platformWindow->propagateSizeHints(); } } } void QWidgetPrivate::scroll_sys(int dx, int dy) { Q_Q(QWidget); scrollChildren(dx, dy); scrollRect(q->rect(), dx, dy); } void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r) { scrollRect(r, dx, dy); } int QWidget::metric(PaintDeviceMetric m) const { Q_D(const QWidget); QScreen *screen = 0; if (QWidget *topLevel = window()) if (QWindow *topLevelWindow = topLevel->windowHandle()) { QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(topLevelWindow); if (platformScreen) screen = platformScreen->screen(); } if (!screen && QGuiApplication::primaryScreen()) screen = QGuiApplication::primaryScreen(); if (!screen) { if (m == PdmDpiX || m == PdmDpiY) return 72; return QPaintDevice::metric(m); } int val; if (m == PdmWidth) { val = data->crect.width(); } else if (m == PdmWidthMM) { val = data->crect.width() * screen->physicalSize().width() / screen->geometry().width(); } else if (m == PdmHeight) { val = data->crect.height(); } else if (m == PdmHeightMM) { val = data->crect.height() * screen->physicalSize().height() / screen->geometry().height(); } else if (m == PdmDepth) { return screen->depth();
841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910
} else if (m == PdmDpiX) { if (d->extra && d->extra->customDpiX) return d->extra->customDpiX; else if (d->parent) return static_cast<QWidget *>(d->parent)->metric(m); return qRound(screen->logicalDotsPerInchX()); } else if (m == PdmDpiY) { if (d->extra && d->extra->customDpiY) return d->extra->customDpiY; else if (d->parent) return static_cast<QWidget *>(d->parent)->metric(m); return qRound(screen->logicalDotsPerInchY()); } else if (m == PdmPhysicalDpiX) { return qRound(screen->physicalDotsPerInchX()); } else if (m == PdmPhysicalDpiY) { return qRound(screen->physicalDotsPerInchY()); } else if (m == PdmDevicePixelRatio) { return screen->devicePixelRatio(); } else { val = QPaintDevice::metric(m);// XXX } return val; } /*! \preliminary Returns the QPlatformWindow this widget will be drawn into. */ QWindow *QWidget::windowHandle() const { Q_D(const QWidget); QTLWExtra *extra = d->maybeTopData(); if (extra) return extra->window; return 0; } void QWidgetPrivate::createSysExtra() { } void QWidgetPrivate::deleteSysExtra() { } void QWidgetPrivate::createTLSysExtra() { Q_Q(QWidget); extra->topextra->screenIndex = 0; extra->topextra->window = 0; if (q->testAttribute(Qt::WA_NativeWindow) || q->isWindow()) { extra->topextra->window = new QWidgetWindow(q); if (extra->minw || extra->minh) extra->topextra->window->setMinimumSize(QSize(extra->minw, extra->minh)); if (extra->maxw != QWIDGETSIZE_MAX || extra->maxh != QWIDGETSIZE_MAX) extra->topextra->window->setMaximumSize(QSize(extra->maxw, extra->maxh)); #ifdef Q_OS_WIN if (q->inherits("QTipLabel") || q->inherits("QAlphaWidget")) extra->topextra->window->setProperty("_q_windowsDropShadow", QVariant(true)); #endif } } void QWidgetPrivate::deleteTLSysExtra() { if (extra && extra->topextra) {
911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980
//the toplevel might have a context with a "qglcontext associated with it. We need to //delete the qglcontext before we delete the qplatformopenglcontext. //One unfortunate thing about this is that we potentially create a glContext just to //delete it straight afterwards. if (extra->topextra->window) { extra->topextra->window->destroy(); } setWinId(0); delete extra->topextra->window; extra->topextra->window = 0; extra->topextra->backingStoreTracker.destroy(); delete extra->topextra->backingStore; extra->topextra->backingStore = 0; } } void QWidgetPrivate::registerDropSite(bool on) { Q_UNUSED(on); } void QWidgetPrivate::setMask_sys(const QRegion &region) { if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowMasks)) { qWarning("%s: Not supported on %s.", Q_FUNC_INFO, qPrintable(QGuiApplication::platformName())); return; } Q_Q(QWidget); if (const QWindow *window = q->windowHandle()) if (QPlatformWindow *platformWindow = window->handle()) platformWindow->setMask(region); } void QWidgetPrivate::updateFrameStrut() { Q_Q(QWidget); if (q->data->fstrut_dirty) { if (QTLWExtra *te = maybeTopData()) { if (te->window) { if (const QPlatformWindow *pw = te->window->handle()) { const QMargins margins = pw->frameMargins(); if (!margins.isNull()) { te->frameStrut.setCoords(margins.left(), margins.top(), margins.right(), margins.bottom()); q->data->fstrut_dirty = false; } } } } } } void QWidgetPrivate::setWindowOpacity_sys(qreal level) { Q_Q(QWidget); if (q->windowHandle()) q->windowHandle()->setOpacity(level); } void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect) { Q_UNUSED(dontShow); Q_UNUSED(oldRect); // XXX } QPaintEngine *QWidget::paintEngine() const { qWarning("QWidget::paintEngine: Should no longer be called");
981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050
#ifdef Q_OS_WIN // We set this bit which is checked in setAttribute for // Qt::WA_PaintOnScreen. We do this to allow these two scenarios: // // 1. Users accidentally set Qt::WA_PaintOnScreen on X and port to // Windows which would mean suddenly their widgets stop working. // // 2. Users set paint on screen and subclass paintEngine() to // return 0, in which case we have a "hole" in the backingstore // allowing use of GDI or DirectX directly. // // 1 is WRONG, but to minimize silent failures, we have set this // bit to ignore the setAttribute call. 2. needs to be // supported because its our only means of embedding native // graphics stuff. const_cast<QWidgetPrivate *>(d_func())->noPaintOnScreen = 1; #endif return 0; //##### @@@ } void QWidgetPrivate::setModal_sys() { Q_Q(QWidget); if (q->windowHandle()) q->windowHandle()->setModality(q->windowModality()); } #ifndef QT_NO_CURSOR static inline void applyCursor(QWidget *w, QCursor c) { if (QWindow *window = w->windowHandle()) 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)) return; static QPointer<QWidget> lastUnderMouse = 0; if (force) { lastUnderMouse = w; } else if (lastUnderMouse) { const WId lastWinId = lastUnderMouse->effectiveWinId(); const WId winId = w->effectiveWinId(); if (lastWinId && lastWinId == winId) w = lastUnderMouse; } else if (!w->internalWinId()) { return; // The mouse is not under this widget, and it's not native, so don't change it. } while (!w->internalWinId() && w->parentWidget() && !w->isWindow() && !w->testAttribute(Qt::WA_SetCursor)) w = w->parentWidget(); QWidget *nativeParent = w; if (!w->internalWinId()) nativeParent = w->nativeParentWidget(); if (!nativeParent || !nativeParent->internalWinId()) return; if (w->isWindow() || w->testAttribute(Qt::WA_SetCursor)) {
10511052105310541055105610571058105910601061106210631064
if (w->isEnabled()) applyCursor(nativeParent, w->cursor()); else // Enforce the windows behavior of clearing the cursor on // disabled widgets. unsetCursor(nativeParent); } else { unsetCursor(nativeParent); } } #endif //QT_NO_CURSOR QT_END_NAMESPACE