From c0b207a2b524b720e54cd583a225b0681ab6e2b2 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 8 Mar 2017 23:54:58 +0100 Subject: [PATCH] support for auto-hidden windows to resize Summary: auto hidden windows were shown again when their geometry changed, this was done for being as easy as possible as the unhide zone changed, but the behavior looked very annoying as autohide panels with an self resize taskbar would unhide themselves every time any window gets open or closed. This makes the edge keep track of windows that can resize/move themselves while auto hidden Test Plan: a self-resizing autohidden panel with a taskbar in it doesn't auto unhide anymore when a window is opened or closed. the unhide area gets properly updated Reviewers: graesslin, #plasma Reviewed By: graesslin, #plasma Subscribers: luebking, plasma-devel, kwin, #kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D4718 --- .../screenedge_client_show_test.cpp | 26 ++++++++++++++----- client.cpp | 7 +++-- client.h | 1 + screenedge.cpp | 11 ++------ 4 files changed, 28 insertions(+), 17 deletions(-) diff --git a/autotests/integration/screenedge_client_show_test.cpp b/autotests/integration/screenedge_client_show_test.cpp index 3aa3779cc2..20b76495c0 100644 --- a/autotests/integration/screenedge_client_show_test.cpp +++ b/autotests/integration/screenedge_client_show_test.cpp @@ -86,15 +86,16 @@ struct XcbConnectionDeleter void ScreenEdgeClientShowTest::testScreenEdgeShowHideX11_data() { QTest::addColumn("windowGeometry"); + QTest::addColumn("resizedWindowGeometry"); QTest::addColumn("location"); QTest::addColumn("triggerPos"); - QTest::newRow("bottom/left") << QRect(50, 1004, 1180, 20) << 2u << QPoint(100, 1023); - QTest::newRow("bottom/right") << QRect(1330, 1004, 1180, 20) << 2u << QPoint(1400, 1023); - QTest::newRow("top/left") << QRect(50, 0, 1180, 20) << 0u << QPoint(100, 0); - QTest::newRow("top/right") << QRect(1330, 0, 1180, 20) << 0u << QPoint(1400, 0); - QTest::newRow("left") << QRect(0, 10, 20, 1000) << 3u << QPoint(0, 50); - QTest::newRow("right") << QRect(2540, 10, 20, 1000) << 1u << QPoint(2559, 60); + QTest::newRow("bottom/left") << QRect(50, 1004, 1180, 20) << QRect(150, 1004, 1000, 20) << 2u << QPoint(100, 1023); + QTest::newRow("bottom/right") << QRect(1330, 1004, 1180, 20) << QRect(1410, 1004, 1000, 20) << 2u << QPoint(1400, 1023); + QTest::newRow("top/left") << QRect(50, 0, 1180, 20) << QRect(150, 0, 1000, 20) << 0u << QPoint(100, 0); + QTest::newRow("top/right") << QRect(1330, 0, 1180, 20) << QRect(1410, 0, 1000, 20) << 0u << QPoint(1400, 0); + QTest::newRow("left") << QRect(0, 10, 20, 1000) << QRect(0, 70, 20, 800) << 3u << QPoint(0, 50); + QTest::newRow("right") << QRect(2540, 10, 20, 1000) << QRect(2540, 70, 20, 800) << 1u << QPoint(2559, 60); } void ScreenEdgeClientShowTest::testScreenEdgeShowHideX11() @@ -161,6 +162,19 @@ void ScreenEdgeClientShowTest::testScreenEdgeShowHideX11() QVERIFY(!client->isHiddenInternal()); QCOMPARE(effectsWindowShownSpy.count(), 1); + //hide window again + Cursor::setPos(QPoint(640, 512)); + xcb_change_property(c.data(), XCB_PROP_MODE_REPLACE, w, atom, XCB_ATOM_CARDINAL, 32, 1, &location); + xcb_flush(c.data()); + QVERIFY(clientHiddenSpy.wait()); + QVERIFY(client->isHiddenInternal()); + QFETCH(QRect, resizedWindowGeometry); + //resizewhile hidden + client->setGeometry(resizedWindowGeometry); + //triggerPos shouldn't be valid anymore + Cursor::setPos(triggerPos); + QVERIFY(client->isHiddenInternal()); + // destroy window again QSignalSpy windowClosedSpy(client, &Client::windowClosed); QVERIFY(windowClosedSpy.isValid()); diff --git a/client.cpp b/client.cpp index 1413951ac4..8c21ae66f1 100644 --- a/client.cpp +++ b/client.cpp @@ -2066,6 +2066,7 @@ void Client::readShowOnScreenEdge(Xcb::Property &property) } if (border != ElectricNone) { disconnect(m_edgeRemoveConnection); + disconnect(m_edgeGeometryTrackingConnection); bool successfullyHidden = false; if (((value >> 8) & 0xFF) == 1) { @@ -2081,8 +2082,9 @@ void Client::readShowOnScreenEdge(Xcb::Property &property) hideClient(true); successfullyHidden = isHiddenInternal(); - m_edgeRemoveConnection = connect(this, &Client::geometryChanged, this, [this](){ - ScreenEdges::self()->reserve(this, ElectricNone); + m_edgeGeometryTrackingConnection = connect(this, &Client::geometryChanged, this, [this, border](){ + hideClient(true); + ScreenEdges::self()->reserve(this, border); }); } @@ -2100,6 +2102,7 @@ void Client::readShowOnScreenEdge(Xcb::Property &property) // TODO: add proper unreserve //this will call showOnScreenEdge to reset the state + disconnect(m_edgeGeometryTrackingConnection); ScreenEdges::self()->reserve(this, ElectricNone); } } diff --git a/client.h b/client.h index 25deaf0461..76dba91500 100644 --- a/client.h +++ b/client.h @@ -604,6 +604,7 @@ private: bool m_clientSideDecorated; QMetaObject::Connection m_edgeRemoveConnection; + QMetaObject::Connection m_edgeGeometryTrackingConnection; }; inline xcb_window_t Client::wrapperId() const diff --git a/screenedge.cpp b/screenedge.cpp index 7e0f2d2263..f28d1f401d 100644 --- a/screenedge.cpp +++ b/screenedge.cpp @@ -986,15 +986,8 @@ void ScreenEdges::reserve(AbstractClient *client, ElectricBorder border) while (it != m_edges.end()) { if ((*it)->client() == client) { hadBorder = true; - if ((*it)->border() == border) { - if (!(*it)->isReserved()) { - (*it)->reserve(); - } - return; - } else { - delete *it; - it = m_edges.erase(it); - } + delete *it; + it = m_edges.erase(it); } else { it++; }