예제 #1
0
파일: qwidget_qpa.cpp 프로젝트: cedrus/qt
// 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;
                    }
                } // windowHandle()
            } // !WA_DontShowOnScreen
        } // posIncludesFrame
    } // QTLWExtra
}
예제 #2
0
파일: qwidget_qws.cpp 프로젝트: Afreeca/qt
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);
    }

    QPoint oldp = q->geometry().topLeft();
    QSize olds = q->size();
    QRect r(x, y, w, h);

    bool isResize = olds != r.size();
    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;

    if ((q->windowType() == Qt::Desktop))
        return;

    if (q->isVisible()) {

        bool toplevelMove = false;
        QWSWindowSurface *surface = 0;

        if (q->isWindow()) {
            //### ConfigPending not implemented, do we need it?
            //setAttribute(Qt::WA_WState_ConfigPending);
            const QWidgetBackingStore *bs = maybeBackingStore();
            if (bs)
                surface = static_cast<QWSWindowSurface*>(bs->windowSurface);
            if (isMove && !isResize && surface) {
                const QPoint offset(x - oldp.x(), y - oldp.y());
                moveSurface(surface, offset);
                toplevelMove = true; //server moves window, but we must send moveEvent, which might trigger painting

#ifdef Q_BACKINGSTORE_SUBSURFACES
                QList<QWindowSurface*> surfaces = bs->subSurfaces;
                for (int i = 0; i < surfaces.size(); ++i)
                    moveSurface(surfaces.at(i), offset);
#endif
            } else {
                    updateFrameStrut();
            }
        }

        if (!toplevelMove) {
            if (q->isWindow()) {
                if (surface)
                    surface->setGeometry(q->frameGeometry());
                else
                    invalidateBuffer(q->rect()); //###

#ifdef Q_BACKINGSTORE_SUBSURFACES
                // XXX: should not resize subsurfaces. Children within a layout
                // will be resized automatically while children with a static
                // geometry should get a new clip region instead.
                const QRect clipRect = q->geometry();
                QWidgetBackingStore *bs = maybeBackingStore();
                QList<QWindowSurface*> surfaces = bs->subSurfaces;
                for (int i = 0; i < surfaces.size(); ++i) {
                    QWSWindowSurface *s = static_cast<QWSWindowSurface*>(surfaces.at(i));
                    QRect srect = s->geometry();
                    s->setGeometry(clipRect & srect);
                }
#endif
            }
#ifdef Q_BACKINGSTORE_SUBSURFACES
            // XXX: merge this case with the isWindow() case
            else if (maybeTopData() && maybeTopData()->windowSurface) {
                QWSWindowSurface *surface;
                surface = static_cast<QWSWindowSurface*>(q->windowSurface());
                if (isMove && !isResize) {
                    moveSurface(surface, QPoint(x - oldp.x(), y - oldp.y()));
                } else {
                    const QPoint p = q->mapToGlobal(QPoint());
                    surface->setGeometry(QRect(p, QSize(w, h)));
                }
            }
#endif
            else {
                if (isMove && !isResize)
                    moveRect(QRect(oldPos, olds), x - oldPos.x(), y - oldPos.y());
                else
                    invalidateBuffer_resizeHelper(oldPos, olds);
            }
        }

        //### must have frame geometry correct before sending move/resize events
        if (isMove) {
            QMoveEvent e(q->pos(), oldPos);
            QApplication::sendEvent(q, &e);
        }
        if (isResize) {
            QResizeEvent e(r.size(), olds);
            QApplication::sendEvent(q, &e);
        }

    } else { // not visible
        if (isMove && q->pos() != oldPos)
            q->setAttribute(Qt::WA_PendingMoveEvent, true);
        if (isResize)
            q->setAttribute(Qt::WA_PendingResizeEvent, true);
    }
}
예제 #3
0
void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow) {
    Q_Q(QWidget);
    static int sw = -1, sh = -1;

    Qt::WindowType type = q->windowType();
    Qt::WindowFlags flags = data.window_flags;

    bool topLevel = (flags & Qt::Window);
    bool popup = (type == Qt::Popup);
    bool dialog = (type == Qt::Dialog
                   || type == Qt::Sheet
                   || (flags & Qt::MSWindowsFixedSizeDialogHint));
    bool desktop = (type == Qt::Desktop);
    bool tool = (type == Qt::Tool || type == Qt::Drawer);

    HINSTANCE appinst  = qWinAppInst();
    HWND parentw, destroyw = 0;
    WId id;

    QString windowClassName = qt_reg_winclass(q);

    if (!window)                                // always initialize
        initializeWindow = true;

    if (popup)
        flags |= Qt::WindowStaysOnTopHint; // a popup stays on top

    if (flags & (Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::WindowContextHelpButtonHint)) {
        flags |= Qt::WindowSystemMenuHint;
        flags |= Qt::WindowTitleHint;
        flags &= ~Qt::FramelessWindowHint;
    }

    if (sw < 0) {                                // get the (primary) screen size
        sw = GetSystemMetrics(SM_CXSCREEN);
        sh = GetSystemMetrics(SM_CYSCREEN);
    }

    if (desktop) {                                // desktop widget
        popup = false;                                // force this flags off
        data.crect.setRect(0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
    }

    parentw = q->parentWidget() ? q->parentWidget()->effectiveWinId() : 0;

    QString title;
    int style = WS_CHILD;
    int exsty = WS_EX_NOPARENTNOTIFY;

    if (topLevel) {
        if (!(flags & Qt::FramelessWindowHint) && !tool && !q->testAttribute(Qt::WA_DontShowOnScreen))
          style = (WS_OVERLAPPED) | WS_SYSMENU;
        else
          style = WS_POPUP;
        if ((type == Qt::ToolTip) || (type == Qt::SplashScreen)) {
            style = WS_POPUP;
            exsty |= WS_EX_NOANIMATION;
        } else {
            if (flags & Qt::WindowTitleHint)
                style |= WS_CAPTION;
            if (flags & Qt::WindowSystemMenuHint)
                style |= WS_SYSMENU;
            if (flags & Qt::WindowContextHelpButtonHint)
                exsty |= WS_EX_CONTEXTHELP;
#ifndef Q_WS_WINCE_WM
            if (flags & Qt::WindowMinimizeButtonHint)
                style |= WS_MINIMIZEBOX;
            if (shouldShowMaximizeButton())
                style |= WS_MAXIMIZEBOX;
#endif
            if (tool)
                exsty |= WS_EX_TOOLWINDOW;
        }
    }
    if (dialog) {
        style = WS_BORDER | WS_CAPTION;
        if (flags & Qt::WindowOkButtonHint)
            exsty |= WS_EX_CAPTIONOKBTN;
        if (flags & Qt::WindowCancelButtonHint || flags & Qt::WA_DeleteOnClose)
            style |= WS_SYSMENU;
        if (flags & Qt::WindowContextHelpButtonHint)
            exsty |= WS_EX_CONTEXTHELP;
    }
    if (popup) {
        style = WS_POPUP;
        exsty |= WS_EX_NOANIMATION;
    }

    if (flags & Qt::WindowTitleHint) {
        title = q->isWindow() ? qAppName() : q->objectName();
    }

    // The Qt::WA_WState_Created flag is checked by translateConfigEvent() in
    // qapplication_win.cpp. We switch it off temporarily to avoid move
    // and resize events during creationt
    q->setAttribute(Qt::WA_WState_Created, false);

    if (window) {                                // override the old window
        if (destroyOldWindow)
            destroyw = data.winid;
        id = window;
        setWinId(window);
        LONG res = SetWindowLong(window, GWL_STYLE, style);
        if (!res)
            qErrnoWarning("QWidget::create: Failed to set window style");

        res = SetWindowLong( window, GWL_WNDPROC, (LONG)QtWndProc );

        if (!res)
            qErrnoWarning("QWidget::create: Failed to set window procedure");
    } else if (desktop) {                        // desktop widget
        id = GetDesktopWindow();
        if (!id) { //Create a dummy desktop
            RECT r;
            SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
            id = CreateWindow(reinterpret_cast<const wchar_t *>(windowClassName.utf16()),
                              reinterpret_cast<const wchar_t *>(title.utf16()), style,
                              r.left, r.top, r.right - r.left, r.bottom - r.top,
                              0, 0, appinst, 0);
        }
        setWinId(id);
    } else if (topLevel) {                       // create top-level widget
        const bool wasMoved = q->testAttribute(Qt::WA_Moved);
        
        int x, y;
        if (qt_wince_is_mobile()) {
            x = wasMoved ? data.crect.left() : CW_USEDEFAULT;
            y = wasMoved ? data.crect.top() : CW_USEDEFAULT;
        } else {
            x = wasMoved ? data.crect.left() : 100;
            y = wasMoved ? data.crect.top() : 100;
        }
        
        int w = CW_USEDEFAULT;
        int h = CW_USEDEFAULT;

        // Adjust for framestrut when needed
        RECT rect = {0,0,0,0};
        if (AdjustWindowRectEx(&rect, style, FALSE, exsty)) {
            QTLWExtra *td = maybeTopData();
            if (wasMoved && (td && !td->posFromMove)) {
                x = data.crect.x() + rect.left;
                y = data.crect.y() + rect.top;
            }

            if (q->testAttribute(Qt::WA_Resized)) {
                w = data.crect.width() + (rect.right - rect.left);
                h = data.crect.height() + (rect.bottom - rect.top);
            }
        }

        id = CreateWindowEx(exsty, reinterpret_cast<const wchar_t *>(windowClassName.utf16()),
                            reinterpret_cast<const wchar_t *>(title.utf16()), style,
                            x, y, w, h,
                            0, 0, appinst, 0);

        if (!id)
            qErrnoWarning("QWidget::create: Failed to create window");
        setWinId(id);
        if ((flags & Qt::WindowStaysOnTopHint) || (type == Qt::ToolTip))
            SetWindowPos(id, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
    } else if (q->testAttribute(Qt::WA_NativeWindow) || paintOnScreen()) { // create child widget
        id = CreateWindowEx(exsty, (wchar_t*)windowClassName.utf16(), (wchar_t*)title.utf16(), style,
                            data.crect.left(), data.crect.top(), data.crect.width(), data.crect.height(),
                            parentw, NULL, appinst, NULL);
        if (!id)
            qErrnoWarning("QWidget::create: Failed to create window");
        SetWindowPos(id, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
        setWinId(id);
    }

    if (desktop) {
        q->setAttribute(Qt::WA_WState_Visible);
    } else if (topLevel && !q->testAttribute(Qt::WA_DontShowOnScreen)) {
        RECT  cr;
        GetClientRect(id, &cr);
        // one cannot trust cr.left and cr.top, use a correction POINT instead
        POINT pt;
        pt.x = 0;
        pt.y = 0;
        if (!q->testAttribute(Qt::WA_DontShowOnScreen) || q->testAttribute(Qt::WA_Moved))
            ClientToScreen(id, &pt);
        data.crect = QRect(QPoint(pt.x, pt.y),
                            QPoint(pt.x + cr.right - 1, pt.y + cr.bottom - 1));

        if (data.fstrut_dirty) {
            // be nice to activeqt
            updateFrameStrut();
        }
    }

    q->setAttribute(Qt::WA_WState_Created);                // accept move/resize events
    hd = 0;                                        // no display context

    if (window) {                                // got window from outside
        if (IsWindowVisible(window))
            q->setAttribute(Qt::WA_WState_Visible);
        else
            q->setAttribute(Qt::WA_WState_Visible, false);
    }

    if (extra && !extra->mask.isEmpty())
        setMask_sys(extra->mask);

#if defined(QT_NON_COMMERCIAL)
    QT_NC_WIDGET_CREATE
#endif

    if (q->hasFocus() && q->testAttribute(Qt::WA_InputMethodEnabled))
        q->inputContext()->setFocusWidget(q);

    if (destroyw) {
        DestroyWindow(destroyw);
    }

    if (q != qt_tablet_widget && QWidgetPrivate::mapper)
        qt_tablet_init_wce();

    if (q->testAttribute(Qt::WA_DropSiteRegistered))
        registerDropSite(true);

    if (maybeTopData() && maybeTopData()->opacity != 255)
        q->setWindowOpacity(maybeTopData()->opacity/255.);

    if (!topLevel && q->testAttribute(Qt::WA_NativeWindow) && q->testAttribute(Qt::WA_Mapped)) {
        Q_ASSERT(q->internalWinId());
        ShowWindow(q->internalWinId(), SW_SHOW);
    }
}