keyboard: Fix focusing / tab key

This commit is contained in:
Peter Hartmann 2018-03-26 15:48:03 +02:00
parent 412267cf9a
commit ddea04445c
4 changed files with 10 additions and 177 deletions

View File

@ -208,9 +208,6 @@ QLocale QskInputContext::locale() const
void QskInputContext::setFocusObject( QObject* focusObject )
{
if ( m_focusObject )
m_focusObject->removeEventFilter( this );
m_focusObject = focusObject;
if ( !m_focusObject )
{
@ -229,8 +226,15 @@ void QskInputContext::setFocusObject( QObject* focusObject )
{
m_inputItem = focusQuickItem;
m_inputCompositionModel->setInputItem( m_inputItem ); // ### use a signal/slot connection
if( m_inputPanel )
m_inputPanel->setTabFence( false );
inputItemChanged = true;
}
else
{
if( m_inputPanel )
m_inputPanel->setTabFence( true );
}
}
if( inputItemChanged )
@ -246,58 +250,9 @@ void QskInputContext::setFocusObject( QObject* focusObject )
}
}
m_focusObject->installEventFilter( this );
update( Qt::InputMethodQuery( Qt::ImQueryAll & ~Qt::ImEnabled ) );
}
bool QskInputContext::eventFilter( QObject* object, QEvent* event )
{
if ( m_inputPanel && event->type() == QEvent::KeyPress )
{
auto keyEvent = static_cast< QKeyEvent* >( event );
const auto key = keyEvent->key();
switch ( key )
{
case Qt::Key_Tab:
case Qt::Key_Backtab:
if ( m_inputPanel->advanceFocus( key == Qt::Key_Tab ) )
{
keyEvent->accept();
return true;
}
break;
case Qt::Key_Select:
case Qt::Key_Space:
// if there is a focused key, treat the key like a push button
if ( m_inputPanel->activateFocusKey() )
{
keyEvent->accept();
return true;
}
break;
}
}
if ( m_inputPanel && event->type() == QEvent::KeyRelease )
{
auto keyEvent = static_cast< QKeyEvent* >( event );
const auto key = keyEvent->key();
switch ( key )
{
case Qt::Key_Select:
case Qt::Key_Space:
if ( m_inputPanel->deactivateFocusKey() )
{
keyEvent->accept();
return true;
}
break;
}
}
return Inherited::eventFilter( object, event );
}
void QskInputContext::invokeAction( QInputMethod::Action action, int cursorPosition )
{
Q_UNUSED(cursorPosition);

View File

@ -36,9 +36,6 @@ public:
QLocale locale() const override;
void setFocusObject( QObject* ) override;
protected:
bool eventFilter( QObject*, QEvent* ) override;
private Q_SLOTS:
void emitAnimatingChanged();
void handleCandidatesChanged();

View File

@ -10,7 +10,6 @@
#include <QskPushButton.h>
#include <QskTextLabel.h>
#include <QskDialog.h>
#include <QFocusEvent>
#include <QGuiApplication>
#include <QStyleHints>
#include <QskLinearBox.h>
@ -81,9 +80,7 @@ static constexpr const QskInputPanelLayouts qskInputPanelLayouts =
QSK_DECLARE_OPERATORS_FOR_FLAGS( Qt::Key ) // Must appear after the LOWER macro
static const Qt::Key KeyPressed = static_cast< Qt::Key >( Qt::ShiftModifier );
static const Qt::Key KeyLocked = static_cast< Qt::Key >( Qt::ControlModifier );
static const Qt::Key KeyFocused = static_cast< Qt::Key >( Qt::MetaModifier );
static const Qt::Key KeyStates = static_cast< Qt::Key >( Qt::KeyboardModifierMask );
static qreal qskKeyStretch( Qt::Key key )
@ -231,7 +228,6 @@ class QskInputPanel::PrivateData
PrivateData():
currentLayout( nullptr ),
mode( QskInputPanel::LowercaseMode ),
focusKeyIndex( -1 ),
selectedGroup( -1 ),
candidateOffset( 0 ),
buttonsBox( nullptr ),
@ -243,7 +239,6 @@ class QskInputPanel::PrivateData
const QskInputPanelLayouts::Layout* currentLayout;
QskInputPanel::Mode mode;
qint16 focusKeyIndex;
qint16 selectedGroup;
qint32 candidateOffset;
@ -282,7 +277,9 @@ QskInputPanel::QskInputPanel( QQuickItem* parent ):
this, &QskInputPanel::updateLocale );
setFlag( ItemIsFocusScope, true );
setTabFence( true );
// ### for some reason we never get focus when this is a tab fence:
// setTabFence( true );
setAutoLayoutChildren( true );
@ -306,8 +303,6 @@ QskInputPanel::QskInputPanel( QQuickItem* parent ):
int keyIndex = m_data->keyTable[ m_data->mode ].indexOf( &keyData );
QskKeyButton* button = new QskKeyButton( keyIndex, this, rowBox );
button->installEventFilter( this );
m_data->keyButtons.append( button );
}
}
@ -512,94 +507,6 @@ void QskInputPanel::setPreeditCandidates( const QVector< Qt::Key >& candidates )
setCandidateOffset( 0 );
}
bool QskInputPanel::advanceFocus( bool forward )
{
deactivateFocusKey();
auto offset = forward ? 1 : -1;
auto focusKeyIndex = m_data->focusKeyIndex;
Q_FOREVER
{
focusKeyIndex += offset;
if( focusKeyIndex < 0 || focusKeyIndex >= RowCount * KeyCount )
{
clearFocusKey();
return false;
}
const auto key = keyDataAt( focusKeyIndex ).key;
if( key && key != Qt::Key_unknown )
{
break;
}
}
if( m_data->focusKeyIndex >= 0 )
{
keyDataAt( m_data->focusKeyIndex ).key &= ~KeyFocused;
}
m_data->focusKeyIndex = focusKeyIndex;
keyDataAt( m_data->focusKeyIndex ).key |= KeyFocused;
update();
return true;
}
bool QskInputPanel::activateFocusKey()
{
if( m_data->focusKeyIndex > 0 && m_data->focusKeyIndex < RowCount * KeyCount )
{
auto& keyData = keyDataAt( m_data->focusKeyIndex );
if( keyData.key & KeyPressed )
{
handleKey( m_data->focusKeyIndex );
}
else
{
keyData.key |= KeyPressed;
}
update();
return true;
}
return false;
}
bool QskInputPanel::deactivateFocusKey()
{
if( m_data->focusKeyIndex > 0 && m_data->focusKeyIndex < RowCount * KeyCount )
{
auto& keyData = keyDataAt( m_data->focusKeyIndex );
if( keyData.key & KeyPressed )
{
keyData.key &= ~KeyPressed;
handleKey( m_data->focusKeyIndex );
}
update();
return true;
}
return true;
}
void QskInputPanel::clearFocusKey()
{
if( m_data->focusKeyIndex > 0 && m_data->focusKeyIndex < RowCount * KeyCount )
{
keyDataAt( m_data->focusKeyIndex ).key &= ~KeyFocused;
update();
}
m_data->focusKeyIndex = -1;
}
void QskInputPanel::setCandidateOffset( int candidateOffset )
{
m_data->candidateOffset = candidateOffset;
@ -665,27 +572,6 @@ void QskInputPanel::geometryChanged(
Q_EMIT keyboardRectChanged();
}
bool QskInputPanel::eventFilter( QObject* object, QEvent* event )
{
if( event->type() == QEvent::InputMethod )
{
QInputMethodEvent* inputMethodEvent = static_cast< QInputMethodEvent* >( event );
Q_EMIT inputMethodEventReceived( inputMethodEvent );
return true;
}
else if( event->type() == QEvent::KeyPress )
{
// Return, Backspace and others are covered here (maybe because they don't carry a 'commit string'):
QKeyEvent* keyEvent = static_cast< QKeyEvent* >( event );
Q_EMIT keyEventReceived( keyEvent );
return true;
}
else
{
return Inherited::eventFilter( object, event );
}
}
void QskInputPanel::updateLayout()
{
if( geometry().isNull() )

View File

@ -112,10 +112,6 @@ public:
public Q_SLOTS:
void setPreeditGroups( const QVector< Qt::Key >& );
void setPreeditCandidates( const QVector< Qt::Key >& );
bool advanceFocus( bool = true );
bool activateFocusKey();
bool deactivateFocusKey();
void clearFocusKey();
void handleKey( int keyIndex );
KeyData& keyDataAt( int ) const;
@ -123,7 +119,6 @@ public Q_SLOTS:
protected:
virtual void geometryChanged( const QRectF&, const QRectF& ) override;
virtual bool eventFilter( QObject* object, QEvent* event ) override;
virtual void updateLayout() override;
private: