Fix input panel event propagation
This commit is contained in:
parent
e365592457
commit
5a250eff8b
|
@ -37,20 +37,20 @@ static QString qskKeyString( int code )
|
||||||
class QskInputCompositionModel::PrivateData
|
class QskInputCompositionModel::PrivateData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
PrivateData() :
|
||||||
|
inputItem( nullptr ),
|
||||||
|
groupIndex( 0 )
|
||||||
|
{
|
||||||
|
}
|
||||||
// QInputMethod
|
// QInputMethod
|
||||||
QString preedit;
|
QString preedit;
|
||||||
QTextCharFormat preeditFormat;
|
QTextCharFormat preeditFormat;
|
||||||
QList< QInputMethodEvent::Attribute > preeditAttributes;
|
QList< QInputMethodEvent::Attribute > preeditAttributes;
|
||||||
|
|
||||||
|
QObject* inputItem;
|
||||||
int groupIndex;
|
int groupIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void sendCompositionEvent( QInputMethodEvent* e )
|
|
||||||
{
|
|
||||||
if ( auto focusObject = QGuiApplication::focusObject() )
|
|
||||||
QCoreApplication::sendEvent( focusObject, e );
|
|
||||||
}
|
|
||||||
|
|
||||||
QskInputCompositionModel::QskInputCompositionModel():
|
QskInputCompositionModel::QskInputCompositionModel():
|
||||||
m_data( new PrivateData )
|
m_data( new PrivateData )
|
||||||
{
|
{
|
||||||
|
@ -77,7 +77,7 @@ void QskInputCompositionModel::composeKey( Qt::Key key )
|
||||||
|
|
||||||
QInputMethodQueryEvent queryEvent(
|
QInputMethodQueryEvent queryEvent(
|
||||||
Qt::ImSurroundingText | Qt::ImMaximumTextLength | Qt::ImHints );
|
Qt::ImSurroundingText | Qt::ImMaximumTextLength | Qt::ImHints );
|
||||||
QCoreApplication::sendEvent( focusObject, &queryEvent );
|
QCoreApplication::sendEvent( m_data->inputItem, &queryEvent );
|
||||||
const auto hints = static_cast< Qt::InputMethodHints >(
|
const auto hints = static_cast< Qt::InputMethodHints >(
|
||||||
queryEvent.value( Qt::ImHints ).toInt() );
|
queryEvent.value( Qt::ImHints ).toInt() );
|
||||||
const int maxLength = queryEvent.value( Qt::ImMaximumTextLength ).toInt();
|
const int maxLength = queryEvent.value( Qt::ImMaximumTextLength ).toInt();
|
||||||
|
@ -237,8 +237,8 @@ void QskInputCompositionModel::backspace()
|
||||||
// Backspace one character only if preedit was inactive
|
// Backspace one character only if preedit was inactive
|
||||||
QKeyEvent keyPress( QEvent::KeyPress, Qt::Key_Backspace, Qt::NoModifier );
|
QKeyEvent keyPress( QEvent::KeyPress, Qt::Key_Backspace, Qt::NoModifier );
|
||||||
QKeyEvent keyRelease( QEvent::KeyRelease, Qt::Key_Backspace, Qt::NoModifier );
|
QKeyEvent keyRelease( QEvent::KeyRelease, Qt::Key_Backspace, Qt::NoModifier );
|
||||||
QCoreApplication::sendEvent( focusWindow, &keyPress );
|
QCoreApplication::sendEvent( m_data->inputItem, &keyPress );
|
||||||
QCoreApplication::sendEvent( focusWindow, &keyRelease );
|
QCoreApplication::sendEvent( m_data->inputItem, &keyRelease );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,6 +267,12 @@ void QskInputCompositionModel::moveCursor( Qt::Key key )
|
||||||
QCoreApplication::sendEvent( focusWindow, &moveCursorRelease );
|
QCoreApplication::sendEvent( focusWindow, &moveCursorRelease );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QskInputCompositionModel::sendCompositionEvent( QInputMethodEvent* e )
|
||||||
|
{
|
||||||
|
if ( m_data->inputItem )
|
||||||
|
QCoreApplication::sendEvent( m_data->inputItem, e );
|
||||||
|
}
|
||||||
|
|
||||||
bool QskInputCompositionModel::hasIntermediate() const
|
bool QskInputCompositionModel::hasIntermediate() const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -300,6 +306,11 @@ QVector< Qt::Key > QskInputCompositionModel::groups() const
|
||||||
return QVector< Qt::Key >();
|
return QVector< Qt::Key >();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QskInputCompositionModel::setInputItem( QObject *inputItem )
|
||||||
|
{
|
||||||
|
m_data->inputItem = inputItem;
|
||||||
|
}
|
||||||
|
|
||||||
bool QskInputCompositionModel::nextGroupIndex(int& index, bool forward) const
|
bool QskInputCompositionModel::nextGroupIndex(int& index, bool forward) const
|
||||||
{
|
{
|
||||||
Q_UNUSED(index);
|
Q_UNUSED(index);
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
class QInputMethodEvent;
|
||||||
class QStringList;
|
class QStringList;
|
||||||
|
|
||||||
class QskInputCompositionModel : public QObject
|
class QskInputCompositionModel : public QObject
|
||||||
|
@ -37,6 +38,8 @@ public:
|
||||||
|
|
||||||
virtual QVector< Qt::Key > groups() const;
|
virtual QVector< Qt::Key > groups() const;
|
||||||
|
|
||||||
|
void setInputItem( QObject* inputItem );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Used for text composition
|
// Used for text composition
|
||||||
virtual bool hasIntermediate() const;
|
virtual bool hasIntermediate() const;
|
||||||
|
@ -50,6 +53,7 @@ Q_SIGNALS:
|
||||||
private:
|
private:
|
||||||
void backspace();
|
void backspace();
|
||||||
void moveCursor( Qt::Key key );
|
void moveCursor( Qt::Key key );
|
||||||
|
void sendCompositionEvent( QInputMethodEvent* e );
|
||||||
|
|
||||||
class PrivateData;
|
class PrivateData;
|
||||||
std::unique_ptr< PrivateData > m_data;
|
std::unique_ptr< PrivateData > m_data;
|
||||||
|
|
|
@ -26,6 +26,8 @@ QskInputContext::QskInputContext():
|
||||||
connect( qskSetup, &QskSetup::inputPanelChanged,
|
connect( qskSetup, &QskSetup::inputPanelChanged,
|
||||||
this, &QskInputContext::setInputPanel );
|
this, &QskInputContext::setInputPanel );
|
||||||
setInputPanel( qskSetup->inputPanel() );
|
setInputPanel( qskSetup->inputPanel() );
|
||||||
|
|
||||||
|
m_inputCompositionModel.reset( new QskInputCompositionModel );
|
||||||
}
|
}
|
||||||
|
|
||||||
QskInputContext::~QskInputContext()
|
QskInputContext::~QskInputContext()
|
||||||
|
@ -41,11 +43,11 @@ bool QskInputContext::isValid() const
|
||||||
|
|
||||||
void QskInputContext::update( Qt::InputMethodQueries queries )
|
void QskInputContext::update( Qt::InputMethodQueries queries )
|
||||||
{
|
{
|
||||||
if ( !m_focusObject )
|
if ( !m_inputItem )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QInputMethodQueryEvent queryEvent( queries );
|
QInputMethodQueryEvent queryEvent( queries );
|
||||||
if ( !QCoreApplication::sendEvent( m_focusObject, &queryEvent ) )
|
if ( !QCoreApplication::sendEvent( m_inputItem, &queryEvent ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Qt::ImCursorRectangle
|
// Qt::ImCursorRectangle
|
||||||
|
@ -209,18 +211,39 @@ void QskInputContext::setFocusObject( QObject* focusObject )
|
||||||
|
|
||||||
m_focusObject = focusObject;
|
m_focusObject = focusObject;
|
||||||
if ( !m_focusObject )
|
if ( !m_focusObject )
|
||||||
return;
|
|
||||||
|
|
||||||
QInputMethodQueryEvent queryEvent( Qt::ImEnabled );
|
|
||||||
if ( !QCoreApplication::sendEvent( m_focusObject, &queryEvent ) )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ( !queryEvent.value( Qt::ImEnabled ).toBool() )
|
|
||||||
{
|
{
|
||||||
hideInputPanel();
|
m_inputItem = nullptr;
|
||||||
|
m_inputCompositionModel->setInputItem( nullptr );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool inputItemChanged = false;
|
||||||
|
|
||||||
|
auto focusQuickItem = qobject_cast< QQuickItem* >( focusObject );
|
||||||
|
if( focusQuickItem )
|
||||||
|
{
|
||||||
|
// Do not change the input item when panel buttons get the focus:
|
||||||
|
if( qskNearestFocusScope( focusQuickItem ) != m_inputPanel )
|
||||||
|
{
|
||||||
|
m_inputItem = focusQuickItem;
|
||||||
|
m_inputCompositionModel->setInputItem( m_inputItem ); // ### use a signal/slot connection
|
||||||
|
inputItemChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( inputItemChanged )
|
||||||
|
{
|
||||||
|
QInputMethodQueryEvent queryEvent( Qt::ImEnabled );
|
||||||
|
if ( !QCoreApplication::sendEvent( m_inputItem, &queryEvent ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( !queryEvent.value( Qt::ImEnabled ).toBool() )
|
||||||
|
{
|
||||||
|
hideInputPanel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_focusObject->installEventFilter( this );
|
m_focusObject->installEventFilter( this );
|
||||||
update( Qt::InputMethodQuery( Qt::ImQueryAll & ~Qt::ImEnabled ) );
|
update( Qt::InputMethodQuery( Qt::ImQueryAll & ~Qt::ImEnabled ) );
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <qpa/qplatforminputcontext.h>
|
#include <qpa/qplatforminputcontext.h>
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
|
#include <QQuickItem>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
@ -45,6 +46,7 @@ private Q_SLOTS:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QPointer< QObject > m_focusObject;
|
QPointer< QObject > m_focusObject;
|
||||||
|
QPointer< QQuickItem > m_inputItem;
|
||||||
QPointer< QskInputPanel > m_inputPanel;
|
QPointer< QskInputPanel > m_inputPanel;
|
||||||
std::unique_ptr< QskInputCompositionModel > m_inputCompositionModel;
|
std::unique_ptr< QskInputCompositionModel > m_inputCompositionModel;
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,3 +10,8 @@ TextInput::~TextInput()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextInput::inputMethodEvent(QInputMethodEvent *event)
|
||||||
|
{
|
||||||
|
QQuickTextInput::inputMethodEvent(event);
|
||||||
|
}
|
||||||
|
|
|
@ -7,7 +7,10 @@ class TextInput : public QQuickTextInput
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TextInput( QQuickItem* parent );
|
TextInput( QQuickItem* parent );
|
||||||
virtual ~TextInput();
|
virtual ~TextInput() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void inputMethodEvent(QInputMethodEvent *) Q_DECL_OVERRIDE;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TEXTINPUT_H
|
#endif // TEXTINPUT_H
|
||||||
|
|
|
@ -148,8 +148,6 @@ QskKeyButton::QskKeyButton( int keyIndex, QskInputPanel* inputPanel, QQuickItem*
|
||||||
m_keyIndex( keyIndex ),
|
m_keyIndex( keyIndex ),
|
||||||
m_inputPanel( inputPanel )
|
m_inputPanel( inputPanel )
|
||||||
{
|
{
|
||||||
setFlag( QQuickItem::ItemAcceptsInputMethod );
|
|
||||||
|
|
||||||
updateText();
|
updateText();
|
||||||
|
|
||||||
connect( this, &QskKeyButton::pressed, this, [ this ]()
|
connect( this, &QskKeyButton::pressed, this, [ this ]()
|
||||||
|
@ -248,6 +246,9 @@ QskInputPanel::QskInputPanel( QQuickItem* parent ):
|
||||||
|
|
||||||
QObject::connect( this, &QskControl::localeChanged,
|
QObject::connect( this, &QskControl::localeChanged,
|
||||||
this, &QskInputPanel::updateLocale );
|
this, &QskInputPanel::updateLocale );
|
||||||
|
|
||||||
|
setFlag( ItemIsFocusScope, true );
|
||||||
|
setTabFence( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
QskInputPanel::~QskInputPanel()
|
QskInputPanel::~QskInputPanel()
|
||||||
|
|
Loading…
Reference in New Issue