File indexing completed on 2026-08-09 12:02:25
0001 /* 0002 SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 #include "previewclient.h" 0007 #include <KDecoration2/DecoratedClient> 0008 #include <KDecoration2/Decoration> 0009 0010 #include <QCoreApplication> 0011 #include <QDebug> 0012 #include <QEvent> 0013 #include <QModelIndex> 0014 0015 namespace KDecoration2 0016 { 0017 namespace Preview 0018 { 0019 0020 PreviewClient::PreviewClient(DecoratedClient *c, Decoration *decoration) 0021 : QObject(decoration) 0022 , ApplicationMenuEnabledDecoratedClientPrivate(c, decoration) 0023 , m_icon(QIcon::fromTheme(QStringLiteral("start-here-kde"))) 0024 , m_iconName(m_icon.name()) 0025 , m_palette(QStringLiteral("kdeglobals")) 0026 , m_active(true) 0027 , m_closeable(true) 0028 , m_keepBelow(false) 0029 , m_keepAbove(false) 0030 , m_maximizable(true) 0031 , m_maximizedHorizontally(false) 0032 , m_maximizedVertically(false) 0033 , m_minimizable(true) 0034 , m_modal(false) 0035 , m_movable(true) 0036 , m_resizable(true) 0037 , m_shadeable(true) 0038 , m_shaded(false) 0039 , m_providesContextHelp(false) 0040 , m_desktop(1) 0041 , m_width(0) 0042 , m_height(0) 0043 , m_bordersTopEdge(false) 0044 , m_bordersLeftEdge(false) 0045 , m_bordersRightEdge(false) 0046 , m_bordersBottomEdge(false) 0047 { 0048 connect(this, &PreviewClient::captionChanged, c, &DecoratedClient::captionChanged); 0049 connect(this, &PreviewClient::activeChanged, c, &DecoratedClient::activeChanged); 0050 connect(this, &PreviewClient::closeableChanged, c, &DecoratedClient::closeableChanged); 0051 connect(this, &PreviewClient::keepAboveChanged, c, &DecoratedClient::keepAboveChanged); 0052 connect(this, &PreviewClient::keepBelowChanged, c, &DecoratedClient::keepBelowChanged); 0053 connect(this, &PreviewClient::maximizableChanged, c, &DecoratedClient::maximizeableChanged); 0054 connect(this, &PreviewClient::maximizedChanged, c, &DecoratedClient::maximizedChanged); 0055 connect(this, &PreviewClient::maximizedVerticallyChanged, c, &DecoratedClient::maximizedVerticallyChanged); 0056 connect(this, &PreviewClient::maximizedHorizontallyChanged, c, &DecoratedClient::maximizedHorizontallyChanged); 0057 connect(this, &PreviewClient::minimizableChanged, c, &DecoratedClient::minimizeableChanged); 0058 connect(this, &PreviewClient::movableChanged, c, &DecoratedClient::moveableChanged); 0059 connect(this, &PreviewClient::onAllDesktopsChanged, c, &DecoratedClient::onAllDesktopsChanged); 0060 connect(this, &PreviewClient::resizableChanged, c, &DecoratedClient::resizeableChanged); 0061 connect(this, &PreviewClient::shadeableChanged, c, &DecoratedClient::shadeableChanged); 0062 connect(this, &PreviewClient::shadedChanged, c, &DecoratedClient::shadedChanged); 0063 connect(this, &PreviewClient::providesContextHelpChanged, c, &DecoratedClient::providesContextHelpChanged); 0064 connect(this, &PreviewClient::onAllDesktopsChanged, c, &DecoratedClient::onAllDesktopsChanged); 0065 connect(this, &PreviewClient::widthChanged, c, &DecoratedClient::widthChanged); 0066 connect(this, &PreviewClient::heightChanged, c, &DecoratedClient::heightChanged); 0067 connect(this, &PreviewClient::iconChanged, c, &DecoratedClient::iconChanged); 0068 connect(this, &PreviewClient::paletteChanged, c, &DecoratedClient::paletteChanged); 0069 connect(this, &PreviewClient::maximizedVerticallyChanged, this, [this]() { 0070 Q_EMIT maximizedChanged(isMaximized()); 0071 }); 0072 connect(this, &PreviewClient::maximizedHorizontallyChanged, this, [this]() { 0073 Q_EMIT maximizedChanged(isMaximized()); 0074 }); 0075 connect(this, &PreviewClient::iconNameChanged, this, [this]() { 0076 m_icon = QIcon::fromTheme(m_iconName); 0077 Q_EMIT iconChanged(m_icon); 0078 }); 0079 connect(this, &PreviewClient::desktopChanged, this, [this]() { 0080 Q_EMIT onAllDesktopsChanged(isOnAllDesktops()); 0081 }); 0082 connect(&m_palette, &KWin::Decoration::DecorationPalette::changed, this, [this]() { 0083 Q_EMIT paletteChanged(m_palette.palette()); 0084 }); 0085 auto emitEdgesChanged = [this, c]() { 0086 Q_EMIT c->adjacentScreenEdgesChanged(adjacentScreenEdges()); 0087 }; 0088 connect(this, &PreviewClient::bordersTopEdgeChanged, this, emitEdgesChanged); 0089 connect(this, &PreviewClient::bordersLeftEdgeChanged, this, emitEdgesChanged); 0090 connect(this, &PreviewClient::bordersRightEdgeChanged, this, emitEdgesChanged); 0091 connect(this, &PreviewClient::bordersBottomEdgeChanged, this, emitEdgesChanged); 0092 auto emitSizeChanged = [c]() { 0093 Q_EMIT c->sizeChanged(c->size()); 0094 }; 0095 connect(this, &PreviewClient::widthChanged, this, emitSizeChanged); 0096 connect(this, &PreviewClient::heightChanged, this, emitSizeChanged); 0097 0098 qApp->installEventFilter(this); 0099 } 0100 0101 PreviewClient::~PreviewClient() = default; 0102 0103 void PreviewClient::setIcon(const QIcon &pixmap) 0104 { 0105 m_icon = pixmap; 0106 Q_EMIT iconChanged(m_icon); 0107 } 0108 0109 int PreviewClient::width() const 0110 { 0111 return m_width; 0112 } 0113 0114 int PreviewClient::height() const 0115 { 0116 return m_height; 0117 } 0118 0119 QSize PreviewClient::size() const 0120 { 0121 return QSize(m_width, m_height); 0122 } 0123 0124 QString PreviewClient::caption() const 0125 { 0126 return m_caption; 0127 } 0128 0129 WId PreviewClient::decorationId() const 0130 { 0131 return 0; 0132 } 0133 0134 int PreviewClient::desktop() const 0135 { 0136 return m_desktop; 0137 } 0138 0139 void PreviewClient::setDesktop(int desktop) 0140 { 0141 if (desktop == 0) { 0142 desktop = 1; 0143 } 0144 if (m_desktop == desktop) { 0145 return; 0146 } 0147 m_desktop = desktop; 0148 Q_EMIT desktopChanged(m_desktop); 0149 } 0150 0151 QIcon PreviewClient::icon() const 0152 { 0153 return m_icon; 0154 } 0155 0156 QString PreviewClient::iconName() const 0157 { 0158 return m_iconName; 0159 } 0160 0161 bool PreviewClient::isActive() const 0162 { 0163 return m_active; 0164 } 0165 0166 bool PreviewClient::isCloseable() const 0167 { 0168 return m_closeable; 0169 } 0170 0171 bool PreviewClient::isKeepAbove() const 0172 { 0173 return m_keepAbove; 0174 } 0175 0176 bool PreviewClient::isKeepBelow() const 0177 { 0178 return m_keepBelow; 0179 } 0180 0181 bool PreviewClient::isMaximizeable() const 0182 { 0183 return m_maximizable; 0184 } 0185 0186 bool PreviewClient::isMaximized() const 0187 { 0188 return isMaximizedHorizontally() && isMaximizedVertically(); 0189 } 0190 0191 bool PreviewClient::isMaximizedHorizontally() const 0192 { 0193 return m_maximizedHorizontally; 0194 } 0195 0196 bool PreviewClient::isMaximizedVertically() const 0197 { 0198 return m_maximizedVertically; 0199 } 0200 0201 bool PreviewClient::isMinimizeable() const 0202 { 0203 return m_minimizable; 0204 } 0205 0206 bool PreviewClient::isModal() const 0207 { 0208 return m_modal; 0209 } 0210 0211 bool PreviewClient::isMoveable() const 0212 { 0213 return m_movable; 0214 } 0215 0216 bool PreviewClient::isOnAllDesktops() const 0217 { 0218 return desktop() == -1; 0219 } 0220 0221 bool PreviewClient::isResizeable() const 0222 { 0223 return m_resizable; 0224 } 0225 0226 bool PreviewClient::isShadeable() const 0227 { 0228 return m_shadeable; 0229 } 0230 0231 bool PreviewClient::isShaded() const 0232 { 0233 return m_shaded; 0234 } 0235 0236 bool PreviewClient::providesContextHelp() const 0237 { 0238 return m_providesContextHelp; 0239 } 0240 0241 WId PreviewClient::windowId() const 0242 { 0243 return 0; 0244 } 0245 0246 QPalette PreviewClient::palette() const 0247 { 0248 return m_palette.palette(); 0249 } 0250 0251 QColor PreviewClient::color(ColorGroup group, ColorRole role) const 0252 { 0253 return m_palette.color(group, role); 0254 } 0255 0256 Qt::Edges PreviewClient::adjacentScreenEdges() const 0257 { 0258 Qt::Edges edges; 0259 if (m_bordersBottomEdge) { 0260 edges |= Qt::BottomEdge; 0261 } 0262 if (m_bordersLeftEdge) { 0263 edges |= Qt::LeftEdge; 0264 } 0265 if (m_bordersRightEdge) { 0266 edges |= Qt::RightEdge; 0267 } 0268 if (m_bordersTopEdge) { 0269 edges |= Qt::TopEdge; 0270 } 0271 return edges; 0272 } 0273 0274 QString PreviewClient::windowClass() const 0275 { 0276 return QString(); 0277 } 0278 0279 bool PreviewClient::hasApplicationMenu() const 0280 { 0281 return true; 0282 } 0283 0284 bool PreviewClient::isApplicationMenuActive() const 0285 { 0286 return false; 0287 } 0288 0289 bool PreviewClient::bordersBottomEdge() const 0290 { 0291 return m_bordersBottomEdge; 0292 } 0293 0294 bool PreviewClient::bordersLeftEdge() const 0295 { 0296 return m_bordersLeftEdge; 0297 } 0298 0299 bool PreviewClient::bordersRightEdge() const 0300 { 0301 return m_bordersRightEdge; 0302 } 0303 0304 bool PreviewClient::bordersTopEdge() const 0305 { 0306 return m_bordersTopEdge; 0307 } 0308 0309 void PreviewClient::setBordersBottomEdge(bool enabled) 0310 { 0311 if (m_bordersBottomEdge == enabled) { 0312 return; 0313 } 0314 m_bordersBottomEdge = enabled; 0315 Q_EMIT bordersBottomEdgeChanged(enabled); 0316 } 0317 0318 void PreviewClient::setBordersLeftEdge(bool enabled) 0319 { 0320 if (m_bordersLeftEdge == enabled) { 0321 return; 0322 } 0323 m_bordersLeftEdge = enabled; 0324 Q_EMIT bordersLeftEdgeChanged(enabled); 0325 } 0326 0327 void PreviewClient::setBordersRightEdge(bool enabled) 0328 { 0329 if (m_bordersRightEdge == enabled) { 0330 return; 0331 } 0332 m_bordersRightEdge = enabled; 0333 Q_EMIT bordersRightEdgeChanged(enabled); 0334 } 0335 0336 void PreviewClient::setBordersTopEdge(bool enabled) 0337 { 0338 if (m_bordersTopEdge == enabled) { 0339 return; 0340 } 0341 m_bordersTopEdge = enabled; 0342 Q_EMIT bordersTopEdgeChanged(enabled); 0343 } 0344 0345 void PreviewClient::requestShowToolTip(const QString &text) 0346 { 0347 } 0348 0349 void PreviewClient::requestHideToolTip() 0350 { 0351 } 0352 0353 void PreviewClient::requestClose() 0354 { 0355 Q_EMIT closeRequested(); 0356 } 0357 0358 void PreviewClient::requestContextHelp() 0359 { 0360 } 0361 0362 void PreviewClient::requestToggleMaximization(Qt::MouseButtons buttons) 0363 { 0364 if (buttons.testFlag(Qt::LeftButton)) { 0365 const bool set = !isMaximized(); 0366 setMaximizedHorizontally(set); 0367 setMaximizedVertically(set); 0368 } else if (buttons.testFlag(Qt::RightButton)) { 0369 setMaximizedHorizontally(!isMaximizedHorizontally()); 0370 } else if (buttons.testFlag(Qt::MiddleButton)) { 0371 setMaximizedVertically(!isMaximizedVertically()); 0372 } 0373 } 0374 0375 void PreviewClient::requestMinimize() 0376 { 0377 Q_EMIT minimizeRequested(); 0378 } 0379 0380 void PreviewClient::requestToggleKeepAbove() 0381 { 0382 setKeepAbove(!isKeepAbove()); 0383 } 0384 0385 void PreviewClient::requestToggleKeepBelow() 0386 { 0387 setKeepBelow(!isKeepBelow()); 0388 } 0389 0390 void PreviewClient::requestShowWindowMenu(const QRect &rect) 0391 { 0392 Q_EMIT showWindowMenuRequested(); 0393 } 0394 0395 void PreviewClient::requestShowApplicationMenu(const QRect &rect, int actionId) 0396 { 0397 } 0398 0399 void PreviewClient::showApplicationMenu(int actionId) 0400 { 0401 } 0402 0403 void PreviewClient::requestToggleOnAllDesktops() 0404 { 0405 setDesktop(isOnAllDesktops() ? 1 : -1); 0406 } 0407 0408 void PreviewClient::requestToggleShade() 0409 { 0410 setShaded(!isShaded()); 0411 } 0412 0413 #define SETTER(type, name, variable) \ 0414 void PreviewClient::name(type variable) \ 0415 { \ 0416 if (m_##variable == variable) { \ 0417 return; \ 0418 } \ 0419 m_##variable = variable; \ 0420 Q_EMIT variable##Changed(m_##variable); \ 0421 } 0422 0423 #define SETTER2(name, variable) SETTER(bool, name, variable) 0424 0425 SETTER(const QString &, setCaption, caption) 0426 SETTER(const QString &, setIconName, iconName) 0427 SETTER(int, setWidth, width) 0428 SETTER(int, setHeight, height) 0429 0430 SETTER2(setActive, active) 0431 SETTER2(setCloseable, closeable) 0432 SETTER2(setMaximizable, maximizable) 0433 SETTER2(setKeepBelow, keepBelow) 0434 SETTER2(setKeepAbove, keepAbove) 0435 SETTER2(setMaximizedHorizontally, maximizedHorizontally) 0436 SETTER2(setMaximizedVertically, maximizedVertically) 0437 SETTER2(setMinimizable, minimizable) 0438 SETTER2(setModal, modal) 0439 SETTER2(setMovable, movable) 0440 SETTER2(setResizable, resizable) 0441 SETTER2(setShadeable, shadeable) 0442 SETTER2(setShaded, shaded) 0443 SETTER2(setProvidesContextHelp, providesContextHelp) 0444 0445 #undef SETTER2 0446 #undef SETTER 0447 0448 } // namespace Preview 0449 } // namespace KDecoration2 0450 0451 #include "moc_previewclient.cpp"