diff --git a/autotests/client/test_wayland_windowmanagement.cpp b/autotests/client/test_wayland_windowmanagement.cpp index e82f5dc..9a6a720 100644 --- a/autotests/client/test_wayland_windowmanagement.cpp +++ b/autotests/client/test_wayland_windowmanagement.cpp @@ -1,262 +1,313 @@ /******************************************************************** Copyright 2015 Marco Martin This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . *********************************************************************/ // Qt #include // KWin #include "../../src/client/compositor.h" #include "../../src/client/connection_thread.h" #include "../../src/client/event_queue.h" #include "../../src/client/region.h" #include "../../src/client/registry.h" #include "../../src/client/surface.h" #include "../../src/client/plasmawindowmanagement.h" #include "../../src/client/surface.h" #include "../../src/server/display.h" #include "../../src/server/compositor_interface.h" #include "../../src/server/region_interface.h" #include "../../src/server/plasmawindowmanagement_interface.h" #include "../../src/server/surface_interface.h" class TestWindowManagement : public QObject { Q_OBJECT public: explicit TestWindowManagement(QObject *parent = nullptr); private Q_SLOTS: void init(); void testWindowTitle(); void testMinimizedGeometry(); void testUseAfterUnmap(); void testServerDelete(); + void testActiveWindowOnUnmapped(); + void testDeleteActiveWindow(); void cleanup(); private: KWayland::Server::Display *m_display; KWayland::Server::CompositorInterface *m_compositorInterface; KWayland::Server::PlasmaWindowManagementInterface *m_windowManagementInterface; KWayland::Server::PlasmaWindowInterface *m_windowInterface; KWayland::Server::SurfaceInterface *m_surfaceInterface = nullptr; KWayland::Client::Surface *m_surface = nullptr; KWayland::Client::ConnectionThread *m_connection; KWayland::Client::Compositor *m_compositor; KWayland::Client::EventQueue *m_queue; KWayland::Client::PlasmaWindowManagement *m_windowManagement; KWayland::Client::PlasmaWindow *m_window; QThread *m_thread; KWayland::Client::Registry *m_registry; }; static const QString s_socketName = QStringLiteral("kwayland-test-wayland-windowmanagement-0"); TestWindowManagement::TestWindowManagement(QObject *parent) : QObject(parent) , m_display(nullptr) , m_compositorInterface(nullptr) , m_connection(nullptr) , m_compositor(nullptr) , m_queue(nullptr) , m_thread(nullptr) { } void TestWindowManagement::init() { using namespace KWayland::Server; delete m_display; m_display = new Display(this); m_display->setSocketName(s_socketName); m_display->start(); QVERIFY(m_display->isRunning()); // setup connection m_connection = new KWayland::Client::ConnectionThread; QSignalSpy connectedSpy(m_connection, SIGNAL(connected())); m_connection->setSocketName(s_socketName); m_thread = new QThread(this); m_connection->moveToThread(m_thread); m_thread->start(); m_connection->initConnection(); QVERIFY(connectedSpy.wait()); m_queue = new KWayland::Client::EventQueue(this); QVERIFY(!m_queue->isValid()); m_queue->setup(m_connection); QVERIFY(m_queue->isValid()); m_registry = new KWayland::Client::Registry(this); QSignalSpy compositorSpy(m_registry, SIGNAL(compositorAnnounced(quint32,quint32))); QVERIFY(compositorSpy.isValid()); QSignalSpy windowManagementSpy(m_registry, SIGNAL(plasmaWindowManagementAnnounced(quint32,quint32))); QVERIFY(windowManagementSpy.isValid()); QVERIFY(!m_registry->eventQueue()); m_registry->setEventQueue(m_queue); QCOMPARE(m_registry->eventQueue(), m_queue); m_registry->create(m_connection->display()); QVERIFY(m_registry->isValid()); m_registry->setup(); m_compositorInterface = m_display->createCompositor(m_display); m_compositorInterface->create(); QVERIFY(m_compositorInterface->isValid()); QVERIFY(compositorSpy.wait()); m_compositor = m_registry->createCompositor(compositorSpy.first().first().value(), compositorSpy.first().last().value(), this); m_windowManagementInterface = m_display->createPlasmaWindowManagement(m_display); m_windowManagementInterface->create(); QVERIFY(m_windowManagementInterface->isValid()); QVERIFY(windowManagementSpy.wait()); m_windowManagement = m_registry->createPlasmaWindowManagement(windowManagementSpy.first().first().value(), windowManagementSpy.first().last().value(), this); QSignalSpy windowSpy(m_windowManagement, SIGNAL(windowCreated(KWayland::Client::PlasmaWindow *))); QVERIFY(windowSpy.isValid()); m_windowInterface = m_windowManagementInterface->createWindow(this); QVERIFY(windowSpy.wait()); m_window = windowSpy.first().first().value(); QSignalSpy serverSurfaceCreated(m_compositorInterface, SIGNAL(surfaceCreated(KWayland::Server::SurfaceInterface*))); QVERIFY(serverSurfaceCreated.isValid()); m_surface = m_compositor->createSurface(this); QVERIFY(m_surface); QVERIFY(serverSurfaceCreated.wait()); m_surfaceInterface = serverSurfaceCreated.first().first().value(); QVERIFY(m_surfaceInterface); } void TestWindowManagement::testWindowTitle() { m_windowInterface->setTitle(QStringLiteral("Test Title")); QSignalSpy titleSpy(m_window, SIGNAL(titleChanged())); QVERIFY(titleSpy.isValid()); QVERIFY(titleSpy.wait()); QCOMPARE(m_window->title(), QString::fromUtf8("Test Title")); } void TestWindowManagement::testMinimizedGeometry() { m_window->setMinimizedGeometry(m_surface, QRect(5, 10, 100, 200)); QSignalSpy geometrySpy(m_windowInterface, SIGNAL(minimizedGeometriesChanged())); QVERIFY(geometrySpy.isValid()); QVERIFY(geometrySpy.wait()); QCOMPARE(m_windowInterface->minimizedGeometries().values().first(), QRect(5, 10, 100, 200)); m_window->unsetMinimizedGeometry(m_surface); QVERIFY(geometrySpy.wait()); QVERIFY(m_windowInterface->minimizedGeometries().isEmpty()); } void TestWindowManagement::cleanup() { if (m_surface) { delete m_surface; m_surface = nullptr; } if (m_compositor) { delete m_compositor; m_compositor = nullptr; } if (m_queue) { delete m_queue; m_queue = nullptr; } if (m_windowManagement) { delete m_windowManagement; m_windowManagement = nullptr; } if (m_registry) { delete m_registry; m_registry = nullptr; } if (m_thread) { if (m_connection) { m_connection->deleteLater(); } m_thread->quit(); m_thread->wait(); delete m_thread; m_thread = nullptr; } m_connection = nullptr; delete m_windowManagementInterface; m_windowManagementInterface = nullptr; delete m_windowInterface; m_windowInterface = nullptr; delete m_surfaceInterface; m_surfaceInterface = nullptr; delete m_display; m_display = nullptr; } void TestWindowManagement::testUseAfterUnmap() { // this test verifies that when the client uses a window after it's unmapped, things don't break QSignalSpy unmappedSpy(m_window, &KWayland::Client::PlasmaWindow::unmapped); QVERIFY(unmappedSpy.isValid()); QSignalSpy destroyedSpy(m_window, &QObject::destroyed); QVERIFY(destroyedSpy.isValid()); m_windowInterface->unmap(); m_window->requestClose(); QVERIFY(unmappedSpy.wait()); QVERIFY(destroyedSpy.wait()); m_window = nullptr; QSignalSpy serverDestroyedSpy(m_windowInterface, &QObject::destroyed); QVERIFY(serverDestroyedSpy.isValid()); QVERIFY(serverDestroyedSpy.wait()); m_windowInterface = nullptr; } void TestWindowManagement::testServerDelete() { QSignalSpy unmappedSpy(m_window, &KWayland::Client::PlasmaWindow::unmapped); QVERIFY(unmappedSpy.isValid()); QSignalSpy destroyedSpy(m_window, &QObject::destroyed); QVERIFY(destroyedSpy.isValid()); delete m_windowInterface; m_windowInterface = nullptr; QVERIFY(unmappedSpy.wait()); QVERIFY(destroyedSpy.wait()); m_window = nullptr; } +void TestWindowManagement::testActiveWindowOnUnmapped() +{ + // This test verifies that unmapping the active window changes the active window. + // first make the window active + QVERIFY(!m_windowManagement->activeWindow()); + QVERIFY(!m_window->isActive()); + QSignalSpy activeWindowChangedSpy(m_windowManagement, &KWayland::Client::PlasmaWindowManagement::activeWindowChanged); + QVERIFY(activeWindowChangedSpy.isValid()); + m_windowInterface->setActive(true); + QVERIFY(activeWindowChangedSpy.wait()); + QCOMPARE(m_windowManagement->activeWindow(), m_window); + QVERIFY(m_window->isActive()); + + // now unmap should change the active window + QSignalSpy destroyedSpy(m_window, &QObject::destroyed); + QVERIFY(destroyedSpy.isValid()); + QSignalSpy serverDestroyedSpy(m_windowInterface, &QObject::destroyed); + QVERIFY(serverDestroyedSpy.isValid()); + m_windowManagementInterface->unmapWindow(m_windowInterface); + QVERIFY(activeWindowChangedSpy.wait()); + QVERIFY(!m_windowManagement->activeWindow()); + QVERIFY(destroyedSpy.wait()); + QCOMPARE(destroyedSpy.count(), 1); + m_window = nullptr; + QVERIFY(serverDestroyedSpy.wait()); + m_windowInterface = nullptr; +} + +void TestWindowManagement::testDeleteActiveWindow() +{ + // This test verifies that deleting the active window on client side changes the active window + // first make the window active + QVERIFY(!m_windowManagement->activeWindow()); + QVERIFY(!m_window->isActive()); + QSignalSpy activeWindowChangedSpy(m_windowManagement, &KWayland::Client::PlasmaWindowManagement::activeWindowChanged); + QVERIFY(activeWindowChangedSpy.isValid()); + m_windowInterface->setActive(true); + QVERIFY(activeWindowChangedSpy.wait()); + QCOMPARE(activeWindowChangedSpy.count(), 1); + QCOMPARE(m_windowManagement->activeWindow(), m_window); + QVERIFY(m_window->isActive()); + + // delete the client side window - that's semantically kind of wrong, but shouldn't make our code crash + delete m_window; + m_window = nullptr; + QCOMPARE(activeWindowChangedSpy.count(), 2); + QVERIFY(!m_windowManagement->activeWindow()); +} + QTEST_GUILESS_MAIN(TestWindowManagement) #include "test_wayland_windowmanagement.moc" diff --git a/src/client/plasmawindowmanagement.cpp b/src/client/plasmawindowmanagement.cpp index 23a4423..ab5474e 100644 --- a/src/client/plasmawindowmanagement.cpp +++ b/src/client/plasmawindowmanagement.cpp @@ -1,792 +1,804 @@ /******************************************************************** Copyright 2015 Martin Gräßlin This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . *********************************************************************/ #include "plasmawindowmanagement.h" #include "plasmawindowmodel.h" #include "event_queue.h" #include "output.h" #include "surface.h" #include "wayland_pointer_p.h" // Wayland #include #include namespace KWayland { namespace Client { class PlasmaWindowManagement::Private { public: Private(PlasmaWindowManagement *q); WaylandPointer wm; EventQueue *queue = nullptr; bool showingDesktop = false; QList windows; PlasmaWindow *activeWindow = nullptr; void setup(org_kde_plasma_window_management *wm); private: static void showDesktopCallback(void *data, org_kde_plasma_window_management *org_kde_plasma_window_management, uint32_t state); static void windowCallback(void *data, org_kde_plasma_window_management *org_kde_plasma_window_management, uint32_t id); void setShowDesktop(bool set); void windowCreated(org_kde_plasma_window *id, quint32 internalId); static struct org_kde_plasma_window_management_listener s_listener; PlasmaWindowManagement *q; }; PlasmaWindowManagement::Private::Private(PlasmaWindowManagement *q) : q(q) { } org_kde_plasma_window_management_listener PlasmaWindowManagement::Private::s_listener = { showDesktopCallback, windowCallback }; void PlasmaWindowManagement::Private::setup(org_kde_plasma_window_management *windowManagement) { Q_ASSERT(!wm); Q_ASSERT(windowManagement); wm.setup(windowManagement); org_kde_plasma_window_management_add_listener(windowManagement, &s_listener, this); } void PlasmaWindowManagement::Private::showDesktopCallback(void *data, org_kde_plasma_window_management *org_kde_plasma_window_management, uint32_t state) { auto wm = reinterpret_cast(data); Q_ASSERT(wm->wm == org_kde_plasma_window_management); switch (state) { case ORG_KDE_PLASMA_WINDOW_MANAGEMENT_SHOW_DESKTOP_ENABLED: wm->setShowDesktop(true); break; case ORG_KDE_PLASMA_WINDOW_MANAGEMENT_SHOW_DESKTOP_DISABLED: wm->setShowDesktop(false); break; default: Q_UNREACHABLE(); break; } } void PlasmaWindowManagement::Private::setShowDesktop(bool set) { if (showingDesktop == set) { return; } showingDesktop = set; emit q->showingDesktopChanged(showingDesktop); } void PlasmaWindowManagement::Private::windowCallback(void *data, org_kde_plasma_window_management *interface, uint32_t id) { auto wm = reinterpret_cast(data); Q_ASSERT(wm->wm == interface); QTimer *timer = new QTimer(); timer->setSingleShot(true); timer->setInterval(0); QObject::connect(timer, &QTimer::timeout, wm->q, [timer, wm, id] { wm->windowCreated(org_kde_plasma_window_management_get_window(wm->wm, id), id); timer->deleteLater(); }, Qt::QueuedConnection ); timer->start(); } void PlasmaWindowManagement::Private::windowCreated(org_kde_plasma_window *id, quint32 internalId) { if (queue) { queue->addProxy(id); } PlasmaWindow *window = new PlasmaWindow(q, id, internalId); windows << window; QObject::connect(window, &QObject::destroyed, q, [this, window] { windows.removeAll(window); + if (activeWindow == window) { + activeWindow = nullptr; + emit q->activeWindowChanged(); + } + } + ); + QObject::connect(window, &PlasmaWindow::unmapped, q, + [this, window] { + if (activeWindow == window) { + activeWindow = nullptr; + emit q->activeWindowChanged(); + } } ); QObject::connect(window, &PlasmaWindow::activeChanged, q, [this, window] { if (window->isActive()) { if (activeWindow == window) { return; } activeWindow = window; emit q->activeWindowChanged(); } else { if (activeWindow == window) { activeWindow = nullptr; emit q->activeWindowChanged(); } } } ); emit q->windowCreated(window); } PlasmaWindowManagement::PlasmaWindowManagement(QObject *parent) : QObject(parent) , d(new Private(this)) { } PlasmaWindowManagement::~PlasmaWindowManagement() { release(); } void PlasmaWindowManagement::destroy() { if (!d->wm) { return; } emit interfaceAboutToBeDestroyed(); d->wm.destroy(); } void PlasmaWindowManagement::release() { if (!d->wm) { return; } emit interfaceAboutToBeReleased(); d->wm.release(); } void PlasmaWindowManagement::setup(org_kde_plasma_window_management *wm) { d->setup(wm); } void PlasmaWindowManagement::setEventQueue(EventQueue *queue) { d->queue = queue; } EventQueue *PlasmaWindowManagement::eventQueue() { return d->queue; } bool PlasmaWindowManagement::isValid() const { return d->wm.isValid(); } PlasmaWindowManagement::operator org_kde_plasma_window_management*() { return d->wm; } PlasmaWindowManagement::operator org_kde_plasma_window_management*() const { return d->wm; } void PlasmaWindowManagement::hideDesktop() { setShowingDesktop(false); } void PlasmaWindowManagement::showDesktop() { setShowingDesktop(true); } void PlasmaWindowManagement::setShowingDesktop(bool show) { org_kde_plasma_window_management_show_desktop(d->wm, show ? ORG_KDE_PLASMA_WINDOW_MANAGEMENT_SHOW_DESKTOP_ENABLED : ORG_KDE_PLASMA_WINDOW_MANAGEMENT_SHOW_DESKTOP_DISABLED); } bool PlasmaWindowManagement::isShowingDesktop() const { return d->showingDesktop; } QList< PlasmaWindow* > PlasmaWindowManagement::windows() const { return d->windows; } PlasmaWindow *PlasmaWindowManagement::activeWindow() const { return d->activeWindow; } PlasmaWindowModel *PlasmaWindowManagement::createWindowModel() { return new PlasmaWindowModel(this); } class PlasmaWindow::Private { public: Private(org_kde_plasma_window *window, quint32 internalId, PlasmaWindow *q); WaylandPointer window; quint32 internalId; QString title; QString appId; quint32 desktop = 0; bool active = false; bool minimized = false; bool maximized = false; bool fullscreen = false; bool keepAbove = false; bool keepBelow = false; bool onAllDesktops = false; bool demandsAttention = false; bool closeable = false; bool minimizeable = false; bool maximizeable = false; bool fullscreenable = false; bool skipTaskbar = false; bool shadeable = false; bool shaded = false; bool movable = false; bool resizable = false; bool virtualDesktopChangeable = false; QIcon icon; private: static void titleChangedCallback(void *data, org_kde_plasma_window *window, const char *title); static void appIdChangedCallback(void *data, org_kde_plasma_window *window, const char *app_id); static void stateChangedCallback(void *data, org_kde_plasma_window *window, uint32_t state); static void virtualDesktopChangedCallback(void *data, org_kde_plasma_window *window, int32_t number); static void themedIconNameChangedCallback(void *data, org_kde_plasma_window *window, const char *name); static void unmappedCallback(void *data, org_kde_plasma_window *window); void setActive(bool set); void setMinimized(bool set); void setMaximized(bool set); void setFullscreen(bool set); void setKeepAbove(bool set); void setKeepBelow(bool set); void setOnAllDesktops(bool set); void setDemandsAttention(bool set); void setCloseable(bool set); void setMinimizeable(bool set); void setMaximizeable(bool set); void setFullscreenable(bool set); void setSkipTaskbar(bool skip); void setShadeable(bool set); void setShaded(bool set); void setMovable(bool set); void setResizable(bool set); void setVirtualDesktopChangeable(bool set); static Private *cast(void *data) { return reinterpret_cast(data); } PlasmaWindow *q; static struct org_kde_plasma_window_listener s_listener; }; org_kde_plasma_window_listener PlasmaWindow::Private::s_listener = { titleChangedCallback, appIdChangedCallback, stateChangedCallback, virtualDesktopChangedCallback, themedIconNameChangedCallback, unmappedCallback }; void PlasmaWindow::Private::titleChangedCallback(void *data, org_kde_plasma_window *window, const char *title) { Q_UNUSED(window) Private *p = cast(data); const QString t = QString::fromUtf8(title); if (p->title == t) { return; } p->title = t; emit p->q->titleChanged(); } void PlasmaWindow::Private::appIdChangedCallback(void *data, org_kde_plasma_window *window, const char *appId) { Q_UNUSED(window) Private *p = cast(data); const QString s = QString::fromUtf8(appId); if (s == p->appId) { return; } p->appId = s; emit p->q->appIdChanged(); } void PlasmaWindow::Private::virtualDesktopChangedCallback(void *data, org_kde_plasma_window *window, int32_t number) { Q_UNUSED(window) Private *p = cast(data); if (p->desktop == static_cast(number)) { return; } p->desktop = number; emit p->q->virtualDesktopChanged(); } void PlasmaWindow::Private::unmappedCallback(void *data, org_kde_plasma_window *window) { auto p = cast(data); Q_UNUSED(window); emit p->q->unmapped(); p->q->deleteLater(); } void PlasmaWindow::Private::stateChangedCallback(void *data, org_kde_plasma_window *window, uint32_t state) { auto p = cast(data); Q_UNUSED(window); p->setActive(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_ACTIVE); p->setMinimized(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MINIMIZED); p->setMaximized(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MAXIMIZED); p->setFullscreen(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_FULLSCREEN); p->setKeepAbove(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_KEEP_ABOVE); p->setKeepBelow(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_KEEP_BELOW); p->setOnAllDesktops(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_ON_ALL_DESKTOPS); p->setDemandsAttention(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_DEMANDS_ATTENTION); p->setCloseable(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_CLOSEABLE); p->setFullscreenable(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_FULLSCREENABLE); p->setMaximizeable(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MAXIMIZABLE); p->setMinimizeable(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MINIMIZABLE); p->setSkipTaskbar(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SKIPTASKBAR); p->setShadeable(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SHADEABLE); p->setShaded(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SHADED); p->setMovable(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MOVABLE); p->setResizable(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_RESIZABLE); p->setVirtualDesktopChangeable(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_VIRTUAL_DESKTOP_CHANGEABLE); } void PlasmaWindow::Private::themedIconNameChangedCallback(void *data, org_kde_plasma_window *window, const char *name) { auto p = cast(data); Q_UNUSED(window); QIcon icon = QIcon::fromTheme(QString::fromUtf8(name)); p->icon = icon; emit p->q->iconChanged(); } void PlasmaWindow::Private::setActive(bool set) { if (active == set) { return; } active = set; emit q->activeChanged(); } void PlasmaWindow::Private::setFullscreen(bool set) { if (fullscreen == set) { return; } fullscreen = set; emit q->fullscreenChanged(); } void PlasmaWindow::Private::setKeepAbove(bool set) { if (keepAbove == set) { return; } keepAbove = set; emit q->keepAboveChanged(); } void PlasmaWindow::Private::setKeepBelow(bool set) { if (keepBelow == set) { return; } keepBelow = set; emit q->keepBelowChanged(); } void PlasmaWindow::Private::setMaximized(bool set) { if (maximized == set) { return; } maximized = set; emit q->maximizedChanged(); } void PlasmaWindow::Private::setMinimized(bool set) { if (minimized == set) { return; } minimized = set; emit q->minimizedChanged(); } void PlasmaWindow::Private::setOnAllDesktops(bool set) { if (onAllDesktops == set) { return; } onAllDesktops = set; emit q->onAllDesktopsChanged(); } void PlasmaWindow::Private::setDemandsAttention(bool set) { if (demandsAttention == set) { return; } demandsAttention = set; emit q->demandsAttentionChanged(); } void PlasmaWindow::Private::setCloseable(bool set) { if (closeable == set) { return; } closeable = set; emit q->closeableChanged(); } void PlasmaWindow::Private::setFullscreenable(bool set) { if (fullscreenable == set) { return; } fullscreenable = set; emit q->fullscreenableChanged(); } void PlasmaWindow::Private::setMaximizeable(bool set) { if (maximizeable == set) { return; } maximizeable = set; emit q->maximizeableChanged(); } void PlasmaWindow::Private::setMinimizeable(bool set) { if (minimizeable == set) { return; } minimizeable = set; emit q->minimizeableChanged(); } void PlasmaWindow::Private::setSkipTaskbar(bool skip) { if (skipTaskbar == skip) { return; } skipTaskbar = skip; emit q->skipTaskbarChanged(); } void PlasmaWindow::Private::setShadeable(bool set) { if (shadeable == set) { return; } shadeable = set; emit q->shadeableChanged(); } void PlasmaWindow::Private::setShaded(bool set) { if (shaded == set) { return; } shaded = set; emit q->shadedChanged(); } void PlasmaWindow::Private::setMovable(bool set) { if (movable == set) { return; } movable = set; emit q->movableChanged(); } void PlasmaWindow::Private::setResizable(bool set) { if (resizable == set) { return; } resizable = set; emit q->resizableChanged(); } void PlasmaWindow::Private::setVirtualDesktopChangeable(bool set) { if (virtualDesktopChangeable == set) { return; } virtualDesktopChangeable = set; emit q->virtualDesktopChangeableChanged(); } PlasmaWindow::Private::Private(org_kde_plasma_window *w, quint32 internalId, PlasmaWindow *q) : internalId(internalId) , q(q) { window.setup(w); org_kde_plasma_window_add_listener(w, &s_listener, this); } PlasmaWindow::PlasmaWindow(PlasmaWindowManagement *parent, org_kde_plasma_window *window, quint32 internalId) : QObject(parent) , d(new Private(window, internalId, this)) { } PlasmaWindow::~PlasmaWindow() { release(); } void PlasmaWindow::destroy() { d->window.destroy(); } void PlasmaWindow::release() { d->window.release(); } bool PlasmaWindow::isValid() const { return d->window.isValid(); } PlasmaWindow::operator org_kde_plasma_window*() const { return d->window; } PlasmaWindow::operator org_kde_plasma_window*() { return d->window; } QString PlasmaWindow::appId() const { return d->appId; } QString PlasmaWindow::title() const { return d->title; } quint32 PlasmaWindow::virtualDesktop() const { return d->desktop; } bool PlasmaWindow::isActive() const { return d->active; } bool PlasmaWindow::isFullscreen() const { return d->fullscreen; } bool PlasmaWindow::isKeepAbove() const { return d->keepAbove; } bool PlasmaWindow::isKeepBelow() const { return d->keepBelow; } bool PlasmaWindow::isMaximized() const { return d->maximized; } bool PlasmaWindow::isMinimized() const { return d->minimized; } bool PlasmaWindow::isOnAllDesktops() const { return d->onAllDesktops; } bool PlasmaWindow::isDemandingAttention() const { return d->demandsAttention; } bool PlasmaWindow::isCloseable() const { return d->closeable; } bool PlasmaWindow::isFullscreenable() const { return d->fullscreenable; } bool PlasmaWindow::isMaximizeable() const { return d->maximizeable; } bool PlasmaWindow::isMinimizeable() const { return d->minimizeable; } bool PlasmaWindow::skipTaskbar() const { return d->skipTaskbar; } QIcon PlasmaWindow::icon() const { return d->icon; } bool PlasmaWindow::isShadeable() const { return d->shadeable; } bool PlasmaWindow::isShaded() const { return d->shaded; } bool PlasmaWindow::isResizable() const { return d->resizable; } bool PlasmaWindow::isMovable() const { return d->movable; } bool PlasmaWindow::isVirtualDesktopChangeable() const { return d->virtualDesktopChangeable; } void PlasmaWindow::requestActivate() { org_kde_plasma_window_set_state(d->window, ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_ACTIVE, ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_ACTIVE); } void PlasmaWindow::requestClose() { org_kde_plasma_window_close(d->window); } void PlasmaWindow::requestMove() { org_kde_plasma_window_request_move(d->window); } void PlasmaWindow::requestResize() { org_kde_plasma_window_request_resize(d->window); } void PlasmaWindow::requestVirtualDesktop(quint32 desktop) { org_kde_plasma_window_set_virtual_desktop(d->window, desktop); } void PlasmaWindow::requestToggleMinimized() { if (d->minimized) { org_kde_plasma_window_set_state(d->window, ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MINIMIZED, 0); } else { org_kde_plasma_window_set_state(d->window, ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MINIMIZED, ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MINIMIZED); } } void PlasmaWindow::requestToggleMaximized() { if (d->maximized) { org_kde_plasma_window_set_state(d->window, ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MAXIMIZED, 0); } else { org_kde_plasma_window_set_state(d->window, ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MAXIMIZED, ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MAXIMIZED); } } void PlasmaWindow::setMinimizedGeometry(Surface *panel, const QRect &geom) { org_kde_plasma_window_set_minimized_geometry(d->window, *panel, geom.x(), geom.y(), geom.width(), geom.height()); } void PlasmaWindow::unsetMinimizedGeometry(Surface *panel) { org_kde_plasma_window_unset_minimized_geometry(d->window, *panel); } void PlasmaWindow::requestToggleShaded() { if (d->shaded) { org_kde_plasma_window_set_state(d->window, ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SHADED, 0); } else { org_kde_plasma_window_set_state(d->window, ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SHADED, ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SHADED); } } quint32 PlasmaWindow::internalId() const { return d->internalId; } } }