File indexing completed on 2024-02-25 17:23:31

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2006 Lubos Lunak <l.lunak@kde.org>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #include "deleted.h"
0011 
0012 #include "group.h"
0013 #include "netinfo.h"
0014 #include "shadow.h"
0015 #include "virtualdesktops.h"
0016 #include "workspace.h"
0017 
0018 #include <QDebug>
0019 
0020 namespace KWin
0021 {
0022 
0023 Deleted::Deleted()
0024     : Window()
0025     , delete_refcount(1)
0026     , m_frame(XCB_WINDOW_NONE)
0027     , m_layer(UnknownLayer)
0028     , m_shade(false)
0029     , m_minimized(false)
0030     , m_modal(false)
0031     , m_wasClient(false)
0032     , m_fullscreen(false)
0033     , m_keepAbove(false)
0034     , m_keepBelow(false)
0035     , m_wasPopupWindow(false)
0036     , m_wasOutline(false)
0037     , m_wasLockScreen(false)
0038 {
0039 }
0040 
0041 Deleted::~Deleted()
0042 {
0043     if (delete_refcount != 0) {
0044         qCCritical(KWIN_CORE) << "Deleted client has non-zero reference count (" << delete_refcount << ")";
0045     }
0046     Q_ASSERT(delete_refcount == 0);
0047     if (workspace()) {
0048         workspace()->removeDeleted(this);
0049     }
0050 }
0051 
0052 std::unique_ptr<WindowItem> Deleted::createItem(Scene *scene)
0053 {
0054     Q_UNREACHABLE();
0055 }
0056 
0057 Deleted *Deleted::create(Window *c)
0058 {
0059     Deleted *d = new Deleted();
0060     d->copyToDeleted(c);
0061     workspace()->addDeleted(d, c);
0062     return d;
0063 }
0064 
0065 // to be used only from Workspace::finishCompositing()
0066 void Deleted::discard()
0067 {
0068     delete_refcount = 0;
0069     delete this;
0070 }
0071 
0072 void Deleted::copyToDeleted(Window *window)
0073 {
0074     Q_ASSERT(!window->isDeleted());
0075     Window::copyToDeleted(window);
0076     m_frameMargins = window->frameMargins();
0077     desk = window->desktop();
0078     m_desktops = window->desktops();
0079     activityList = window->activities();
0080     contentsRect = QRectF(window->clientPos(), window->clientSize());
0081     m_layer = window->layer();
0082     m_frame = window->frameId();
0083     m_type = window->windowType();
0084     m_windowRole = window->windowRole();
0085     m_shade = window->isShade();
0086     if (WinInfo *cinfo = dynamic_cast<WinInfo *>(info)) {
0087         cinfo->disable();
0088     }
0089     if (window->isDecorated()) {
0090         window->layoutDecorationRects(decoration_left,
0091                                       decoration_top,
0092                                       decoration_right,
0093                                       decoration_bottom);
0094     }
0095     m_wasClient = true;
0096     m_minimized = window->isMinimized();
0097     m_modal = window->isModal();
0098     m_mainWindows = window->mainWindows();
0099     for (Window *w : std::as_const(m_mainWindows)) {
0100         connect(w, &Window::windowClosed, this, &Deleted::mainWindowClosed);
0101     }
0102     m_fullscreen = window->isFullScreen();
0103     m_keepAbove = window->keepAbove();
0104     m_keepBelow = window->keepBelow();
0105     m_caption = window->caption();
0106 
0107     for (auto vd : std::as_const(m_desktops)) {
0108         connect(vd, &QObject::destroyed, this, [=, this] {
0109             m_desktops.removeOne(vd);
0110         });
0111     }
0112 
0113     m_wasPopupWindow = window->isPopupWindow();
0114     m_wasOutline = window->isOutline();
0115     m_wasLockScreen = window->isLockScreen();
0116 }
0117 
0118 void Deleted::unrefWindow()
0119 {
0120     if (--delete_refcount > 0) {
0121         return;
0122     }
0123     // needs to be delayed
0124     // a) when calling from effects, otherwise it'd be rather complicated to handle the case of the
0125     // window going away during a painting pass
0126     // b) to prevent dangeling pointers in the stacking order, see bug #317765
0127     deleteLater();
0128 }
0129 
0130 QMargins Deleted::frameMargins() const
0131 {
0132     return m_frameMargins;
0133 }
0134 
0135 int Deleted::desktop() const
0136 {
0137     return desk;
0138 }
0139 
0140 QStringList Deleted::activities() const
0141 {
0142     return activityList;
0143 }
0144 
0145 QVector<VirtualDesktop *> Deleted::desktops() const
0146 {
0147     return m_desktops;
0148 }
0149 
0150 QPointF Deleted::clientPos() const
0151 {
0152     return contentsRect.topLeft();
0153 }
0154 
0155 void Deleted::layoutDecorationRects(QRectF &left, QRectF &top, QRectF &right, QRectF &bottom) const
0156 {
0157     left = decoration_left;
0158     top = decoration_top;
0159     right = decoration_right;
0160     bottom = decoration_bottom;
0161 }
0162 
0163 bool Deleted::isDeleted() const
0164 {
0165     return true;
0166 }
0167 
0168 NET::WindowType Deleted::windowType(bool direct, int supportedTypes) const
0169 {
0170     return m_type;
0171 }
0172 
0173 void Deleted::mainWindowClosed(Window *window)
0174 {
0175     m_mainWindows.removeAll(window);
0176 }
0177 
0178 xcb_window_t Deleted::frameId() const
0179 {
0180     return m_frame;
0181 }
0182 
0183 QString Deleted::windowRole() const
0184 {
0185     return m_windowRole;
0186 }
0187 
0188 QVector<uint> Deleted::x11DesktopIds() const
0189 {
0190     const auto desks = desktops();
0191     QVector<uint> x11Ids;
0192     x11Ids.reserve(desks.count());
0193     std::transform(desks.constBegin(), desks.constEnd(),
0194                    std::back_inserter(x11Ids),
0195                    [](const VirtualDesktop *vd) {
0196                        return vd->x11DesktopNumber();
0197                    });
0198     return x11Ids;
0199 }
0200 
0201 } // namespace