plugins: add a "hidecursor" effect
This hides the mouse cursor on inactivity or keypress (configurable in the KCM). BUG: 465119
This commit is contained in:
parent
494daab3d5
commit
7d7344a983
11 changed files with 344 additions and 0 deletions
|
@ -66,6 +66,7 @@ add_subdirectory(fallapart)
|
|||
add_subdirectory(frozenapp)
|
||||
add_subdirectory(fullscreen)
|
||||
add_subdirectory(glide)
|
||||
add_subdirectory(hidecursor)
|
||||
add_subdirectory(highlightwindow)
|
||||
add_subdirectory(idletime)
|
||||
add_subdirectory(invert)
|
||||
|
|
34
src/plugins/hidecursor/CMakeLists.txt
Normal file
34
src/plugins/hidecursor/CMakeLists.txt
Normal file
|
@ -0,0 +1,34 @@
|
|||
kwin_add_builtin_effect(hidecursor)
|
||||
|
||||
target_sources(hidecursor PRIVATE
|
||||
hidecursor.cpp
|
||||
main.cpp
|
||||
)
|
||||
|
||||
kconfig_add_kcfg_files(hidecursor
|
||||
hidecursorconfig.kcfgc
|
||||
)
|
||||
|
||||
target_link_libraries(hidecursor PRIVATE
|
||||
kwin
|
||||
|
||||
KF6::ConfigGui
|
||||
)
|
||||
|
||||
#######################################
|
||||
# Config
|
||||
if (KWIN_BUILD_KCMS)
|
||||
set(kwin_hidecursor_config_SRCS hidecursor_config.cpp)
|
||||
ki18n_wrap_ui(kwin_hidecursor_config_SRCS hidecursor_config.ui)
|
||||
kconfig_add_kcfg_files(kwin_hidecursor_config_SRCS hidecursorconfig.kcfgc)
|
||||
|
||||
kwin_add_effect_config(kwin_hidecursor_config ${kwin_hidecursor_config_SRCS})
|
||||
|
||||
target_link_libraries(kwin_hidecursor_config
|
||||
KF6::KCMUtils
|
||||
KF6::CoreAddons
|
||||
KF6::I18n
|
||||
KF6::XmlGui
|
||||
KWinEffectsInterface
|
||||
)
|
||||
endif()
|
107
src/plugins/hidecursor/hidecursor.cpp
Normal file
107
src/plugins/hidecursor/hidecursor.cpp
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2024 Jin Liu <m.liu.jin@gmail.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "hidecursor.h"
|
||||
#include "cursor.h"
|
||||
#include "effect/effecthandler.h"
|
||||
#include "hidecursorconfig.h"
|
||||
#include "input_event.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
HideCursorEffect::HideCursorEffect()
|
||||
: m_cursor(Cursors::self()->mouse())
|
||||
{
|
||||
input()->installInputEventSpy(this);
|
||||
|
||||
m_inactivityTimer.setSingleShot(true);
|
||||
connect(&m_inactivityTimer, &QTimer::timeout, this, [this]() {
|
||||
hideCursor();
|
||||
});
|
||||
|
||||
HideCursorConfig::instance(effects->config());
|
||||
reconfigure(ReconfigureAll);
|
||||
}
|
||||
|
||||
HideCursorEffect::~HideCursorEffect()
|
||||
{
|
||||
showCursor();
|
||||
}
|
||||
|
||||
bool HideCursorEffect::supported()
|
||||
{
|
||||
return effects->waylandDisplay();
|
||||
}
|
||||
|
||||
void HideCursorEffect::reconfigure(ReconfigureFlags flags)
|
||||
{
|
||||
HideCursorConfig::self()->read();
|
||||
m_inactivityDuration = HideCursorConfig::inactivityDuration() * 1000;
|
||||
m_hideOnTyping = HideCursorConfig::hideOnTyping();
|
||||
|
||||
m_inactivityTimer.stop();
|
||||
showCursor();
|
||||
if (m_inactivityDuration > 0) {
|
||||
m_inactivityTimer.start(m_inactivityDuration);
|
||||
}
|
||||
}
|
||||
|
||||
bool HideCursorEffect::isActive() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void HideCursorEffect::pointerEvent(MouseEvent *event)
|
||||
{
|
||||
showCursor();
|
||||
if (m_inactivityDuration > 0) {
|
||||
m_inactivityTimer.start(m_inactivityDuration);
|
||||
}
|
||||
}
|
||||
|
||||
void HideCursorEffect::keyEvent(KeyEvent *event)
|
||||
{
|
||||
if (m_hideOnTyping && event->type() == QEvent::KeyPress) {
|
||||
auto key = event->key();
|
||||
switch (key) {
|
||||
case Qt::Key_Shift:
|
||||
case Qt::Key_Control:
|
||||
case Qt::Key_Meta:
|
||||
case Qt::Key_Alt:
|
||||
case Qt::Key_AltGr:
|
||||
case Qt::Key_Super_L:
|
||||
case Qt::Key_Super_R:
|
||||
case Qt::Key_Hyper_L:
|
||||
case Qt::Key_Hyper_R:
|
||||
case Qt::Key_Escape:
|
||||
break;
|
||||
|
||||
default:
|
||||
hideCursor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HideCursorEffect::showCursor()
|
||||
{
|
||||
if (m_cursorHidden) {
|
||||
effects->showCursor();
|
||||
m_cursorHidden = false;
|
||||
}
|
||||
}
|
||||
|
||||
void HideCursorEffect::hideCursor()
|
||||
{
|
||||
if (!m_cursorHidden) {
|
||||
effects->hideCursor();
|
||||
m_cursorHidden = true;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace KWin
|
||||
|
||||
#include "moc_hidecursor.cpp"
|
47
src/plugins/hidecursor/hidecursor.h
Normal file
47
src/plugins/hidecursor/hidecursor.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2024 Jin Liu <m.liu.jin@gmail.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "effect/effect.h"
|
||||
#include "input_event_spy.h"
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
class Cursor;
|
||||
|
||||
class HideCursorEffect : public Effect, public InputEventSpy
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
HideCursorEffect();
|
||||
~HideCursorEffect() override;
|
||||
|
||||
static bool supported();
|
||||
|
||||
void reconfigure(ReconfigureFlags flags) override;
|
||||
bool isActive() const override;
|
||||
|
||||
void pointerEvent(MouseEvent *event) override;
|
||||
void keyEvent(KeyEvent *event) override;
|
||||
|
||||
private:
|
||||
void showCursor();
|
||||
void hideCursor();
|
||||
|
||||
int m_inactivityDuration;
|
||||
bool m_hideOnTyping;
|
||||
|
||||
Cursor *m_cursor;
|
||||
bool m_cursorHidden = false;
|
||||
QTimer m_inactivityTimer;
|
||||
};
|
||||
|
||||
} // namespace KWin
|
43
src/plugins/hidecursor/hidecursor_config.cpp
Normal file
43
src/plugins/hidecursor/hidecursor_config.cpp
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2024 Jin Liu <m.liu.jin@gmail.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
#include "hidecursor_config.h"
|
||||
|
||||
#include <config-kwin.h>
|
||||
|
||||
// KConfigSkeleton
|
||||
#include "hidecursorconfig.h"
|
||||
|
||||
#include <KPluginFactory>
|
||||
#include <kwineffects_interface.h>
|
||||
|
||||
K_PLUGIN_CLASS(KWin::HideCursorEffectConfig)
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
HideCursorEffectConfig::HideCursorEffectConfig(QObject *parent, const KPluginMetaData &data)
|
||||
: KCModule(parent, data)
|
||||
{
|
||||
HideCursorConfig::instance(KWIN_CONFIG);
|
||||
m_ui.setupUi(widget());
|
||||
|
||||
addConfig(HideCursorConfig::self(), widget());
|
||||
}
|
||||
|
||||
void HideCursorEffectConfig::save()
|
||||
{
|
||||
KCModule::save();
|
||||
OrgKdeKwinEffectsInterface interface(QStringLiteral("org.kde.KWin"),
|
||||
QStringLiteral("/Effects"),
|
||||
QDBusConnection::sessionBus());
|
||||
interface.reconfigureEffect(QStringLiteral("hidecursor"));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#include "hidecursor_config.moc"
|
||||
|
||||
#include "moc_hidecursor_config.cpp"
|
30
src/plugins/hidecursor/hidecursor_config.h
Normal file
30
src/plugins/hidecursor/hidecursor_config.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2024 Jin Liu <m.liu.jin@gmail.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <kcmodule.h>
|
||||
|
||||
#include "ui_hidecursor_config.h"
|
||||
|
||||
class KActionCollection;
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
class HideCursorEffectConfig : public KCModule
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit HideCursorEffectConfig(QObject *parent, const KPluginMetaData &data);
|
||||
|
||||
public Q_SLOTS:
|
||||
void save() override;
|
||||
|
||||
private:
|
||||
Ui::HideCursorEffectConfig m_ui;
|
||||
};
|
||||
|
||||
} // namespace
|
31
src/plugins/hidecursor/hidecursor_config.ui
Normal file
31
src/plugins/hidecursor/hidecursor_config.ui
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>HideCursorEffectConfig</class>
|
||||
<widget class="QWidget" name="HideCursorEffectConfig">
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_InactivityDuration">
|
||||
<property name="text">
|
||||
<string>Inactivity duration (seconds):</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="kcfg_InactivityDuration">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="kcfg_HideOnTyping">
|
||||
<property name="text">
|
||||
<string>Hide cursor on typing</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
15
src/plugins/hidecursor/hidecursorconfig.kcfg
Normal file
15
src/plugins/hidecursor/hidecursorconfig.kcfg
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
|
||||
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
|
||||
<kcfgfile arg="true"/>
|
||||
<group name="Effect-hidecursor">
|
||||
<entry name="InactivityDuration" type="UInt">
|
||||
<default>5</default>
|
||||
</entry>
|
||||
<entry name="HideOnTyping" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
</group>
|
||||
</kcfg>
|
8
src/plugins/hidecursor/hidecursorconfig.kcfgc
Normal file
8
src/plugins/hidecursor/hidecursorconfig.kcfgc
Normal file
|
@ -0,0 +1,8 @@
|
|||
# SPDX-FileCopyrightText: 2024 Jin Liu <m.liu.jin@gmail.com>
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
File=hidecursorconfig.kcfg
|
||||
ClassName=HideCursorConfig
|
||||
NameSpace=KWin
|
||||
Singleton=true
|
18
src/plugins/hidecursor/main.cpp
Normal file
18
src/plugins/hidecursor/main.cpp
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2024 Jin Liu <m.liu.jin@gmail.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "hidecursor.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
KWIN_EFFECT_FACTORY_SUPPORTED(HideCursorEffect,
|
||||
"metadata.json.stripped",
|
||||
return HideCursorEffect::supported();)
|
||||
|
||||
} // namespace KWin
|
||||
|
||||
#include "main.moc"
|
10
src/plugins/hidecursor/metadata.json
Normal file
10
src/plugins/hidecursor/metadata.json
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"KPlugin": {
|
||||
"Category": "Accessibility",
|
||||
"Description": "Hide mouse cursor on inactivity or keyboard input",
|
||||
"EnabledByDefault": false,
|
||||
"License": "GPL",
|
||||
"Name": "Hide Cursor"
|
||||
},
|
||||
"X-KDE-ConfigModule": "kwin_hidecursor_config"
|
||||
}
|
Loading…
Reference in a new issue