diff --git a/libkwineffects/kwinxrenderutils.cpp b/libkwineffects/kwinxrenderutils.cpp index 835240a235..bae0c21dcb 100644 --- a/libkwineffects/kwinxrenderutils.cpp +++ b/libkwineffects/kwinxrenderutils.cpp @@ -21,8 +21,6 @@ along with this program. If not, see . #include "kwinxrenderutils.h" #include "kwinglobals.h" -#ifdef KWIN_HAVE_XRENDER_COMPOSITING - #include #include #include @@ -263,5 +261,3 @@ QPixmap *xRenderOffscreenTarget() } } // namespace - -#endif diff --git a/libkwineffects/kwinxrenderutils.h b/libkwineffects/kwinxrenderutils.h index 5b7a95326e..9a9a8bc7ee 100644 --- a/libkwineffects/kwinxrenderutils.h +++ b/libkwineffects/kwinxrenderutils.h @@ -23,8 +23,6 @@ along with this program. If not, see . #include -#ifdef KWIN_HAVE_XRENDER_COMPOSITING - #include #include #include @@ -164,8 +162,6 @@ KWIN_EXPORT XRenderPicture *scene_xRenderOffscreenTarget(); } // namespace -#endif - /** @} */ #endif diff --git a/outline.cpp b/outline.cpp index 7819eba969..708ceb42f9 100644 --- a/outline.cpp +++ b/outline.cpp @@ -3,6 +3,7 @@ This file is part of the KDE project. Copyright (C) 2011 Arthur Arlt +Copyright (C) 2013 Martin Gräßlin This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,13 +18,14 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *********************************************************************/ - +// own #include "outline.h" +// KWin #include "effects.h" -#include -#include -#include -#include +// KWin libs +#include +// xcb +#include namespace KWin { @@ -35,12 +37,6 @@ Outline::Outline() Outline::~Outline() { - if (m_initialized) { - XDestroyWindow(QX11Info::display(), m_leftOutline); - XDestroyWindow(QX11Info::display(), m_rightOutline); - XDestroyWindow(QX11Info::display(), m_topOutline); - XDestroyWindow(QX11Info::display(), m_bottomOutline); - } } void Outline::show() @@ -63,7 +59,7 @@ void Outline::hide() static_cast(effects)->slotHideOutline(); return; // done by effect } - hideWithX(); + forEachWindow(&Xcb::Window::unmap); } void Outline::show(const QRect& outlineGeometry) @@ -77,9 +73,9 @@ void Outline::setGeometry(const QRect& outlineGeometry) m_outlineGeometry = outlineGeometry; } -QVector< Window > Outline::windowIds() const +QVector< xcb_window_t > Outline::windowIds() const { - QVector windows; + QVector windows; if (m_initialized) { windows.reserve(4); windows << m_leftOutline << m_topOutline << m_rightOutline << m_bottomOutline; @@ -90,113 +86,114 @@ QVector< Window > Outline::windowIds() const void Outline::showWithX() { if (!m_initialized) { - XSetWindowAttributes attr; - attr.override_redirect = 1; - m_leftOutline = XCreateWindow(QX11Info::display(), QX11Info::appRootWindow(), 0, 0, 1, 1, 0, - CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attr); - m_rightOutline = XCreateWindow(QX11Info::display(), QX11Info::appRootWindow(), 0, 0, 1, 1, 0, - CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attr); - m_topOutline = XCreateWindow(QX11Info::display(), QX11Info::appRootWindow(), 0, 0, 1, 1, 0, - CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attr); - m_bottomOutline = XCreateWindow(QX11Info::display(), QX11Info::appRootWindow(), 0, 0, 1, 1, 0, - CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attr); - m_initialized = true; + const QRect geo(0, 0, 1, 1); + const uint32_t values[] = {true}; + // TODO: use template variant + m_leftOutline.create(geo, XCB_CW_OVERRIDE_REDIRECT, values); + m_rightOutline.create(geo, XCB_CW_OVERRIDE_REDIRECT, values); + m_topOutline.create(geo, XCB_CW_OVERRIDE_REDIRECT, values); + m_bottomOutline.create(geo, XCB_CW_OVERRIDE_REDIRECT, values); + m_initialized = true; } - int defaultDepth = XDefaultDepth(QX11Info::display(), QX11Info::appScreen()); + int screen = QX11Info::appScreen(); + int defaultDepth = 0; + // TODO: move into xcbutils or maybe kwinglobals + for (xcb_screen_iterator_t it = xcb_setup_roots_iterator(xcb_get_setup(connection())); + it.rem; + --screen, xcb_screen_next(&it)) { + if (screen == 0) { + defaultDepth = it.data->root_depth; + break; + } + } // left/right parts are between top/bottom, they don't reach as far as the corners - XMoveResizeWindow(QX11Info::display(), m_leftOutline, m_outlineGeometry.x(), m_outlineGeometry.y() + 5, 5, m_outlineGeometry.height() - 10); - XMoveResizeWindow(QX11Info::display(), m_rightOutline, m_outlineGeometry.x() + m_outlineGeometry.width() - 5, m_outlineGeometry.y() + 5, 5, m_outlineGeometry.height() - 10); - XMoveResizeWindow(QX11Info::display(), m_topOutline, m_outlineGeometry.x(), m_outlineGeometry.y(), m_outlineGeometry.width(), 5); - XMoveResizeWindow(QX11Info::display(), m_bottomOutline, m_outlineGeometry.x(), m_outlineGeometry.y() + m_outlineGeometry.height() - 5, m_outlineGeometry.width(), 5); - { - Pixmap xpix = XCreatePixmap(display(), rootWindow(), 5, - m_outlineGeometry.height() - 10, defaultDepth); - QPixmap pix = QPixmap::fromX11Pixmap(xpix, QPixmap::ExplicitlyShared); - QPainter p(&pix); - p.setPen(Qt::white); - p.drawLine(0, 0, 0, pix.height() - 1); - p.drawLine(4, 0, 4, pix.height() - 1); - p.setPen(Qt::gray); - p.drawLine(1, 0, 1, pix.height() - 1); - p.drawLine(3, 0, 3, pix.height() - 1); - p.setPen(Qt::black); - p.drawLine(2, 0, 2, pix.height() - 1); - p.end(); - XSetWindowBackgroundPixmap(QX11Info::display(), m_leftOutline, pix.handle()); - XSetWindowBackgroundPixmap(QX11Info::display(), m_rightOutline, pix.handle()); - // According to the XSetWindowBackgroundPixmap documentation the pixmap can be freed. - XFreePixmap (display(), xpix); - } - { - Pixmap xpix = XCreatePixmap(display(), rootWindow(), m_outlineGeometry.width(), - 5, defaultDepth); - QPixmap pix = QPixmap::fromX11Pixmap(xpix, QPixmap::ExplicitlyShared); - QPainter p(&pix); - p.setPen(Qt::white); - p.drawLine(0, 0, pix.width() - 1 - 0, 0); - p.drawLine(4, 4, pix.width() - 1 - 4, 4); - p.drawLine(0, 0, 0, 4); - p.drawLine(pix.width() - 1 - 0, 0, pix.width() - 1 - 0, 4); - p.setPen(Qt::gray); - p.drawLine(1, 1, pix.width() - 1 - 1, 1); - p.drawLine(3, 3, pix.width() - 1 - 3, 3); - p.drawLine(1, 1, 1, 4); - p.drawLine(3, 3, 3, 4); - p.drawLine(pix.width() - 1 - 1, 1, pix.width() - 1 - 1, 4); - p.drawLine(pix.width() - 1 - 3, 3, pix.width() - 1 - 3, 4); - p.setPen(Qt::black); - p.drawLine(2, 2, pix.width() - 1 - 2, 2); - p.drawLine(2, 2, 2, 4); - p.drawLine(pix.width() - 1 - 2, 2, pix.width() - 1 - 2, 4); - p.end(); - XSetWindowBackgroundPixmap(QX11Info::display(), m_topOutline, pix.handle()); - // According to the XSetWindowBackgroundPixmap documentation the pixmap can be freed. - XFreePixmap (display(), xpix); - } - { - Pixmap xpix = XCreatePixmap(display(), rootWindow(), m_outlineGeometry.width(), - 5, defaultDepth); - QPixmap pix = QPixmap::fromX11Pixmap(xpix, QPixmap::ExplicitlyShared); - QPainter p(&pix); - p.setPen(Qt::white); - p.drawLine(4, 0, pix.width() - 1 - 4, 0); - p.drawLine(0, 4, pix.width() - 1 - 0, 4); - p.drawLine(0, 4, 0, 0); - p.drawLine(pix.width() - 1 - 0, 4, pix.width() - 1 - 0, 0); - p.setPen(Qt::gray); - p.drawLine(3, 1, pix.width() - 1 - 3, 1); - p.drawLine(1, 3, pix.width() - 1 - 1, 3); - p.drawLine(3, 1, 3, 0); - p.drawLine(1, 3, 1, 0); - p.drawLine(pix.width() - 1 - 3, 1, pix.width() - 1 - 3, 0); - p.drawLine(pix.width() - 1 - 1, 3, pix.width() - 1 - 1, 0); - p.setPen(Qt::black); - p.drawLine(2, 2, pix.width() - 1 - 2, 2); - p.drawLine(2, 0, 2, 2); - p.drawLine(pix.width() - 1 - 2, 0, pix.width() - 1 - 2, 2); - p.end(); - XSetWindowBackgroundPixmap(QX11Info::display(), m_bottomOutline, pix.handle()); - // According to the XSetWindowBackgroundPixmap documentation the pixmap can be freed. - XFreePixmap (display(), xpix); - } - XClearWindow(QX11Info::display(), m_leftOutline); - XClearWindow(QX11Info::display(), m_rightOutline); - XClearWindow(QX11Info::display(), m_topOutline); - XClearWindow(QX11Info::display(), m_bottomOutline); - XMapWindow(QX11Info::display(), m_leftOutline); - XMapWindow(QX11Info::display(), m_rightOutline); - XMapWindow(QX11Info::display(), m_topOutline); - XMapWindow(QX11Info::display(), m_bottomOutline); -} + const uint16_t verticalWidth = 5; + const uint16_t verticalHeight = m_outlineGeometry.height() - 10; + const uint16_t horizontalWidth = m_outlineGeometry.width(); + const uint horizontalHeight = 5; + m_leftOutline.setGeometry(m_outlineGeometry.x(), m_outlineGeometry.y() + 5, verticalWidth, verticalHeight); + m_rightOutline.setGeometry(m_outlineGeometry.x() + m_outlineGeometry.width() - 5, m_outlineGeometry.y() + 5, verticalWidth, verticalHeight); + m_topOutline.setGeometry(m_outlineGeometry.x(), m_outlineGeometry.y(), horizontalWidth, horizontalHeight); + m_bottomOutline.setGeometry(m_outlineGeometry.x(), m_outlineGeometry.y() + m_outlineGeometry.height() - 5, horizontalWidth, horizontalHeight); -void Outline::hideWithX() -{ - XUnmapWindow(QX11Info::display(), m_leftOutline); - XUnmapWindow(QX11Info::display(), m_rightOutline); - XUnmapWindow(QX11Info::display(), m_topOutline); - XUnmapWindow(QX11Info::display(), m_bottomOutline); + const xcb_render_color_t white = {0xffff, 0xffff, 0xffff, 0xffff}; + QColor qGray(Qt::gray); + const xcb_render_color_t gray = { + uint16_t(0xffff * qGray.redF()), + uint16_t(0xffff * qGray.greenF()), + uint16_t(0xffff * qGray.blueF()), + 0xffff + }; + const xcb_render_color_t black = {0, 0, 0, 0xffff}; + { + xcb_pixmap_t xpix = xcb_generate_id(connection()); + xcb_create_pixmap(connection(), defaultDepth, xpix, rootWindow(), verticalWidth, verticalHeight); + XRenderPicture pic(xpix, defaultDepth); + + xcb_rectangle_t rect = {0, 0, 5, verticalHeight}; + xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_SRC, pic, white, 1, &rect); + rect.x = 1; + rect.width = 3; + xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_SRC, pic, gray, 1, &rect); + rect.x = 2; + rect.width = 1; + xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_SRC, pic, black, 1, &rect); + + m_leftOutline.setBackgroundPixmap(xpix); + m_rightOutline.setBackgroundPixmap(xpix); + // According to the XSetWindowBackgroundPixmap documentation the pixmap can be freed. + xcb_free_pixmap(connection(), xpix); + } + { + xcb_pixmap_t xpix = xcb_generate_id(connection()); + xcb_create_pixmap(connection(), defaultDepth, xpix, rootWindow(), horizontalWidth, horizontalHeight); + XRenderPicture pic(xpix, defaultDepth); + + xcb_rectangle_t rect = {0, 0, horizontalWidth, horizontalHeight}; + xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_SRC, pic, white, 1, &rect); + xcb_rectangle_t grayRects[] = { + {1, 1, uint16_t(horizontalWidth -2), 3}, + {1, 4, 3, 1}, + {int16_t(horizontalWidth - 4), 4, 3, 1} + }; + xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_SRC, pic, gray, 3, grayRects); + xcb_rectangle_t blackRects[] = { + {2, 2, uint16_t(horizontalWidth -4), 1}, + {2, 3, 1, 2}, + {int16_t(horizontalWidth - 3), 3, 1, 2} + }; + xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_SRC, pic, black, 3, blackRects); + m_topOutline.setBackgroundPixmap(xpix); + // According to the XSetWindowBackgroundPixmap documentation the pixmap can be freed. + xcb_free_pixmap(connection(), xpix); + } + { + xcb_pixmap_t xpix = xcb_generate_id(connection()); + xcb_create_pixmap(connection(), defaultDepth, xpix, rootWindow(), m_outlineGeometry.width(), 5); + XRenderPicture pic(xpix, defaultDepth); + + xcb_rectangle_t rect = {0, 0, horizontalWidth, horizontalHeight}; + xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_SRC, pic, white, 1, &rect); + xcb_rectangle_t grayRects[] = { + {1, 1, uint16_t(horizontalWidth -2), 3}, + {1, 0, 3, 1}, + {int16_t(horizontalWidth - 4), 0, 3, 1} + }; + xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_SRC, pic, gray, 3, grayRects); + xcb_rectangle_t blackRects[] = { + {2, 2, uint16_t(horizontalWidth -4), 1}, + {2, 0, 1, 2}, + {int16_t(horizontalWidth - 3), 0, 1, 2} + }; + xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_SRC, pic, black, 3, blackRects); + m_bottomOutline.setBackgroundPixmap(xpix); + // According to the XSetWindowBackgroundPixmap documentation the pixmap can be freed. + xcb_free_pixmap(connection(), xpix); + } + forEachWindow(&Xcb::Window::clear); + forEachWindow(&Xcb::Window::map); } } // namespace diff --git a/outline.h b/outline.h index 20e7a8668b..81b1abd3bb 100644 --- a/outline.h +++ b/outline.h @@ -20,8 +20,7 @@ along with this program. If not, see . #ifndef KWIN_OUTLINE_H #define KWIN_OUTLINE_H -#include -#include +#include "xcbutils.h" #include #include @@ -77,7 +76,7 @@ public: * Return outline window ids * @return The window ids created to represent the outline */ - QVector windowIds() const; + QVector windowIds() const; private: /** @@ -85,20 +84,29 @@ private: */ void showWithX(); - /** - * Hide previously shown outline used the X implementation - */ - void hideWithX(); + // TODO: variadic template arguments for adding method arguments + template + void forEachWindow(T method); - Window m_topOutline; - Window m_rightOutline; - Window m_bottomOutline; - Window m_leftOutline; + Xcb::Window m_topOutline; + Xcb::Window m_rightOutline; + Xcb::Window m_bottomOutline; + Xcb::Window m_leftOutline; QRect m_outlineGeometry; bool m_initialized; bool m_active; }; +template +inline +void Outline::forEachWindow(T method) +{ + (m_topOutline.*method)(); + (m_rightOutline.*method)(); + (m_bottomOutline.*method)(); + (m_leftOutline.*method)(); +} + } #endif diff --git a/tabbox/tabbox.cpp b/tabbox/tabbox.cpp index 8a3b364b0b..cb2120f53f 100644 --- a/tabbox/tabbox.cpp +++ b/tabbox/tabbox.cpp @@ -326,7 +326,7 @@ void TabBoxHandlerImpl::hideOutline() Workspace::self()->outline()->hide(); } -QVector< Window > TabBoxHandlerImpl::outlineWindowIds() const +QVector< xcb_window_t > TabBoxHandlerImpl::outlineWindowIds() const { return Workspace::self()->outline()->windowIds(); } diff --git a/tabbox/tabbox.h b/tabbox/tabbox.h index a17494456d..1a54a96158 100644 --- a/tabbox/tabbox.h +++ b/tabbox/tabbox.h @@ -64,7 +64,7 @@ public: virtual QWeakPointer< TabBoxClient > desktopClient() const; virtual void hideOutline(); virtual void showOutline(const QRect &outline); - virtual QVector< Window > outlineWindowIds() const; + virtual QVector< xcb_window_t > outlineWindowIds() const; virtual void activateAndClose(); private: diff --git a/tabbox/tabboxhandler.cpp b/tabbox/tabboxhandler.cpp index ad3919aa03..d84d2d338f 100644 --- a/tabbox/tabboxhandler.cpp +++ b/tabbox/tabboxhandler.cpp @@ -186,7 +186,7 @@ void TabBoxHandlerPrivate::updateHighlightWindows() } data[ 0 ] = currentClient ? currentClient->window() : 0L; if (config.isShowOutline()) { - QVector outlineWindows = q->outlineWindowIds(); + QVector outlineWindows = q->outlineWindowIds(); data.resize(2+outlineWindows.size()); for (int i=0; i. #include #include #include +#include /** * @file @@ -351,7 +352,7 @@ protected: * @return The outline window ids given in the order left, top, right, bottom * @since 4.7 **/ - virtual QVector outlineWindowIds() const = 0; + virtual QVector outlineWindowIds() const = 0; signals: /** diff --git a/tabbox/tests/mock_tabboxhandler.h b/tabbox/tests/mock_tabboxhandler.h index 5578001a01..78ee542bf1 100644 --- a/tabbox/tests/mock_tabboxhandler.h +++ b/tabbox/tests/mock_tabboxhandler.h @@ -68,8 +68,8 @@ public: virtual int numberOfDesktops() const { return 1; } - virtual QVector< Window > outlineWindowIds() const { - return QVector(); + virtual QVector< xcb_window_t > outlineWindowIds() const { + return QVector(); } virtual void raiseClient(TabBox::TabBoxClient *c) const { Q_UNUSED(c)