File indexing completed on 2024-11-10 04:57:17
0001 /* 0002 KWin - the KDE window manager 0003 This file is part of the KDE project. 0004 0005 SPDX-FileCopyrightText: 2013 Martin Gräßlin <mgraesslin@kde.org> 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 #include "workspacescene_qpainter.h" 0010 // KWin 0011 #include "decorations/decoratedclient.h" 0012 #include "scene/itemrenderer_qpainter.h" 0013 #include "window.h" 0014 0015 // Qt 0016 #include <KDecoration2/Decoration> 0017 #include <QDebug> 0018 #include <QPainter> 0019 0020 #include <cmath> 0021 0022 namespace KWin 0023 { 0024 0025 //**************************************** 0026 // SceneQPainter 0027 //**************************************** 0028 0029 WorkspaceSceneQPainter::WorkspaceSceneQPainter(QPainterBackend *backend) 0030 : WorkspaceScene(std::make_unique<ItemRendererQPainter>()) 0031 , m_backend(backend) 0032 { 0033 } 0034 0035 WorkspaceSceneQPainter::~WorkspaceSceneQPainter() 0036 { 0037 } 0038 0039 std::unique_ptr<DecorationRenderer> WorkspaceSceneQPainter::createDecorationRenderer(Decoration::DecoratedClientImpl *impl) 0040 { 0041 return std::make_unique<SceneQPainterDecorationRenderer>(impl); 0042 } 0043 0044 std::unique_ptr<ShadowTextureProvider> WorkspaceSceneQPainter::createShadowTextureProvider(Shadow *shadow) 0045 { 0046 return std::make_unique<QPainterShadowTextureProvider>(shadow); 0047 } 0048 0049 //**************************************** 0050 // QPainterShadow 0051 //**************************************** 0052 QPainterShadowTextureProvider::QPainterShadowTextureProvider(Shadow *shadow) 0053 : ShadowTextureProvider(shadow) 0054 { 0055 } 0056 0057 void QPainterShadowTextureProvider::update() 0058 { 0059 } 0060 0061 //**************************************** 0062 // QPainterDecorationRenderer 0063 //**************************************** 0064 SceneQPainterDecorationRenderer::SceneQPainterDecorationRenderer(Decoration::DecoratedClientImpl *client) 0065 : DecorationRenderer(client) 0066 { 0067 } 0068 0069 QImage SceneQPainterDecorationRenderer::image(SceneQPainterDecorationRenderer::DecorationPart part) const 0070 { 0071 Q_ASSERT(part != DecorationPart::Count); 0072 return m_images[int(part)]; 0073 } 0074 0075 void SceneQPainterDecorationRenderer::render(const QRegion ®ion) 0076 { 0077 if (areImageSizesDirty()) { 0078 resizeImages(); 0079 resetImageSizesDirty(); 0080 } 0081 0082 auto imageSize = [this](DecorationPart part) { 0083 return m_images[int(part)].size() / m_images[int(part)].devicePixelRatio(); 0084 }; 0085 0086 const QRect top(QPoint(0, 0), imageSize(DecorationPart::Top)); 0087 const QRect left(QPoint(0, top.height()), imageSize(DecorationPart::Left)); 0088 const QRect right(QPoint(top.width() - imageSize(DecorationPart::Right).width(), top.height()), imageSize(DecorationPart::Right)); 0089 const QRect bottom(QPoint(0, left.y() + left.height()), imageSize(DecorationPart::Bottom)); 0090 0091 const QRect geometry = region.boundingRect(); 0092 auto renderPart = [this](const QRect &rect, const QRect &partRect, int index) { 0093 if (rect.isEmpty()) { 0094 return; 0095 } 0096 QPainter painter(&m_images[index]); 0097 painter.setRenderHint(QPainter::Antialiasing); 0098 painter.setWindow(QRect(partRect.topLeft(), partRect.size() * effectiveDevicePixelRatio())); 0099 painter.setClipRect(rect); 0100 painter.save(); 0101 // clear existing part 0102 painter.setCompositionMode(QPainter::CompositionMode_Source); 0103 painter.fillRect(rect, Qt::transparent); 0104 painter.restore(); 0105 client()->decoration()->paint(&painter, rect); 0106 }; 0107 0108 renderPart(left.intersected(geometry), left, int(DecorationPart::Left)); 0109 renderPart(top.intersected(geometry), top, int(DecorationPart::Top)); 0110 renderPart(right.intersected(geometry), right, int(DecorationPart::Right)); 0111 renderPart(bottom.intersected(geometry), bottom, int(DecorationPart::Bottom)); 0112 } 0113 0114 void SceneQPainterDecorationRenderer::resizeImages() 0115 { 0116 QRectF left, top, right, bottom; 0117 client()->window()->layoutDecorationRects(left, top, right, bottom); 0118 0119 auto checkAndCreate = [this](int index, const QSizeF &size) { 0120 auto dpr = effectiveDevicePixelRatio(); 0121 if (m_images[index].size() != size * dpr || m_images[index].devicePixelRatio() != dpr) { 0122 m_images[index] = QImage(size.toSize() * dpr, QImage::Format_ARGB32_Premultiplied); 0123 m_images[index].setDevicePixelRatio(dpr); 0124 m_images[index].fill(Qt::transparent); 0125 } 0126 }; 0127 checkAndCreate(int(DecorationPart::Left), left.size()); 0128 checkAndCreate(int(DecorationPart::Right), right.size()); 0129 checkAndCreate(int(DecorationPart::Top), top.size()); 0130 checkAndCreate(int(DecorationPart::Bottom), bottom.size()); 0131 } 0132 0133 } // KWin 0134 0135 #include "moc_workspacescene_qpainter.cpp"