File indexing completed on 2025-01-19 11:19:17
0001 /* 0002 SPDX-FileCopyrightText: 2016 Smith AR <audoban@openmailbox.org> 0003 SPDX-FileCopyrightText: 2016 Michail Vourlakos <mvourlakos@gmail.com> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "infoview.h" 0009 0010 // local 0011 #include <config-latte.h> 0012 #include "wm/abstractwindowinterface.h" 0013 #include "view/panelshadows_p.h" 0014 0015 // Qt 0016 #include <QQuickItem> 0017 #include <QQmlContext> 0018 #include <QQmlEngine> 0019 #include <QScreen> 0020 0021 // KDE 0022 #include <KLocalizedContext> 0023 #include <KDeclarative/KDeclarative> 0024 #include <KWindowSystem> 0025 #include <KWayland/Client/plasmashell.h> 0026 #include <KWayland/Client/surface.h> 0027 0028 // Plasma 0029 #include <Plasma/Package> 0030 0031 namespace Latte { 0032 0033 InfoView::InfoView(Latte::Corona *corona, QString message, QScreen *screen, QWindow *parent) 0034 : QQuickView(parent), 0035 m_corona(corona), 0036 m_message(message), 0037 m_screen(screen) 0038 { 0039 m_id = QString::number(qrand() % 1000); 0040 0041 setTitle(validTitle()); 0042 0043 setupWaylandIntegration(); 0044 0045 setResizeMode(QQuickView::SizeViewToRootObject); 0046 setColor(QColor(Qt::transparent)); 0047 setDefaultAlphaBuffer(true); 0048 0049 setIcon(qGuiApp->windowIcon()); 0050 0051 setScreen(screen); 0052 setFlags(wFlags()); 0053 0054 if (KWindowSystem::isPlatformX11()) { 0055 m_trackedWindowId = winId(); 0056 m_corona->wm()->registerIgnoredWindow(m_trackedWindowId); 0057 } else { 0058 connect(m_corona->wm(), &WindowSystem::AbstractWindowInterface::latteWindowAdded, this, &InfoView::updateWaylandId); 0059 } 0060 0061 init(); 0062 } 0063 0064 InfoView::~InfoView() 0065 { 0066 PanelShadows::self()->removeWindow(this); 0067 0068 qDebug() << "InfoView deleting ..."; 0069 0070 if (m_shellSurface) { 0071 delete m_shellSurface; 0072 m_shellSurface = nullptr; 0073 } 0074 } 0075 0076 void InfoView::init() 0077 { 0078 rootContext()->setContextProperty(QStringLiteral("infoWindow"), this); 0079 0080 KDeclarative::KDeclarative kdeclarative; 0081 kdeclarative.setDeclarativeEngine(engine()); 0082 kdeclarative.setTranslationDomain(QStringLiteral("latte-dock")); 0083 kdeclarative.setupContext(); 0084 kdeclarative.setupEngine(engine()); 0085 0086 auto source = QUrl::fromLocalFile(m_corona->kPackage().filePath("infoviewui")); 0087 setSource(source); 0088 0089 rootObject()->setProperty("message", m_message); 0090 0091 syncGeometry(); 0092 } 0093 0094 QString InfoView::validTitle() const 0095 { 0096 return "#layoutinfowindow#" + m_id; 0097 } 0098 0099 Plasma::FrameSvg::EnabledBorders InfoView::enabledBorders() const 0100 { 0101 return m_borders; 0102 } 0103 0104 0105 inline Qt::WindowFlags InfoView::wFlags() const 0106 { 0107 return (flags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint) & ~Qt::WindowDoesNotAcceptFocus; 0108 } 0109 0110 void InfoView::syncGeometry() 0111 { 0112 const QSize size(rootObject()->width(), rootObject()->height()); 0113 const auto sGeometry = screen()->geometry(); 0114 0115 setMaximumSize(size); 0116 setMinimumSize(size); 0117 resize(size); 0118 0119 QPoint position{sGeometry.center().x() - size.width() / 2, sGeometry.center().y() - size.height() / 2 }; 0120 0121 setPosition(position); 0122 0123 if (m_shellSurface) { 0124 m_shellSurface->setPosition(position); 0125 } 0126 } 0127 0128 void InfoView::showEvent(QShowEvent *ev) 0129 { 0130 QQuickWindow::showEvent(ev); 0131 0132 m_corona->wm()->setViewExtraFlags(this); 0133 setFlags(wFlags()); 0134 0135 m_corona->wm()->enableBlurBehind(*this); 0136 0137 syncGeometry(); 0138 0139 QTimer::singleShot(400, this, &InfoView::syncGeometry); 0140 0141 PanelShadows::self()->addWindow(this); 0142 PanelShadows::self()->setEnabledBorders(this, m_borders); 0143 } 0144 0145 void InfoView::updateWaylandId() 0146 { 0147 Latte::WindowSystem::WindowId newId = m_corona->wm()->winIdFor("latte-dock", validTitle()); 0148 0149 if (m_trackedWindowId != newId) { 0150 if (!m_trackedWindowId.isNull()) { 0151 m_corona->wm()->unregisterIgnoredWindow(m_trackedWindowId); 0152 } 0153 0154 m_trackedWindowId = newId; 0155 m_corona->wm()->registerIgnoredWindow(m_trackedWindowId); 0156 } 0157 } 0158 0159 void InfoView::setupWaylandIntegration() 0160 { 0161 if (m_shellSurface) { 0162 // already setup 0163 return; 0164 } 0165 0166 if (m_corona) { 0167 using namespace KWayland::Client; 0168 PlasmaShell *interface = m_corona->waylandCoronaInterface(); 0169 0170 if (!interface) { 0171 return; 0172 } 0173 0174 Surface *s = Surface::fromWindow(this); 0175 0176 if (!s) { 0177 return; 0178 } 0179 0180 qDebug() << "wayland dock window surface was created..."; 0181 0182 m_shellSurface = interface->createSurface(s, this); 0183 m_corona->wm()->setViewExtraFlags(m_shellSurface); 0184 } 0185 } 0186 0187 bool InfoView::event(QEvent *e) 0188 { 0189 if (e->type() == QEvent::PlatformSurface) { 0190 if (auto pe = dynamic_cast<QPlatformSurfaceEvent *>(e)) { 0191 switch (pe->surfaceEventType()) { 0192 case QPlatformSurfaceEvent::SurfaceCreated: 0193 0194 if (m_shellSurface) { 0195 break; 0196 } 0197 0198 setupWaylandIntegration(); 0199 break; 0200 0201 case QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed: 0202 if (m_shellSurface) { 0203 delete m_shellSurface; 0204 m_shellSurface = nullptr; 0205 } 0206 0207 PanelShadows::self()->removeWindow(this); 0208 break; 0209 } 0210 } 0211 } 0212 0213 return QQuickWindow::event(e); 0214 } 0215 0216 void InfoView::setOnActivities(QStringList activities) 0217 { 0218 KWindowSystem::setOnActivities(winId(), activities); 0219 } 0220 0221 } 0222 // kate: indent-mode cstyle; indent-width 4; replace-tabs on;