Make keyboard shortcuts work

QAction keyboard shortcuts cannot work with QML2 (and probably newver will
since in Qt qtquick and qwidgets cannot depend from each other in any way)
so do a simple keyboard shortcut matching here

BUG:336203
Change-Id: I2d7ada7dfcb0e326e63ce7f1e39573709f6fe560
This commit is contained in:
Marco Martin 2015-01-23 17:55:59 +01:00
parent 9898e1be4f
commit 4c1438c59a
2 changed files with 63 additions and 0 deletions

View File

@ -47,6 +47,7 @@
#include <Plasma/ContainmentActions>
#include "containmentinterface.h"
#include "wallpaperinterface.h"
#include <kdeclarative/configpropertymap.h>
#include <kdeclarative/qmlobject.h>
@ -60,6 +61,7 @@ AppletInterface::AppletInterface(DeclarativeAppletScript *script, const QVariant
m_backgroundHints(Plasma::Types::StandardBackground),
m_busy(false),
m_hideOnDeactivate(true),
m_oldKeyboardShortcut(0),
m_positionBeforeRemoval(QPointF(-1, -1))
{
qmlRegisterType<QAction>();
@ -599,6 +601,64 @@ void AppletInterface::executeAction(const QString &name)
}
}
bool AppletInterface::event(QEvent *event)
{
// QAction keyboard shortcuts cannot work with QML2 (and probably newver will
// since in Qt qtquick and qwidgets cannot depend from each other in any way)
// so do a simple keyboard shortcut matching here
if (event->type() == QEvent::KeyPress) {
QKeyEvent *ke = static_cast<QKeyEvent *>(event);
QKeySequence seq(ke->key()|ke->modifiers());
QList <QAction *> actions = applet()->actions()->actions();
//find the wallpaper action if we are a containment
ContainmentInterface *ci = qobject_cast<ContainmentInterface *>(this);
if (ci) {
WallpaperInterface *wi = ci->wallpaperInterface();
if (wi) {
actions << wi->contextualActions();
}
}
bool keySequenceUsed = false;
for (auto a : actions) {
if (a->shortcut().isEmpty()) {
continue;
}
//this will happen on a normal, non emacs shortcut
if (seq.matches(a->shortcut()) == QKeySequence::ExactMatch) {
event->accept();
a->trigger();
m_oldKeyboardShortcut = 0;
return true;
//first part of an emacs style shortcut?
} else if (seq.matches(a->shortcut()) == QKeySequence::PartialMatch) {
keySequenceUsed = true;
m_oldKeyboardShortcut = ke->key()|ke->modifiers();
//no match at all, but it can be the second part of an emacs style shortcut
} else {
QKeySequence seq(m_oldKeyboardShortcut, ke->key()|ke->modifiers());
if (seq.matches(a->shortcut()) == QKeySequence::ExactMatch) {
event->accept();
a->trigger();
return true;
}
}
}
if (!keySequenceUsed) {
m_oldKeyboardShortcut = 0;
}
}
return AppletQuickItem::event(event);
}
bool AppletInterface::eventFilter(QObject *watched, QEvent *event)
{
if (event->type() == QEvent::MouseButtonPress) {

View File

@ -351,6 +351,7 @@ protected Q_SLOTS:
virtual void init();
protected:
bool event(QEvent *event);
bool eventFilter(QObject *watched, QEvent *event);
private Q_SLOTS:
@ -372,6 +373,8 @@ private:
Plasma::Types::BackgroundHints m_backgroundHints;
bool m_busy : 1;
bool m_hideOnDeactivate : 1;
//this is used to build an emacs style shortcut
int m_oldKeyboardShortcut;
friend class ContainmentInterface;
//This is used by ContainmentInterface