diff --git a/CHANGES b/CHANGES index ac8bf5855..1f6f104da 100644 --- a/CHANGES +++ b/CHANGES @@ -10,7 +10,9 @@ website will have to do for older versions. # 3.2.33 (unreleased) # This release contains contributions from (alphabetically by first name): - - No external contributors yet + - Anke Boersma + - Andrius Štikonas + - Gaël PORTAY ## Core ## - Calamares now sets the C++ standard for compilation to C++17; this diff --git a/src/calamares/CalamaresWindow.cpp b/src/calamares/CalamaresWindow.cpp index b062c0b4d..a141317e0 100644 --- a/src/calamares/CalamaresWindow.cpp +++ b/src/calamares/CalamaresWindow.cpp @@ -271,6 +271,7 @@ flavoredWidget( Calamares::Branding::PanelFlavor flavor, case Calamares::Branding::PanelFlavor::None: return nullptr; } + __builtin_unreachable(); } /** @brief Adds widgets to @p layout if they belong on this @p side diff --git a/src/libcalamares/partition/PartitionSize.cpp b/src/libcalamares/partition/PartitionSize.cpp index 82444da6a..ddd3be2ef 100644 --- a/src/libcalamares/partition/PartitionSize.cpp +++ b/src/libcalamares/partition/PartitionSize.cpp @@ -139,6 +139,7 @@ PartitionSize::toBytes( qint64 totalSectors, qint64 sectorSize ) const case SizeUnit::GiB: return toBytes(); } + __builtin_unreachable(); } qint64 @@ -175,7 +176,7 @@ PartitionSize::toBytes( qint64 totalBytes ) const case SizeUnit::GiB: return toBytes(); } - + __builtin_unreachable(); } qint64 @@ -206,6 +207,7 @@ PartitionSize::toBytes() const case SizeUnit::GiB: return CalamaresUtils::GiBtoBytes( static_cast< unsigned long long >( value() ) ); } + __builtin_unreachable(); } bool @@ -231,6 +233,7 @@ PartitionSize::operator<( const PartitionSize& other ) const case SizeUnit::GiB: return ( toBytes() < other.toBytes() ); } + __builtin_unreachable(); } bool @@ -256,6 +259,7 @@ PartitionSize::operator>( const PartitionSize& other ) const case SizeUnit::GiB: return ( toBytes() > other.toBytes() ); } + __builtin_unreachable(); } bool @@ -281,6 +285,7 @@ PartitionSize::operator==( const PartitionSize& other ) const case SizeUnit::GiB: return ( toBytes() == other.toBytes() ); } + __builtin_unreachable(); } } // namespace Partition diff --git a/src/libcalamares/utils/Yaml.cpp b/src/libcalamares/utils/Yaml.cpp index f999b8bb0..dd7523ae4 100644 --- a/src/libcalamares/utils/Yaml.cpp +++ b/src/libcalamares/utils/Yaml.cpp @@ -52,6 +52,7 @@ yamlToVariant( const YAML::Node& node ) case YAML::NodeType::Undefined: return QVariant(); } + __builtin_unreachable(); } diff --git a/src/modules/keyboard/AdditionalLayoutInfo.h b/src/modules/keyboard/AdditionalLayoutInfo.h new file mode 100644 index 000000000..660449952 --- /dev/null +++ b/src/modules/keyboard/AdditionalLayoutInfo.h @@ -0,0 +1,24 @@ +/* === This file is part of Calamares - === + * + * SPDX-FileCopyrightText: 2020 Artem Grinev + * SPDX-License-Identifier: GPL-3.0-or-later + * + * Calamares is Free Software: see the License-Identifier above. + * + */ + +#ifndef KEYBOARD_ADDITIONAL_LAYOUT_INFO_H +#define KEYBOARD_ADDITIONAL_LAYOUT_INFO_H + +#include + +struct AdditionalLayoutInfo { + QString additionalLayout; + QString additionalVariant; + + QString groupSwitcher; + + QString vconsoleKeymap; +}; + +#endif diff --git a/src/modules/keyboard/Config.cpp b/src/modules/keyboard/Config.cpp index efb345edf..2df2e8935 100644 --- a/src/modules/keyboard/Config.cpp +++ b/src/modules/keyboard/Config.cpp @@ -49,6 +49,100 @@ xkbmap_layout_args( const QString& layout, const QString& variant ) return r; } +static inline QStringList +xkbmap_layout_args( const QStringList& layouts, const QStringList& variants, const QString& switchOption = "grp:alt_shift_toggle") +{ + if ( layouts.size() != variants.size() ) + { + cError() << "Number of layouts and variants must be equal (empty string should be used if there is no corresponding variant)"; + return QStringList(); + } + + QStringList r{ "-layout", layouts.join( "," ) }; + + if ( !variants.isEmpty() ) + { + r << "-variant" << variants.join( "," ); + } + + if ( !switchOption.isEmpty()) + { + r << "-option" << switchOption; + } + + return r; +} + +/* Returns group-switch setxkbd option if set + * or an empty string otherwise + */ +static inline QString +xkbmap_query_grp_option() +{ + QProcess setxkbmapQuery; + setxkbmapQuery.start( "setxkbmap", { "-query" } ); + setxkbmapQuery.waitForFinished(); + + QString outputLine; + + do + { + outputLine = setxkbmapQuery.readLine(); + } + while( setxkbmapQuery.canReadLine() && !outputLine.startsWith("options:") ); + + if( !outputLine.startsWith( "options:" ) ) + { + return QString(); + } + + int index = outputLine.indexOf( "grp:" ); + + if( index == -1 ) + { + return QString(); + } + + //it's either in the end of line or before the other option so \s or , + int lastIndex = outputLine.indexOf( QRegExp( "[\\s,]" ), index ); + + return outputLine.mid( index, lastIndex-1 ); +} + +AdditionalLayoutInfo Config::getAdditionalLayoutInfo( const QString &layout ) +{ + QFile layoutTable( ":/non-ascii-layouts" ); + + if( !layoutTable.open( QIODevice::ReadOnly | QIODevice::Text ) ) { + cError() << "Non-ASCII layout table could not be opened"; + return AdditionalLayoutInfo(); + } + + QString tableLine; + + do + { + tableLine = layoutTable.readLine(); + } + while( layoutTable.canReadLine() && !tableLine.startsWith( layout ) ); + + if( !tableLine.startsWith( layout ) ) + { + return AdditionalLayoutInfo(); + } + + QStringList tableEntries = tableLine.split( " ", SplitSkipEmptyParts ); + + AdditionalLayoutInfo r; + + r.additionalLayout = tableEntries[1]; + r.additionalVariant = tableEntries[2] == "-" ? "" : tableEntries[2]; + + r.vconsoleKeymap = tableEntries[3]; + + return r; +} + Config::Config( QObject* parent ) : QObject( parent ) , m_keyboardModelsModel( new KeyboardModelsModel( this ) ) @@ -82,8 +176,35 @@ Config::Config( QObject* parent ) } connect( &m_setxkbmapTimer, &QTimer::timeout, this, [=] { - QProcess::execute( "setxkbmap", xkbmap_layout_args( m_selectedLayout, m_selectedVariant ) ); - cDebug() << "xkbmap selection changed to: " << m_selectedLayout << '-' << m_selectedVariant; + m_additionalLayoutInfo = getAdditionalLayoutInfo( m_selectedLayout ); + + if ( !m_additionalLayoutInfo.additionalLayout.isEmpty() ) + { + m_additionalLayoutInfo.groupSwitcher = xkbmap_query_grp_option(); + + if( m_additionalLayoutInfo.groupSwitcher.isEmpty() ) + { + m_additionalLayoutInfo.groupSwitcher = "grp:alt_shift_toggle"; + } + + QProcess::execute( "setxkbmap", xkbmap_layout_args( + { m_additionalLayoutInfo.additionalLayout, m_selectedLayout }, + { m_additionalLayoutInfo.additionalVariant, m_selectedVariant }, + m_additionalLayoutInfo.groupSwitcher ) + ); + + + + cDebug() << "xkbmap selection changed to: " << m_selectedLayout << '-' << m_selectedVariant + << "(added " << m_additionalLayoutInfo.additionalLayout << "-" + << m_additionalLayoutInfo.additionalVariant << " since current layout is not ASCII-capable)"; + + } + else + { + QProcess::execute( "setxkbmap", xkbmap_layout_args( m_selectedLayout, m_selectedVariant ) ); + cDebug() << "xkbmap selection changed to: " << m_selectedLayout << '-' << m_selectedVariant; + } m_setxkbmapTimer.disconnect( this ); } ); m_setxkbmapTimer.start( QApplication::keyboardInputInterval() ); @@ -222,6 +343,7 @@ Config::createJobs() Calamares::Job* j = new SetKeyboardLayoutJob( m_selectedModel, m_selectedLayout, m_selectedVariant, + m_additionalLayoutInfo, m_xOrgConfFileName, m_convertedKeymapPath, m_writeEtcDefaultKeyboard ); @@ -372,6 +494,13 @@ Config::finalize() { gs->insert( "keyboardLayout", m_selectedLayout ); gs->insert( "keyboardVariant", m_selectedVariant ); //empty means default variant + + if ( !m_additionalLayoutInfo.additionalLayout.isEmpty() ) + { + gs->insert( "keyboardAdditionalLayout", m_additionalLayoutInfo.additionalLayout); + gs->insert( "keyboardAdditionalLayout", m_additionalLayoutInfo.additionalVariant); + gs->insert( "keyboardVConsoleKeymap", m_additionalLayoutInfo.vconsoleKeymap ); + } } //FIXME: also store keyboard model for something? diff --git a/src/modules/keyboard/Config.h b/src/modules/keyboard/Config.h index 7c18577f6..0446da525 100644 --- a/src/modules/keyboard/Config.h +++ b/src/modules/keyboard/Config.h @@ -13,6 +13,7 @@ #include "Job.h" #include "KeyboardLayoutModel.h" +#include "AdditionalLayoutInfo.h" #include #include @@ -41,6 +42,8 @@ public: void setConfigurationMap( const QVariantMap& configurationMap ); + static AdditionalLayoutInfo getAdditionalLayoutInfo( const QString& layout ); + private: void guessLayout( const QStringList& langParts ); void updateVariants( const QPersistentModelIndex& currentItem, QString currentVariant = QString() ); @@ -52,6 +55,10 @@ private: QString m_selectedLayout; QString m_selectedModel; QString m_selectedVariant; + + // Layout (and corresponding info) added if current one doesn't support ASCII (e.g. Russian or Japanese) + AdditionalLayoutInfo m_additionalLayoutInfo; + QTimer m_setxkbmapTimer; // From configuration diff --git a/src/modules/keyboard/SetKeyboardLayoutJob.cpp b/src/modules/keyboard/SetKeyboardLayoutJob.cpp index cabe0b5c0..766044179 100644 --- a/src/modules/keyboard/SetKeyboardLayoutJob.cpp +++ b/src/modules/keyboard/SetKeyboardLayoutJob.cpp @@ -30,9 +30,10 @@ #include -SetKeyboardLayoutJob::SetKeyboardLayoutJob( const QString& model, +SetKeyboardLayoutJob::SetKeyboardLayoutJob(const QString& model, const QString& layout, const QString& variant, + const AdditionalLayoutInfo& additionalLayoutInfo, const QString& xOrgConfFileName, const QString& convertedKeymapPath, bool writeEtcDefaultKeyboard ) @@ -40,6 +41,7 @@ SetKeyboardLayoutJob::SetKeyboardLayoutJob( const QString& model, , m_model( model ) , m_layout( layout ) , m_variant( variant ) + , m_additionalLayoutInfo( additionalLayoutInfo ) , m_xOrgConfFileName( xOrgConfFileName ) , m_convertedKeymapPath( convertedKeymapPath ) , m_writeEtcDefaultKeyboard( writeEtcDefaultKeyboard ) @@ -250,19 +252,32 @@ SetKeyboardLayoutJob::writeX11Data( const QString& keyboardConfPath ) const " Identifier \"system-keyboard\"\n" " MatchIsKeyboard \"on\"\n"; - if ( !m_layout.isEmpty() ) - { - stream << " Option \"XkbLayout\" \"" << m_layout << "\"\n"; - } - if ( !m_model.isEmpty() ) + if ( m_additionalLayoutInfo.additionalLayout.isEmpty() ) { - stream << " Option \"XkbModel\" \"" << m_model << "\"\n"; - } + if ( !m_layout.isEmpty() ) + { + stream << " Option \"XkbLayout\" \"" << m_layout << "\"\n"; + } - if ( !m_variant.isEmpty() ) + if ( !m_variant.isEmpty() ) + { + stream << " Option \"XkbVariant\" \"" << m_variant << "\"\n"; + } + } + else { - stream << " Option \"XkbVariant\" \"" << m_variant << "\"\n"; + if ( !m_layout.isEmpty() ) + { + stream << " Option \"XkbLayout\" \"" << m_additionalLayoutInfo.additionalLayout << "," << m_layout << "\"\n"; + } + + if ( !m_variant.isEmpty() ) + { + stream << " Option \"XkbVariant\" \"" << m_additionalLayoutInfo.additionalVariant << "," << m_variant << "\"\n"; + } + + stream << " Option \"XkbOptions\" \"" << m_additionalLayoutInfo.groupSwitcher << "\"\n"; } stream << "EndSection\n"; diff --git a/src/modules/keyboard/SetKeyboardLayoutJob.h b/src/modules/keyboard/SetKeyboardLayoutJob.h index f1eabe195..b1ce0bb15 100644 --- a/src/modules/keyboard/SetKeyboardLayoutJob.h +++ b/src/modules/keyboard/SetKeyboardLayoutJob.h @@ -12,6 +12,8 @@ #define SETKEYBOARDLAYOUTJOB_H #include "Job.h" +#include "AdditionalLayoutInfo.h" + class SetKeyboardLayoutJob : public Calamares::Job @@ -21,6 +23,7 @@ public: SetKeyboardLayoutJob( const QString& model, const QString& layout, const QString& variant, + const AdditionalLayoutInfo& additionaLayoutInfo, const QString& xOrgConfFileName, const QString& convertedKeymapPath, bool writeEtcDefaultKeyboard ); @@ -38,6 +41,7 @@ private: QString m_model; QString m_layout; QString m_variant; + AdditionalLayoutInfo m_additionalLayoutInfo; QString m_xOrgConfFileName; QString m_convertedKeymapPath; const bool m_writeEtcDefaultKeyboard; diff --git a/src/modules/keyboard/keyboard.qrc b/src/modules/keyboard/keyboard.qrc index dd211e630..4283d8190 100644 --- a/src/modules/keyboard/keyboard.qrc +++ b/src/modules/keyboard/keyboard.qrc @@ -2,5 +2,6 @@ kbd-model-map images/restore.png + non-ascii-layouts diff --git a/src/modules/keyboard/non-ascii-layouts b/src/modules/keyboard/non-ascii-layouts new file mode 100644 index 000000000..83935c190 --- /dev/null +++ b/src/modules/keyboard/non-ascii-layouts @@ -0,0 +1,4 @@ +# Layouts stored here need additional layout (usually us) to provide ASCII support for user + +#layout additional-layout additional-variant vconsole-keymap +ru us - ruwin_alt_sh-UTF-8 diff --git a/src/modules/keyboardq/keyboardq.qrc b/src/modules/keyboardq/keyboardq.qrc index 492f6e213..d2473a8ec 100644 --- a/src/modules/keyboardq/keyboardq.qrc +++ b/src/modules/keyboardq/keyboardq.qrc @@ -3,5 +3,6 @@ ../keyboard/kbd-model-map ../keyboard/images/restore.png keyboardq.qml + ../keyboard/non-ascii-layouts diff --git a/src/modules/netinstall/Config.cpp b/src/modules/netinstall/Config.cpp index 92cdcb2bf..e69b3c2a4 100644 --- a/src/modules/netinstall/Config.cpp +++ b/src/modules/netinstall/Config.cpp @@ -43,6 +43,7 @@ Config::status() const case Status::FailedNetworkError: return tr( "Network Installation. (Disabled: Unable to fetch package lists, check your network connection)" ); } + __builtin_unreachable(); } diff --git a/src/modules/packagechooser/PackageChooserViewStep.cpp b/src/modules/packagechooser/PackageChooserViewStep.cpp index b649e6431..d576f2753 100644 --- a/src/modules/packagechooser/PackageChooserViewStep.cpp +++ b/src/modules/packagechooser/PackageChooserViewStep.cpp @@ -110,6 +110,7 @@ PackageChooserViewStep::isNextEnabled() const // exactly one OR one or more return m_widget->hasSelection(); } + __builtin_unreachable(); }