Commit e90e5968 authored by Martin Flöser's avatar Martin Flöser
Browse files

Add way to hide/show cursor in Platform

Summary:
Some platforms support to hide and show the cursor. This will be needed
by e.g. the zoom effect which currently only provides this functionality
on X11.

This change introduces a new method in the Platform to hide and show the
cursor. The methods need to be called balanced and the implementation
takes care of only showing again if all hide got matched by a show.

The actual hiding and showing is performed in the platform plugins. So
far the DRM and X11/Standalone platforms implement the required
functionality, though other platforms probably could implement as well.

Reviewers: #kwin, #plasma_on_wayland

Subscribers: plasma-devel, kwin

Tags: #plasma_on_wayland, #kwin

Differential Revision: https://phabricator.kde.org/D3119
parent 32d5e83a
......@@ -43,6 +43,7 @@ private Q_SLOTS:
void testScreens();
void testNoWindowsAtStart();
void testCreateWindow();
void testHideShowCursor();
};
void StartTest::initTestCase()
......@@ -129,6 +130,33 @@ void StartTest::testCreateWindow()
QVERIFY(waylandServer()->clients().isEmpty());
}
void StartTest::testHideShowCursor()
{
QCOMPARE(kwinApp()->platform()->isCursorHidden(), false);
kwinApp()->platform()->hideCursor();
QCOMPARE(kwinApp()->platform()->isCursorHidden(), true);
kwinApp()->platform()->showCursor();
QCOMPARE(kwinApp()->platform()->isCursorHidden(), false);
kwinApp()->platform()->hideCursor();
QCOMPARE(kwinApp()->platform()->isCursorHidden(), true);
kwinApp()->platform()->hideCursor();
kwinApp()->platform()->hideCursor();
kwinApp()->platform()->hideCursor();
QCOMPARE(kwinApp()->platform()->isCursorHidden(), true);
kwinApp()->platform()->showCursor();
QCOMPARE(kwinApp()->platform()->isCursorHidden(), true);
kwinApp()->platform()->showCursor();
QCOMPARE(kwinApp()->platform()->isCursorHidden(), true);
kwinApp()->platform()->showCursor();
QCOMPARE(kwinApp()->platform()->isCursorHidden(), true);
kwinApp()->platform()->showCursor();
QCOMPARE(kwinApp()->platform()->isCursorHidden(), false);
}
}
WAYLANDTEST_MAIN(KWin::StartTest)
......
......@@ -59,6 +59,30 @@ PlatformCursorImage Platform::cursorImage() const
return PlatformCursorImage(softwareCursor(), softwareCursorHotspot());
}
void Platform::hideCursor()
{
m_hideCursorCounter++;
if (m_hideCursorCounter == 1) {
doHideCursor();
}
}
void Platform::doHideCursor()
{
}
void Platform::showCursor()
{
m_hideCursorCounter--;
if (m_hideCursorCounter == 0) {
doShowCursor();
}
}
void Platform::doShowCursor()
{
}
Screens *Platform::createScreens(QObject *parent)
{
Q_UNUSED(parent)
......
......@@ -176,6 +176,34 @@ public:
**/
virtual PlatformCursorImage cursorImage() const;
/**
* The Platform cursor image should be hidden.
* @see showCursor
* @see doHideCursor
* @see isCursorHidden
* @since 5.9
**/
void hideCursor();
/**
* The Platform cursor image should be shown again.
* @see hideCursor
* @see doShowCursor
* @see isCursorHidden
* @since 5.9
**/
void showCursor();
/**
* Whether the cursor is currently hidden.
* @see showCursor
* @see hideCursor
* @since 5.9
**/
bool isCursorHidden() const {
return m_hideCursorCounter > 0;
}
bool handlesOutputs() const {
return m_handlesOutputs;
}
......@@ -248,6 +276,30 @@ protected:
m_pointerWarping = set;
}
/**
* Actual platform specific way to hide the cursor.
* Sub-classes need to implement if they support hiding the cursor.
*
* This method is invoked by hideCursor if the cursor needs to be hidden.
* The default implementation does nothing.
*
* @see doShowCursor
* @see hideCursor
* @see showCursor
**/
virtual void doHideCursor();
/**
* Actual platform specific way to show the cursor.
* Sub-classes need to implement if they support showing the cursor.
*
* This method is invoked by showCursor if the cursor needs to be shown again.
*
* @see doShowCursor
* @see hideCursor
* @see showCursor
**/
virtual void doShowCursor();
private:
void triggerCursorRepaint();
bool m_softWareCursor = false;
......@@ -262,6 +314,7 @@ private:
bool m_outputsEnabled = true;
int m_initialOutputCount = 1;
EGLDisplay m_eglDisplay;
int m_hideCursorCounter = 0;
};
}
......
......@@ -619,9 +619,12 @@ void DrmBackend::updateCursor()
if (usesSoftwareCursor()) {
return;
}
if (isCursorHidden()) {
return;
}
const QImage &cursorImage = softwareCursor();
if (cursorImage.isNull()) {
hideCursor();
doHideCursor();
return;
}
QImage *c = m_cursor[m_cursorIndex]->image();
......@@ -635,7 +638,12 @@ void DrmBackend::updateCursor()
moveCursor();
}
void DrmBackend::hideCursor()
void DrmBackend::doShowCursor()
{
updateCursor();
}
void DrmBackend::doHideCursor()
{
if (!m_cursorEnabled) {
return;
......@@ -648,7 +656,7 @@ void DrmBackend::hideCursor()
void DrmBackend::moveCursor()
{
const QPoint p = Cursor::pos() - softwareCursorHotspot();
if (!m_cursorEnabled) {
if (!m_cursorEnabled || isCursorHidden()) {
return;
}
for (auto it = m_outputs.constBegin(); it != m_outputs.constEnd(); ++it) {
......
......@@ -113,6 +113,11 @@ Q_SIGNALS:
void outputRemoved(KWin::DrmOutput *output);
void outputAdded(KWin::DrmOutput *output);
protected:
void doHideCursor() override;
void doShowCursor() override;
private:
static void pageFlipHandler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data);
void openDrm();
......@@ -122,7 +127,6 @@ private:
void queryResources();
void setCursor();
void updateCursor();
void hideCursor();
void moveCursor();
void initCursor();
quint32 findCrtc(drmModeRes *res, drmModeConnector *connector, bool *ok = nullptr);
......
......@@ -262,4 +262,14 @@ PlatformCursorImage X11StandalonePlatform::cursorImage() const
return PlatformCursorImage(qcursorimg.copy(), QPoint(cursor->xhot, cursor->yhot));
}
void X11StandalonePlatform::doHideCursor()
{
xcb_xfixes_hide_cursor(kwinApp()->x11Connection(), kwinApp()->x11RootWindow());
}
void X11StandalonePlatform::doShowCursor()
{
xcb_xfixes_show_cursor(kwinApp()->x11Connection(), kwinApp()->x11RootWindow());
}
}
......@@ -51,6 +51,10 @@ public:
PlatformCursorImage cursorImage() const override;
protected:
void doHideCursor() override;
void doShowCursor() override;
private:
/**
* Tests whether GLX is supported and returns @c true
......
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