diff options
Diffstat (limited to 'src/plugins/platforms/wasm/qwasmcompositor.cpp')
-rw-r--r-- | src/plugins/platforms/wasm/qwasmcompositor.cpp | 721 |
1 files changed, 721 insertions, 0 deletions
diff --git a/src/plugins/platforms/wasm/qwasmcompositor.cpp b/src/plugins/platforms/wasm/qwasmcompositor.cpp new file mode 100644 index 0000000000..f3ea013325 --- /dev/null +++ b/src/plugins/platforms/wasm/qwasmcompositor.cpp @@ -0,0 +1,721 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** 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 The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwasmcompositor.h" +#include "qwasmwindow.h" +#include "qwasmstylepixmaps_p.h" + +#include <QtGui/qopengltexture.h> + +#include <QtGui/private/qwindow_p.h> +#include <QtGui/qopenglcontext.h> +#include <QtGui/qopenglfunctions.h> +#include <QtGui/qopengltextureblitter.h> +#include <QtGui/qpainter.h> +#include <private/qpixmapcache_p.h> + +#include <private/qguiapplication_p.h> + +#include <qpa/qwindowsysteminterface.h> +#include <QtCore/qcoreapplication.h> +#include <QtGui/qguiapplication.h> + +Q_GUI_EXPORT int qt_defaultDpiX(); + +QWasmCompositedWindow::QWasmCompositedWindow() + : window(nullptr) + , parentWindow(nullptr) + , flushPending(false) + , visible(false) +{ +} + +QWasmCompositor::QWasmCompositor() + : m_frameBuffer(nullptr) + , m_blitter(new QOpenGLTextureBlitter) + , m_needComposit(false) + , m_inFlush(false) + , m_inResize(false) + , m_isEnabled(true) + , m_targetDevicePixelRatio(1) +{ +} + +QWasmCompositor::~QWasmCompositor() +{ + delete m_frameBuffer; +} + +void QWasmCompositor::setEnabled(bool enabled) +{ + m_isEnabled = enabled; +} + +void QWasmCompositor::addWindow(QWasmWindow *window, QWasmWindow *parentWindow) +{ + QWasmCompositedWindow compositedWindow; + compositedWindow.window = window; + compositedWindow.parentWindow = parentWindow; + m_compositedWindows.insert(window, compositedWindow); + + if (parentWindow == 0) + m_windowStack.append(window); + else + m_compositedWindows[parentWindow].childWindows.append(window); + + notifyTopWindowChanged(window); +} + +void QWasmCompositor::removeWindow(QWasmWindow *window) +{ + QWasmWindow *platformWindow = m_compositedWindows[window].parentWindow; + + if (platformWindow) { + QWasmWindow *parentWindow = window; + m_compositedWindows[parentWindow].childWindows.removeAll(window); + } + + m_windowStack.removeAll(window); + m_compositedWindows.remove(window); + + notifyTopWindowChanged(window); +} + +void QWasmCompositor::setScreen(QWasmScreen *screen) +{ + m_screen = screen; +} + +void QWasmCompositor::setVisible(QWasmWindow *window, bool visible) +{ + QWasmCompositedWindow &compositedWindow = m_compositedWindows[window]; + if (compositedWindow.visible == visible) + return; + + compositedWindow.visible = visible; + compositedWindow.flushPending = true; + if (visible) + compositedWindow.damage = compositedWindow.window->geometry(); + else + m_globalDamage = compositedWindow.window->geometry(); // repaint previosly covered area. + + requestRedraw(); +} + +void QWasmCompositor::raise(QWasmWindow *window) +{ + if (m_compositedWindows.size() <= 1) + return; + + QWasmCompositedWindow &compositedWindow = m_compositedWindows[window]; + compositedWindow.damage = compositedWindow.window->geometry(); + m_windowStack.removeAll(window); + m_windowStack.append(window); + + notifyTopWindowChanged(window); +} + +void QWasmCompositor::lower(QWasmWindow *window) +{ + if (m_compositedWindows.size() <= 1) + return; + + m_windowStack.removeAll(window); + m_windowStack.prepend(window); + QWasmCompositedWindow &compositedWindow = m_compositedWindows[window]; + m_globalDamage = compositedWindow.window->geometry(); // repaint previosly covered area. + + notifyTopWindowChanged(window); +} + +void QWasmCompositor::setParent(QWasmWindow *window, QWasmWindow *parent) +{ + m_compositedWindows[window].parentWindow = parent; + + requestRedraw(); +} + +void QWasmCompositor::flush(QWasmWindow *window, const QRegion ®ion) +{ + QWasmCompositedWindow &compositedWindow = m_compositedWindows[window]; + compositedWindow.flushPending = true; + compositedWindow.damage = region; + + requestRedraw(); +} + +int QWasmCompositor::windowCount() const +{ + return m_windowStack.count(); +} + + +void QWasmCompositor::redrawWindowContent() +{ + // Redraw window content by sending expose events. This redraw + // will cause a backing store flush, which will call requestRedraw() + // to composit. + for (QWasmWindow *platformWindow : m_windowStack) { + QWindow *window = platformWindow->window(); + QWindowSystemInterface::handleExposeEvent<QWindowSystemInterface::SynchronousDelivery>( + window, QRect(QPoint(0, 0), window->geometry().size())); + } +} + +void QWasmCompositor::requestRedraw() +{ + if (m_needComposit) + return; + + m_needComposit = true; + QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest)); +} + +QWindow *QWasmCompositor::windowAt(QPoint p, int padding) const +{ + int index = m_windowStack.count() - 1; + // qDebug() << "window at" << "point" << p << "window count" << index; + + while (index >= 0) { + const QWasmCompositedWindow &compositedWindow = m_compositedWindows[m_windowStack.at(index)]; + //qDebug() << "windwAt testing" << compositedWindow.window << + + QRect geometry = compositedWindow.window->windowFrameGeometry() + .adjusted(-padding, -padding, padding, padding); + + if (compositedWindow.visible && geometry.contains(p)) + return m_windowStack.at(index)->window(); + --index; + } + + return 0; +} + +QWindow *QWasmCompositor::keyWindow() const +{ + return m_windowStack.at(m_windowStack.count() - 1)->window(); +} + +bool QWasmCompositor::event(QEvent *ev) +{ + if (ev->type() == QEvent::UpdateRequest) { + if (m_isEnabled) + frame(); + return true; + } + + return QObject::event(ev); +} + +void QWasmCompositor::blit(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, const QOpenGLTexture *texture, QRect targetGeometry) +{ + QMatrix4x4 m; + m.translate(-1.0f, -1.0f); + + m.scale(2.0f / (float)screen->geometry().width(), + 2.0f / (float)screen->geometry().height()); + + m.translate((float)targetGeometry.width() / 2.0f, + (float)-targetGeometry.height() / 2.0f); + + m.translate(targetGeometry.x(), screen->geometry().height() - targetGeometry.y()); + + m.scale(0.5f * (float)targetGeometry.width(), + 0.5f * (float)targetGeometry.height()); + + blitter->blit(texture->textureId(), m, QOpenGLTextureBlitter::OriginTopLeft); +} + +void QWasmCompositor::drawWindowContent(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, QWasmWindow *window) +{ + QWasmBackingStore *backingStore = window->backingStore(); + + QOpenGLTexture const *texture = backingStore->getUpdatedTexture(); + + blit(blitter, screen, texture, window->geometry()); +} + +QPalette QWasmCompositor::makeWindowPalette() +{ + QPalette palette; + palette.setColor(QPalette::Active, QPalette::Highlight, + palette.color(QPalette::Active, QPalette::Highlight)); + palette.setColor(QPalette::Active, QPalette::Base, + palette.color(QPalette::Active, QPalette::Highlight)); + palette.setColor(QPalette::Inactive, QPalette::Highlight, + palette.color(QPalette::Inactive, QPalette::Dark)); + palette.setColor(QPalette::Inactive, QPalette::Base, + palette.color(QPalette::Inactive, QPalette::Dark)); + palette.setColor(QPalette::Inactive, QPalette::HighlightedText, + palette.color(QPalette::Inactive, QPalette::Window)); + + return palette; +} + +QRect QWasmCompositor::titlebarRect(QWasmTitleBarOptions tb, QWasmCompositor::SubControls subcontrol) +{ + QRect ret; + const int controlMargin = 2; + const int controlHeight = tb.rect.height() - controlMargin *2; + const int delta = controlHeight + controlMargin; + int offset = 0; + + bool isMinimized = tb.state & Qt::WindowMinimized; + bool isMaximized = tb.state & Qt::WindowMaximized; + + ret = tb.rect; + switch (subcontrol) { + case SC_TitleBarLabel: + if (tb.flags & Qt::WindowSystemMenuHint) + ret.adjust(delta, 0, -delta, 0); + break; + case SC_TitleBarCloseButton: + if (tb.flags & Qt::WindowSystemMenuHint) { + ret.adjust(0, 0, -delta, 0); + offset += delta; + } + break; + case SC_TitleBarMaxButton: + if (!isMaximized && tb.flags & Qt::WindowMaximizeButtonHint) { + ret.adjust(0, 0, -delta*2, 0); + offset += (delta +delta); + } + break; + case SC_TitleBarNormalButton: + if (isMinimized && (tb.flags & Qt::WindowMinimizeButtonHint)) + offset += delta; + else if (isMaximized && (tb.flags & Qt::WindowMaximizeButtonHint)) + ret.adjust(0, 0, -delta*2, 0); + offset += (delta +delta); + break; + case SC_TitleBarSysMenu: + if (tb.flags & Qt::WindowSystemMenuHint) { + ret.setRect(tb.rect.left() + controlMargin, tb.rect.top() + controlMargin, + controlHeight, controlHeight); + } + break; + default: + break; + }; + + if (subcontrol != SC_TitleBarLabel && subcontrol != SC_TitleBarSysMenu) { + ret.setRect(tb.rect.right() - offset, tb.rect.top() + controlMargin, + controlHeight, controlHeight); + } + + if (qApp->layoutDirection() == Qt::LeftToRight) + return ret; + + QRect rect = ret; + rect.translate(2 * (tb.rect.right() - ret.right()) + + ret.width() - tb.rect.width(), 0); + + return rect; +} + +int dpiScaled(qreal value) +{ + return value * (qreal(qt_defaultDpiX()) / 96.0); +} + +QWasmCompositor::QWasmTitleBarOptions QWasmCompositor::makeTitleBarOptions(const QWasmWindow *window) +{ + int width = window->windowFrameGeometry().width(); + int border = window->borderWidth(); + + QWasmTitleBarOptions titleBarOptions; + + titleBarOptions.rect = QRect(border, border, width - 2 * border, window->titleHeight()); + titleBarOptions.flags = window->window()->flags(); + titleBarOptions.state = window->window()->windowState(); + + bool isMaximized = titleBarOptions.state & Qt::WindowMaximized; // this gets reset when maximized + + if (titleBarOptions.flags & (Qt::WindowTitleHint)) + titleBarOptions.subControls |= SC_TitleBarLabel; + if (titleBarOptions.flags & Qt::WindowMaximizeButtonHint) { + if (isMaximized) + titleBarOptions.subControls |= SC_TitleBarNormalButton; + else + titleBarOptions.subControls |= SC_TitleBarMaxButton; + } + if (titleBarOptions.flags & Qt::WindowSystemMenuHint) { + titleBarOptions.subControls |= SC_TitleBarCloseButton; + titleBarOptions.subControls |= SC_TitleBarSysMenu; + } + + + titleBarOptions.palette = QWasmCompositor::makeWindowPalette(); + + if (window->window()->isActive()) + titleBarOptions.palette.setCurrentColorGroup(QPalette::Active); + else + titleBarOptions.palette.setCurrentColorGroup(QPalette::Inactive); + + if (window->activeSubControl() != QWasmCompositor::SC_None) + titleBarOptions.subControls = window->activeSubControl(); + + if (!window->window()->title().isEmpty()) + titleBarOptions.titleBarOptionsString = window->window()->title(); + + return titleBarOptions; +} + +void QWasmCompositor::drawWindowDecorations(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, QWasmWindow *window) +{ + int width = window->windowFrameGeometry().width(); + int height = window->windowFrameGeometry().height(); + qreal dpr = window->devicePixelRatio(); + + QImage image(QSize(width * dpr, height * dpr), QImage::Format_RGB32); + image.setDevicePixelRatio(dpr); + QPainter painter(&image); + painter.fillRect(QRect(0, 0, width, height), painter.background()); + + QWasmTitleBarOptions titleBarOptions = makeTitleBarOptions(window); + + drawTitlebarWindow(titleBarOptions, &painter); + + QWasmFrameOptions frameOptions; + frameOptions.rect = QRect(0, 0, width, height); + frameOptions.lineWidth = dpiScaled(4.); + + drawFrameWindow(frameOptions, &painter); + + painter.end(); + + QOpenGLTexture texture(QOpenGLTexture::Target2D); + texture.setMinificationFilter(QOpenGLTexture::Nearest); + texture.setMagnificationFilter(QOpenGLTexture::Nearest); + texture.setWrapMode(QOpenGLTexture::ClampToEdge); + texture.setData(image, QOpenGLTexture::DontGenerateMipMaps); + texture.create(); + texture.bind(); + + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image.width(), image.height(), GL_RGBA, GL_UNSIGNED_BYTE, + image.constScanLine(0)); + + blit(blitter, screen, &texture, QRect(window->windowFrameGeometry().topLeft(), QSize(width, height))); +} + +void QWasmCompositor::drawFrameWindow(QWasmFrameOptions options, QPainter *painter) +{ + int x = options.rect.x(); + int y = options.rect.y(); + int w = options.rect.width(); + int h = options.rect.height(); + const QColor &c1 = options.palette.light().color(); + const QColor &c2 = options.palette.shadow().color(); + const QColor &c3 = options.palette.midlight().color(); + const QColor &c4 = options.palette.dark().color(); + const QBrush *fill = 0; + + const qreal devicePixelRatio = painter->device()->devicePixelRatioF(); + if (!qFuzzyCompare(devicePixelRatio, qreal(1))) { + const qreal inverseScale = qreal(1) / devicePixelRatio; + painter->scale(inverseScale, inverseScale); + x = qRound(devicePixelRatio * x); + y = qRound(devicePixelRatio * y); + w = qRound(devicePixelRatio * w); + h = qRound(devicePixelRatio * h); + } + + QPen oldPen = painter->pen(); + QPoint a[3] = { QPoint(x, y+h-2), QPoint(x, y), QPoint(x+w-2, y) }; + painter->setPen(c1); + painter->drawPolyline(a, 3); + QPoint b[3] = { QPoint(x, y+h-1), QPoint(x+w-1, y+h-1), QPoint(x+w-1, y) }; + painter->setPen(c2); + painter->drawPolyline(b, 3); + if (w > 4 && h > 4) { + QPoint c[3] = { QPoint(x+1, y+h-3), QPoint(x+1, y+1), QPoint(x+w-3, y+1) }; + painter->setPen(c3); + painter->drawPolyline(c, 3); + QPoint d[3] = { QPoint(x+1, y+h-2), QPoint(x+w-2, y+h-2), QPoint(x+w-2, y+1) }; + painter->setPen(c4); + painter->drawPolyline(d, 3); + if (fill) + painter->fillRect(QRect(x+2, y+2, w-4, h-4), *fill); + } + painter->setPen(oldPen); +} + +//from commonstyle.cpp +static QPixmap cachedPixmapFromXPM(const char * const *xpm) +{ + QPixmap result; + const QString tag = QString::asprintf("xpm:0x%p", static_cast<const void*>(xpm)); + if (!QPixmapCache::find(tag, &result)) { + result = QPixmap(xpm); + QPixmapCache::insert(tag, result); + } + return result; +} + +void QWasmCompositor::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, + const QPixmap &pixmap) const +{ + qreal scale = pixmap.devicePixelRatio(); + QSize size = pixmap.size() / scale; + int x = rect.x(); + int y = rect.y(); + int w = size.width(); + int h = size.height(); + if ((alignment & Qt::AlignVCenter) == Qt::AlignVCenter) + y += rect.size().height()/2 - h/2; + else if ((alignment & Qt::AlignBottom) == Qt::AlignBottom) + y += rect.size().height() - h; + if ((alignment & Qt::AlignRight) == Qt::AlignRight) + x += rect.size().width() - w; + else if ((alignment & Qt::AlignHCenter) == Qt::AlignHCenter) + x += rect.size().width()/2 - w/2; + + QRect aligned = QRect(x, y, w, h); + QRect inter = aligned.intersected(rect); + + painter->drawPixmap(inter.x(), inter.y(), pixmap, inter.x() - aligned.x(), inter.y() - aligned.y(), inter.width() * scale, inter.height() *scale); +} + + +void QWasmCompositor::drawTitlebarWindow(QWasmTitleBarOptions tb, QPainter *painter) +{ + QRect ir; + if (tb.subControls.testFlag(SC_TitleBarLabel)) { + QColor left = tb.palette.highlight().color(); + QColor right = tb.palette.base().color(); + + QBrush fillBrush(left); + if (left != right) { + QPoint p1(tb.rect.x(), tb.rect.top() + tb.rect.height()/2); + QPoint p2(tb.rect.right(), tb.rect.top() + tb.rect.height()/2); + QLinearGradient lg(p1, p2); + lg.setColorAt(0, left); + lg.setColorAt(1, right); + fillBrush = lg; + } + + painter->fillRect(tb.rect, fillBrush); + ir = titlebarRect(tb, SC_TitleBarLabel); + painter->setPen(tb.palette.highlightedText().color()); + painter->drawText(ir.x() + 2, ir.y(), ir.width() - 2, ir.height(), + Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, tb.titleBarOptionsString); + } // SC_TitleBarLabel + + bool down = false; + QPixmap pixmap; + + if (tb.subControls.testFlag(SC_TitleBarCloseButton) + && tb.flags & Qt::WindowSystemMenuHint) { + ir = titlebarRect(tb, SC_TitleBarCloseButton); + down = tb.subControls & SC_TitleBarCloseButton && (tb.state & State_Sunken); + pixmap = cachedPixmapFromXPM(qt_close_xpm).scaled(QSize(10, 10)); + drawItemPixmap(painter, ir, Qt::AlignCenter, pixmap); + } //SC_TitleBarCloseButton + + if (tb.subControls.testFlag(SC_TitleBarMaxButton) + && tb.flags & Qt::WindowMaximizeButtonHint + && !(tb.state & Qt::WindowMaximized)) { + ir = titlebarRect(tb, SC_TitleBarMaxButton); + down = tb.subControls & SC_TitleBarMaxButton && (tb.state & State_Sunken); + pixmap = cachedPixmapFromXPM(qt_maximize_xpm).scaled(QSize(10, 10)); + drawItemPixmap(painter, ir, Qt::AlignCenter, pixmap); + } //SC_TitleBarMaxButton + + bool drawNormalButton = (tb.subControls & SC_TitleBarNormalButton) + && (((tb.flags & Qt::WindowMinimizeButtonHint) + && (tb.flags & Qt::WindowMinimized)) + || ((tb.flags & Qt::WindowMaximizeButtonHint) + && (tb.flags & Qt::WindowMaximized))); + + if (drawNormalButton) { + ir = titlebarRect(tb, SC_TitleBarNormalButton); + down = tb.subControls & SC_TitleBarNormalButton && (tb.state & State_Sunken); + pixmap = cachedPixmapFromXPM(qt_normalizeup_xpm).scaled( QSize(10, 10)); + + drawItemPixmap(painter, ir, Qt::AlignCenter, pixmap); + } // SC_TitleBarNormalButton + + if (tb.subControls & SC_TitleBarSysMenu && tb.flags & Qt::WindowSystemMenuHint) { + ir = titlebarRect(tb, SC_TitleBarSysMenu); + pixmap = cachedPixmapFromXPM(qt_menu_xpm).scaled(QSize(10, 10)); + drawItemPixmap(painter, ir, Qt::AlignCenter, pixmap); + } +} + +void QWasmCompositor::drawShadePanel(QWasmTitleBarOptions options, QPainter *painter) +{ + int lineWidth = 1; + QPalette palette = options.palette; + const QBrush *fill = &options.palette.brush(QPalette::Button); + + int x = options.rect.x(); + int y = options.rect.y(); + int w = options.rect.width(); + int h = options.rect.height(); + + const qreal devicePixelRatio = painter->device()->devicePixelRatioF(); + if (!qFuzzyCompare(devicePixelRatio, qreal(1))) { + const qreal inverseScale = qreal(1) / devicePixelRatio; + painter->scale(inverseScale, inverseScale); + + x = qRound(devicePixelRatio * x); + y = qRound(devicePixelRatio * y); + w = qRound(devicePixelRatio * w); + h = qRound(devicePixelRatio * h); + lineWidth = qRound(devicePixelRatio * lineWidth); + } + + QColor shade = palette.dark().color(); + QColor light = palette.light().color(); + + if (fill) { + if (fill->color() == shade) + shade = palette.shadow().color(); + if (fill->color() == light) + light = palette.midlight().color(); + } + QPen oldPen = painter->pen(); + QVector<QLineF> lines; + lines.reserve(2*lineWidth); + + painter->setPen(light); + int x1, y1, x2, y2; + int i; + x1 = x; + y1 = y2 = y; + x2 = x + w - 2; + for (i = 0; i < lineWidth; i++) // top shadow + lines << QLineF(x1, y1++, x2--, y2++); + + x2 = x1; + y1 = y + h - 2; + for (i = 0; i < lineWidth; i++) // left shado + lines << QLineF(x1++, y1, x2++, y2--); + + painter->drawLines(lines); + lines.clear(); + painter->setPen(shade); + x1 = x; + y1 = y2 = y+h-1; + x2 = x+w-1; + for (i=0; i<lineWidth; i++) { // bottom shadow + lines << QLineF(x1++, y1--, x2, y2--); + } + x1 = x2; + y1 = y; + y2 = y + h - lineWidth - 1; + for (i = 0; i < lineWidth; i++) // right shadow + lines << QLineF(x1--, y1++, x2--, y2); + + painter->drawLines(lines); + if (fill) // fill with fill color + painter->fillRect(x+lineWidth, y+lineWidth, w-lineWidth*2, h-lineWidth*2, *fill); + painter->setPen(oldPen); // restore pen + +} + +void QWasmCompositor::drawWindow(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, QWasmWindow *window) +{ + if (window->window()->type() != Qt::Popup) + drawWindowDecorations(blitter, screen, window); + drawWindowContent(blitter, screen, window); +} + +void QWasmCompositor::frame() +{ + if (!m_needComposit) + return; + + m_needComposit = false; + + if (m_windowStack.empty() || !m_screen) + return; + + QWasmWindow *someWindow = nullptr; + + foreach (QWasmWindow *window, m_windowStack) { + if (window->window()->surfaceClass() == QSurface::Window + && qt_window_private(static_cast<QWindow *>(window->window()))->receivedExpose) { + someWindow = window; + break; + } + } + + if (!someWindow) + return; + + if (m_context.isNull()) { + m_context.reset(new QOpenGLContext()); + //mContext->setFormat(mScreen->format()); + m_context->setScreen(m_screen->screen()); + m_context->create(); + } + + m_context->makeCurrent(someWindow->window()); + + if (!m_blitter->isCreated()) + m_blitter->create(); + + qreal dpr = m_screen->devicePixelRatio(); + glViewport(0, 0, m_screen->geometry().width() * dpr, m_screen->geometry().height() * dpr); + + m_context->functions()->glClearColor(0.2, 0.2, 0.2, 1.0); + m_context->functions()->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + m_blitter->bind(); + m_blitter->setRedBlueSwizzle(true); + + foreach (QWasmWindow *window, m_windowStack) { + QWasmCompositedWindow &compositedWindow = m_compositedWindows[window]; + + if (!compositedWindow.visible) + continue; + + drawWindow(m_blitter.data(), m_screen, window); + } + + m_blitter->release(); + + if (someWindow && someWindow->window()->surfaceType() == QSurface::OpenGLSurface) + m_context->swapBuffers(someWindow->window()); +} + +void QWasmCompositor::notifyTopWindowChanged(QWasmWindow *window) +{ + QWindow *modalWindow; + bool blocked = QGuiApplicationPrivate::instance()->isWindowBlocked(window->window(), &modalWindow); + + if (blocked) { + raise(static_cast<QWasmWindow*>(modalWindow->handle())); + return; + } + + requestRedraw(); + QWindowSystemInterface::handleWindowActivated(window->window()); +} |