sending of input method update hints improved

This commit is contained in:
Uwe Rathmann 2018-06-12 10:56:06 +02:00
parent e195614654
commit 9e5ded43c6
6 changed files with 61 additions and 56 deletions

View File

@ -76,7 +76,7 @@ public:
virtual bool filterEvent( const QEvent* ) override; virtual bool filterEvent( const QEvent* ) override;
Q_INVOKABLE QQuickItem* inputItem(); Q_INVOKABLE void update( const QQuickItem*, Qt::InputMethodQueries );
protected: protected:
virtual bool event( QEvent* ) override; virtual bool event( QEvent* ) override;
@ -150,7 +150,14 @@ bool QskPlatformInputContext::hasCapability( Capability ) const
void QskPlatformInputContext::update( Qt::InputMethodQueries queries ) void QskPlatformInputContext::update( Qt::InputMethodQueries queries )
{ {
if ( m_context ) if ( m_context )
m_context->update( queries ); m_context->update( nullptr, queries );
}
void QskPlatformInputContext::update(
const QQuickItem* item, Qt::InputMethodQueries queries )
{
if ( m_context )
m_context->update( item, queries );
} }
void QskPlatformInputContext::invokeAction( void QskPlatformInputContext::invokeAction(
@ -233,14 +240,6 @@ bool QskPlatformInputContext::filterEvent( const QEvent* )
return false; return false;
} }
QQuickItem* QskPlatformInputContext::inputItem()
{
if ( m_context )
return m_context->inputItem();
return nullptr;
}
bool QskPlatformInputContext::event( QEvent* event ) bool QskPlatformInputContext::event( QEvent* event )
{ {
switch( event->type() ) switch( event->type() )

View File

@ -138,59 +138,54 @@ void qskForceActiveFocus( QQuickItem* item, Qt::FocusReason reason )
} }
} }
QQuickItem* qskInputContextItem() void qskUpdateInputMethod( const QQuickItem* item, Qt::InputMethodQueries queries )
{ {
/* if ( item == nullptr || !( item->flags() & QQuickItem::ItemAcceptsInputMethod ) )
The item that is connected to the input context. return;
- often the item having the active focus.
*/
QQuickItem* inputItem = nullptr; static QPlatformInputContext* context = nullptr;
static int methodId = -1;
/* /*
We could also get the inputContext from QInputMethodPrivate We could also get the inputContext from QInputMethodPrivate
but for some reason the gcc sanitizer reports errors but for some reason the gcc sanitizer reports errors
when using it. So let's go with QGuiApplicationPrivate. when using it. So let's go with QGuiApplicationPrivate.
*/ */
const auto inputContext =
QGuiApplicationPrivate::platformIntegration()->inputContext();
if ( inputContext && inputContext->isInputPanelVisible() ) auto inputContext = QGuiApplicationPrivate::platformIntegration()->inputContext();
if ( inputContext == nullptr )
{ {
/* context = nullptr;
QskInputContext allows to navigate inside the input panel methodId = -1;
without losing the connected input item
*/
if ( inputContext->metaObject()->indexOfMethod( "inputItem()" ) >= 0 ) return;
{
QMetaObject::invokeMethod( inputContext, "inputItem",
Qt::DirectConnection, Q_RETURN_ARG( QQuickItem*, inputItem ) );
}
} }
return inputItem; if ( inputContext != context )
} {
context = inputContext;
methodId = inputContext->metaObject()->indexOfMethod(
"update(const QQuickItem*,Qt::InputMethodQueries)" );
}
void qskUpdateInputMethod( const QQuickItem* item, Qt::InputMethodQueries queries ) if ( methodId >= 0 )
{ {
if ( item == nullptr ) /*
return; The protocol for input methods does not fit well for a
virtual keyboard as it is tied to the focus.
So we try to bypass QInputMethod calling the
inputContext directly.
*/
#if 1 inputContext->metaObject()->method( methodId ).invoke(
if ( !( item->flags() & QQuickItem::ItemAcceptsInputMethod ) ) inputContext, Qt::DirectConnection,
return; Q_ARG( const QQuickItem*, item ),
#endif Q_ARG( Qt::InputMethodQueries, queries ) );
}
bool doUpdate;
if ( const QQuickItem* inputItem = qskInputContextItem() )
doUpdate = ( item == inputItem );
else else
doUpdate = item->hasActiveFocus(); {
if ( doUpdate )
QGuiApplication::inputMethod()->update( queries ); QGuiApplication::inputMethod()->update( queries );
}
} }
QList< QQuickItem* > qskPaintOrderChildItems( const QQuickItem* item ) QList< QQuickItem* > qskPaintOrderChildItems( const QQuickItem* item )

View File

@ -31,7 +31,6 @@ QSK_EXPORT void qskForceActiveFocus( QQuickItem*, Qt::FocusReason );
QSK_EXPORT QList< QQuickItem* > qskPaintOrderChildItems( const QQuickItem* ); QSK_EXPORT QList< QQuickItem* > qskPaintOrderChildItems( const QQuickItem* );
QSK_EXPORT void qskUpdateInputMethod( const QQuickItem*, Qt::InputMethodQueries ); QSK_EXPORT void qskUpdateInputMethod( const QQuickItem*, Qt::InputMethodQueries );
QSK_EXPORT QQuickItem* qskInputContextItem();
QSK_EXPORT const QSGNode* qskItemNode( const QQuickItem* ); QSK_EXPORT const QSGNode* qskItemNode( const QQuickItem* );
QSK_EXPORT const QSGNode* qskPaintNode( const QQuickItem* ); QSK_EXPORT const QSGNode* qskPaintNode( const QQuickItem* );

View File

@ -164,13 +164,17 @@ QskTextPredictor* QskInputContext::textPredictor( const QLocale& locale )
return nullptr; return nullptr;
} }
QQuickItem* QskInputContext::inputItem() const void QskInputContext::update( const QQuickItem* item, Qt::InputMethodQueries queries )
{ {
return m_data->inputItem; if ( item == nullptr )
} {
item = qobject_cast< QQuickItem* >( QGuiApplication::focusObject() );
#if 1
// those are coming from QQuickWindow based on focus changes
return;
#endif
}
void QskInputContext::update( Qt::InputMethodQueries queries )
{
if ( queries & Qt::ImEnabled ) if ( queries & Qt::ImEnabled )
{ {
QInputMethodQueryEvent event( Qt::ImEnabled ); QInputMethodQueryEvent event( Qt::ImEnabled );

View File

@ -74,10 +74,10 @@ private:
friend class QskPlatformInputContext; friend class QskPlatformInputContext;
// called from QskPlatformInputContext // called from QskPlatformInputContext
virtual void setFocusObject( QObject* ); void setFocusObject( QObject* );
virtual void update( Qt::InputMethodQueries ); void update( const QQuickItem*, Qt::InputMethodQueries );
virtual void processClickAt( int cursorPosition ); void processClickAt( int cursorPosition );
virtual void commitPrediction( bool ); void commitPrediction( bool );
void ensurePanel(); void ensurePanel();

View File

@ -345,6 +345,14 @@ void QskInputPanel::updateInputPanel( Qt::InputMethodQueries queries )
{ {
setLocale( event.value( Qt::ImPreferredLanguage ).toLocale() ); setLocale( event.value( Qt::ImPreferredLanguage ).toLocale() );
} }
if ( queries & Qt::ImInputItemClipRectangle )
{
/*
Could be used to move the panel,
so that it does not hide the item.
*/
}
} }
void QskInputPanel::updateLocale( const QLocale& locale ) void QskInputPanel::updateLocale( const QLocale& locale )