filtering of input method events moved to QskInputContext
This commit is contained in:
parent
02ea027ca8
commit
67dee082ec
@ -323,6 +323,8 @@ void QskInputContext::hideInputPanel()
|
|||||||
{
|
{
|
||||||
m_data->inputPanel->setVisible( false );
|
m_data->inputPanel->setVisible( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qGuiApp->removeEventFilter( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QskInputContext::isInputPanelVisible() const
|
bool QskInputContext::isInputPanelVisible() const
|
||||||
@ -365,6 +367,14 @@ void QskInputContext::setFocusObject( QObject* focusObject )
|
|||||||
if( qskNearestFocusScope( focusItem ) != m_data->inputPanel )
|
if( qskNearestFocusScope( focusItem ) != m_data->inputPanel )
|
||||||
setInputItem( focusItem );
|
setInputItem( focusItem );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( m_data->inputPanel && m_data->inputPanel->isVisible() )
|
||||||
|
{
|
||||||
|
if ( m_data->inputItem && focusItem != m_data->inputItem )
|
||||||
|
qGuiApp->installEventFilter( this );
|
||||||
|
else
|
||||||
|
qGuiApp->removeEventFilter( this );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskInputContext::setCompositionModel(
|
void QskInputContext::setCompositionModel(
|
||||||
@ -468,11 +478,12 @@ void QskInputContext::setInputPanel( QQuickItem* inputPanel )
|
|||||||
|
|
||||||
if ( inputPanel )
|
if ( inputPanel )
|
||||||
{
|
{
|
||||||
// maybe using a QQuickItemChangeListener instead
|
|
||||||
#if 1
|
|
||||||
connect( inputPanel, &QQuickItem::visibleChanged,
|
connect( inputPanel, &QQuickItem::visibleChanged,
|
||||||
this, &QPlatformInputContext::emitInputPanelVisibleChanged );
|
this, &QPlatformInputContext::emitInputPanelVisibleChanged );
|
||||||
|
|
||||||
|
// maybe using a QQuickItemChangeListener instead
|
||||||
|
#if 1
|
||||||
|
|
||||||
connect( inputPanel, &QQuickItem::xChanged,
|
connect( inputPanel, &QQuickItem::xChanged,
|
||||||
this, &QPlatformInputContext::emitKeyboardRectChanged );
|
this, &QPlatformInputContext::emitKeyboardRectChanged );
|
||||||
|
|
||||||
@ -508,6 +519,28 @@ void QskInputContext::commit()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QskInputContext::eventFilter( QObject* object, QEvent* event )
|
||||||
|
{
|
||||||
|
if ( event->type() == QEvent::InputMethodQuery )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Qt/Quick expects that the item associated with the input context
|
||||||
|
holds the focus. But this does not work, when a virtual
|
||||||
|
keyboard is used, where you can navigate and select inside.
|
||||||
|
So we have to fix the receiver.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( ( object != m_data->inputItem )
|
||||||
|
&& qskIsAncestorOf( m_data->inputPanel, m_data->inputItem ) )
|
||||||
|
{
|
||||||
|
sendEventToInputItem( event );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Inherited::eventFilter( object, event );
|
||||||
|
}
|
||||||
|
|
||||||
bool QskInputContext::filterEvent( const QEvent* event )
|
bool QskInputContext::filterEvent( const QEvent* event )
|
||||||
{
|
{
|
||||||
// called from QXcbKeyboard, but what about other platforms
|
// called from QXcbKeyboard, but what about other platforms
|
||||||
|
@ -57,6 +57,8 @@ private Q_SLOTS:
|
|||||||
void handleCandidatesChanged();
|
void handleCandidatesChanged();
|
||||||
void setInputPanel( QQuickItem* );
|
void setInputPanel( QQuickItem* );
|
||||||
|
|
||||||
|
virtual bool eventFilter( QObject*, QEvent* ) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setInputItem( QQuickItem* );
|
void setInputItem( QQuickItem* );
|
||||||
QskInputCompositionModel* compositionModel() const;
|
QskInputCompositionModel* compositionModel() const;
|
||||||
|
@ -78,6 +78,9 @@ bool qskIsItemComplete( const QQuickItem* item )
|
|||||||
|
|
||||||
bool qskIsAncestorOf( const QQuickItem* item, const QQuickItem* child )
|
bool qskIsAncestorOf( const QQuickItem* item, const QQuickItem* child )
|
||||||
{
|
{
|
||||||
|
if ( item == nullptr || child == nullptr )
|
||||||
|
return false;
|
||||||
|
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
|
||||||
return item->isAncestorOf( child );
|
return item->isAncestorOf( child );
|
||||||
#else
|
#else
|
||||||
|
@ -10,13 +10,7 @@
|
|||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QLocale>
|
#include <QLocale>
|
||||||
|
#include <QGuiApplication>
|
||||||
QSK_QT_PRIVATE_BEGIN
|
|
||||||
#include <private/qinputmethod_p.h>
|
|
||||||
QSK_QT_PRIVATE_END
|
|
||||||
|
|
||||||
#include <qpa/qplatformintegration.h>
|
|
||||||
#include <qpa/qplatforminputcontext.h>
|
|
||||||
|
|
||||||
QString qskNativeLocaleString( const QLocale& locale )
|
QString qskNativeLocaleString( const QLocale& locale )
|
||||||
{
|
{
|
||||||
@ -105,32 +99,6 @@ QString qskNativeLocaleString( const QLocale& locale )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline QQuickItem* qskInputItem()
|
|
||||||
{
|
|
||||||
QPlatformInputContext* inputContext;
|
|
||||||
#if 1
|
|
||||||
inputContext = QGuiApplicationPrivate::platformIntegration()->inputContext();
|
|
||||||
#else
|
|
||||||
// for some reason the gcc sanitizer does not like this one
|
|
||||||
inputContext = QInputMethodPrivate::get( inputMethod )->platformInputContext();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QQuickItem* item = nullptr;
|
|
||||||
|
|
||||||
QMetaObject::invokeMethod( inputContext, "inputItem",
|
|
||||||
Qt::DirectConnection, Q_RETURN_ARG( QQuickItem*, item ) );
|
|
||||||
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void qskInstallEventFilter( QskInputPanel* panel, bool on )
|
|
||||||
{
|
|
||||||
if ( on )
|
|
||||||
qGuiApp->installEventFilter( panel );
|
|
||||||
else
|
|
||||||
qGuiApp->removeEventFilter( panel );
|
|
||||||
}
|
|
||||||
|
|
||||||
class QskInputPanel::PrivateData
|
class QskInputPanel::PrivateData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -201,57 +169,4 @@ void QskInputPanel::commitKey( Qt::Key key )
|
|||||||
static_cast< QInputMethod::Action >( Compose ), key );
|
static_cast< QInputMethod::Action >( Compose ), key );
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskInputPanel::updateLayout()
|
|
||||||
{
|
|
||||||
if ( !isInitiallyPainted() )
|
|
||||||
qskInstallEventFilter( this, isVisible() );
|
|
||||||
|
|
||||||
Inherited::updateLayout();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QskInputPanel::itemChange( QQuickItem::ItemChange change,
|
|
||||||
const QQuickItem::ItemChangeData& value )
|
|
||||||
{
|
|
||||||
switch( change )
|
|
||||||
{
|
|
||||||
case QQuickItem::ItemVisibleHasChanged:
|
|
||||||
case QQuickItem::ItemSceneChange:
|
|
||||||
{
|
|
||||||
if ( isInitiallyPainted() )
|
|
||||||
qskInstallEventFilter( this, isVisible() );
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Inherited::itemChange( change, value );
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QskInputPanel::eventFilter( QObject* object, QEvent* event )
|
|
||||||
{
|
|
||||||
if ( event->type() == QEvent::InputMethodQuery )
|
|
||||||
{
|
|
||||||
const auto item = qskInputItem();
|
|
||||||
|
|
||||||
/*
|
|
||||||
Qt/Quick expects that the item associated with the input context
|
|
||||||
always has the focus. But this does not work, when a virtual
|
|
||||||
keyboard is used, where you can navigate and select inside.
|
|
||||||
So we have to fix the receiver.
|
|
||||||
|
|
||||||
Maybe QEvent::EnterEditFocus is good for something ??
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ( item && ( object != item ) && qskIsAncestorOf( this, item ) )
|
|
||||||
{
|
|
||||||
QGuiApplication::sendEvent( item, event );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Inherited::eventFilter( object, event );
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "moc_QskInputPanel.cpp"
|
#include "moc_QskInputPanel.cpp"
|
||||||
|
@ -38,11 +38,6 @@ public Q_SLOTS:
|
|||||||
void setCandidatesEnabled( bool );
|
void setCandidatesEnabled( bool );
|
||||||
void setCandidates( const QVector< QString >& );
|
void setCandidates( const QVector< QString >& );
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void updateLayout() override;
|
|
||||||
virtual void itemChange( ItemChange, const ItemChangeData& ) override;
|
|
||||||
virtual bool eventFilter( QObject*, QEvent* ) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void commitKey( Qt::Key );
|
void commitKey( Qt::Key );
|
||||||
void commitCandidate( int );
|
void commitCandidate( int );
|
||||||
|
Loading…
x
Reference in New Issue
Block a user