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
This commit is contained in:
Marco Martin 2017-03-08 23:54:58 +01:00
parent dcdcc6ef69
commit c0b207a2b5
4 changed files with 28 additions and 17 deletions

View file

@ -86,15 +86,16 @@ struct XcbConnectionDeleter
void ScreenEdgeClientShowTest::testScreenEdgeShowHideX11_data() void ScreenEdgeClientShowTest::testScreenEdgeShowHideX11_data()
{ {
QTest::addColumn<QRect>("windowGeometry"); QTest::addColumn<QRect>("windowGeometry");
QTest::addColumn<QRect>("resizedWindowGeometry");
QTest::addColumn<quint32>("location"); QTest::addColumn<quint32>("location");
QTest::addColumn<QPoint>("triggerPos"); QTest::addColumn<QPoint>("triggerPos");
QTest::newRow("bottom/left") << QRect(50, 1004, 1180, 20) << 2u << QPoint(100, 1023); 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) << 2u << QPoint(1400, 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) << 0u << QPoint(100, 0); 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) << 0u << QPoint(1400, 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) << 3u << QPoint(0, 50); 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) << 1u << QPoint(2559, 60); QTest::newRow("right") << QRect(2540, 10, 20, 1000) << QRect(2540, 70, 20, 800) << 1u << QPoint(2559, 60);
} }
void ScreenEdgeClientShowTest::testScreenEdgeShowHideX11() void ScreenEdgeClientShowTest::testScreenEdgeShowHideX11()
@ -161,6 +162,19 @@ void ScreenEdgeClientShowTest::testScreenEdgeShowHideX11()
QVERIFY(!client->isHiddenInternal()); QVERIFY(!client->isHiddenInternal());
QCOMPARE(effectsWindowShownSpy.count(), 1); 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 // destroy window again
QSignalSpy windowClosedSpy(client, &Client::windowClosed); QSignalSpy windowClosedSpy(client, &Client::windowClosed);
QVERIFY(windowClosedSpy.isValid()); QVERIFY(windowClosedSpy.isValid());

View file

@ -2066,6 +2066,7 @@ void Client::readShowOnScreenEdge(Xcb::Property &property)
} }
if (border != ElectricNone) { if (border != ElectricNone) {
disconnect(m_edgeRemoveConnection); disconnect(m_edgeRemoveConnection);
disconnect(m_edgeGeometryTrackingConnection);
bool successfullyHidden = false; bool successfullyHidden = false;
if (((value >> 8) & 0xFF) == 1) { if (((value >> 8) & 0xFF) == 1) {
@ -2081,8 +2082,9 @@ void Client::readShowOnScreenEdge(Xcb::Property &property)
hideClient(true); hideClient(true);
successfullyHidden = isHiddenInternal(); successfullyHidden = isHiddenInternal();
m_edgeRemoveConnection = connect(this, &Client::geometryChanged, this, [this](){ m_edgeGeometryTrackingConnection = connect(this, &Client::geometryChanged, this, [this, border](){
ScreenEdges::self()->reserve(this, ElectricNone); hideClient(true);
ScreenEdges::self()->reserve(this, border);
}); });
} }
@ -2100,6 +2102,7 @@ void Client::readShowOnScreenEdge(Xcb::Property &property)
// TODO: add proper unreserve // TODO: add proper unreserve
//this will call showOnScreenEdge to reset the state //this will call showOnScreenEdge to reset the state
disconnect(m_edgeGeometryTrackingConnection);
ScreenEdges::self()->reserve(this, ElectricNone); ScreenEdges::self()->reserve(this, ElectricNone);
} }
} }

View file

@ -604,6 +604,7 @@ private:
bool m_clientSideDecorated; bool m_clientSideDecorated;
QMetaObject::Connection m_edgeRemoveConnection; QMetaObject::Connection m_edgeRemoveConnection;
QMetaObject::Connection m_edgeGeometryTrackingConnection;
}; };
inline xcb_window_t Client::wrapperId() const inline xcb_window_t Client::wrapperId() const

View file

@ -986,15 +986,8 @@ void ScreenEdges::reserve(AbstractClient *client, ElectricBorder border)
while (it != m_edges.end()) { while (it != m_edges.end()) {
if ((*it)->client() == client) { if ((*it)->client() == client) {
hadBorder = true; hadBorder = true;
if ((*it)->border() == border) { delete *it;
if (!(*it)->isReserved()) { it = m_edges.erase(it);
(*it)->reserve();
}
return;
} else {
delete *it;
it = m_edges.erase(it);
}
} else { } else {
it++; it++;
} }