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 );
|
||||
}
|
||||
|
||||
qGuiApp->removeEventFilter( this );
|
||||
}
|
||||
|
||||
bool QskInputContext::isInputPanelVisible() const
|
||||
@ -365,6 +367,14 @@ void QskInputContext::setFocusObject( QObject* focusObject )
|
||||
if( qskNearestFocusScope( focusItem ) != m_data->inputPanel )
|
||||
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(
|
||||
@ -468,11 +478,12 @@ void QskInputContext::setInputPanel( QQuickItem* inputPanel )
|
||||
|
||||
if ( inputPanel )
|
||||
{
|
||||
// maybe using a QQuickItemChangeListener instead
|
||||
#if 1
|
||||
connect( inputPanel, &QQuickItem::visibleChanged,
|
||||
this, &QPlatformInputContext::emitInputPanelVisibleChanged );
|
||||
|
||||
// maybe using a QQuickItemChangeListener instead
|
||||
#if 1
|
||||
|
||||
connect( inputPanel, &QQuickItem::xChanged,
|
||||
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 )
|
||||
{
|
||||
// called from QXcbKeyboard, but what about other platforms
|
||||
|
@ -57,6 +57,8 @@ private Q_SLOTS:
|
||||
void handleCandidatesChanged();
|
||||
void setInputPanel( QQuickItem* );
|
||||
|
||||
virtual bool eventFilter( QObject*, QEvent* ) override;
|
||||
|
||||
private:
|
||||
void setInputItem( QQuickItem* );
|
||||
QskInputCompositionModel* compositionModel() const;
|
||||
|
@ -78,6 +78,9 @@ bool qskIsItemComplete( const QQuickItem* item )
|
||||
|
||||
bool qskIsAncestorOf( const QQuickItem* item, const QQuickItem* child )
|
||||
{
|
||||
if ( item == nullptr || child == nullptr )
|
||||
return false;
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
|
||||
return item->isAncestorOf( child );
|
||||
#else
|
||||
|
@ -10,13 +10,7 @@
|
||||
|
||||
#include <QString>
|
||||
#include <QLocale>
|
||||
|
||||
QSK_QT_PRIVATE_BEGIN
|
||||
#include <private/qinputmethod_p.h>
|
||||
QSK_QT_PRIVATE_END
|
||||
|
||||
#include <qpa/qplatformintegration.h>
|
||||
#include <qpa/qplatforminputcontext.h>
|
||||
#include <QGuiApplication>
|
||||
|
||||
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
|
||||
{
|
||||
public:
|
||||
@ -201,57 +169,4 @@ void QskInputPanel::commitKey( Qt::Key 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"
|
||||
|
@ -38,11 +38,6 @@ public Q_SLOTS:
|
||||
void setCandidatesEnabled( bool );
|
||||
void setCandidates( const QVector< QString >& );
|
||||
|
||||
protected:
|
||||
virtual void updateLayout() override;
|
||||
virtual void itemChange( ItemChange, const ItemChangeData& ) override;
|
||||
virtual bool eventFilter( QObject*, QEvent* ) override;
|
||||
|
||||
private:
|
||||
void commitKey( Qt::Key );
|
||||
void commitCandidate( int );
|
||||
|
Loading…
x
Reference in New Issue
Block a user