diff --git a/client.cpp b/client.cpp index 5a76c25185..e8e20d5ba2 100644 --- a/client.cpp +++ b/client.cpp @@ -371,6 +371,9 @@ void Client::updateInputWindow() if (brokenQtInputHandling) return; + if (!Xcb::Extensions::self()->isShapeInputAvailable()) + return; + QRegion region; if (!noBorder()) { diff --git a/composite.cpp b/composite.cpp index 097d08500f..de674b6c91 100644 --- a/composite.cpp +++ b/composite.cpp @@ -989,7 +989,7 @@ void Toplevel::addDamageFull() return; damage_region = rect(); - repaints_region = rect(); + repaints_region |= rect(); emit damaged(this, rect()); } diff --git a/effects/invert/invert.cpp b/effects/invert/invert.cpp index c412e31644..291aa6b017 100644 --- a/effects/invert/invert.cpp +++ b/effects/invert/invert.cpp @@ -56,6 +56,7 @@ InvertEffect::InvertEffect() b->setGlobalShortcut(KShortcut(Qt::CTRL + Qt::META + Qt::Key_U)); connect(b, SIGNAL(triggered(bool)), this, SLOT(toggleWindow())); connect(effects, SIGNAL(windowClosed(KWin::EffectWindow*)), this, SLOT(slotWindowClosed(KWin::EffectWindow*))); + connect(effects, SIGNAL(screenGeometryChanged(const QSize&)), this, SLOT(resetShader())); } InvertEffect::~InvertEffect() @@ -175,6 +176,11 @@ bool InvertEffect::provides(Feature f) return f == ScreenInversion; } +void InvertEffect::resetShader() +{ + ShaderManager::instance()->resetShader(m_shader, ShaderManager::GenericShader); +} + } // namespace #include "invert.moc" diff --git a/effects/invert/invert.h b/effects/invert/invert.h index 908eef4aff..ef6cd91424 100644 --- a/effects/invert/invert.h +++ b/effects/invert/invert.h @@ -54,6 +54,9 @@ public slots: void toggleWindow(); void slotWindowClosed(KWin::EffectWindow *w); +private Q_SLOTS: + void resetShader(); + protected: bool loadData(); diff --git a/effects/windowgeometry/windowgeometry.cpp b/effects/windowgeometry/windowgeometry.cpp index fca5bda351..5f3176f1eb 100644 --- a/effects/windowgeometry/windowgeometry.cpp +++ b/effects/windowgeometry/windowgeometry.cpp @@ -150,8 +150,15 @@ void WindowGeometry::slotWindowStepUserMovedResized(EffectWindow *w, const QRect myExtraDirtyArea = QRect(); myCurrentGeometry = geometry; + QPoint center = geometry.center(); const QRect &r = geometry; const QRect &r2 = myOriginalGeometry; + const QRect screen = effects->clientArea(ScreenArea, center, w->desktop()); + QRect expandedGeometry = w->expandedGeometry(); + expandedGeometry = geometry.adjusted(expandedGeometry.x() - w->x(), + expandedGeometry.y() - w->y(), + expandedGeometry.right() - w->geometry().right(), + expandedGeometry.bottom() - w->geometry().bottom()); // sufficient for moves, resizes calculated otherwise int dx = r.x() - r2.x(); @@ -162,7 +169,9 @@ void WindowGeometry::slotWindowStepUserMovedResized(EffectWindow *w, const QRect myMeasure[0]->setText( i18nc(myCoordString_1, r.x(), r.y(), number(dx), number(dy) ) ); else myMeasure[0]->setText( i18nc(myCoordString_0, r.x(), r.y() ) ); - myMeasure[0]->setPosition(w->expandedGeometry().topLeft() + QPoint(6,6)); // "6" is magic number because the unstyled effectframe has 5px padding + QPoint pos = expandedGeometry.topLeft(); + pos = QPoint(qMax(pos.x(), screen.x()), qMax(pos.y(), screen.y())); + myMeasure[0]->setPosition(pos + QPoint(6,6)); // "6" is magic number because the unstyled effectframe has 5px padding // center ---------------------- if (w->isUserResize()) { @@ -183,15 +192,22 @@ void WindowGeometry::slotWindowStepUserMovedResized(EffectWindow *w, const QRect dy = r.bottom() - r2.bottom(); } else myMeasure[1]->setText( i18nc(myCoordString_0, number(dx), number(dy) ) ); - - myMeasure[1]->setPosition(geometry.center()); + const int cdx = myMeasure[1]->geometry().width() / 2 + 3; // "3" = 6/2 is magic number because + const int cdy = myMeasure[1]->geometry().height() / 2 + 3; // the unstyled effectframe has 5px padding + center = QPoint(qMax(center.x(), screen.x() + cdx), + qMax(center.y(), screen.y() + cdy)); + center = QPoint(qMin(center.x(), screen.right() - cdx), + qMin(center.y(), screen.bottom() - cdy)); + myMeasure[1]->setPosition(center); // lower right ---------------------- if (w->isUserResize()) myMeasure[2]->setText( i18nc(myCoordString_1, r.right(), r.bottom(), number(dx), number(dy) ) ); else myMeasure[2]->setText( i18nc(myCoordString_0, r.right(), r.bottom() ) ); - myMeasure[2]->setPosition(w->expandedGeometry().bottomRight() - QPoint(6,6)); // "6" is magic number because the unstyled effectframe has 5px padding + pos = expandedGeometry.bottomRight(); + pos = QPoint(qMin(pos.x(), screen.right()), qMin(pos.y(), screen.bottom())); + myMeasure[2]->setPosition(pos - QPoint(6,6)); // "6" is magic number because the unstyled effectframe has 5px padding myExtraDirtyArea |= myMeasure[0]->geometry(); myExtraDirtyArea |= myMeasure[1]->geometry(); diff --git a/events.cpp b/events.cpp index 904811864b..1e8ba5008f 100644 --- a/events.cpp +++ b/events.cpp @@ -1521,6 +1521,7 @@ void Unmanaged::configureNotifyEvent(XConfigureEvent* e) addWorkspaceRepaint(visibleRect()); // damage old area QRect old = geom; geom = newgeom; + emit geometryChanged(); // update shadow region addRepaintFull(); if (old.size() != geom.size()) discardWindowPixmap(); diff --git a/libkwineffects/kwingltexture.cpp b/libkwineffects/kwingltexture.cpp index f6082d88f8..7423ed4a74 100644 --- a/libkwineffects/kwingltexture.cpp +++ b/libkwineffects/kwingltexture.cpp @@ -46,7 +46,10 @@ namespace KWin bool GLTexturePrivate::sNPOTTextureSupported = false; bool GLTexturePrivate::sFramebufferObjectSupported = false; bool GLTexturePrivate::sSaturationSupported = false; -bool GLTexturePrivate::sTextureFormatBGRA = false; +GLenum GLTexturePrivate::sTextureFormat = GL_RGBA; // custom dummy, GL_BGRA is not present on GLES +uint GLTexturePrivate::s_textureObjectCounter = 0; +uint GLTexturePrivate::s_fbo = 0; + GLTexture::GLTexture() : d_ptr(new GLTexturePrivate()) @@ -97,11 +100,8 @@ GLTexture::GLTexture(int width, int height) glGenTextures(1, &d->m_texture); bind(); #ifdef KWIN_HAVE_OPENGLES - if (GLTexturePrivate::sTextureFormatBGRA) { - glTexImage2D(d->m_target, 0, GL_BGRA_EXT, width, height, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, 0); - } else { - glTexImage2D(d->m_target, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - } + glTexImage2D(d->m_target, 0, GLTexturePrivate::sTextureFormat, width, height, + 0, GLTexturePrivate::sTextureFormat, GL_UNSIGNED_BYTE, 0); #else glTexImage2D(d->m_target, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, 0); #endif @@ -133,6 +133,7 @@ GLTexturePrivate::GLTexturePrivate() m_vbo = 0; m_filterChanged = true; m_wrapModeChanged = false; + ++s_textureObjectCounter; } GLTexturePrivate::~GLTexturePrivate() @@ -143,6 +144,11 @@ GLTexturePrivate::~GLTexturePrivate() if (m_texture != 0) { glDeleteTextures(1, &m_texture); } + // Delete the FBO if this is the last Texture + if (--s_textureObjectCounter == 0 && s_fbo) { + glDeleteFramebuffers(1, &s_fbo); + s_fbo = 0; + } } void GLTexturePrivate::initStatic() @@ -151,14 +157,17 @@ void GLTexturePrivate::initStatic() sNPOTTextureSupported = true; sFramebufferObjectSupported = true; sSaturationSupported = true; - sTextureFormatBGRA = hasGLExtension("GL_EXT_texture_format_BGRA8888"); + if (hasGLExtension("GL_EXT_texture_format_BGRA8888")) + sTextureFormat = GL_BGRA_EXT; + else + sTextureFormat = GL_RGBA; #else sNPOTTextureSupported = hasGLExtension("GL_ARB_texture_non_power_of_two"); sFramebufferObjectSupported = hasGLExtension("GL_EXT_framebuffer_object"); sSaturationSupported = ((hasGLExtension("GL_ARB_texture_env_crossbar") && hasGLExtension("GL_ARB_texture_env_dot3")) || hasGLVersion(1, 4)) && (glTextureUnitsCount >= 4) && glActiveTexture != NULL; - sTextureFormatBGRA = true; + sTextureFormat = GL_BGRA; #endif } @@ -215,11 +224,8 @@ bool GLTexture::load(const QImage& image, GLenum target) } bind(); #ifdef KWIN_HAVE_OPENGLES - if (GLTexturePrivate::sTextureFormatBGRA) { - glTexImage2D(d->m_target, 0, GL_BGRA_EXT, img.width(), img.height(), 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, img.bits()); - } else { - glTexImage2D(d->m_target, 0, GL_RGBA, img.width(), img.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); - } + glTexImage2D(d->m_target, 0, GLTexturePrivate::sTextureFormat, img.width(), img.height(), + 0, GLTexturePrivate::sTextureFormat, GL_UNSIGNED_BYTE, img.bits()); #else glTexImage2D(d->m_target, 0, GL_RGBA8, img.width(), img.height(), 0, GL_BGRA, GL_UNSIGNED_BYTE, img.bits()); @@ -258,15 +264,8 @@ void GLTexture::update(const QImage &image, const QPoint &offset, const QRect &s const QImage &img = d->convertToGLFormat(tmpImage.isNull() ? image : tmpImage); bind(); -#ifdef KWIN_HAVE_OPENGLES - if (GLTexturePrivate::sTextureFormatBGRA) { - glTexSubImage2D(d->m_target, 0, offset.x(), offset.y(), width, height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, img.bits()); - } else { - glTexSubImage2D(d->m_target, 0, offset.x(), offset.y(), width, height, GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); - } -#else - glTexSubImage2D(d->m_target, 0, offset.x(), offset.y(), width, height, GL_BGRA, GL_UNSIGNED_BYTE, img.bits()); -#endif + glTexSubImage2D(d->m_target, 0, offset.x(), offset.y(), width, height, + GLTexturePrivate::sTextureFormat, GL_UNSIGNED_BYTE, img.bits()); checkGLError("update texture"); unbind(); setDirty(); @@ -428,6 +427,33 @@ GLenum GLTexture::filter() const return d->m_filter; } +void GLTexture::clear() +{ + Q_D(GLTexture); + if (!GLTexturePrivate::s_fbo && GLRenderTarget::supported() && + GLPlatform::instance()->driver() != Driver_Catalyst) // fail. -> bug #323065 + glGenFramebuffers(1, &GLTexturePrivate::s_fbo); + + if (GLTexturePrivate::s_fbo) { + // Clear the texture + glBindFramebuffer(GL_FRAMEBUFFER, GLTexturePrivate::s_fbo); + glClearColor(0, 0, 0, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, d->m_texture, 0); + glClear(GL_COLOR_BUFFER_BIT); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + } else { + if (const int size = width()*height()) { + uint32_t *buffer = new uint32_t[size]; + memset(buffer, 0, size*sizeof(uint32_t)); + bind(); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width(), height(), + GLTexturePrivate::sTextureFormat, GL_UNSIGNED_BYTE, buffer); + unbind(); + delete[] buffer; + } + } +} + bool GLTexture::isDirty() const { Q_D(const GLTexture); @@ -470,7 +496,7 @@ QImage GLTexturePrivate::convertToGLFormat(const QImage& img) const // Copied from Qt's QGLWidget::convertToGLFormat() QImage res; - if (sTextureFormatBGRA) { + if (sTextureFormat != GL_RGBA) { if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { res = QImage(img.size(), QImage::Format_ARGB32); QImage imgARGB32 = img.convertToFormat(QImage::Format_ARGB32_Premultiplied); diff --git a/libkwineffects/kwingltexture.h b/libkwineffects/kwingltexture.h index 18e0a80081..200d24f322 100644 --- a/libkwineffects/kwingltexture.h +++ b/libkwineffects/kwingltexture.h @@ -93,6 +93,11 @@ public: GLuint texture() const; GLenum target() const; GLenum filter() const; + /** @short + * Make the texture fully transparent + * Warning: this clobbers the current framebuffer binding except on fglrx + */ + void clear(); bool isDirty() const; void setFilter(GLenum filter); void setWrapMode(GLenum mode); diff --git a/libkwineffects/kwingltexture_p.h b/libkwineffects/kwingltexture_p.h index 2afc9aa7a4..0b57d9742b 100644 --- a/libkwineffects/kwingltexture_p.h +++ b/libkwineffects/kwingltexture_p.h @@ -73,7 +73,9 @@ public: static bool sNPOTTextureSupported; static bool sFramebufferObjectSupported; static bool sSaturationSupported; - static bool sTextureFormatBGRA; + static GLenum sTextureFormat; + static uint s_fbo; + static uint s_textureObjectCounter; private: Q_DISABLE_COPY(GLTexturePrivate) }; diff --git a/paintredirector.cpp b/paintredirector.cpp index 982ab6f58b..528827ea53 100644 --- a/paintredirector.cpp +++ b/paintredirector.cpp @@ -28,6 +28,7 @@ DEALINGS IN THE SOFTWARE. #include "client.h" #include "deleted.h" #include "effects.h" +#include #include #include #include @@ -310,21 +311,12 @@ void ImageBasedPaintRedirector::discardScratch() // ------------------------------------------------------------------ - -unsigned int OpenGLPaintRedirector::s_count = 0; -unsigned int OpenGLPaintRedirector::s_fbo = 0; - OpenGLPaintRedirector::OpenGLPaintRedirector(Client *c, QWidget *widget) : ImageBasedPaintRedirector(c, widget) { - s_count++; - for (int i = 0; i < TextureCount; ++i) m_textures[i] = NULL; - if (!s_fbo && GLRenderTarget::supported()) - glGenFramebuffers(1, &s_fbo); - PaintRedirector::resizePixmaps(); } @@ -332,12 +324,6 @@ OpenGLPaintRedirector::~OpenGLPaintRedirector() { for (int i = 0; i < TextureCount; ++i) delete m_textures[i]; - - // Delete the FBO if this is the last OpenGLPaintRedirector - if (--s_count == 0 && s_fbo) { - glDeleteFramebuffers(1, &s_fbo); - s_fbo = 0; - } } void OpenGLPaintRedirector::resizePixmaps(const QRect *rects) @@ -355,8 +341,6 @@ void OpenGLPaintRedirector::resizePixmaps(const QRect *rects) } } - bool fbo_bound = false; - for (int i = 0; i < 2; i++) { if (m_textures[i] && m_textures[i]->size() == size[i]) continue; @@ -370,22 +354,8 @@ void OpenGLPaintRedirector::resizePixmaps(const QRect *rects) m_textures[i] = new GLTexture(size[i].width(), size[i].height()); m_textures[i]->setYInverted(true); m_textures[i]->setWrapMode(GL_CLAMP_TO_EDGE); - - if (s_fbo) { - // Clear the texture - if (!fbo_bound) { - glBindFramebuffer(GL_FRAMEBUFFER, s_fbo); - glClearColor(0, 0, 0, 0); - fbo_bound = true; - } - - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_textures[i]->texture(), 0); - glClear(GL_COLOR_BUFFER_BIT); - } + m_textures[i]->clear(); } - - if (fbo_bound) - glBindFramebuffer(GL_FRAMEBUFFER, 0); } void OpenGLPaintRedirector::preparePaint(const QPixmap &pending) diff --git a/paintredirector.h b/paintredirector.h index fbc53042c5..be96f051e6 100644 --- a/paintredirector.h +++ b/paintredirector.h @@ -157,9 +157,6 @@ protected: private: QImage m_tempImage; GLTexture *m_textures[2]; - - static unsigned int s_fbo; - static unsigned int s_count; }; class NativeXRenderPaintRedirector : public PaintRedirector diff --git a/xcbutils.h b/xcbutils.h index 1a4befd751..fca15f849d 100644 --- a/xcbutils.h +++ b/xcbutils.h @@ -197,7 +197,7 @@ inline xcb_get_input_focus_cookie_t get_input_focus(xcb_connection_t *c, xcb_win class CurrentInput : public Wrapper { public: - CurrentInput() : Wrapper() {} + CurrentInput() : Wrapper(XCB_WINDOW_NONE) {} inline xcb_window_t window() { if (isNull())