Show notification when modifier keys are used
If the relevant accessibility setting is enabled BUG: 395559
This commit is contained in:
parent
0419c9a3b1
commit
de9eb16527
6 changed files with 209 additions and 0 deletions
|
@ -113,6 +113,10 @@ add_subdirectory(windowview)
|
|||
add_subdirectory(wobblywindows)
|
||||
add_subdirectory(zoom)
|
||||
|
||||
if (KWIN_BUILD_NOTIFICATIONS)
|
||||
add_subdirectory(keynotification)
|
||||
endif()
|
||||
|
||||
if (KWIN_BUILD_DECORATIONS)
|
||||
add_subdirectory(kdecorations)
|
||||
endif()
|
||||
|
|
15
src/plugins/keynotification/CMakeLists.txt
Normal file
15
src/plugins/keynotification/CMakeLists.txt
Normal file
|
@ -0,0 +1,15 @@
|
|||
# SPDX-FileCopyrightText: 2024 Nicolas Fella <nicolas.fella@kdab.com>
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
kcoreaddons_add_plugin(KeyNotificationPlugin INSTALL_NAMESPACE "kwin/plugins")
|
||||
|
||||
target_compile_definitions(KeyNotificationPlugin PRIVATE
|
||||
-DTRANSLATION_DOMAIN=\"kwin\"
|
||||
)
|
||||
|
||||
target_sources(KeyNotificationPlugin PRIVATE
|
||||
main.cpp
|
||||
keynotification.cpp
|
||||
)
|
||||
target_link_libraries(KeyNotificationPlugin PRIVATE kwin KF6::Notifications KF6::I18n XKB::XKB)
|
||||
|
119
src/plugins/keynotification/keynotification.cpp
Normal file
119
src/plugins/keynotification/keynotification.cpp
Normal file
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2024 Nicolas Fella <nicolas.fella@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
*/
|
||||
|
||||
#include "keynotification.h"
|
||||
#include "keyboard_input.h"
|
||||
#include "xkb.h"
|
||||
|
||||
#include <KLocalizedString>
|
||||
#include <KNotification>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
KeyNotificationPlugin::KeyNotificationPlugin()
|
||||
: m_configWatcher(KConfigWatcher::create(KSharedConfig::openConfig("kaccessrc")))
|
||||
{
|
||||
const QLatin1String groupName("Keyboard");
|
||||
connect(m_configWatcher.get(), &KConfigWatcher::configChanged, this, [this, groupName](const KConfigGroup &group) {
|
||||
if (group.name() == groupName) {
|
||||
loadConfig(group);
|
||||
}
|
||||
});
|
||||
loadConfig(m_configWatcher->config()->group(groupName));
|
||||
|
||||
connect(input()->keyboard(), &KeyboardInputRedirection::ledsChanged, this,
|
||||
&KeyNotificationPlugin::ledsChanged);
|
||||
|
||||
connect(input()->keyboard()->xkb(), &Xkb::modifierStateChanged, this, &KeyNotificationPlugin::modifiersChanged);
|
||||
}
|
||||
|
||||
void KeyNotificationPlugin::ledsChanged(LEDs leds)
|
||||
{
|
||||
if (m_enabled) {
|
||||
if (!m_currentLEDs.testFlag(LED::CapsLock) && leds.testFlag(LED::CapsLock)) {
|
||||
sendNotification("lockkey-locked", i18n("The Caps Lock key has been activated"));
|
||||
}
|
||||
|
||||
if (m_currentLEDs.testFlag(LED::CapsLock) && !leds.testFlag(LED::CapsLock)) {
|
||||
sendNotification("lockkey-unlocked", i18n("The Caps Lock key is now inactive"));
|
||||
}
|
||||
|
||||
if (!m_currentLEDs.testFlag(LED::NumLock) && leds.testFlag(LED::NumLock)) {
|
||||
sendNotification("lockkey-locked", i18n("The Num Lock key has been activated"));
|
||||
}
|
||||
|
||||
if (m_currentLEDs.testFlag(LED::NumLock) && !leds.testFlag(LED::NumLock)) {
|
||||
sendNotification("lockkey-unlocked", i18n("The Num Lock key is now inactive"));
|
||||
}
|
||||
|
||||
if (!m_currentLEDs.testFlag(LED::ScrollLock) && leds.testFlag(LED::ScrollLock)) {
|
||||
sendNotification("lockkey-locked", i18n("The Scroll Lock key has been activated"));
|
||||
}
|
||||
|
||||
if (m_currentLEDs.testFlag(LED::ScrollLock) && !leds.testFlag(LED::ScrollLock)) {
|
||||
sendNotification("lockkey-unlocked", i18n("The Scroll Lock key is now inactive"));
|
||||
}
|
||||
}
|
||||
|
||||
m_currentLEDs = leds;
|
||||
}
|
||||
|
||||
void KeyNotificationPlugin::modifiersChanged()
|
||||
{
|
||||
Qt::KeyboardModifiers mods = input()->keyboard()->xkb()->modifiers();
|
||||
|
||||
if (m_enabled) {
|
||||
if (!m_currentModifiers.testFlag(Qt::ShiftModifier) && mods.testFlag(Qt::ShiftModifier)) {
|
||||
sendNotification("modifierkey-latched", i18n("The Shift key is now active."));
|
||||
}
|
||||
|
||||
if (m_currentModifiers.testFlag(Qt::ShiftModifier) && !mods.testFlag(Qt::ShiftModifier)) {
|
||||
sendNotification("modifierkey-unlatched", i18n("The Shift key is now inactive."));
|
||||
}
|
||||
|
||||
if (!m_currentModifiers.testFlag(Qt::ControlModifier) && mods.testFlag(Qt::ControlModifier)) {
|
||||
sendNotification("modifierkey-latched", i18n("The Control key is now active."));
|
||||
}
|
||||
|
||||
if (m_currentModifiers.testFlag(Qt::ControlModifier) && !mods.testFlag(Qt::ControlModifier)) {
|
||||
sendNotification("modifierkey-unlatched", i18n("The Control key is now inactive."));
|
||||
}
|
||||
|
||||
if (!m_currentModifiers.testFlag(Qt::AltModifier) && mods.testFlag(Qt::AltModifier)) {
|
||||
sendNotification("modifierkey-latched", i18n("The Alt key is now active."));
|
||||
}
|
||||
|
||||
if (m_currentModifiers.testFlag(Qt::AltModifier) && !mods.testFlag(Qt::AltModifier)) {
|
||||
sendNotification("modifierkey-unlatched", i18n("The Alt key is now inactive."));
|
||||
}
|
||||
|
||||
if (!m_currentModifiers.testFlag(Qt::MetaModifier) && mods.testFlag(Qt::MetaModifier)) {
|
||||
sendNotification("modifierkey-latched", i18n("The Meta key is now active."));
|
||||
}
|
||||
|
||||
if (m_currentModifiers.testFlag(Qt::MetaModifier) && !mods.testFlag(Qt::AltModifier)) {
|
||||
sendNotification("modifierkey-unlatched", i18n("The Meta key is now inactive."));
|
||||
}
|
||||
}
|
||||
|
||||
m_currentModifiers = input()->keyboard()->xkb()->modifiers();
|
||||
}
|
||||
|
||||
void KeyNotificationPlugin::sendNotification(const QString &eventId, const QString &text)
|
||||
{
|
||||
KNotification *notification = new KNotification(QStringLiteral("modifierkey-locked"));
|
||||
notification->setComponentName(QStringLiteral("kaccess"));
|
||||
notification->setText(text);
|
||||
notification->sendEvent();
|
||||
}
|
||||
|
||||
void KeyNotificationPlugin::loadConfig(const KConfigGroup &group)
|
||||
{
|
||||
m_enabled = group.readEntry("kNotifyModifiers", false);
|
||||
}
|
||||
}
|
||||
|
||||
#include "moc_keynotification.cpp"
|
34
src/plugins/keynotification/keynotification.h
Normal file
34
src/plugins/keynotification/keynotification.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2024 Nicolas Fella <nicolas.fella@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "effect/globals.h"
|
||||
#include "plugin.h"
|
||||
|
||||
#include <KConfigGroup>
|
||||
#include <KConfigWatcher>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
class KeyNotificationPlugin : public KWin::Plugin
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit KeyNotificationPlugin();
|
||||
|
||||
private:
|
||||
void loadConfig(const KConfigGroup &group);
|
||||
void ledsChanged(KWin::LEDs leds);
|
||||
void modifiersChanged();
|
||||
void sendNotification(const QString &eventId, const QString &text);
|
||||
|
||||
KConfigWatcher::Ptr m_configWatcher;
|
||||
bool m_enabled = false;
|
||||
KWin::LEDs m_currentLEDs;
|
||||
Qt::KeyboardModifiers m_currentModifiers;
|
||||
};
|
||||
}
|
32
src/plugins/keynotification/main.cpp
Normal file
32
src/plugins/keynotification/main.cpp
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2024 Nicolas Fella <nicolas.fella@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "plugin.h"
|
||||
|
||||
#include "keynotification.h"
|
||||
|
||||
class KWIN_EXPORT KeyNotificationFactory : public KWin::PluginFactory
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PLUGIN_METADATA(IID PluginFactory_iid FILE "metadata.json")
|
||||
Q_INTERFACES(KWin::PluginFactory)
|
||||
|
||||
public:
|
||||
std::unique_ptr<KWin::Plugin> create() const override
|
||||
{
|
||||
switch (KWin::kwinApp()->operationMode()) {
|
||||
case KWin::Application::OperationModeXwayland:
|
||||
case KWin::Application::OperationModeWaylandOnly:
|
||||
return std::make_unique<KWin::KeyNotificationPlugin>();
|
||||
case KWin::Application::OperationModeX11:
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#include "main.moc"
|
5
src/plugins/keynotification/metadata.json
Normal file
5
src/plugins/keynotification/metadata.json
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"KPlugin": {
|
||||
"EnabledByDefault": true
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue