Do not snap to windows of the Dock type
We do not snap to docks (i.e. panels) since the ones we actually want to snap to (i.e. always visible ones) will restrict the workspace area, and the window will snap to that, effectively snapping to the panel too. Explicitedly avoiding panel snapping solves any possible issue of floating panels, since they change their size when a window gets near them.
This commit is contained in:
parent
de88370577
commit
b59ba5b9b7
2 changed files with 8 additions and 164 deletions
|
@ -54,10 +54,6 @@ private Q_SLOTS:
|
|||
void testPointerMoveEnd_data();
|
||||
void testPointerMoveEnd();
|
||||
void testClientSideMove();
|
||||
void testAdjustClientGeometryOfHiddenX11Panel_data();
|
||||
void testAdjustClientGeometryOfHiddenX11Panel();
|
||||
void testAdjustClientGeometryOfHiddenWaylandPanel_data();
|
||||
void testAdjustClientGeometryOfHiddenWaylandPanel();
|
||||
void testResizeForVirtualKeyboard_data();
|
||||
void testResizeForVirtualKeyboard();
|
||||
void testResizeForVirtualKeyboardWithMaximize();
|
||||
|
@ -535,165 +531,6 @@ void MoveResizeWindowTest::testClientSideMove()
|
|||
QCOMPARE(pointerEnteredSpy.last().last().toPoint(), QPoint(50, 25));
|
||||
}
|
||||
|
||||
void MoveResizeWindowTest::testAdjustClientGeometryOfHiddenX11Panel_data()
|
||||
{
|
||||
QTest::addColumn<QRect>("panelGeometry");
|
||||
QTest::addColumn<QPoint>("targetPoint");
|
||||
QTest::addColumn<QPoint>("expectedAdjustedPoint");
|
||||
QTest::addColumn<quint32>("hideLocation");
|
||||
|
||||
QTest::newRow("top") << QRect(0, 0, 100, 20) << QPoint(50, 25) << QPoint(50, 20) << 0u;
|
||||
QTest::newRow("bottom") << QRect(0, 1024 - 20, 100, 20) << QPoint(50, 1024 - 25 - 50) << QPoint(50, 1024 - 20 - 50) << 2u;
|
||||
QTest::newRow("left") << QRect(0, 0, 20, 100) << QPoint(25, 50) << QPoint(20, 50) << 3u;
|
||||
QTest::newRow("right") << QRect(1280 - 20, 0, 20, 100) << QPoint(1280 - 25 - 100, 50) << QPoint(1280 - 20 - 100, 50) << 1u;
|
||||
}
|
||||
|
||||
void MoveResizeWindowTest::testAdjustClientGeometryOfHiddenX11Panel()
|
||||
{
|
||||
// this test verifies that auto hiding panels are ignored when adjusting client geometry
|
||||
// see BUG 365892
|
||||
|
||||
// first create our panel
|
||||
Test::XcbConnectionPtr c = Test::createX11Connection();
|
||||
QVERIFY(!xcb_connection_has_error(c.get()));
|
||||
|
||||
xcb_window_t windowId = xcb_generate_id(c.get());
|
||||
QFETCH(QRect, panelGeometry);
|
||||
xcb_create_window(c.get(), XCB_COPY_FROM_PARENT, windowId, rootWindow(),
|
||||
panelGeometry.x(), panelGeometry.y(), panelGeometry.width(), panelGeometry.height(),
|
||||
0, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_COPY_FROM_PARENT, 0, nullptr);
|
||||
xcb_size_hints_t hints;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
xcb_icccm_size_hints_set_position(&hints, 1, panelGeometry.x(), panelGeometry.y());
|
||||
xcb_icccm_size_hints_set_size(&hints, 1, panelGeometry.width(), panelGeometry.height());
|
||||
xcb_icccm_set_wm_normal_hints(c.get(), windowId, &hints);
|
||||
NETWinInfo winInfo(c.get(), windowId, rootWindow(), NET::WMWindowType, NET::Properties2());
|
||||
winInfo.setWindowType(NET::Dock);
|
||||
xcb_map_window(c.get(), windowId);
|
||||
xcb_flush(c.get());
|
||||
|
||||
QSignalSpy windowCreatedSpy(workspace(), &Workspace::windowAdded);
|
||||
QVERIFY(windowCreatedSpy.wait());
|
||||
X11Window *panel = windowCreatedSpy.first().first().value<X11Window *>();
|
||||
QVERIFY(panel);
|
||||
QCOMPARE(panel->window(), windowId);
|
||||
QCOMPARE(panel->frameGeometry(), panelGeometry);
|
||||
QVERIFY(panel->isDock());
|
||||
|
||||
// let's create a window
|
||||
std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface());
|
||||
QVERIFY(surface != nullptr);
|
||||
|
||||
std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get()));
|
||||
QVERIFY(shellSurface != nullptr);
|
||||
auto testWindow = Test::renderAndWaitForShown(surface.get(), QSize(100, 50), Qt::blue);
|
||||
|
||||
QVERIFY(testWindow);
|
||||
QVERIFY(testWindow->isMovable());
|
||||
// panel is not yet hidden, we should snap against it
|
||||
QFETCH(QPoint, targetPoint);
|
||||
QTEST(Workspace::self()->adjustWindowPosition(testWindow, targetPoint, false).toPoint(), "expectedAdjustedPoint");
|
||||
|
||||
// now let's hide the panel
|
||||
QSignalSpy panelHiddenSpy(panel, &Window::hiddenChanged);
|
||||
QFETCH(quint32, hideLocation);
|
||||
xcb_change_property(c.get(), XCB_PROP_MODE_REPLACE, windowId, atoms->kde_screen_edge_show, XCB_ATOM_CARDINAL, 32, 1, &hideLocation);
|
||||
xcb_flush(c.get());
|
||||
QVERIFY(panelHiddenSpy.wait());
|
||||
|
||||
// now try to snap again
|
||||
QCOMPARE(Workspace::self()->adjustWindowPosition(testWindow, targetPoint, false), targetPoint);
|
||||
|
||||
// and destroy the panel again
|
||||
xcb_unmap_window(c.get(), windowId);
|
||||
xcb_destroy_window(c.get(), windowId);
|
||||
xcb_flush(c.get());
|
||||
c.reset();
|
||||
|
||||
QSignalSpy panelClosedSpy(panel, &X11Window::closed);
|
||||
QVERIFY(panelClosedSpy.wait());
|
||||
|
||||
// snap once more
|
||||
QCOMPARE(Workspace::self()->adjustWindowPosition(testWindow, targetPoint, false), targetPoint);
|
||||
|
||||
// and close
|
||||
QSignalSpy windowClosedSpy(testWindow, &Window::closed);
|
||||
shellSurface.reset();
|
||||
surface.reset();
|
||||
QVERIFY(windowClosedSpy.wait());
|
||||
}
|
||||
|
||||
void MoveResizeWindowTest::testAdjustClientGeometryOfHiddenWaylandPanel_data()
|
||||
{
|
||||
QTest::addColumn<uint32_t>("anchor");
|
||||
QTest::addColumn<QRect>("panelGeometry");
|
||||
QTest::addColumn<QPoint>("targetPoint");
|
||||
QTest::addColumn<QPoint>("expectedAdjustedPoint");
|
||||
|
||||
QTest::newRow("top") << uint32_t(Test::LayerSurfaceV1::anchor_top) << QRect(0, 0, 1280, 20) << QPoint(50, 25) << QPoint(50, 20);
|
||||
QTest::newRow("bottom") << uint32_t(Test::LayerSurfaceV1::anchor_bottom) << QRect(0, 1024 - 20, 1280, 20) << QPoint(50, 1024 - 25 - 50) << QPoint(50, 1024 - 20 - 50);
|
||||
QTest::newRow("left") << uint32_t(Test::LayerSurfaceV1::anchor_left) << QRect(0, 0, 20, 1024) << QPoint(25, 50) << QPoint(20, 50);
|
||||
QTest::newRow("right") << uint32_t(Test::LayerSurfaceV1::anchor_right) << QRect(1280 - 20, 0, 20, 1024) << QPoint(1280 - 25 - 100, 50) << QPoint(1280 - 20 - 100, 50);
|
||||
}
|
||||
|
||||
void MoveResizeWindowTest::testAdjustClientGeometryOfHiddenWaylandPanel()
|
||||
{
|
||||
// this test verifies that hidden panels are ignored when adjusting client geometry
|
||||
// see BUG 365892
|
||||
|
||||
// first create our panel
|
||||
std::unique_ptr<KWayland::Client::Surface> panelSurface(Test::createSurface());
|
||||
std::unique_ptr<Test::LayerSurfaceV1> panelShellSurface(Test::createLayerSurfaceV1(panelSurface.get(), QStringLiteral("dock")));
|
||||
QFETCH(QRect, panelGeometry);
|
||||
QFETCH(uint32_t, anchor);
|
||||
panelShellSurface->set_anchor(anchor);
|
||||
panelShellSurface->set_size(panelGeometry.width(), panelGeometry.height());
|
||||
panelSurface->commit(KWayland::Client::Surface::CommitFlag::None);
|
||||
|
||||
// let's render
|
||||
QSignalSpy panelConfigureRequestedSpy(panelShellSurface.get(), &Test::LayerSurfaceV1::configureRequested);
|
||||
QVERIFY(panelConfigureRequestedSpy.wait());
|
||||
auto panel = Test::renderAndWaitForShown(panelSurface.get(), panelConfigureRequestedSpy.last().at(1).toSize(), Qt::blue);
|
||||
QVERIFY(panel);
|
||||
QCOMPARE(panel->frameGeometry(), panelGeometry);
|
||||
QVERIFY(panel->isDock());
|
||||
|
||||
// let's create a window
|
||||
std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface());
|
||||
QVERIFY(surface != nullptr);
|
||||
|
||||
std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get()));
|
||||
QVERIFY(shellSurface != nullptr);
|
||||
auto testWindow = Test::renderAndWaitForShown(surface.get(), QSize(100, 50), Qt::blue);
|
||||
|
||||
QVERIFY(testWindow);
|
||||
QVERIFY(testWindow->isMovable());
|
||||
// panel is not yet hidden, we should snap against it
|
||||
QFETCH(QPoint, targetPoint);
|
||||
QTEST(Workspace::self()->adjustWindowPosition(testWindow, targetPoint, false).toPoint(), "expectedAdjustedPoint");
|
||||
|
||||
// now let's hide the panel
|
||||
panel->setHidden(true);
|
||||
|
||||
// now try to snap again
|
||||
QCOMPARE(Workspace::self()->adjustWindowPosition(testWindow, targetPoint, false), targetPoint);
|
||||
|
||||
// and destroy the panel again
|
||||
QSignalSpy panelClosedSpy(panel, &Window::closed);
|
||||
panelShellSurface.reset();
|
||||
panelSurface.reset();
|
||||
QVERIFY(panelClosedSpy.wait());
|
||||
|
||||
// snap once more
|
||||
QCOMPARE(Workspace::self()->adjustWindowPosition(testWindow, targetPoint, false), targetPoint);
|
||||
|
||||
// and close
|
||||
QSignalSpy windowClosedSpy(testWindow, &Window::closed);
|
||||
shellSurface.reset();
|
||||
surface.reset();
|
||||
QVERIFY(windowClosedSpy.wait());
|
||||
}
|
||||
|
||||
void MoveResizeWindowTest::testResizeForVirtualKeyboard_data()
|
||||
{
|
||||
QTest::addColumn<QRect>("windowRect");
|
||||
|
|
|
@ -2719,7 +2719,14 @@ QPointF Workspace::adjustWindowPosition(const Window *window, QPointF pos, bool
|
|||
if (!(*l)->isOnCurrentActivity()) {
|
||||
continue; // wrong activity
|
||||
}
|
||||
if ((*l)->isUnmanaged() || (*l)->isDesktop() || (*l)->isSplash() || (*l)->isNotification() || (*l)->isCriticalNotification() || (*l)->isOnScreenDisplay() || (*l)->isAppletPopup()) {
|
||||
|
||||
// We do not snap to docks (i.e. panels) since the ones we actually want to snap to
|
||||
// (i.e. always visible ones) will restrict the workspace area, and the window will
|
||||
// snap to that, effectively snapping to the panel too. Explicitly avoiding panel
|
||||
// snapping solves any possible issue of floating panels, since they change their
|
||||
// size when a window gets near them.
|
||||
|
||||
if ((*l)->isUnmanaged() || (*l)->isDesktop() || (*l)->isSplash() || (*l)->isNotification() || (*l)->isCriticalNotification() || (*l)->isOnScreenDisplay() || (*l)->isAppletPopup() || (*l)->isDock()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue