File indexing completed on 2026-08-09 14:49:15

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"