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