diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/dialogs/qmessagebox.cpp | 49 | ||||
-rw-r--r-- | src/gui/itemviews/qheaderview.cpp | 9 | ||||
-rw-r--r-- | src/gui/itemviews/qtreeview.cpp | 234 | ||||
-rw-r--r-- | src/gui/itemviews/qtreeview_p.h | 7 | ||||
-rw-r--r-- | src/opengl/qglbuffer.cpp | 32 | ||||
-rw-r--r-- | src/opengl/qglbuffer.h | 2 | ||||
-rw-r--r-- | src/opengl/qpixmapdata_x11gl_egl.cpp | 72 | ||||
-rw-r--r-- | src/opengl/qpixmapdata_x11gl_p.h | 5 | ||||
-rw-r--r-- | src/opengl/qwindowsurface_x11gl.cpp | 54 | ||||
-rw-r--r-- | src/opengl/qwindowsurface_x11gl_p.h | 3 |
10 files changed, 218 insertions, 249 deletions
diff --git a/src/gui/dialogs/qmessagebox.cpp b/src/gui/dialogs/qmessagebox.cpp index 121ba62..df8b525 100644 --- a/src/gui/dialogs/qmessagebox.cpp +++ b/src/gui/dialogs/qmessagebox.cpp @@ -118,14 +118,44 @@ public: } void setText(const QString &text) { textEdit->setPlainText(text); } QString text() const { return textEdit->toPlainText(); } - QString label(DetailButtonLabel label) - { return label == ShowLabel ? QMessageBox::tr("Show Details...") - : QMessageBox::tr("Hide Details..."); } private: TextEdit *textEdit; }; #endif // QT_NO_TEXTEDIT +class DetailButton : public QPushButton +{ +public: + DetailButton(QWidget *parent) : QPushButton(label(ShowLabel), parent) + { + setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + } + + QString label(DetailButtonLabel label) const + { return label == ShowLabel ? QMessageBox::tr("Show Details...") : QMessageBox::tr("Hide Details..."); } + + void setLabel(DetailButtonLabel lbl) + { setText(label(lbl)); } + + QSize sizeHint() const + { + ensurePolished(); + QStyleOptionButton opt; + initStyleOption(&opt); + const QFontMetrics fm = fontMetrics(); + opt.text = label(ShowLabel); + QSize sz = fm.size(Qt::TextShowMnemonic, opt.text); + QSize ret = style()->sizeFromContents(QStyle::CT_PushButton, &opt, sz, this). + expandedTo(QApplication::globalStrut()); + opt.text = label(HideLabel); + sz = fm.size(Qt::TextShowMnemonic, opt.text); + ret.expandedTo(style()->sizeFromContents(QStyle::CT_PushButton, &opt, sz, this). + expandedTo(QApplication::globalStrut())); + return ret; + } +}; + + class QMessageBoxPrivate : public QDialogPrivate { Q_DECLARE_PUBLIC(QMessageBox) @@ -181,7 +211,7 @@ public: QAbstractButton *escapeButton; QPushButton *defaultButton; QAbstractButton *clickedButton; - QPushButton *detailsButton; + DetailButton *detailsButton; #ifndef QT_NO_TEXTEDIT QMessageBoxDetailsText *detailsText; #endif @@ -421,7 +451,7 @@ void QMessageBoxPrivate::_q_buttonClicked(QAbstractButton *button) Q_Q(QMessageBox); #ifndef QT_NO_TEXTEDIT if (detailsButton && detailsText && button == detailsButton) { - detailsButton->setText(detailsText->isHidden() ? detailsText->label(HideLabel) : detailsText->label(ShowLabel)); + detailsButton->setLabel(detailsText->isHidden() ? HideLabel : ShowLabel); detailsText->setHidden(!detailsText->isHidden()); updateSize(); } else @@ -1891,7 +1921,7 @@ void QMessageBoxPrivate::retranslateStrings() { #ifndef QT_NO_TEXTEDIT if (detailsButton) - detailsButton->setText(detailsText->isHidden() ? detailsText->label(HideLabel) : detailsText->label(ShowLabel)); + detailsButton->setLabel(detailsText->isHidden() ? HideLabel : ShowLabel); #endif } @@ -2399,11 +2429,8 @@ void QMessageBox::setDetailedText(const QString &text) grid->addWidget(d->detailsText, grid->rowCount(), 0, 1, grid->columnCount()); d->detailsText->hide(); } - if (!d->detailsButton) { - d->detailsButton = new QPushButton(d->detailsText->label(ShowLabel), this); - QPushButton hideDetails(d->detailsText->label(HideLabel)); - d->detailsButton->setFixedSize(d->detailsButton->sizeHint().expandedTo(hideDetails.sizeHint())); - } + if (!d->detailsButton) + d->detailsButton = new DetailButton(this); d->detailsText->setText(text); } #endif // QT_NO_TEXTEDIT diff --git a/src/gui/itemviews/qheaderview.cpp b/src/gui/itemviews/qheaderview.cpp index eb3db21..586e5d4 100644 --- a/src/gui/itemviews/qheaderview.cpp +++ b/src/gui/itemviews/qheaderview.cpp @@ -1698,13 +1698,10 @@ void QHeaderView::sectionsInserted(const QModelIndex &parent, if (!d->sectionHidden.isEmpty()) { QBitArray sectionHidden(d->sectionHidden); sectionHidden.resize(sectionHidden.count() + insertCount); - //sectionHidden.fill(false, logicalFirst, logicalLast + 1); - for (int i = logicalFirst; i <= logicalLast; ++i) - // visual == logical in this range (see previous block) - sectionHidden.setBit(i, false); + sectionHidden.fill(false, logicalFirst, logicalLast + 1); for (int j = logicalLast + 1; j < sectionHidden.count(); ++j) - sectionHidden.setBit(d->visualIndex(j), - d->sectionHidden.testBit(d->visualIndex(j - insertCount))); + //here we simply copy the old sectionHidden + sectionHidden.setBit(j, d->sectionHidden.testBit(j - insertCount)); d->sectionHidden = sectionHidden; } diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index 4135ba0..ada3936 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -1997,6 +1997,24 @@ QModelIndex QTreeView::indexBelow(const QModelIndex &index) const void QTreeView::doItemsLayout() { Q_D(QTreeView); + if (d->hasRemovedItems) { + //clean the QSet that may contains old (and this invalid) indexes + d->hasRemovedItems = false; + QSet<QPersistentModelIndex>::iterator it = d->expandedIndexes.begin(); + while (it != d->expandedIndexes.constEnd()) { + if (!it->isValid()) + it = d->expandedIndexes.erase(it); + else + ++it; + } + it = d->hiddenIndexes.begin(); + while (it != d->hiddenIndexes.constEnd()) { + if (!it->isValid()) + it = d->hiddenIndexes.erase(it); + else + ++it; + } + } d->viewItems.clear(); // prepare for new layout QModelIndex parent = d->root; if (d->model->hasChildren(parent)) { @@ -2406,24 +2424,6 @@ void QTreeView::reexpand() } /*! - \internal - This function assume that left is a (grand-)child of the parent of left. -*/ -static bool treeViewItemLessThanInInsert(const QTreeViewItem &left, const QTreeViewItem &right) -{ - if (left.level != right.level) { - Q_ASSERT(left.level > right.level); - QModelIndex leftParent = left.index.parent(); - QModelIndex rightParent = right.index.parent(); - // computer parent, don't get - while (leftParent.isValid() && leftParent.parent() != rightParent) - leftParent = leftParent.parent(); - return (leftParent.row() < right.index.row()); - } - return (left.index.row() < right.index.row()); -} - -/*! Informs the view that the rows from the \a start row to the \a end row inclusive have been inserted into the \a parent model item. */ @@ -2452,83 +2452,6 @@ void QTreeView::rowsInserted(const QModelIndex &parent, int start, int end) const int parentItem = d->viewIndex(parent); if (((parentItem != -1) && d->viewItems.at(parentItem).expanded && updatesEnabled()) || (parent == d->root)) { - const uint childLevel = (parentItem == -1) - ? uint(0) : d->viewItems.at(parentItem).level + 1; - const int firstChildItem = parentItem + 1; - const int lastChildItem = firstChildItem + ((parentItem == -1) - ? d->viewItems.count() - : d->viewItems.at(parentItem).total) - 1; - - if (parentRowCount == end + 1 && start > 0) { - //need to Update hasMoreSiblings - int previousRow = start - 1; - QModelIndex previousSibilingModelIndex = d->model->index(previousRow, 0, parent); - bool isHidden = d->isRowHidden(previousSibilingModelIndex); - while (isHidden && previousRow > 0) { - previousRow--; - previousSibilingModelIndex = d->model->index(previousRow, 0, parent); - isHidden = d->isRowHidden(previousSibilingModelIndex); - } - if (!isHidden) { - const int previousSibilling = d->viewIndex(previousSibilingModelIndex); - if(previousSibilling != -1) - d->viewItems[previousSibilling].hasMoreSiblings = true; - } - } - - QVector<QTreeViewItem> insertedItems(delta); - for (int i = 0; i < delta; ++i) { - QTreeViewItem &item = insertedItems[i]; - item.index = d->model->index(i + start, 0, parent); - item.parentItem = parentItem; - item.level = childLevel; - item.hasChildren = d->hasVisibleChildren(item.index); - item.hasMoreSiblings = !((i == delta - 1) && (parentRowCount == end +1)); - } - if (d->viewItems.isEmpty()) - d->defaultItemHeight = indexRowSizeHint(insertedItems[0].index); - - int insertPos; - if (lastChildItem < firstChildItem) { // no children - insertPos = firstChildItem; - } else { - // do a binary search to figure out where to insert - QVector<QTreeViewItem>::iterator it; - it = qLowerBound(d->viewItems.begin() + firstChildItem, - d->viewItems.begin() + lastChildItem + 1, - insertedItems.at(0), treeViewItemLessThanInInsert); - insertPos = it - d->viewItems.begin(); - - // update stale model indexes of siblings - for (int item = insertPos; item <= lastChildItem; ) { - Q_ASSERT(d->viewItems.at(item).level == childLevel); - const QModelIndex modelIndex = d->viewItems.at(item).index; - //Q_ASSERT(modelIndex.parent() == parent); - d->viewItems[item].index = d->model->index( - modelIndex.row() + delta, modelIndex.column(), parent); - - if (!d->viewItems[item].index.isValid()) { - // Something really bad is happening, a bad model is - // often the cause. We can't optimize in this case :( - qWarning() << "QTreeView::rowsInserted internal representation of the model has been corrupted, resetting."; - doItemsLayout(); - return; - } - - item += d->viewItems.at(item).total + 1; - } - } - - d->insertViewItems(insertPos, delta, insertedItems.at(0)); - if (delta > 1) { - qCopy(insertedItems.begin() + 1, insertedItems.end(), - d->viewItems.begin() + insertPos + 1); - } - - if (parentItem != -1) - d->viewItems[parentItem].hasChildren = true; - d->updateChildCount(parentItem, delta); - d->doDelayedItemsLayout(); } else if ((parentItem != -1) && d->viewItems.at(parentItem).expanded) { d->doDelayedItemsLayout(); @@ -2547,8 +2470,8 @@ void QTreeView::rowsInserted(const QModelIndex &parent, int start, int end) void QTreeView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) { Q_D(QTreeView); - d->rowsRemoved(parent, start, end, false); QAbstractItemView::rowsAboutToBeRemoved(parent, start, end); + d->viewItems.clear(); } /*! @@ -2560,7 +2483,10 @@ void QTreeView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int e void QTreeView::rowsRemoved(const QModelIndex &parent, int start, int end) { Q_D(QTreeView); - d->rowsRemoved(parent, start, end, true); + d->viewItems.clear(); + d->doDelayedItemsLayout(); + d->hasRemovedItems = true; + d->_q_rowsRemoved(parent, start, end); } /*! @@ -3398,7 +3324,7 @@ int QTreeViewPrivate::viewIndex(const QModelIndex &_index) const const int totalCount = viewItems.count(); const QModelIndex index = _index.sibling(_index.row(), 0); const int row = index.row(); - const quint64 internalId = index.internalId(); + const qint64 internalId = index.internalId(); // We start nearest to the lastViewedItem int localCount = qMin(lastViewedItem - 1, totalCount - lastViewedItem); @@ -3751,118 +3677,6 @@ bool QTreeViewPrivate::hasVisibleChildren(const QModelIndex& parent) const return false; } -void QTreeViewPrivate::rowsRemoved(const QModelIndex &parent, - int start, int end, bool after) -{ - // if we are going to do a complete relayout anyway, there is no need to update - if (delayedPendingLayout) { - _q_rowsRemoved(parent, start, end); - return; - } - - const int parentItem = viewIndex(parent); - if ((parentItem != -1) || (parent == root)) { - - const uint childLevel = (parentItem == -1) - ? uint(0) : viewItems.at(parentItem).level + 1; - Q_UNUSED(childLevel); // unused in release mode, used in assert below - - const int firstChildItem = parentItem + 1; - int lastChildItem = firstChildItem + ((parentItem == -1) - ? viewItems.count() - : viewItems.at(parentItem).total) - 1; - - const int delta = end - start + 1; - - int previousSibiling = -1; - int removedCount = 0; - for (int item = firstChildItem; item <= lastChildItem; ) { - Q_ASSERT(viewItems.at(item).level == childLevel); - const QModelIndex modelIndex = viewItems.at(item).index; - //Q_ASSERT(modelIndex.parent() == parent); - const int count = viewItems.at(item).total + 1; - if (modelIndex.row() < start) { - previousSibiling = item; - // not affected by the removal - item += count; - } else if (modelIndex.row() <= end) { - // removed - removeViewItems(item, count); - removedCount += count; - lastChildItem -= count; - } else { - if (after) { - // moved; update the model index - viewItems[item].index = model->index( - modelIndex.row() - delta, modelIndex.column(), parent); - } - item += count; - } - } - - if (previousSibiling != -1 && after && model->rowCount(parent) == start) - viewItems[previousSibiling].hasMoreSiblings = false; - - if (parentItem != -1) { - if (viewItems.at(parentItem).expanded) { - updateChildCount(parentItem, -removedCount); - if (viewItems.at(parentItem).total == 0) - viewItems[parentItem].hasChildren = false; //every children have been removed; - } else if (viewItems[parentItem].hasChildren && !hasVisibleChildren(parent)) { - viewItems[parentItem].hasChildren = false; - } - } - if (after) { - doDelayedItemsLayout(); - } else { - //we have removed items: we should at least update the scroll bar values. - // They are used to determine the item geometry. - updateScrollBars(); - } - } else { - // If an ancestor of root is removed then relayout - QModelIndex idx = root; - while (idx.isValid()) { - idx = idx.parent(); - if (idx == parent) { - doDelayedItemsLayout(); - break; - } - } - } - _q_rowsRemoved(parent, start, end); - - QSet<QPersistentModelIndex>::iterator it = expandedIndexes.begin(); - while (it != expandedIndexes.constEnd()) { - if (!it->isValid()) - it = expandedIndexes.erase(it); - else - ++it; - } - it = hiddenIndexes.begin(); - while (it != hiddenIndexes.constEnd()) { - if (!it->isValid()) - it = hiddenIndexes.erase(it); - else - ++it; - } -} - -void QTreeViewPrivate::updateChildCount(const int parentItem, const int delta) -{ - if ((parentItem != -1) && delta) { - int level = viewItems.at(parentItem).level; - int item = parentItem; - do { - Q_ASSERT(item >= 0); - for ( ; int(viewItems.at(item).level) != level; --item) ; - viewItems[item].total += delta; - --level; - } while (level >= 0); - } -} - - void QTreeViewPrivate::_q_sortIndicatorChanged(int column, Qt::SortOrder order) { model->sort(column, order); diff --git a/src/gui/itemviews/qtreeview_p.h b/src/gui/itemviews/qtreeview_p.h index 48997b7..261af31 100644 --- a/src/gui/itemviews/qtreeview_p.h +++ b/src/gui/itemviews/qtreeview_p.h @@ -91,7 +91,7 @@ public: expandsOnDoubleClick(true), allColumnsShowFocus(false), current(0), spanning(false), animationsEnabled(false), columnResizeTimerID(0), - autoExpandDelay(-1), hoverBranch(-1), geometryRecursionBlock(false) {} + autoExpandDelay(-1), hoverBranch(-1), geometryRecursionBlock(false), hasRemovedItems(false) {} ~QTreeViewPrivate() {} void initialize(); @@ -165,8 +165,6 @@ public: QPair<int,int> startAndEndColumns(const QRect &rect) const; void updateChildCount(const int parentItem, const int delta); - void rowsRemoved(const QModelIndex &parent, - int start, int end, bool before); void paintAlternatingRowColors(QPainter *painter, QStyleOptionViewItemV4 *option, int y, int bottom) const; @@ -242,6 +240,9 @@ public: // used for blocking recursion when calling setViewportMargins from updateGeometries bool geometryRecursionBlock; + + // If we should clean the set + bool hasRemovedItems; }; QT_END_NAMESPACE diff --git a/src/opengl/qglbuffer.cpp b/src/opengl/qglbuffer.cpp index 7022a53..2ab7c32 100644 --- a/src/opengl/qglbuffer.cpp +++ b/src/opengl/qglbuffer.cpp @@ -369,6 +369,38 @@ void QGLBuffer::release() const glBindBuffer(d->type, 0); } +#undef ctx + +/*! + Binds a raw \a bufferId to the specified buffer \a type + in the current QGLContext. Returns false if there is + no context current or the GL buffer extension could + not be resolved. + + This function is a direct call to \c{glBindBuffer()} for + use when the caller does not have a QGLBuffer but does + have a raw \a bufferId. It can also be used to release + the current buffer when the caller does not know which + QGLBuffer object is currently bound: + + \code + QGLBuffer::bind(QGLBuffer::VertexBuffer, 0); + \endcode +*/ +bool QGLBuffer::bind(QGLBuffer::Type type, uint bufferId) +{ + const QGLContext *ctx = QGLContext::currentContext(); + if (ctx) { + if (qt_resolve_buffer_extensions(const_cast<QGLContext *>(ctx))) { + glBindBuffer(GLenum(type), GLuint(bufferId)); + return true; + } + } + return false; +} + +#define ctx d->guard.context() + /*! Returns the GL identifier associated with this buffer; zero if the buffer has not been created. diff --git a/src/opengl/qglbuffer.h b/src/opengl/qglbuffer.h index ecb86e2..a060733 100644 --- a/src/opengl/qglbuffer.h +++ b/src/opengl/qglbuffer.h @@ -97,6 +97,8 @@ public: bool bind() const; void release() const; + static bool bind(QGLBuffer::Type type, uint bufferId); + uint bufferId() const; int size() const; diff --git a/src/opengl/qpixmapdata_x11gl_egl.cpp b/src/opengl/qpixmapdata_x11gl_egl.cpp index a01eec4..3ab385a 100644 --- a/src/opengl/qpixmapdata_x11gl_egl.cpp +++ b/src/opengl/qpixmapdata_x11gl_egl.cpp @@ -41,19 +41,22 @@ #include <QDebug> -#include <private/qgl_p.h> -#include <private/qegl_p.h> -#include <private/qeglproperties_p.h> -#include <private/qeglcontext_p.h> +#include <QtGui/private/qt_x11_p.h> +#include <QtGui/private/qegl_p.h> +#include <QtGui/private/qeglproperties_p.h> +#include <QtGui/private/qeglcontext_p.h> #if !defined(QT_OPENGL_ES_1) -#include <private/qpaintengineex_opengl2_p.h> +#include <QtOpenGL/private/qpaintengineex_opengl2_p.h> #endif #ifndef QT_OPENGL_ES_2 -#include <private/qpaintengine_opengl_p.h> +#include <QtOpenGL/private/qpaintengine_opengl_p.h> #endif +#include <QtOpenGL/private/qgl_p.h> +#include <QtOpenGL/private/qgl_egl_p.h> + #include "qpixmapdata_x11gl_p.h" QT_BEGIN_NAMESPACE @@ -185,6 +188,60 @@ QX11GLPixmapData::~QX11GLPixmapData() delete ctx; } + +void QX11GLPixmapData::fill(const QColor &color) +{ + if (ctx) { + ctx->makeCurrent(); + glFinish(); + eglWaitClient(); + } + + QX11PixmapData::fill(color); + XSync(X11->display, False); + + if (ctx) { + ctx->makeCurrent(); + eglWaitNative(EGL_CORE_NATIVE_ENGINE); + } +} + +void QX11GLPixmapData::copy(const QPixmapData *data, const QRect &rect) +{ + if (ctx) { + ctx->makeCurrent(); + glFinish(); + eglWaitClient(); + } + + QX11PixmapData::copy(data, rect); + XSync(X11->display, False); + + if (ctx) { + ctx->makeCurrent(); + eglWaitNative(EGL_CORE_NATIVE_ENGINE); + } +} + +bool QX11GLPixmapData::scroll(int dx, int dy, const QRect &rect) +{ + if (ctx) { + ctx->makeCurrent(); + glFinish(); + eglWaitClient(); + } + + bool success = QX11PixmapData::scroll(dx, dy, rect); + XSync(X11->display, False); + + if (ctx) { + ctx->makeCurrent(); + eglWaitNative(EGL_CORE_NATIVE_ENGINE); + } + + return success; +} + #if !defined(QT_OPENGL_ES_1) Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_gl_pixmap_2_engine) #endif @@ -201,6 +258,8 @@ QPaintEngine* QX11GLPixmapData::paintEngine() const ctx = new QGLContext(glFormat()); Q_ASSERT(ctx->d_func()->eglContext == 0); ctx->d_func()->eglContext = hasAlphaChannel() ? argbContext : rgbContext; + // Update the glFormat for the QGLContext: + qt_glformat_from_eglconfig(ctx->d_func()->glFormat, ctx->d_func()->eglContext->config()); } QPaintEngine* engine; @@ -249,6 +308,7 @@ void QX11GLPixmapData::beginPaint() EGLConfig cfg = ctx->d_func()->eglContext->config(); Q_ASSERT(cfg != QEGL_NO_CONFIG); +// qDebug("QX11GLPixmapData - using EGL Config ID %d", ctx->d_func()->eglContext->configAttrib(EGL_CONFIG_ID)); EGLSurface surface = QEgl::createSurface(&tmpPixmap, cfg); if (surface == EGL_NO_SURFACE) { qWarning() << "Error creating EGL surface for pixmap:" << QEgl::errorString(); diff --git a/src/opengl/qpixmapdata_x11gl_p.h b/src/opengl/qpixmapdata_x11gl_p.h index 83cd780..8681336 100644 --- a/src/opengl/qpixmapdata_x11gl_p.h +++ b/src/opengl/qpixmapdata_x11gl_p.h @@ -71,6 +71,11 @@ public: QX11GLPixmapData(); virtual ~QX11GLPixmapData(); + // Re-implemented from QX11PixmapData: + void fill(const QColor &color); + void copy(const QPixmapData *data, const QRect &rect); + bool scroll(int dx, int dy, const QRect &rect); + // Re-implemented from QGLPaintDevice QPaintEngine* paintEngine() const; // Also re-implements QX11PixmapData::paintEngine void beginPaint(); diff --git a/src/opengl/qwindowsurface_x11gl.cpp b/src/opengl/qwindowsurface_x11gl.cpp index 27b91ba..7befe03 100644 --- a/src/opengl/qwindowsurface_x11gl.cpp +++ b/src/opengl/qwindowsurface_x11gl.cpp @@ -51,14 +51,16 @@ QT_BEGIN_NAMESPACE QX11GLWindowSurface::QX11GLWindowSurface(QWidget* window) - : QWindowSurface(window), m_GC(0), m_window(window) + : QWindowSurface(window), m_windowGC(0), m_pixmapGC(0), m_window(window) { } QX11GLWindowSurface::~QX11GLWindowSurface() { - if (m_GC) - XFree(m_GC); + if (m_windowGC) + XFree(m_windowGC); + if (m_pixmapGC) + XFree(m_pixmapGC); } QPaintDevice *QX11GLWindowSurface::paintDevice() @@ -92,16 +94,22 @@ void QX11GLWindowSurface::flush(QWidget *widget, const QRegion &widgetRegion, co // for (int i = 0; i < num; ++i) // qDebug() << ' ' << i << rects[i].x << rects[i].x << rects[i].y << rects[i].width << rects[i].height; - if (m_GC == 0) { - m_GC = XCreateGC(X11->display, m_window->handle(), 0, 0); - XSetGraphicsExposures(X11->display, m_GC, False); + if (m_windowGC == 0) { + m_windowGC = XCreateGC(X11->display, m_window->handle(), 0, 0); + XSetGraphicsExposures(X11->display, m_windowGC, False); } - XSetClipRectangles(X11->display, m_GC, 0, 0, rects, rectCount, YXBanded); - XCopyArea(X11->display, m_backBuffer.handle(), m_window->handle(), m_GC, + XSetClipRectangles(X11->display, m_windowGC, 0, 0, rects, rectCount, YXBanded); + XCopyArea(X11->display, m_backBuffer.handle(), m_window->handle(), m_windowGC, boundingRect.x() + offset.x(), boundingRect.y() + offset.y(), boundingRect.width(), boundingRect.height(), windowBoundingRect.x(), windowBoundingRect.y()); + + QX11GLPixmapData* pmd = static_cast<QX11GLPixmapData*>(m_backBuffer.data_ptr().data()); + Q_ASSERT(pmd->context()); + pmd->context()->makeCurrent(); + XSync(X11->display, False); + eglWaitNative(EGL_CORE_NATIVE_ENGINE); } void QX11GLWindowSurface::setGeometry(const QRect &rect) @@ -113,6 +121,8 @@ void QX11GLWindowSurface::setGeometry(const QRect &rect) QX11GLPixmapData *pd = new QX11GLPixmapData; pd->resize(newSize.width(), newSize.height()); m_backBuffer = QPixmap(pd); + if (window()->testAttribute(Qt::WA_TranslucentBackground)) + m_backBuffer.fill(Qt::transparent); } // if (gc) @@ -124,10 +134,30 @@ void QX11GLWindowSurface::setGeometry(const QRect &rect) bool QX11GLWindowSurface::scroll(const QRegion &area, int dx, int dy) { - Q_UNUSED(area); - Q_UNUSED(dx); - Q_UNUSED(dy); - return false; + if (m_backBuffer.isNull()) + return false; + + Q_ASSERT(m_backBuffer.data_ptr()->classId() == QPixmapData::X11Class); + + QX11GLPixmapData* pmd = static_cast<QX11GLPixmapData*>(m_backBuffer.data_ptr().data()); + Q_ASSERT(pmd->context()); + pmd->context()->makeCurrent(); + glFinish(); + eglWaitClient(); + + if (!m_pixmapGC) + m_pixmapGC = XCreateGC(X11->display, m_backBuffer.handle(), 0, 0); + + foreach (const QRect& rect, area.rects()) { + XCopyArea(X11->display, m_backBuffer.handle(), m_backBuffer.handle(), m_pixmapGC, + rect.x(), rect.y(), rect.width(), rect.height(), + rect.x()+dx, rect.y()+dy); + } + + XSync(X11->display, False); + eglWaitNative(EGL_CORE_NATIVE_ENGINE); + + return true; } /* diff --git a/src/opengl/qwindowsurface_x11gl_p.h b/src/opengl/qwindowsurface_x11gl_p.h index 90f3ad5..3a952e8 100644 --- a/src/opengl/qwindowsurface_x11gl_p.h +++ b/src/opengl/qwindowsurface_x11gl_p.h @@ -70,7 +70,8 @@ public: bool scroll(const QRegion &area, int dx, int dy); private: - GC m_GC; + GC m_windowGC; + GC m_pixmapGC; QPixmap m_backBuffer; QWidget *m_window; }; |