Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package kf6-kguiaddons for openSUSE:Factory checked in at 2024-04-15 20:11:59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/kf6-kguiaddons (Old) and /work/SRC/openSUSE:Factory/.kf6-kguiaddons.new.26366 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "kf6-kguiaddons" Mon Apr 15 20:11:59 2024 rev:2 rq:1167188 version:6.1.0 Changes: -------- --- /work/SRC/openSUSE:Factory/kf6-kguiaddons/kf6-kguiaddons.changes 2024-03-11 15:26:02.044987585 +0100 +++ /work/SRC/openSUSE:Factory/.kf6-kguiaddons.new.26366/kf6-kguiaddons.changes 2024-04-15 20:15:03.893057745 +0200 @@ -1,0 +2,9 @@ +Fri Apr 5 12:52:39 UTC 2024 - Christophe Marin <[email protected]> + +- Update to 6.1.0 + * New feature release +- Changes since 6.0.0: + * recorder/KKeySequenceRecorderPrivate: support recording multi-key modifier-only shortcuts + * update version for new release + +------------------------------------------------------------------- Old: ---- kguiaddons-6.0.0.tar.xz kguiaddons-6.0.0.tar.xz.sig New: ---- kguiaddons-6.1.0.tar.xz kguiaddons-6.1.0.tar.xz.sig ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ kf6-kguiaddons.spec ++++++ --- /var/tmp/diff_new_pack.yPLqPO/_old 2024-04-15 20:15:05.577119726 +0200 +++ /var/tmp/diff_new_pack.yPLqPO/_new 2024-04-15 20:15:05.577119726 +0200 @@ -1,7 +1,7 @@ # # spec file for package kf6-kguiaddons # -# Copyright (c) 2023 SUSE LLC +# Copyright (c) 2024 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -19,13 +19,13 @@ %define qt6_version 6.6.0 %define rname kguiaddons -# Full KF6 version (e.g. 6.0.0) +# Full KF6 version (e.g. 6.1.0) %{!?_kf6_version: %global _kf6_version %{version}} # Last major and minor KF6 version (e.g. 6.0) %{!?_kf6_bugfix_version: %define _kf6_bugfix_version %(echo %{_kf6_version} | awk -F. '{print $1"."$2}')} %bcond_without released Name: kf6-kguiaddons -Version: 6.0.0 +Version: 6.1.0 Release: 0 Summary: Utilities for graphical user interfaces License: LGPL-2.1-or-later @@ -103,8 +103,8 @@ %files devel %doc %{_kf6_qchdir}/KF6GuiAddons.* -%{_kf6_includedir}/KGuiAddons/ %{_kf6_cmakedir}/KF6GuiAddons/ +%{_kf6_includedir}/KGuiAddons/ %{_kf6_libdir}/libKF6GuiAddons.so %{_kf6_pkgconfigdir}/KF6GuiAddons.pc ++++++ kguiaddons-6.0.0.tar.xz -> kguiaddons-6.1.0.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kguiaddons-6.0.0/CMakeLists.txt new/kguiaddons-6.1.0/CMakeLists.txt --- old/kguiaddons-6.0.0/CMakeLists.txt 2024-02-21 12:25:02.000000000 +0100 +++ new/kguiaddons-6.1.0/CMakeLists.txt 2024-04-05 12:56:25.000000000 +0200 @@ -1,10 +1,10 @@ cmake_minimum_required(VERSION 3.16) -set(KF_VERSION "6.0.0") # handled by release scripts +set(KF_VERSION "6.1.0") # handled by release scripts project(KGuiAddons VERSION ${KF_VERSION}) include(FeatureSummary) -find_package(ECM 6.0.0 NO_MODULE) +find_package(ECM 6.1.0 NO_MODULE) set_package_properties(ECM PROPERTIES TYPE REQUIRED DESCRIPTION "Extra CMake Modules." URL "https://commits.kde.org/extra-cmake-modules") feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND FATAL_ON_MISSING_REQUIRED_PACKAGES) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kguiaddons-6.0.0/autotests/kkeysequencerecordertest.cpp new/kguiaddons-6.1.0/autotests/kkeysequencerecordertest.cpp --- old/kguiaddons-6.0.0/autotests/kkeysequencerecordertest.cpp 2024-02-21 12:25:02.000000000 +0100 +++ new/kguiaddons-6.1.0/autotests/kkeysequencerecordertest.cpp 2024-04-05 12:56:25.000000000 +0200 @@ -149,6 +149,63 @@ QCOMPARE(recorder.currentKeySequence(), QKeySequence(Qt::Key_Shift)); } +void KKeySequenceRecorderTest::testModifierOnlyMultiple() +{ + KKeySequenceRecorder recorder(m_window); + recorder.setModifierOnlyAllowed(true); + recorder.setModifierlessAllowed(true); + QSignalSpy resultSpy(&recorder, &KKeySequenceRecorder::gotKeySequence); + QSignalSpy recordingSpy(&recorder, &KKeySequenceRecorder::recordingChanged); + + recorder.startRecording(); + QVERIFY(recorder.isRecording()); + + QTest::keyPress(m_window, Qt::Key_Shift); + Qt::KeyboardModifiers modifiers = Qt::ShiftModifier; + QTest::keyPress(m_window, Qt::Key_Control, modifiers); + modifiers |= Qt::ControlModifier; + modifiers |= Qt::AltModifier; + QTest::keyPress(m_window, Qt::Key_Alt, modifiers); + QTest::keyPress(m_window, Qt::Key_Meta, modifiers); + modifiers |= Qt::MetaModifier; + QTest::qWait(200); + QTest::keyRelease(m_window, Qt::Key_Control, modifiers); + modifiers &= ~Qt::ControlModifier; + QTest::qWait(10); + QTest::keyRelease(m_window, Qt::Key_Alt, modifiers); + modifiers &= ~Qt::AltModifier; + modifiers &= ~Qt::ShiftModifier; + QTest::qWait(10); + QTest::keyRelease(m_window, Qt::Key_Shift, modifiers); + QTest::qWait(10); + QTest::keyRelease(m_window, Qt::Key_Meta, modifiers); + recordingSpy.wait(); + QVERIFY(!recorder.isRecording()); + QCOMPARE(resultSpy.count(), 1); + QCOMPARE(resultSpy.takeFirst().at(0).value<QKeySequence>(), QKeySequence(Qt::MetaModifier | Qt::ControlModifier | Qt::AltModifier | Qt::Key_Shift)); +} + +void KKeySequenceRecorderTest::testModifierOnlyMultipleInterrupt() +{ + KKeySequenceRecorder recorder(m_window); + recorder.setModifierOnlyAllowed(true); + recorder.setModifierlessAllowed(true); + QSignalSpy resultSpy(&recorder, &KKeySequenceRecorder::gotKeySequence); + QSignalSpy recordingSpy(&recorder, &KKeySequenceRecorder::recordingChanged); + + recorder.startRecording(); + QVERIFY(recorder.isRecording()); + + QTest::keyPress(m_window, Qt::Key_Control); + QTest::keyPress(m_window, Qt::Key_Meta, Qt::ControlModifier); + QTest::keyClick(m_window, Qt::Key_A, Qt::ControlModifier); + + recordingSpy.wait(); + QVERIFY(!recorder.isRecording()); + QCOMPARE(resultSpy.count(), 1); + QCOMPARE(resultSpy.takeFirst().at(0).value<QKeySequence>(), QKeySequence(Qt::ControlModifier | Qt::Key_A)); +} + void KKeySequenceRecorderTest::testModifierOnlyDisabled() { KKeySequenceRecorder recorder(m_window); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kguiaddons-6.0.0/autotests/kkeysequencerecordertest.h new/kguiaddons-6.1.0/autotests/kkeysequencerecordertest.h --- old/kguiaddons-6.0.0/autotests/kkeysequencerecordertest.h 2024-02-21 12:25:02.000000000 +0100 +++ new/kguiaddons-6.1.0/autotests/kkeysequencerecordertest.h 2024-04-05 12:56:25.000000000 +0200 @@ -21,6 +21,8 @@ void testModifiers(); void testModifierless(); void testModifierOnly(); + void testModifierOnlyMultiple(); + void testModifierOnlyMultipleInterrupt(); void testModifierOnlyDisabled(); void testMultiKeyAllowed(); void testKeyNonLetterNoModifier(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kguiaddons-6.0.0/src/geo-scheme-handler/google-maps-geo-handler.desktop new/kguiaddons-6.1.0/src/geo-scheme-handler/google-maps-geo-handler.desktop --- old/kguiaddons-6.0.0/src/geo-scheme-handler/google-maps-geo-handler.desktop 2024-02-21 12:25:02.000000000 +0100 +++ new/kguiaddons-6.1.0/src/geo-scheme-handler/google-maps-geo-handler.desktop 2024-04-05 12:56:25.000000000 +0200 @@ -16,6 +16,7 @@ Name[fi]=Google Maps Name[fr]=Google Maps Name[gl]=Google Maps +Name[he]=Google ×פ×ת Name[hi]=à¤à¥à¤à¤² मà¥à¤ªà¥à¤¸ Name[hu]=Google Térképek Name[ia]=Google Maps (Mappas de Google) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kguiaddons-6.0.0/src/geo-scheme-handler/openstreetmap-geo-handler.desktop new/kguiaddons-6.1.0/src/geo-scheme-handler/openstreetmap-geo-handler.desktop --- old/kguiaddons-6.0.0/src/geo-scheme-handler/openstreetmap-geo-handler.desktop 2024-02-21 12:25:02.000000000 +0100 +++ new/kguiaddons-6.1.0/src/geo-scheme-handler/openstreetmap-geo-handler.desktop 2024-04-05 12:56:25.000000000 +0200 @@ -16,6 +16,7 @@ Name[fi]=OpenStreetMap Name[fr]=OpenStreetMap Name[gl]=OpenStreetMap +Name[he]=OpenStreetMap Name[hi]=à¤à¤ªà¤¨à¤¸à¥à¤à¥à¤°à¥à¤à¤®à¥à¤ª Name[hu]=OpenStreetMap Name[ia]=OpenStreetMap diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kguiaddons-6.0.0/src/geo-scheme-handler/qwant-maps-geo-handler.desktop new/kguiaddons-6.1.0/src/geo-scheme-handler/qwant-maps-geo-handler.desktop --- old/kguiaddons-6.0.0/src/geo-scheme-handler/qwant-maps-geo-handler.desktop 2024-02-21 12:25:02.000000000 +0100 +++ new/kguiaddons-6.1.0/src/geo-scheme-handler/qwant-maps-geo-handler.desktop 2024-04-05 12:56:25.000000000 +0200 @@ -16,6 +16,7 @@ Name[fi]=Qwant Maps Name[fr]=Qwant Maps Name[gl]=Qwant Maps +Name[he]=Qwant Maps Name[hi]=à¤à¥à¤µà¤¾à¤¨à¥à¤ मà¥à¤ªà¥à¤¸ Name[hu]=Qwant Térképek Name[ia]=Qwant Maps (Mappas de Qwant) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kguiaddons-6.0.0/src/geo-scheme-handler/wheelmap-geo-handler.desktop new/kguiaddons-6.1.0/src/geo-scheme-handler/wheelmap-geo-handler.desktop --- old/kguiaddons-6.0.0/src/geo-scheme-handler/wheelmap-geo-handler.desktop 2024-02-21 12:25:02.000000000 +0100 +++ new/kguiaddons-6.1.0/src/geo-scheme-handler/wheelmap-geo-handler.desktop 2024-04-05 12:56:25.000000000 +0200 @@ -16,6 +16,7 @@ Name[fi]=wheelmap.org Name[fr]=wheelmap.org Name[gl]=wheelmap.org +Name[he]=wheelmap.org Name[hi]=वà¥à¤¹à¥à¤²à¤®à¥à¤ªà¥à¤¸.à¤à¤°à¥à¤ Name[hu]=wheelmap.org Name[ia]=wheelmap.org diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kguiaddons-6.0.0/src/recorder/kkeysequencerecorder.cpp new/kguiaddons-6.1.0/src/recorder/kkeysequencerecorder.cpp --- old/kguiaddons-6.0.0/src/recorder/kkeysequencerecorder.cpp 2024-02-21 12:25:02.000000000 +0100 +++ new/kguiaddons-6.1.0/src/recorder/kkeysequencerecorder.cpp 2024-04-05 12:56:25.000000000 +0200 @@ -21,6 +21,7 @@ #include <QWindow> #include <array> +#include <chrono> /// Singleton whose only purpose is to tell us about other sequence recorders getting started class KKeySequenceRecorderGlobal : public QObject @@ -65,6 +66,10 @@ Qt::KeyboardModifiers m_currentModifiers; QTimer m_modifierlessTimer; std::unique_ptr<ShortcutInhibition> m_inhibition; + // For use in modifier only shortcuts + Qt::KeyboardModifiers m_lastPressedModifiers; + bool m_isReleasingModifierOnly = false; + std::chrono::nanoseconds m_modifierFirstReleaseTime; }; constexpr Qt::KeyboardModifiers modifierMask = Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier | Qt::KeypadModifier; @@ -340,8 +345,28 @@ return QObject::eventFilter(watched, event); } +static Qt::KeyboardModifiers keyToModifier(int key) +{ + switch (key) { + case Qt::Key_Meta: + case Qt::Key_Super_L: + case Qt::Key_Super_R: + // Qt doesn't properly recognize Super_L/Super_R as MetaModifier + return Qt::MetaModifier; + case Qt::Key_Shift: + return Qt::ShiftModifier; + case Qt::Key_Control: + return Qt::ControlModifier; + case Qt::Key_Alt: + return Qt::AltModifier; + default: + return Qt::NoModifier; + } +} + void KKeySequenceRecorderPrivate::handleKeyPress(QKeyEvent *event) { + m_isReleasingModifierOnly = false; m_currentModifiers = event->modifiers() & modifierMask; int key = event->key(); switch (key) { @@ -356,17 +381,17 @@ break; case Qt::Key_Super_L: case Qt::Key_Super_R: - // Qt doesn't properly recognize Super_L/Super_R as MetaModifier - m_currentModifiers |= Qt::MetaModifier; - Q_FALLTHROUGH(); case Qt::Key_Shift: case Qt::Key_Control: case Qt::Key_Alt: case Qt::Key_Meta: + m_currentModifiers |= keyToModifier(key); + m_lastPressedModifiers = m_currentModifiers; controlModifierlessTimeout(); Q_EMIT q->currentKeySequenceChanged(); break; default: + m_lastPressedModifiers = Qt::NoModifier; if (m_currentKeySequence.count() == 0 && !(m_currentModifiers & ~Qt::ShiftModifier)) { // It's the first key and no modifier pressed. Check if this is allowed if (!(isOkWhenModifierless(key) || m_modifierlessAllowed)) { @@ -399,44 +424,56 @@ event->accept(); } +// Turn a bunch of modifiers into mods + key +// so that the ordering is always Meta + Ctrl + Alt + Shift +static int prettifyModifierOnly(Qt::KeyboardModifiers modifier) +{ + if (modifier & Qt::ShiftModifier) { + return (Qt::Key_Shift | (modifier & ~Qt::ShiftModifier)).toCombined(); + } else if (modifier & Qt::AltModifier) { + return (Qt::Key_Alt | (modifier & ~Qt::AltModifier)).toCombined(); + } else if (modifier & Qt::ControlModifier) { + return (Qt::Key_Control | (modifier & ~Qt::ControlModifier)).toCombined(); + } else if (modifier & Qt::MetaModifier) { + return (Qt::Key_Meta | (modifier & ~Qt::MetaModifier)).toCombined(); + } else { + return Qt::Key(0); + } +} + void KKeySequenceRecorderPrivate::handleKeyRelease(QKeyEvent *event) { Qt::KeyboardModifiers modifiers = event->modifiers() & modifierMask; - /* The modifier release event (e.g. Qt::Key_Shift) also has the modifier - flag set so we were interpreting the "Shift" press as "Shift + Shift". - This function makes it so we just take the key part but not the modifier - if we are doing this one alone. */ - const auto justKey = [&](Qt::KeyboardModifiers modifier) { - modifiers &= ~modifier; - if (m_currentKeySequence.isEmpty() && m_modifierOnlyAllowed) { - m_currentKeySequence = appendToSequence(m_currentKeySequence, event->key()); - } - }; switch (event->key()) { case -1: return; case Qt::Key_Super_L: case Qt::Key_Super_R: case Qt::Key_Meta: - justKey(Qt::MetaModifier); - break; case Qt::Key_Shift: - justKey(Qt::ShiftModifier); - break; case Qt::Key_Control: - justKey(Qt::ControlModifier); - break; case Qt::Key_Alt: - justKey(Qt::AltModifier); - break; + modifiers &= ~keyToModifier(event->key()); } - if ((modifiers & m_currentModifiers) < m_currentModifiers) { + constexpr auto releaseTimeout = std::chrono::milliseconds(200); + const auto currentTime = std::chrono::steady_clock::now().time_since_epoch(); + if (!m_isReleasingModifierOnly) { + m_isReleasingModifierOnly = true; + m_modifierFirstReleaseTime = currentTime; + } + if (m_modifierOnlyAllowed && !modifiers && (currentTime - m_modifierFirstReleaseTime) < releaseTimeout) { + m_currentKeySequence = appendToSequence(m_currentKeySequence, prettifyModifierOnly(m_lastPressedModifiers)); + m_lastPressedModifiers = Qt::NoModifier; + } m_currentModifiers = modifiers; - controlModifierlessTimeout(); Q_EMIT q->currentKeySequenceChanged(); - } + if (m_currentKeySequence.count() == (m_multiKeyShortcutsAllowed ? MaxKeyCount : 1)) { + finishRecording(); + } + controlModifierlessTimeout(); + }; } void KKeySequenceRecorderPrivate::receivedRecording() @@ -444,6 +481,8 @@ m_modifierlessTimer.stop(); m_isRecording = false; m_currentModifiers = Qt::NoModifier; + m_lastPressedModifiers = Qt::NoModifier; + m_isReleasingModifierOnly = false; if (m_inhibition) { m_inhibition->disableInhibition(); }
