From d09d08c33815f40f40dbc30761db14207357751e Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Sat, 30 Mar 2019 19:17:45 +0100 Subject: [PATCH] closing the input panel, when the corresponding input item gets destroyed --- src/inputpanel/QskInputContext.cpp | 56 +++++++++++++++++++++++++----- src/inputpanel/QskInputContext.h | 3 +- src/inputpanel/QskInputPanel.cpp | 6 ++++ src/inputpanel/QskInputPanel.h | 1 + 4 files changed, 56 insertions(+), 10 deletions(-) diff --git a/src/inputpanel/QskInputContext.cpp b/src/inputpanel/QskInputContext.cpp index 3c516d85..c5a016b1 100644 --- a/src/inputpanel/QskInputContext.cpp +++ b/src/inputpanel/QskInputContext.cpp @@ -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 diff --git a/src/inputpanel/QskInputContext.h b/src/inputpanel/QskInputContext.h index d10b1e1f..25ddac9d 100644 --- a/src/inputpanel/QskInputContext.h +++ b/src/inputpanel/QskInputContext.h @@ -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 ); diff --git a/src/inputpanel/QskInputPanel.cpp b/src/inputpanel/QskInputPanel.cpp index 94954f70..f84b727f 100644 --- a/src/inputpanel/QskInputPanel.cpp +++ b/src/inputpanel/QskInputPanel.cpp @@ -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 ) diff --git a/src/inputpanel/QskInputPanel.h b/src/inputpanel/QskInputPanel.h index ecaf01fd..251bb662 100644 --- a/src/inputpanel/QskInputPanel.h +++ b/src/inputpanel/QskInputPanel.h @@ -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& );