From 1ac3459afa8be34749ef44e125b54e1b9e1f69b5 Mon Sep 17 00:00:00 2001 From: Ivan Borzenkov Date: Sat, 8 Jul 2023 22:59:33 +0300 Subject: [PATCH 1/3] add keyboard layout switch selector --- src/modules/keyboard/Config.cpp | 42 ++++++++++++-- src/modules/keyboard/Config.h | 8 ++- src/modules/keyboard/KeyboardData_p.cxxtr | 55 +++++++++++++++++++ src/modules/keyboard/KeyboardLayoutModel.cpp | 20 +++++++ src/modules/keyboard/KeyboardLayoutModel.h | 14 +++++ src/modules/keyboard/KeyboardPage.cpp | 16 ++++++ src/modules/keyboard/KeyboardPage.ui | 25 +++++++++ .../keyboardwidget/keyboardglobal.cpp | 48 ++++++++++++++++ .../keyboard/keyboardwidget/keyboardglobal.h | 2 + src/modules/keyboard/layout-extractor.py | 19 ++++++- 10 files changed, 239 insertions(+), 10 deletions(-) diff --git a/src/modules/keyboard/Config.cpp b/src/modules/keyboard/Config.cpp index 2eca1ffb5..143d55d69 100644 --- a/src/modules/keyboard/Config.cpp +++ b/src/modules/keyboard/Config.cpp @@ -160,6 +160,7 @@ Config::Config( QObject* parent ) , m_keyboardModelsModel( new KeyboardModelsModel( this ) ) , m_keyboardLayoutsModel( new KeyboardLayoutModel( this ) ) , m_keyboardVariantsModel( new KeyboardVariantsModel( this ) ) + , m_keyboardGroupsModel( new KeyboardGroupsModel( this ) ) { m_setxkbmapTimer.setSingleShot( true ); @@ -190,25 +191,40 @@ Config::Config( QObject* parent ) emit prettyStatusChanged(); } ); - connect( m_keyboardVariantsModel, &KeyboardVariantsModel::currentIndexChanged, this, &Config::xkbChanged ); + connect( m_keyboardVariantsModel, + &KeyboardVariantsModel::currentIndexChanged, + [ & ]( int index ) + { + m_selectedVariant = m_keyboardVariantsModel->key( index ); + Config::xkbChanged(); + emit prettyStatusChanged(); + } ); + connect( m_keyboardGroupsModel, + &KeyboardGroupsModel::currentIndexChanged, + [ & ]( int index ) + { + m_selectedGroup = m_keyboardGroupsModel->key( index ); + Config::xkbChanged(); + emit prettyStatusChanged(); + } ); // If the user picks something explicitly -- not a consequence of // a guess -- then move to UserSelected state and stay there. connect( m_keyboardModelsModel, &KeyboardModelsModel::currentIndexChanged, this, &Config::selectionChange ); connect( m_keyboardLayoutsModel, &KeyboardLayoutModel::currentIndexChanged, this, &Config::selectionChange ); connect( m_keyboardVariantsModel, &KeyboardVariantsModel::currentIndexChanged, this, &Config::selectionChange ); + connect( m_keyboardGroupsModel, &KeyboardGroupsModel::currentIndexChanged, this, &Config::selectionChange ); m_selectedModel = m_keyboardModelsModel->key( m_keyboardModelsModel->currentIndex() ); m_selectedLayout = m_keyboardLayoutsModel->item( m_keyboardLayoutsModel->currentIndex() ).first; m_selectedVariant = m_keyboardVariantsModel->key( m_keyboardVariantsModel->currentIndex() ); + m_selectedGroup = m_keyboardGroupsModel->key( m_keyboardGroupsModel->currentIndex() ); } void -Config::xkbChanged( int index ) +Config::xkbChanged() { // Set Xorg keyboard layout + variant - m_selectedVariant = m_keyboardVariantsModel->key( index ); - if ( m_setxkbmapTimer.isActive() ) { m_setxkbmapTimer.stop(); @@ -271,8 +287,15 @@ Config::xkbApply() if ( !m_additionalLayoutInfo.additionalLayout.isEmpty() ) { - m_additionalLayoutInfo.groupSwitcher = xkbmap_query_grp_option(); + if ( !m_selectedGroup.isEmpty() ) + { + m_additionalLayoutInfo.groupSwitcher = "grp:" + m_selectedGroup; + } + if ( m_additionalLayoutInfo.groupSwitcher.isEmpty() ) + { + m_additionalLayoutInfo.groupSwitcher = xkbmap_query_grp_option(); + } if ( m_additionalLayoutInfo.groupSwitcher.isEmpty() ) { m_additionalLayoutInfo.groupSwitcher = "grp:alt_shift_toggle"; @@ -315,6 +338,12 @@ Config::keyboardVariants() const return m_keyboardVariantsModel; } +KeyboardGroupsModel* +Config::keyboardGroups() const +{ + return m_keyboardGroupsModel; +} + static QPersistentModelIndex findLayout( const KeyboardLayoutModel* klm, const QString& currentLayout ) { @@ -647,7 +676,8 @@ Config::finalize() if ( !m_additionalLayoutInfo.additionalLayout.isEmpty() ) { gs->insert( "keyboardAdditionalLayout", m_additionalLayoutInfo.additionalLayout ); - gs->insert( "keyboardAdditionalLayout", m_additionalLayoutInfo.additionalVariant ); + gs->insert( "keyboardAdditionalVariant", m_additionalLayoutInfo.additionalVariant ); + gs->insert( "keyboardGroupSwitcher", m_additionalLayoutInfo.groupSwitcher ); gs->insert( "keyboardVConsoleKeymap", m_additionalLayoutInfo.vconsoleKeymap ); } } diff --git a/src/modules/keyboard/Config.h b/src/modules/keyboard/Config.h index 7f72826f5..c03cbcecb 100644 --- a/src/modules/keyboard/Config.h +++ b/src/modules/keyboard/Config.h @@ -27,6 +27,7 @@ class Config : public QObject Q_PROPERTY( KeyboardModelsModel* keyboardModelsModel READ keyboardModels CONSTANT FINAL ) Q_PROPERTY( KeyboardLayoutModel* keyboardLayoutsModel READ keyboardLayouts CONSTANT FINAL ) Q_PROPERTY( KeyboardVariantsModel* keyboardVariantsModel READ keyboardVariants CONSTANT FINAL ) + Q_PROPERTY( KeyboardGroupsModel* keyboardGroupsModel READ keyboardGroups CONSTANT FINAL ) Q_PROPERTY( QString prettyStatus READ prettyStatus NOTIFY prettyStatusChanged FINAL ) public: @@ -58,6 +59,9 @@ public: * (dvorak). */ KeyboardVariantsModel* keyboardVariants() const; + /* A group describes a toggle groups of change layouts + */ + KeyboardGroupsModel* keyboardGroups() const; /** @brief Call this to change application language * @@ -87,7 +91,7 @@ private: * xkbChanged() is called when the selection changes, and triggers * a delayed call to xkbApply() which does the actual work. */ - void xkbChanged( int index ); + void xkbChanged(); void xkbApply(); void locale1Apply(); @@ -97,10 +101,12 @@ private: KeyboardModelsModel* m_keyboardModelsModel; KeyboardLayoutModel* m_keyboardLayoutsModel; KeyboardVariantsModel* m_keyboardVariantsModel; + KeyboardGroupsModel* m_keyboardGroupsModel; QString m_selectedLayout; QString m_selectedModel; QString m_selectedVariant; + QString m_selectedGroup; // Layout (and corresponding info) added if current one doesn't support ASCII (e.g. Russian or Japanese) AdditionalLayoutInfo m_additionalLayoutInfo; diff --git a/src/modules/keyboard/KeyboardData_p.cxxtr b/src/modules/keyboard/KeyboardData_p.cxxtr index 39783035a..20675367a 100644 --- a/src/modules/keyboard/KeyboardData_p.cxxtr +++ b/src/modules/keyboard/KeyboardData_p.cxxtr @@ -823,3 +823,58 @@ public: } } +/* This returns a reference to local, which is a terrible idea. + * Good thing it's not meant to be compiled. + */ +class kb_groups : public QObject { +Q_OBJECT +public: + const QStringList& table() + { + return QStringList { + tr("Alt+Caps Lock", "kb_group"), + tr("Alt+Ctrl", "kb_group"), + tr("Alt+Shift", "kb_group"), + tr("Alt+Space", "kb_group"), + tr("Any Win (while pressed)", "kb_group"), + tr("Both Alts together", "kb_group"), + tr("Both Alts together; AltGr alone chooses third level", "kb_group"), + tr("Both Ctrls together", "kb_group"), + tr("Both Shifts together", "kb_group"), + tr("Caps Lock", "kb_group"), + tr("Caps Lock (while pressed), Alt+Caps Lock for the original Caps Lock action", "kb_group"), + tr("Caps Lock to first layout; Shift+Caps Lock to second layout", "kb_group"), + tr("Ctrl+Left Win to first layout; Ctrl+Menu to second layout", "kb_group"), + tr("Ctrl+Shift", "kb_group"), + tr("Ctrl+Space", "kb_group"), + tr("Left Alt", "kb_group"), + tr("Left Alt (while pressed)", "kb_group"), + tr("Left Alt+Left Shift", "kb_group"), + tr("Left Ctrl", "kb_group"), + tr("Left Ctrl to first layout; Right Ctrl to second layout", "kb_group"), + tr("Left Ctrl+Left Shift", "kb_group"), + tr("Left Ctrl+Left Win", "kb_group"), + tr("Left Shift", "kb_group"), + tr("Left Win", "kb_group"), + tr("Left Win (while pressed)", "kb_group"), + tr("Left Win to first layout; Right Win/Menu to second layout", "kb_group"), + tr("Menu", "kb_group"), + tr("Menu (while pressed), Shift+Menu for Menu", "kb_group"), + tr("None", "kb_group"), + tr("Right Alt", "kb_group"), + tr("Right Alt (while pressed)", "kb_group"), + tr("Right Alt+Right Shift", "kb_group"), + tr("Right Ctrl", "kb_group"), + tr("Right Ctrl (while pressed)", "kb_group"), + tr("Right Ctrl+Right Shift", "kb_group"), + tr("Right Shift", "kb_group"), + tr("Right Win", "kb_group"), + tr("Right Win (while pressed)", "kb_group"), + tr("Scroll Lock", "kb_group"), + tr("Shift+Caps Lock", "kb_group"), + tr("Win+Space", "kb_group"), + QString() + }; +} +} + diff --git a/src/modules/keyboard/KeyboardLayoutModel.cpp b/src/modules/keyboard/KeyboardLayoutModel.cpp index ed171a476..a52927e27 100644 --- a/src/modules/keyboard/KeyboardLayoutModel.cpp +++ b/src/modules/keyboard/KeyboardLayoutModel.cpp @@ -272,3 +272,23 @@ KeyboardVariantsModel::setVariants( QMap< QString, QString > variants ) m_currentIndex = -1; endResetModel(); } + +KeyboardGroupsModel::KeyboardGroupsModel( QObject* parent ) + : XKBListModel( parent ) +{ + m_contextname = "kb_groups"; + + // The groups map is from human-readable names (!) to xkb identifier + const auto groups = KeyboardGlobal::getKeyboardGroups(); + m_list.reserve( groups.count() ); + int index = 0; + for ( const auto& key : groups.keys() ) + { + // So here *key* is the key in the map, which is the human-readable thing, + // while the struct fields are xkb-id, and human-readable + m_list << ModelInfo { groups[ key ], key }; + index++; + } + + cDebug() << "Loaded" << m_list.count() << "keyboard groups"; +} diff --git a/src/modules/keyboard/KeyboardLayoutModel.h b/src/modules/keyboard/KeyboardLayoutModel.h index 1fd6a7819..1dc925b33 100644 --- a/src/modules/keyboard/KeyboardLayoutModel.h +++ b/src/modules/keyboard/KeyboardLayoutModel.h @@ -154,6 +154,20 @@ public: void setVariants( QMap< QString, QString > variants ); }; +/** @brief A list of variants (xkb id and human-readable) + * + * The variants that are available depend on the Layout that is used, + * so the `setVariants()` function can be used to update the variants + * when the two models are related. + */ +class KeyboardGroupsModel : public XKBListModel +{ + Q_OBJECT + +public: + explicit KeyboardGroupsModel( QObject* parent = nullptr ); +}; + /** @brief Adjust to changes in application language. */ void retranslateKeyboardModels(); diff --git a/src/modules/keyboard/KeyboardPage.cpp b/src/modules/keyboard/KeyboardPage.cpp index c821c4633..1a4251e53 100644 --- a/src/modules/keyboard/KeyboardPage.cpp +++ b/src/modules/keyboard/KeyboardPage.cpp @@ -68,6 +68,12 @@ KeyboardPage::KeyboardPage( Config* config, QWidget* parent ) ui->variantSelector->setCurrentIndex( model->index( model->currentIndex() ) ); cDebug() << "Variants now total=" << model->rowCount() << "selected=" << model->currentIndex(); } + { + auto* model = config->keyboardGroups(); + ui->groupSelector->setModel( model ); + ui->groupSelector->setCurrentIndex( model->currentIndex() ); + cDebug() << "Groups now total=" << model->rowCount() << "selected=" << model->currentIndex(); + } connect( ui->buttonRestore, &QPushButton::clicked, @@ -107,6 +113,16 @@ KeyboardPage::KeyboardPage( Config* config, QWidget* parent ) ui->variantSelector->setCurrentIndex( m_config->keyboardVariants()->index( index ) ); m_keyboardPreview->setVariant( m_config->keyboardVariants()->key( index ) ); } ); + + connect( ui->groupSelector, + QOverload< int >::of( &QComboBox::currentIndexChanged ), + config->keyboardGroups(), + QOverload< int >::of( &XKBListModel::setCurrentIndex ) ); + connect( config->keyboardGroups(), + &KeyboardGroupsModel::currentIndexChanged, + ui->groupSelector, + &QComboBox::setCurrentIndex ); + CALAMARES_RETRANSLATE_SLOT( &KeyboardPage::retranslate ); } diff --git a/src/modules/keyboard/KeyboardPage.ui b/src/modules/keyboard/KeyboardPage.ui index fa54ed7c8..c3c4a2499 100644 --- a/src/modules/keyboard/KeyboardPage.ui +++ b/src/modules/keyboard/KeyboardPage.ui @@ -117,6 +117,30 @@ SPDX-License-Identifier: GPL-3.0-or-later + + + + 0 + + + + + Keyboard Switch: + + + + + + + + 0 + 0 + + + + + + @@ -142,6 +166,7 @@ SPDX-License-Identifier: GPL-3.0-or-later physicalModelSelector layoutSelector variantSelector + groupSelector LE_TestKeyboard buttonRestore diff --git a/src/modules/keyboard/keyboardwidget/keyboardglobal.cpp b/src/modules/keyboard/keyboardwidget/keyboardglobal.cpp index 5dc6de66e..3f6f2ecf4 100644 --- a/src/modules/keyboard/keyboardwidget/keyboardglobal.cpp +++ b/src/modules/keyboard/keyboardwidget/keyboardglobal.cpp @@ -199,6 +199,48 @@ parseKeyboardLayouts( const char* filepath ) return layouts; } +static KeyboardGlobal::GroupsMap +parseKeyboardGroups( const char* filepath ) +{ + KeyboardGlobal::GroupsMap models; + + QFile fh( filepath ); + fh.open( QIODevice::ReadOnly ); + + if ( !fh.isOpen() ) + { + cDebug() << "X11 Keyboard model definitions not found!"; + return models; + } + + bool modelsFound = findSection( fh, "! option" ); + // read the file until the end or until we break the loop + while ( modelsFound && !fh.atEnd() ) + { + QByteArray line = fh.readLine(); + + // check if we start a new section + if ( line.startsWith( '!' ) ) + { + break; + } + + // here we are in the model section, otherwise we would continue or break + QRegExp rx; + rx.setPattern( "^\\s+grp:(\\S+)\\s+(\\w.*)\n$" ); + + // insert into the model map + if ( rx.indexIn( line ) != -1 ) + { + QString modelDesc = rx.cap( 2 ); + QString model = rx.cap( 1 ); + models.insert( modelDesc, model ); + } + } + + return models; +} + KeyboardGlobal::LayoutsMap KeyboardGlobal::getKeyboardLayouts() @@ -212,3 +254,9 @@ KeyboardGlobal::getKeyboardModels() { return parseKeyboardModels( XKB_FILE ); } + +KeyboardGlobal::GroupsMap +KeyboardGlobal::getKeyboardGroups() +{ + return parseKeyboardGroups( XKB_FILE ); +} diff --git a/src/modules/keyboard/keyboardwidget/keyboardglobal.h b/src/modules/keyboard/keyboardwidget/keyboardglobal.h index 2d60bd768..5166f88bc 100644 --- a/src/modules/keyboard/keyboardwidget/keyboardglobal.h +++ b/src/modules/keyboard/keyboardwidget/keyboardglobal.h @@ -30,9 +30,11 @@ public: using LayoutsMap = QMap< QString, KeyboardInfo >; using ModelsMap = QMap< QString, QString >; + using GroupsMap = QMap< QString, QString >; static LayoutsMap getKeyboardLayouts(); static ModelsMap getKeyboardModels(); + static GroupsMap getKeyboardGroups(); }; #endif // KEYBOARDGLOBAL_H diff --git a/src/modules/keyboard/layout-extractor.py b/src/modules/keyboard/layout-extractor.py index 44b0d6b50..0827c844d 100644 --- a/src/modules/keyboard/layout-extractor.py +++ b/src/modules/keyboard/layout-extractor.py @@ -15,14 +15,15 @@ Prints out a few tables of keyboard model, layout, variant names for use in translations. """ -def scrape_file(file, modelsset, layoutsset, variantsset): +def scrape_file(file, modelsset, layoutsset, variantsset, groupsset): import re # These RE's match what is in keyboardglobal.cpp model_re = re.compile("^\\s+(\\S+)\\s+(\\w.*)\n$") layout_re = re.compile("^\\s+(\\S+)\\s+(\\w.*)\n$") variant_re = re.compile("^\\s+(\\S+)\\s+(\\S+): (\\w.*)\n$") + group_re = re.compile("^\\s+grp:(\\S+)\\s+(\\w.*)\n$") - MODEL, LAYOUT, VARIANT = range(3) + MODEL, LAYOUT, VARIANT, GROUP = range(4) state = None for line in file.readlines(): # Handle changes in section @@ -35,6 +36,9 @@ def scrape_file(file, modelsset, layoutsset, variantsset): elif line.startswith("! variant"): state = VARIANT continue + elif line.startswith("! option"): + state = GROUP + continue elif not line.strip(): state = None # Unchanged from last blank @@ -53,6 +57,12 @@ def scrape_file(file, modelsset, layoutsset, variantsset): v = variant_re.match(line) name = v.groups()[2] variantsset.add(name) + if state == GROUP: + v = group_re.match(line) + if v is None: + continue + name = v.groups()[1] + groupsset.add(name) def write_set(file, label, set): @@ -85,12 +95,15 @@ if __name__ == "__main__": models=set() layouts=set() variants=set() + groups=set() variants.add( "Default" ) + groups.add( "None" ) with open("/usr/local/share/X11/xkb/rules/base.lst", "r") as f: - scrape_file(f, models, layouts, variants) + scrape_file(f, models, layouts, variants, groups) with open("KeyboardData_p.cxxtr", "w") as f: f.write(cpp_header_comment) write_set(f, "kb_models", models) write_set(f, "kb_layouts", layouts) write_set(f, "kb_variants", variants) + write_set(f, "kb_groups", groups) From ea725da79b52d51c507ad9536ef39397972cdec4 Mon Sep 17 00:00:00 2001 From: Ivan Borzenkov Date: Thu, 7 Sep 2023 19:14:39 +0300 Subject: [PATCH 2/3] keyboard switch to same line --- src/modules/keyboard/Config.cpp | 18 +++---- src/modules/keyboard/Config.h | 6 +-- src/modules/keyboard/KeyboardLayoutModel.cpp | 2 +- src/modules/keyboard/KeyboardLayoutModel.h | 12 ++--- src/modules/keyboard/KeyboardPage.cpp | 8 +-- src/modules/keyboard/KeyboardPage.ui | 54 +++++++++++-------- .../keyboardwidget/keyboardglobal.cpp | 4 +- 7 files changed, 58 insertions(+), 46 deletions(-) diff --git a/src/modules/keyboard/Config.cpp b/src/modules/keyboard/Config.cpp index 143d55d69..9cd23d059 100644 --- a/src/modules/keyboard/Config.cpp +++ b/src/modules/keyboard/Config.cpp @@ -160,7 +160,7 @@ Config::Config( QObject* parent ) , m_keyboardModelsModel( new KeyboardModelsModel( this ) ) , m_keyboardLayoutsModel( new KeyboardLayoutModel( this ) ) , m_keyboardVariantsModel( new KeyboardVariantsModel( this ) ) - , m_keyboardGroupsModel( new KeyboardGroupsModel( this ) ) + , m_KeyboardGroupSwitcherModel( new KeyboardGroupsSwitchersModel( this ) ) { m_setxkbmapTimer.setSingleShot( true ); @@ -199,11 +199,11 @@ Config::Config( QObject* parent ) Config::xkbChanged(); emit prettyStatusChanged(); } ); - connect( m_keyboardGroupsModel, - &KeyboardGroupsModel::currentIndexChanged, + connect( m_KeyboardGroupSwitcherModel, + &KeyboardGroupsSwitchersModel::currentIndexChanged, [ & ]( int index ) { - m_selectedGroup = m_keyboardGroupsModel->key( index ); + m_selectedGroup = m_KeyboardGroupSwitcherModel->key( index ); Config::xkbChanged(); emit prettyStatusChanged(); } ); @@ -213,12 +213,12 @@ Config::Config( QObject* parent ) connect( m_keyboardModelsModel, &KeyboardModelsModel::currentIndexChanged, this, &Config::selectionChange ); connect( m_keyboardLayoutsModel, &KeyboardLayoutModel::currentIndexChanged, this, &Config::selectionChange ); connect( m_keyboardVariantsModel, &KeyboardVariantsModel::currentIndexChanged, this, &Config::selectionChange ); - connect( m_keyboardGroupsModel, &KeyboardGroupsModel::currentIndexChanged, this, &Config::selectionChange ); + connect( m_KeyboardGroupSwitcherModel, &KeyboardGroupsSwitchersModel::currentIndexChanged, this, &Config::selectionChange ); m_selectedModel = m_keyboardModelsModel->key( m_keyboardModelsModel->currentIndex() ); m_selectedLayout = m_keyboardLayoutsModel->item( m_keyboardLayoutsModel->currentIndex() ).first; m_selectedVariant = m_keyboardVariantsModel->key( m_keyboardVariantsModel->currentIndex() ); - m_selectedGroup = m_keyboardGroupsModel->key( m_keyboardGroupsModel->currentIndex() ); + m_selectedGroup = m_KeyboardGroupSwitcherModel->key( m_KeyboardGroupSwitcherModel->currentIndex() ); } void @@ -338,10 +338,10 @@ Config::keyboardVariants() const return m_keyboardVariantsModel; } -KeyboardGroupsModel* -Config::keyboardGroups() const +KeyboardGroupsSwitchersModel* +Config::keyboardGroupsSwitchers() const { - return m_keyboardGroupsModel; + return m_KeyboardGroupSwitcherModel; } static QPersistentModelIndex diff --git a/src/modules/keyboard/Config.h b/src/modules/keyboard/Config.h index c03cbcecb..04659514d 100644 --- a/src/modules/keyboard/Config.h +++ b/src/modules/keyboard/Config.h @@ -27,7 +27,7 @@ class Config : public QObject Q_PROPERTY( KeyboardModelsModel* keyboardModelsModel READ keyboardModels CONSTANT FINAL ) Q_PROPERTY( KeyboardLayoutModel* keyboardLayoutsModel READ keyboardLayouts CONSTANT FINAL ) Q_PROPERTY( KeyboardVariantsModel* keyboardVariantsModel READ keyboardVariants CONSTANT FINAL ) - Q_PROPERTY( KeyboardGroupsModel* keyboardGroupsModel READ keyboardGroups CONSTANT FINAL ) + Q_PROPERTY( KeyboardGroupsSwitchersModel* keyboardGroupsSwitchersModel READ keyboardGroupsSwitchers CONSTANT FINAL ) Q_PROPERTY( QString prettyStatus READ prettyStatus NOTIFY prettyStatusChanged FINAL ) public: @@ -61,7 +61,7 @@ public: KeyboardVariantsModel* keyboardVariants() const; /* A group describes a toggle groups of change layouts */ - KeyboardGroupsModel* keyboardGroups() const; + KeyboardGroupsSwitchersModel* keyboardGroupsSwitchers() const; /** @brief Call this to change application language * @@ -101,7 +101,7 @@ private: KeyboardModelsModel* m_keyboardModelsModel; KeyboardLayoutModel* m_keyboardLayoutsModel; KeyboardVariantsModel* m_keyboardVariantsModel; - KeyboardGroupsModel* m_keyboardGroupsModel; + KeyboardGroupsSwitchersModel* m_KeyboardGroupSwitcherModel; QString m_selectedLayout; QString m_selectedModel; diff --git a/src/modules/keyboard/KeyboardLayoutModel.cpp b/src/modules/keyboard/KeyboardLayoutModel.cpp index a52927e27..8ba30b02e 100644 --- a/src/modules/keyboard/KeyboardLayoutModel.cpp +++ b/src/modules/keyboard/KeyboardLayoutModel.cpp @@ -273,7 +273,7 @@ KeyboardVariantsModel::setVariants( QMap< QString, QString > variants ) endResetModel(); } -KeyboardGroupsModel::KeyboardGroupsModel( QObject* parent ) +KeyboardGroupsSwitchersModel::KeyboardGroupsSwitchersModel( QObject* parent ) : XKBListModel( parent ) { m_contextname = "kb_groups"; diff --git a/src/modules/keyboard/KeyboardLayoutModel.h b/src/modules/keyboard/KeyboardLayoutModel.h index 1dc925b33..850f194c4 100644 --- a/src/modules/keyboard/KeyboardLayoutModel.h +++ b/src/modules/keyboard/KeyboardLayoutModel.h @@ -154,18 +154,18 @@ public: void setVariants( QMap< QString, QString > variants ); }; -/** @brief A list of variants (xkb id and human-readable) +/** @brief A list of groupsSwitcher (xkb id and human-readable) * - * The variants that are available depend on the Layout that is used, - * so the `setVariants()` function can be used to update the variants - * when the two models are related. + * The list of group switching combinations `getKeyboardGroups()` + * function can be used to update the switching when the two models + * are related. */ -class KeyboardGroupsModel : public XKBListModel +class KeyboardGroupsSwitchersModel : public XKBListModel { Q_OBJECT public: - explicit KeyboardGroupsModel( QObject* parent = nullptr ); + explicit KeyboardGroupsSwitchersModel( QObject* parent = nullptr ); }; /** @brief Adjust to changes in application language. diff --git a/src/modules/keyboard/KeyboardPage.cpp b/src/modules/keyboard/KeyboardPage.cpp index 1a4251e53..dbb80c600 100644 --- a/src/modules/keyboard/KeyboardPage.cpp +++ b/src/modules/keyboard/KeyboardPage.cpp @@ -69,7 +69,7 @@ KeyboardPage::KeyboardPage( Config* config, QWidget* parent ) cDebug() << "Variants now total=" << model->rowCount() << "selected=" << model->currentIndex(); } { - auto* model = config->keyboardGroups(); + auto* model = config->keyboardGroupsSwitchers(); ui->groupSelector->setModel( model ); ui->groupSelector->setCurrentIndex( model->currentIndex() ); cDebug() << "Groups now total=" << model->rowCount() << "selected=" << model->currentIndex(); @@ -116,10 +116,10 @@ KeyboardPage::KeyboardPage( Config* config, QWidget* parent ) connect( ui->groupSelector, QOverload< int >::of( &QComboBox::currentIndexChanged ), - config->keyboardGroups(), + config->keyboardGroupsSwitchers(), QOverload< int >::of( &XKBListModel::setCurrentIndex ) ); - connect( config->keyboardGroups(), - &KeyboardGroupsModel::currentIndexChanged, + connect( config->keyboardGroupsSwitchers(), + &KeyboardGroupsSwitchersModel::currentIndexChanged, ui->groupSelector, &QComboBox::setCurrentIndex ); diff --git a/src/modules/keyboard/KeyboardPage.ui b/src/modules/keyboard/KeyboardPage.ui index c3c4a2499..7d30655f0 100644 --- a/src/modules/keyboard/KeyboardPage.ui +++ b/src/modules/keyboard/KeyboardPage.ui @@ -122,6 +122,31 @@ SPDX-License-Identifier: GPL-3.0-or-later 0 + + + + + 2 + 0 + + + + + 50 + false + + + + + + + + + + Type here to test your keyboard + + + @@ -132,34 +157,21 @@ SPDX-License-Identifier: GPL-3.0-or-later - - 0 + + 1 0 + + + 0 + 0 + + - - - - - 50 - false - - - - - - - - - - Type here to test your keyboard - - - diff --git a/src/modules/keyboard/keyboardwidget/keyboardglobal.cpp b/src/modules/keyboard/keyboardwidget/keyboardglobal.cpp index 3f6f2ecf4..0e0fea010 100644 --- a/src/modules/keyboard/keyboardwidget/keyboardglobal.cpp +++ b/src/modules/keyboard/keyboardwidget/keyboardglobal.cpp @@ -200,7 +200,7 @@ parseKeyboardLayouts( const char* filepath ) } static KeyboardGlobal::GroupsMap -parseKeyboardGroups( const char* filepath ) +parseKeyboardGroupsSwitchers( const char* filepath ) { KeyboardGlobal::GroupsMap models; @@ -258,5 +258,5 @@ KeyboardGlobal::getKeyboardModels() KeyboardGlobal::GroupsMap KeyboardGlobal::getKeyboardGroups() { - return parseKeyboardGroups( XKB_FILE ); + return parseKeyboardGroupsSwitchers( XKB_FILE ); } From 4d00eef8220db0de3502bc884f66030ebacaf494 Mon Sep 17 00:00:00 2001 From: Ivan Borzenkov Date: Thu, 7 Sep 2023 23:26:21 +0300 Subject: [PATCH 3/3] fixes --- CHANGES-3.3 | 1 + src/modules/keyboard/Config.cpp | 4 ++-- .../keyboard/keyboardwidget/keyboardglobal.cpp | 18 ++++++++++-------- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/CHANGES-3.3 b/CHANGES-3.3 index ca3a02813..7add5ca5d 100644 --- a/CHANGES-3.3 +++ b/CHANGES-3.3 @@ -30,6 +30,7 @@ This release contains contributions from (alphabetically by first name): in a Wayland session. (thanks Hector) - *keyboard* module now writes X11 layout configuration with variants for all non-ASCII (e.g. us) layouts. (thanks Ivan) + - *keyboard* module now can configure keyboard switch. (thanks Ivan) # 3.3.0-alpha3 (2023-08-28) diff --git a/src/modules/keyboard/Config.cpp b/src/modules/keyboard/Config.cpp index 9cd23d059..785f12458 100644 --- a/src/modules/keyboard/Config.cpp +++ b/src/modules/keyboard/Config.cpp @@ -196,7 +196,7 @@ Config::Config( QObject* parent ) [ & ]( int index ) { m_selectedVariant = m_keyboardVariantsModel->key( index ); - Config::xkbChanged(); + xkbChanged(); emit prettyStatusChanged(); } ); connect( m_KeyboardGroupSwitcherModel, @@ -204,7 +204,7 @@ Config::Config( QObject* parent ) [ & ]( int index ) { m_selectedGroup = m_KeyboardGroupSwitcherModel->key( index ); - Config::xkbChanged(); + xkbChanged(); emit prettyStatusChanged(); } ); diff --git a/src/modules/keyboard/keyboardwidget/keyboardglobal.cpp b/src/modules/keyboard/keyboardwidget/keyboardglobal.cpp index 0e0fea010..83b8d825f 100644 --- a/src/modules/keyboard/keyboardwidget/keyboardglobal.cpp +++ b/src/modules/keyboard/keyboardwidget/keyboardglobal.cpp @@ -213,9 +213,12 @@ parseKeyboardGroupsSwitchers( const char* filepath ) return models; } - bool modelsFound = findSection( fh, "! option" ); + QRegularExpression rx; + rx.setPattern( "^\\s+grp:(\\S+)\\s+(\\w.*)\n$" ); + + bool optionSectionFound = findSection( fh, "! option" ); // read the file until the end or until we break the loop - while ( modelsFound && !fh.atEnd() ) + while ( optionSectionFound && !fh.atEnd() ) { QByteArray line = fh.readLine(); @@ -225,15 +228,14 @@ parseKeyboardGroupsSwitchers( const char* filepath ) break; } - // here we are in the model section, otherwise we would continue or break - QRegExp rx; - rx.setPattern( "^\\s+grp:(\\S+)\\s+(\\w.*)\n$" ); + // here we are in the option section - find all "grp:" options // insert into the model map - if ( rx.indexIn( line ) != -1 ) + QRegularExpressionMatch match = rx.match( line ); + if ( match.hasMatch() ) { - QString modelDesc = rx.cap( 2 ); - QString model = rx.cap( 1 ); + QString modelDesc = match.captured( 2 ); + QString model = match.captured( 1 ); models.insert( modelDesc, model ); } }