1
0
mirror of https://github.com/KDE/latte-dock.git synced 2025-01-10 21:18:19 +03:00
latte-dock/app/wm/waylandinterface.cpp
Michail Vourlakos 8b32be15b9 support GtkFrameExtents under X11
--this way to dock windows can now snap beautifully
with windows around them, very beautiful behavior!
That was pretty annoying in the past.
2020-05-11 17:31:51 +03:00

924 lines
25 KiB
C++

/*
* Copyright 2016 Smith AR <audoban@openmailbox.org>
* Michail Vourlakos <mvourlakos@gmail.com>
*
* This file is part of Latte-Dock
*
* Latte-Dock is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* Latte-Dock is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "waylandinterface.h"
// local
#include <coretypes.h>
#include "view/positioner.h"
#include "view/view.h"
#include "view/helpers/screenedgeghostwindow.h"
#include "../lattecorona.h"
// Qt
#include <QDebug>
#include <QTimer>
#include <QApplication>
#include <QtX11Extras/QX11Info>
#include <QRasterWindow>
// KDE
#include <KWindowSystem>
#include <KWindowInfo>
#include <KWayland/Client/surface.h>
#if KF5_VERSION_MINOR >= 52
#include <KWayland/Client/plasmavirtualdesktop.h>
#endif
// X11
#include <NETWM>
using namespace KWayland::Client;
namespace Latte {
class Private::GhostWindow : public QRasterWindow
{
Q_OBJECT
public:
WindowSystem::WindowId m_winId;
GhostWindow(WindowSystem::WaylandInterface *waylandInterface)
: m_waylandInterface(waylandInterface) {
setFlags(Qt::FramelessWindowHint
| Qt::WindowStaysOnTopHint
| Qt::NoDropShadowWindowHint
| Qt::WindowDoesNotAcceptFocus);
connect(m_waylandInterface, &WindowSystem::AbstractWindowInterface::latteWindowAdded, this, &GhostWindow::identifyWinId);
setupWaylandIntegration();
show();
}
~GhostWindow() {
m_waylandInterface->unregisterIgnoredWindow(m_winId);
delete m_shellSurface;
}
void setGeometry(const QRect &rect) {
if (geometry() == rect) {
return;
}
m_validGeometry = rect;
setMinimumSize(rect.size());
setMaximumSize(rect.size());
resize(rect.size());
m_shellSurface->setPosition(rect.topLeft());
}
void setupWaylandIntegration() {
using namespace KWayland::Client;
if (m_shellSurface)
return;
Surface *s{Surface::fromWindow(this)};
if (!s)
return;
m_shellSurface = m_waylandInterface->waylandCoronaInterface()->createSurface(s, this);
qDebug() << "wayland ghost window surface was created...";
m_shellSurface->setSkipTaskbar(true);
m_shellSurface->setPanelTakesFocus(false);
m_shellSurface->setRole(PlasmaShellSurface::Role::Panel);
m_shellSurface->setPanelBehavior(PlasmaShellSurface::PanelBehavior::AlwaysVisible);
}
KWayland::Client::PlasmaShellSurface *m_shellSurface{nullptr};
WindowSystem::WaylandInterface *m_waylandInterface{nullptr};
//! geometry() function under wayland does not return nice results
QRect m_validGeometry;
public slots:
void identifyWinId() {
if (m_winId.isNull()) {
m_winId = m_waylandInterface->winIdFor("latte-dock", m_validGeometry);
m_waylandInterface->registerIgnoredWindow(m_winId);
}
}
};
namespace WindowSystem {
WaylandInterface::WaylandInterface(QObject *parent)
: AbstractWindowInterface(parent)
{
m_corona = qobject_cast<Latte::Corona *>(parent);
}
WaylandInterface::~WaylandInterface()
{
}
void WaylandInterface::init()
{
}
void WaylandInterface::initWindowManagement(KWayland::Client::PlasmaWindowManagement *windowManagement)
{
if (m_windowManagement == windowManagement) {
return;
}
m_windowManagement = windowManagement;
connect(m_windowManagement, &PlasmaWindowManagement::windowCreated, this, &WaylandInterface::windowCreatedProxy);
connect(m_windowManagement, &PlasmaWindowManagement::activeWindowChanged, this, [&]() noexcept {
auto w = m_windowManagement->activeWindow();
if (!w || (w && (!m_ignoredWindows.contains(w->internalId()))) ) {
emit activeWindowChanged(w ? w->internalId() : 0);
}
}, Qt::QueuedConnection);
}
#if KF5_VERSION_MINOR >= 52
void WaylandInterface::initVirtualDesktopManagement(KWayland::Client::PlasmaVirtualDesktopManagement *virtualDesktopManagement)
{
if (m_virtualDesktopManagement == virtualDesktopManagement) {
return;
}
m_virtualDesktopManagement = virtualDesktopManagement;
connect(m_virtualDesktopManagement, &KWayland::Client::PlasmaVirtualDesktopManagement::desktopCreated, this,
[this](const QString &id, quint32 position) {
addDesktop(id, position);
});
connect(m_virtualDesktopManagement, &KWayland::Client::PlasmaVirtualDesktopManagement::desktopRemoved, this,
[this](const QString &id) {
m_desktops.removeAll(id);
if (m_currentDesktop == id) {
setCurrentDesktop(QString());
}
});
}
void WaylandInterface::addDesktop(const QString &id, quint32 position)
{
if (m_desktops.contains(id)) {
return;
}
m_desktops.append(id);
const KWayland::Client::PlasmaVirtualDesktop *desktop = m_virtualDesktopManagement->getVirtualDesktop(id);
QObject::connect(desktop, &KWayland::Client::PlasmaVirtualDesktop::activated, this,
[desktop, this]() {
setCurrentDesktop(desktop->id());
}
);
if (desktop->isActive()) {
setCurrentDesktop(id);
}
}
void WaylandInterface::setCurrentDesktop(QString desktop)
{
if (m_currentDesktop == desktop) {
return;
}
m_currentDesktop = desktop;
emit currentDesktopChanged();
}
#endif
KWayland::Client::PlasmaShell *WaylandInterface::waylandCoronaInterface() const
{
return m_corona->waylandCoronaInterface();
}
//! Register Latte Ignored Windows in order to NOT be tracked
void WaylandInterface::registerIgnoredWindow(WindowId wid)
{
if (!wid.isNull() && !m_ignoredWindows.contains(wid)) {
m_ignoredWindows.append(wid);
KWayland::Client::PlasmaWindow *w = windowFor(wid);
if (w) {
untrackWindow(w);
}
emit windowChanged(wid);
}
}
void WaylandInterface::unregisterIgnoredWindow(WindowId wid)
{
if (m_ignoredWindows.contains(wid)) {
m_ignoredWindows.removeAll(wid);
emit windowRemoved(wid);
}
}
void WaylandInterface::setViewExtraFlags(QObject *view, bool isPanelWindow, Latte::Types::Visibility mode)
{
KWayland::Client::PlasmaShellSurface *surface = qobject_cast<KWayland::Client::PlasmaShellSurface *>(view);
Latte::View *latteView = qobject_cast<Latte::View *>(view);
if (latteView) {
surface = latteView->surface();
}
if (!surface) {
return;
}
surface->setSkipTaskbar(true);
#if KF5_VERSION_MINOR >= 47
surface->setSkipSwitcher(true);
#endif
bool atBottom{!isPanelWindow && (mode == Latte::Types::WindowsCanCover || mode == Latte::Types::WindowsAlwaysCover)};
if (isPanelWindow) {
surface->setRole(PlasmaShellSurface::Role::Panel);
surface->setPanelBehavior(PlasmaShellSurface::PanelBehavior::AutoHide);
} else {
surface->setRole(PlasmaShellSurface::Role::Normal);
}
if (latteView) {
WindowId winId = latteView->positioner()->trackedWindowId();
auto w = windowFor(winId);
if (w && !w->isOnAllDesktops()) {
requestToggleIsOnAllDesktops(winId);
}
//! Layer to be applied
if (mode == Latte::Types::WindowsCanCover || mode == Latte::Types::WindowsAlwaysCover) {
setKeepBelow(winId, true);
} else if (mode == Latte::Types::NormalWindow) {
setKeepBelow(winId, false);
setKeepAbove(winId, false);
} else {
setKeepAbove(winId, true);
}
}
if (atBottom){
//! trying to workaround WM behavior in order
//! 1. View at the end MUST NOT HAVE FOCUSABILITY (issue example: clicking a single active task is not minimized)
//! 2. View at the end MUST BE AT THE BOTTOM of windows stack
QTimer::singleShot(50, [this, surface]() {
surface->setRole(PlasmaShellSurface::Role::ToolTip);
});
}
}
void WaylandInterface::setViewStruts(QWindow &view, const QRect &rect, Plasma::Types::Location location)
{
if (!m_ghostWindows.contains(view.winId())) {
m_ghostWindows[view.winId()] = new Private::GhostWindow(this);
}
auto w = m_ghostWindows[view.winId()];
switch (location) {
case Plasma::Types::TopEdge:
case Plasma::Types::BottomEdge:
w->setGeometry({rect.x() + rect.width() / 2, rect.y(), 1, rect.height()});
break;
case Plasma::Types::LeftEdge:
case Plasma::Types::RightEdge:
w->setGeometry({rect.x(), rect.y() + rect.height() / 2, rect.width(), 1});
break;
default:
break;
}
}
void WaylandInterface::switchToNextVirtualDesktop()
{
#if KF5_VERSION_MINOR >= 52
if (!m_virtualDesktopManagement || m_desktops.count() <= 1) {
return;
}
int curPos = m_desktops.indexOf(m_currentDesktop);
int nextPos = curPos + 1;
if (curPos == m_desktops.count()-1) {
nextPos = 0;
}
KWayland::Client::PlasmaVirtualDesktop *desktopObj = m_virtualDesktopManagement->getVirtualDesktop(m_desktops[nextPos]);
if (desktopObj) {
desktopObj->requestActivate();
}
#endif
}
void WaylandInterface::switchToPreviousVirtualDesktop()
{
#if KF5_VERSION_MINOR >= 52
if (!m_virtualDesktopManagement || m_desktops.count() <= 1) {
return;
}
int curPos = m_desktops.indexOf(m_currentDesktop);
int nextPos = curPos - 1;
if (curPos == 0) {
nextPos = m_desktops.count()-1;
}
KWayland::Client::PlasmaVirtualDesktop *desktopObj = m_virtualDesktopManagement->getVirtualDesktop(m_desktops[nextPos]);
if (desktopObj) {
desktopObj->requestActivate();
}
#endif
}
void WaylandInterface::setWindowOnActivities(QWindow &window, const QStringList &activities)
{
//! needs to updated to wayland case
// KWindowSystem::setOnActivities(view.winId(), activities);
}
void WaylandInterface::removeViewStruts(QWindow &view)
{
delete m_ghostWindows.take(view.winId());
}
WindowId WaylandInterface::activeWindow()
{
if (!m_windowManagement) {
return 0;
}
auto wid = m_windowManagement->activeWindow();
return wid ? wid->internalId() : 0;
}
void WaylandInterface::skipTaskBar(const QDialog &dialog)
{
KWindowSystem::setState(dialog.winId(), NET::SkipTaskbar);
}
void WaylandInterface::slideWindow(QWindow &view, AbstractWindowInterface::Slide location)
{
auto slideLocation = KWindowEffects::NoEdge;
switch (location) {
case Slide::Top:
slideLocation = KWindowEffects::TopEdge;
break;
case Slide::Bottom:
slideLocation = KWindowEffects::BottomEdge;
break;
case Slide::Left:
slideLocation = KWindowEffects::LeftEdge;
break;
case Slide::Right:
slideLocation = KWindowEffects::RightEdge;
break;
default:
break;
}
KWindowEffects::slideWindow(view.winId(), slideLocation, -1);
}
void WaylandInterface::enableBlurBehind(QWindow &view)
{
KWindowEffects::enableBlurBehind(view.winId());
}
void WaylandInterface::setActiveEdge(QWindow *view, bool active)
{
ViewPart::ScreenEdgeGhostWindow *window = qobject_cast<ViewPart::ScreenEdgeGhostWindow *>(view);
if (!window) {
return;
}
if (window->parentView()->surface() && window->parentView()->visibility()
&& (window->parentView()->visibility()->mode() == Types::DodgeActive
|| window->parentView()->visibility()->mode() == Types::DodgeMaximized
|| window->parentView()->visibility()->mode() == Types::DodgeAllWindows
|| window->parentView()->visibility()->mode() == Types::AutoHide)) {
if (active) {
window->showWithMask();
window->surface()->requestHideAutoHidingPanel();
} else {
window->hideWithMask();
window->surface()->requestShowAutoHidingPanel();
}
}
}
void WaylandInterface::setFrameExtents(QWindow *view, const QMargins &extents)
{
//! do nothing yet until there is a wayland way to provide this
}
WindowInfoWrap WaylandInterface::requestInfoActive()
{
if (!m_windowManagement) {
return {};
}
auto w = m_windowManagement->activeWindow();
if (!w) return {};
return requestInfo(w->internalId());
}
WindowInfoWrap WaylandInterface::requestInfo(WindowId wid)
{
WindowInfoWrap winfoWrap;
auto w = windowFor(wid);
if (w && isValidWindow(w)) {
winfoWrap.setIsValid(true);
winfoWrap.setWid(wid);
winfoWrap.setParentId(w->parentWindow() ? w->parentWindow()->internalId() : 0);
winfoWrap.setIsActive(w->isActive());
winfoWrap.setIsMinimized(w->isMinimized());
winfoWrap.setIsMaxVert(w->isMaximized());
winfoWrap.setIsMaxHoriz(w->isMaximized());
winfoWrap.setIsFullscreen(w->isFullscreen());
winfoWrap.setIsShaded(w->isShaded());
winfoWrap.setIsOnAllDesktops(w->isOnAllDesktops());
winfoWrap.setIsOnAllActivities(true);
winfoWrap.setIsKeepAbove(w->isKeepAbove());
winfoWrap.setIsKeepBelow(w->isKeepBelow());
winfoWrap.setGeometry(w->geometry());
#if KF5_VERSION_MINOR >= 47
winfoWrap.setHasSkipSwitcher(w->skipSwitcher());
#endif
winfoWrap.setHasSkipTaskbar(w->skipTaskbar());
//! BEGIN:Window Abilities
winfoWrap.setIsClosable(w->isCloseable());
winfoWrap.setIsFullScreenable(w->isFullscreenable());
winfoWrap.setIsMaximizable(w->isMaximizeable());
winfoWrap.setIsMinimizable(w->isMinimizeable());
winfoWrap.setIsMovable(w->isMovable());
winfoWrap.setIsResizable(w->isResizable());
winfoWrap.setIsShadeable(w->isShadeable());
winfoWrap.setIsVirtualDesktopsChangeable(w->isVirtualDesktopChangeable());
//! END:Window Abilities
winfoWrap.setDisplay(w->title());
#if KF5_VERSION_MINOR >= 52
winfoWrap.setDesktops(w->plasmaVirtualDesktops());
#endif
winfoWrap.setActivities(QStringList());
} else {
winfoWrap.setIsValid(false);
}
return winfoWrap;
}
AppData WaylandInterface::appDataFor(WindowId wid)
{
auto window = windowFor(wid);
if (window) {
const AppData &data = appDataFromUrl(windowUrlFromMetadata(window->appId(),
window->pid(), rulesConfig));
return data;
}
AppData empty;
return empty;
}
KWayland::Client::PlasmaWindow *WaylandInterface::windowFor(WindowId wid)
{
auto it = std::find_if(m_windowManagement->windows().constBegin(), m_windowManagement->windows().constEnd(), [&wid](PlasmaWindow * w) noexcept {
return w->isValid() && w->internalId() == wid;
});
if (it == m_windowManagement->windows().constEnd()) {
return nullptr;
}
return *it;
}
QIcon WaylandInterface::iconFor(WindowId wid)
{
auto window = windowFor(wid);
if (window) {
return window->icon();
}
return QIcon();
}
WindowId WaylandInterface::winIdFor(QString appId, QString title)
{
auto it = std::find_if(m_windowManagement->windows().constBegin(), m_windowManagement->windows().constEnd(), [&appId, &title](PlasmaWindow * w) noexcept {
return w->isValid() && w->appId() == appId && w->title().startsWith(title);
});
if (it == m_windowManagement->windows().constEnd()) {
return QVariant();
}
return (*it)->internalId();
}
WindowId WaylandInterface::winIdFor(QString appId, QRect geometry)
{
auto it = std::find_if(m_windowManagement->windows().constBegin(), m_windowManagement->windows().constEnd(), [&appId, &geometry](PlasmaWindow * w) noexcept {
return w->isValid() && w->appId() == appId && w->geometry() == geometry;
});
if (it == m_windowManagement->windows().constEnd()) {
return QVariant();
}
return (*it)->internalId();
}
bool WaylandInterface::windowCanBeDragged(WindowId wid)
{
auto w = windowFor(wid);
if (w && isValidWindow(w)) {
WindowInfoWrap winfo = requestInfo(wid);
return (winfo.isValid()
&& w->isMovable()
&& !winfo.isMinimized()
&& inCurrentDesktopActivity(winfo));
}
return false;
}
bool WaylandInterface::windowCanBeMaximized(WindowId wid)
{
auto w = windowFor(wid);
if (w && isValidWindow(w)) {
WindowInfoWrap winfo = requestInfo(wid);
return (winfo.isValid()
&& w->isMaximizeable()
&& !winfo.isMinimized()
&& inCurrentDesktopActivity(winfo));
}
return false;
}
void WaylandInterface::requestActivate(WindowId wid)
{
auto w = windowFor(wid);
if (w) {
w->requestActivate();
}
}
void WaylandInterface::requestClose(WindowId wid)
{
auto w = windowFor(wid);
if (w) {
w->requestClose();
}
}
void WaylandInterface::requestMoveWindow(WindowId wid, QPoint from)
{
WindowInfoWrap wInfo = requestInfo(wid);
if (windowCanBeDragged(wid) && inCurrentDesktopActivity(wInfo)) {
auto w = windowFor(wid);
if (w && isValidWindow(w)) {
w->requestMove();
}
}
}
void WaylandInterface::requestToggleIsOnAllDesktops(WindowId wid)
{
#if KF5_VERSION_MINOR >= 52
auto w = windowFor(wid);
if (w && isValidWindow(w) && m_desktops.count() > 1) {
if (w->isOnAllDesktops()) {
w->requestEnterVirtualDesktop(m_currentDesktop);
} else {
const QStringList &now = w->plasmaVirtualDesktops();
foreach (const QString &desktop, now) {
w->requestLeaveVirtualDesktop(desktop);
}
}
}
#endif
}
void WaylandInterface::requestToggleKeepAbove(WindowId wid)
{
auto w = windowFor(wid);
if (w) {
w->requestToggleKeepAbove();
}
}
void WaylandInterface::setKeepAbove(WindowId wid, bool active)
{
auto w = windowFor(wid);
if (w) {
if (active) {
setKeepBelow(wid, false);
}
if ((w->isKeepAbove() && active) || (!w->isKeepAbove() && !active)) {
return;
}
w->requestToggleKeepAbove();
}
}
void WaylandInterface::setKeepBelow(WindowId wid, bool active)
{
auto w = windowFor(wid);
if (w) {
if (active) {
setKeepAbove(wid, false);
}
if ((w->isKeepBelow() && active) || (!w->isKeepBelow() && !active)) {
return;
}
w->requestToggleKeepBelow();
}
}
void WaylandInterface::requestToggleMinimized(WindowId wid)
{
auto w = windowFor(wid);
WindowInfoWrap wInfo = requestInfo(wid);
if (w && isValidWindow(w) && inCurrentDesktopActivity(wInfo)) {
#if KF5_VERSION_MINOR >= 52
if (!m_currentDesktop.isEmpty()) {
w->requestEnterVirtualDesktop(m_currentDesktop);
}
#endif
w->requestToggleMinimized();
}
}
void WaylandInterface::requestToggleMaximized(WindowId wid)
{
auto w = windowFor(wid);
WindowInfoWrap wInfo = requestInfo(wid);
if (w && isValidWindow(w) && windowCanBeMaximized(wid) && inCurrentDesktopActivity(wInfo)) {
#if KF5_VERSION_MINOR >= 52
if (!m_currentDesktop.isEmpty()) {
w->requestEnterVirtualDesktop(m_currentDesktop);
}
#endif
w->requestToggleMaximized();
}
}
bool WaylandInterface::isPlasmaPanel(const KWayland::Client::PlasmaWindow *w) const
{
if (!w || (w->appId() != QLatin1String("org.kde.plasmashell"))) {
return false;
}
return AbstractWindowInterface::isPlasmaPanel(w->geometry());
}
bool WaylandInterface::isFullScreenWindow(const KWayland::Client::PlasmaWindow *w) const
{
if (!w) {
return false;
}
return w->isFullscreen() || AbstractWindowInterface::isFullScreenWindow(w->geometry());
}
bool WaylandInterface::isSidepanel(const KWayland::Client::PlasmaWindow *w) const
{
if (!w) {
return false;
}
return AbstractWindowInterface::isSidepanel(w->geometry());
}
bool WaylandInterface::isValidWindow(const KWayland::Client::PlasmaWindow *w)
{
if (!w || !w->isValid()) {
return false;
}
if (windowsTracker()->isValidFor(w->internalId())) {
return true;
}
return isAcceptableWindow(w);
}
bool WaylandInterface::isAcceptableWindow(const KWayland::Client::PlasmaWindow *w)
{
if (!w || !w->isValid()) {
return false;
}
//! ignored windows that are not tracked
if (hasBlockedTracking(w->internalId())) {
return false;
}
//! whitelisted/approved windows
if (isWhitelistedWindow(w->internalId())) {
return true;
}
//! Window Checks
bool hasSkipTaskbar = w->skipTaskbar();
bool isSkipped = hasSkipTaskbar;
#if KF5_VERSION_MINOR >= 47
bool hasSkipSwitcher = w->skipSwitcher();
isSkipped = hasSkipTaskbar && hasSkipSwitcher;
#endif
if (isSkipped
&& ((w->appId() == QLatin1String("yakuake")
|| (w->appId() == QLatin1String("krunner"))) )) {
registerWhitelistedWindow(w->internalId());
} else if (w->appId() == QLatin1String("org.kde.plasmashell")) {
if (isSkipped && isSidepanel(w)) {
registerWhitelistedWindow(w->internalId());
return true;
} else if (isPlasmaPanel(w) || isFullScreenWindow(w)) {
registerPlasmaIgnoredWindow(w->internalId());
return false;
}
} else if ((w->appId() == QLatin1String("latte-dock"))
|| (w->appId().startsWith(QLatin1String("ksmserver")))) {
if (isFullScreenWindow(w)) {
registerIgnoredWindow(w->internalId());
return false;
}
}
return !isSkipped;
}
void WaylandInterface::updateWindow()
{
PlasmaWindow *pW = qobject_cast<PlasmaWindow*>(QObject::sender());
if (isValidWindow(pW)) {
considerWindowChanged(pW->internalId());
}
}
void WaylandInterface::windowUnmapped()
{
PlasmaWindow *pW = qobject_cast<PlasmaWindow*>(QObject::sender());
if (pW) {
untrackWindow(pW);
emit windowRemoved(pW->internalId());
}
}
void WaylandInterface::trackWindow(KWayland::Client::PlasmaWindow *w)
{
if (!w) {
return;
}
connect(w, &PlasmaWindow::activeChanged, this, &WaylandInterface::updateWindow);
connect(w, &PlasmaWindow::titleChanged, this, &WaylandInterface::updateWindow);
connect(w, &PlasmaWindow::fullscreenChanged, this, &WaylandInterface::updateWindow);
connect(w, &PlasmaWindow::geometryChanged, this, &WaylandInterface::updateWindow);
connect(w, &PlasmaWindow::maximizedChanged, this, &WaylandInterface::updateWindow);
connect(w, &PlasmaWindow::minimizedChanged, this, &WaylandInterface::updateWindow);
connect(w, &PlasmaWindow::shadedChanged, this, &WaylandInterface::updateWindow);
connect(w, &PlasmaWindow::skipTaskbarChanged, this, &WaylandInterface::updateWindow);
connect(w, &PlasmaWindow::onAllDesktopsChanged, this, &WaylandInterface::updateWindow);
connect(w, &PlasmaWindow::parentWindowChanged, this, &WaylandInterface::updateWindow);
#if KF5_VERSION_MINOR >= 52
connect(w, &PlasmaWindow::plasmaVirtualDesktopEntered, this, &WaylandInterface::updateWindow);
connect(w, &PlasmaWindow::plasmaVirtualDesktopLeft, this, &WaylandInterface::updateWindow);
#else
connect(w, &PlasmaWindow::virtualDesktopChanged, this, &WaylandInterface::updateWindow);
#endif
connect(w, &PlasmaWindow::unmapped, this, &WaylandInterface::windowUnmapped);
}
void WaylandInterface::untrackWindow(KWayland::Client::PlasmaWindow *w)
{
if (!w) {
return;
}
disconnect(w, &PlasmaWindow::activeChanged, this, &WaylandInterface::updateWindow);
disconnect(w, &PlasmaWindow::titleChanged, this, &WaylandInterface::updateWindow);
disconnect(w, &PlasmaWindow::fullscreenChanged, this, &WaylandInterface::updateWindow);
disconnect(w, &PlasmaWindow::geometryChanged, this, &WaylandInterface::updateWindow);
disconnect(w, &PlasmaWindow::maximizedChanged, this, &WaylandInterface::updateWindow);
disconnect(w, &PlasmaWindow::minimizedChanged, this, &WaylandInterface::updateWindow);
disconnect(w, &PlasmaWindow::shadedChanged, this, &WaylandInterface::updateWindow);
disconnect(w, &PlasmaWindow::skipTaskbarChanged, this, &WaylandInterface::updateWindow);
disconnect(w, &PlasmaWindow::onAllDesktopsChanged, this, &WaylandInterface::updateWindow);
disconnect(w, &PlasmaWindow::parentWindowChanged, this, &WaylandInterface::updateWindow);
#if KF5_VERSION_MINOR >= 52
disconnect(w, &PlasmaWindow::plasmaVirtualDesktopEntered, this, &WaylandInterface::updateWindow);
disconnect(w, &PlasmaWindow::plasmaVirtualDesktopLeft, this, &WaylandInterface::updateWindow);
#else
disconnect(w, &PlasmaWindow::virtualDesktopChanged, this, &WaylandInterface::updateWindow);
#endif
disconnect(w, &PlasmaWindow::unmapped, this, &WaylandInterface::windowUnmapped);
}
void WaylandInterface::windowCreatedProxy(KWayland::Client::PlasmaWindow *w)
{
if (!isAcceptableWindow(w)) {
return;
}
trackWindow(w);
emit windowAdded(w->internalId());
if (w->appId() == "latte-dock") {
emit latteWindowAdded();
}
}
}
}
#include "waylandinterface.moc"