closing the input panel, when the corresponding input item gets

destroyed
This commit is contained in:
Uwe Rathmann 2019-03-30 19:17:45 +01:00
parent d3e9c1f010
commit d09d08c338
4 changed files with 56 additions and 10 deletions

View File

@ -107,13 +107,34 @@ namespace
return nullptr;
}
inline Channel* channel( const QskInputPanel* panel ) const
{
if ( panel )
{
QMap< const QQuickWindow*, Channel >::const_iterator it;
for( it = m_map.constBegin(); it != m_map.constEnd(); ++it )
{
if( it.value().panel == panel )
return const_cast< Channel* >( &it.value() );
}
}
return nullptr;
}
inline Channel* channel( const QQuickItem* item ) const
{
if ( item )
{
auto channel = this->channel( item->window() );
if ( channel && channel->item == item )
return channel;
// item->window() might already been gone
QMap< const QQuickWindow*, Channel >::const_iterator it;
for( it = m_map.constBegin(); it != m_map.constEnd(); ++it )
{
if( it.value().item == item )
return const_cast< Channel* >( &it.value() );
}
}
return nullptr;
@ -210,6 +231,9 @@ class QskInputContext::PrivateData
connect( panel, &QskInputPanel::localeChanged,
context, [] { qskSendToPlatformContext( QEvent::LocaleChange ); } );
connect( panel, &QskInputPanel::inputItemDestroyed,
context, [ context, panel ] { context->hideChannel( panel ); } );
return panel;
}
@ -266,6 +290,15 @@ class QskInputContext::PrivateData
return window;
}
void closeChannel( Channel* channel )
{
if ( channel->popup )
channel->popup->close(); // deleteOnClose is set
if ( channel->window )
channel->window->close(); // deleteOnClose is set
}
ChannelTable channels;
QPointer< QskInputContextFactory > factory;
};
@ -414,16 +447,21 @@ void QskInputContext::hidePanel( const QQuickItem* item )
if ( auto channel = m_data->channels.channel( item ) )
{
if ( channel->popup )
channel->popup->close(); // deleteOnClose is set
if ( channel->window )
channel->window->close(); // deleteOnClose is set
m_data->closeChannel( channel );
m_data->channels.remove( item->window() );
}
}
void QskInputContext::hideChannel( const QskInputPanel* panel )
{
if ( auto channel = m_data->channels.channel( panel ) )
{
// channel->item is already dead here
m_data->closeChannel( channel );
m_data->channels.remove( panel->window() );
}
}
void QskInputContext::setInputPanelVisible( const QQuickItem* item, bool on )
{
// called from inside the controls

View File

@ -69,9 +69,10 @@ class QSK_EXPORT QskInputContext : public QObject
virtual void hidePanel( const QQuickItem* );
private:
friend class QskPlatformInputContext;
void hideChannel( const QskInputPanel* );
// called from QskPlatformInputContext
friend class QskPlatformInputContext;
virtual void setFocusObject( QObject* );
virtual void update( const QQuickItem*, Qt::InputMethodQueries );
virtual void invokeAction( QInputMethod::Action, int cursorPosition );

View File

@ -294,6 +294,12 @@ void QskInputPanel::attachInputItem( QQuickItem* item )
if ( item == m_data->inputItem )
return;
if ( m_data->inputItem )
{
disconnect( m_data->inputItem, &QObject::destroyed,
this, &QskInputPanel::inputItemDestroyed );
}
m_data->inputItem = item;
if ( item )

View File

@ -38,6 +38,7 @@ class QSK_EXPORT QskInputPanel : public QskControl
Q_SIGNALS:
void keySelected( int keyCode );
void predictiveTextSelected( int );
void inputItemDestroyed();
public Q_SLOTS:
virtual void setPrompt( const QString& );