Commit 9b3d9e58 authored by Arjen Hiemstra's avatar Arjen Hiemstra
Browse files

ScreenEdge: Do not use localtime for measuring duration

Summary:
QDateTime::fromMSecSinceEpoch uses Qt::LocalTime by default. This involves an
expensive localtime conversion. So instead force things to use UTC, as there
is no need for timezone information when tracking durations.

This is especially noticeable on Bedrock Linux, which uses a Fuse mounted
/etc, which is slower than a plain /etc and causes quite some slowdown there.
See https://github.com/bedrocklinux/bedrocklinux-userland/issues/140 for
details.

Test Plan: The screenedge unit test still passes.

Reviewers: #kwin, davidedmundson

Reviewed By: #kwin, davidedmundson

Subscribers: zzag, anthonyfieroni, davidedmundson, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D27114
parent 9ca27c66
......@@ -1330,7 +1330,7 @@ void AbstractClient::handleMoveResize(int x, int y, int x_root, int y_root)
performMoveResize();
if (isMove()) {
ScreenEdges::self()->check(globalPos, QDateTime::fromMSecsSinceEpoch(xTime()));
ScreenEdges::self()->check(globalPos, QDateTime::fromMSecsSinceEpoch(xTime(), Qt::UTC));
}
}
......
......@@ -468,7 +468,7 @@ void TestScreenEdges::testCallback()
event.time = QDateTime::currentMSecsSinceEpoch();
setPos(QPoint(0, 50));
auto isEntered = [s] (xcb_enter_notify_event_t *event) {
return s->handleEnterNotifiy(event->event, QPoint(event->root_x, event->root_y), QDateTime::fromMSecsSinceEpoch(event->time));
return s->handleEnterNotifiy(event->event, QPoint(event->root_x, event->root_y), QDateTime::fromMSecsSinceEpoch(event->time, Qt::UTC));
};
QVERIFY(isEntered(&event));
// doesn't trigger as the edge was not triggered yet
......@@ -574,12 +574,12 @@ void TestScreenEdges::testCallbackWithCheck()
s->reserve(ElectricLeft, &callback, "callback");
// check activating a different edge doesn't do anything
s->check(QPoint(50, 0), QDateTime::currentDateTime(), true);
s->check(QPoint(50, 0), QDateTime::currentDateTimeUtc(), true);
QVERIFY(spy.isEmpty());
// try a direct activate without pushback
Cursor::setPos(0, 50);
s->check(QPoint(0, 50), QDateTime::currentDateTime(), true);
s->check(QPoint(0, 50), QDateTime::currentDateTimeUtc(), true);
QCOMPARE(spy.count(), 1);
QEXPECT_FAIL("", "Argument says force no pushback, but it gets pushed back. Needs investigation", Continue);
QCOMPARE(Cursor::pos(), QPoint(0, 50));
......@@ -587,14 +587,14 @@ void TestScreenEdges::testCallbackWithCheck()
// use a different edge, this time with pushback
s->reserve(KWin::ElectricRight, &callback, "callback");
Cursor::setPos(99, 50);
s->check(QPoint(99, 50), QDateTime::currentDateTime());
s->check(QPoint(99, 50), QDateTime::currentDateTimeUtc());
QCOMPARE(spy.count(), 1);
QCOMPARE(spy.last().first().value<ElectricBorder>(), ElectricLeft);
QCOMPARE(Cursor::pos(), QPoint(98, 50));
// and trigger it again
QTest::qWait(160);
Cursor::setPos(99, 50);
s->check(QPoint(99, 50), QDateTime::currentDateTime());
s->check(QPoint(99, 50), QDateTime::currentDateTimeUtc());
QCOMPARE(spy.count(), 2);
QCOMPARE(spy.last().first().value<ElectricBorder>(), ElectricRight);
QCOMPARE(Cursor::pos(), QPoint(98, 50));
......@@ -658,7 +658,7 @@ void TestScreenEdges::testPushBack()
// do the same without the event, but the check method
Cursor::setPos(trigger);
s->check(trigger, QDateTime::currentDateTime());
s->check(trigger, QDateTime::currentDateTimeUtc());
QVERIFY(spy.isEmpty());
QTEST(Cursor::pos(), "expected");
}
......@@ -863,7 +863,7 @@ void TestScreenEdges::testClientEdge()
s->reserve(&client, KWin::ElectricTop);
QCOMPARE(client.isHiddenInternal(), true);
Cursor::setPos(50, 0);
s->check(QPoint(50, 0), QDateTime::currentDateTime());
s->check(QPoint(50, 0), QDateTime::currentDateTimeUtc());
QCOMPARE(client.isHiddenInternal(), false);
QCOMPARE(Cursor::pos(), QPoint(50, 1));
......@@ -872,7 +872,7 @@ void TestScreenEdges::testClientEdge()
// check on previous edge again, should fail
client.setHiddenInternal(true);
Cursor::setPos(50, 0);
s->check(QPoint(50, 0), QDateTime::currentDateTime());
s->check(QPoint(50, 0), QDateTime::currentDateTimeUtc());
QCOMPARE(client.isHiddenInternal(), true);
QCOMPARE(Cursor::pos(), QPoint(50, 0));
......@@ -960,12 +960,12 @@ void TestScreenEdges::testTouchEdge()
event.time = QDateTime::currentMSecsSinceEpoch();
setPos(QPoint(0, 50));
auto isEntered = [s] (xcb_enter_notify_event_t *event) {
return s->handleEnterNotifiy(event->event, QPoint(event->root_x, event->root_y), QDateTime::fromMSecsSinceEpoch(event->time));
return s->handleEnterNotifiy(event->event, QPoint(event->root_x, event->root_y), QDateTime::fromMSecsSinceEpoch(event->time, Qt::UTC));
};
QCOMPARE(isEntered(&event), false);
QVERIFY(approachingSpy.isEmpty());
// let's also verify the check
s->check(QPoint(0, 50), QDateTime::currentDateTime(), false);
s->check(QPoint(0, 50), QDateTime::currentDateTimeUtc(), false);
QVERIFY(approachingSpy.isEmpty());
s->gestureRecognizer()->startSwipeGesture(QPoint(0, 50));
......
......@@ -40,16 +40,16 @@ bool ScreenEdgesFilter::event(xcb_generic_event_t *event)
const auto mouseEvent = reinterpret_cast<xcb_motion_notify_event_t*>(event);
const QPoint rootPos(mouseEvent->root_x, mouseEvent->root_y);
if (QWidget::mouseGrabber()) {
ScreenEdges::self()->check(rootPos, QDateTime::fromMSecsSinceEpoch(xTime()), true);
ScreenEdges::self()->check(rootPos, QDateTime::fromMSecsSinceEpoch(xTime(), Qt::UTC), true);
} else {
ScreenEdges::self()->check(rootPos, QDateTime::fromMSecsSinceEpoch(mouseEvent->time));
ScreenEdges::self()->check(rootPos, QDateTime::fromMSecsSinceEpoch(mouseEvent->time, Qt::UTC));
}
// not filtered out
break;
}
case XCB_ENTER_NOTIFY: {
const auto enter = reinterpret_cast<xcb_enter_notify_event_t*>(event);
return ScreenEdges::self()->handleEnterNotifiy(enter->event, QPoint(enter->root_x, enter->root_y), QDateTime::fromMSecsSinceEpoch(enter->time));
return ScreenEdges::self()->handleEnterNotifiy(enter->event, QPoint(enter->root_x, enter->root_y), QDateTime::fromMSecsSinceEpoch(enter->time, Qt::UTC));
}
case XCB_CLIENT_MESSAGE: {
const auto ce = reinterpret_cast<xcb_client_message_event_t*>(event);
......
......@@ -1394,7 +1394,7 @@ bool ScreenEdges::isEntered(QMouseEvent *event)
}
}
if (edge->geometry().contains(event->globalPos())) {
if (edge->check(event->globalPos(), QDateTime::fromMSecsSinceEpoch(event->timestamp()))) {
if (edge->check(event->globalPos(), QDateTime::fromMSecsSinceEpoch(event->timestamp(), Qt::UTC))) {
if (edge->client()) {
activatedForClient = true;
}
......@@ -1404,7 +1404,7 @@ bool ScreenEdges::isEntered(QMouseEvent *event)
if (activatedForClient) {
for (auto it = m_edges.constBegin(); it != m_edges.constEnd(); ++it) {
if ((*it)->client()) {
(*it)->markAsTriggered(event->globalPos(), QDateTime::fromMSecsSinceEpoch(event->timestamp()));
(*it)->markAsTriggered(event->globalPos(), QDateTime::fromMSecsSinceEpoch(event->timestamp(), Qt::UTC));
}
}
}
......@@ -1460,7 +1460,7 @@ bool ScreenEdges::handleDndNotify(xcb_window_t window, const QPoint &point)
}
if (edge->isReserved() && edge->window() == window) {
updateXTime();
edge->check(point, QDateTime::fromMSecsSinceEpoch(xTime()), true);
edge->check(point, QDateTime::fromMSecsSinceEpoch(xTime(), Qt::UTC), true);
return true;
}
}
......
......@@ -101,7 +101,7 @@ void X11Filter::motion(xcb_generic_event_t *event)
auto *mouseEvent = reinterpret_cast<xcb_motion_notify_event_t*>(event);
const QPoint rootPos(mouseEvent->root_x, mouseEvent->root_y);
// TODO: this should be in ScreenEdges directly
ScreenEdges::self()->check(rootPos, QDateTime::fromMSecsSinceEpoch(xTime()), true);
ScreenEdges::self()->check(rootPos, QDateTime::fromMSecsSinceEpoch(xTime(), Qt::UTC), true);
xcb_allow_events(connection(), XCB_ALLOW_ASYNC_POINTER, XCB_CURRENT_TIME);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment