Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package plasma6-keyboard for
openSUSE:Factory checked in at 2026-06-25 10:51:10
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/plasma6-keyboard (Old)
and /work/SRC/openSUSE:Factory/.plasma6-keyboard.new.2088 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "plasma6-keyboard"
Thu Jun 25 10:51:10 2026 rev:8 rq:1361422 version:6.7.1
Changes:
--------
--- /work/SRC/openSUSE:Factory/plasma6-keyboard/plasma6-keyboard.changes
2026-06-18 21:38:13.738105799 +0200
+++
/work/SRC/openSUSE:Factory/.plasma6-keyboard.new.2088/plasma6-keyboard.changes
2026-06-25 10:55:12.793247520 +0200
@@ -1,0 +2,12 @@
+Tue Jun 23 11:00:26 UTC 2026 - Fabian Vogt <[email protected]>
+
+- Update to 6.7.1:
+ * New bugfix release
+ * For more details see https://kde.org/announcements/plasma/6/6.7.1
+- Changes since 6.7.0:
+ * Update version for new release 6.7.1
+ * fix: Don't try to close diacritics overlay twice
+ * fix: Don't disable key repeat when diacritics overlay is enabled
+ * fix: improve reliability of dead key and compose key handling w/ overlay
(kde#518141,kde#519339,kde#520410,kde#520344)
+
+-------------------------------------------------------------------
Old:
----
plasma-keyboard-6.7.0.tar.xz
plasma-keyboard-6.7.0.tar.xz.sig
New:
----
plasma-keyboard-6.7.1.tar.xz
plasma-keyboard-6.7.1.tar.xz.sig
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ plasma6-keyboard.spec ++++++
--- /var/tmp/diff_new_pack.jSb6lv/_old 2026-06-25 10:55:13.857284333 +0200
+++ /var/tmp/diff_new_pack.jSb6lv/_new 2026-06-25 10:55:13.869284748 +0200
@@ -30,14 +30,14 @@
%{!?_plasma6_version: %define _plasma6_version %(echo %{_plasma6_bugfix} | awk
-F. '{print $1"."$2}')}
%bcond_without released
Name: plasma6-keyboard
-Version: 6.7.0
+Version: 6.7.1
Release: 0
Summary: Virtual Keyboard for Qt based desktops
License: GPL-2.0-or-later AND GPL-3.0-only
URL: https://invent.kde.org/plasma/plasma-keyboard
-Source: %{rname}-%{version}.tar.xz
+Source:
https://download.kde.org/stable/plasma/%{version}/%{rname}-%{version}.tar.xz
%if %{with released}
-Source1: %{rname}-%{version}.tar.xz.sig
+Source1:
https://download.kde.org/stable/plasma/%{version}/%{rname}-%{version}.tar.xz.sig
Source2: plasma.keyring
%endif
++++++ plasma-keyboard-6.7.0.tar.xz -> plasma-keyboard-6.7.1.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/plasma-keyboard-6.7.0/CMakeLists.txt
new/plasma-keyboard-6.7.1/CMakeLists.txt
--- old/plasma-keyboard-6.7.0/CMakeLists.txt 2026-06-11 11:36:13.000000000
+0200
+++ new/plasma-keyboard-6.7.1/CMakeLists.txt 2026-06-23 10:15:21.000000000
+0200
@@ -3,7 +3,7 @@
cmake_minimum_required(VERSION 3.16)
-set(PROJECT_VERSION "6.7.0")
+set(PROJECT_VERSION "6.7.1")
project(plasma-keyboard VERSION ${PROJECT_VERSION})
@@ -63,6 +63,9 @@
ecm_setup_version(${PROJECT_VERSION} VARIABLE_PREFIX PLASMA_KEYBOARD
VERSION_HEADER plasma_keyboard_version.h)
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(XKBCommon REQUIRED IMPORTED_TARGET xkbcommon)
+
find_package(Wayland 1.2 REQUIRED COMPONENTS Client)
find_package(QtWaylandScanner REQUIRED ${QT_MIN_VERSION})
find_package(WaylandProtocols 1.19 REQUIRED)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/plasma-keyboard-6.7.0/autotests/CMakeLists.txt
new/plasma-keyboard-6.7.1/autotests/CMakeLists.txt
--- old/plasma-keyboard-6.7.0/autotests/CMakeLists.txt 2026-06-11
11:36:13.000000000 +0200
+++ new/plasma-keyboard-6.7.1/autotests/CMakeLists.txt 2026-06-23
10:15:21.000000000 +0200
@@ -9,7 +9,16 @@
CONTENT "#pragma once\n#define PLASMA_KEYBOARD_BINARY_PATH
\"$<TARGET_FILE:plasma-keyboard>\"\n"
)
-ecm_add_test(mockinputmethodcompositor.cpp LINK_LIBRARIES KF6::ConfigCore
Qt::Core Qt::Gui Qt::GuiPrivate Qt::Test Qt::WaylandCompositor Wayland::Server)
+ecm_add_test(mockinputmethodcompositor.cpp LINK_LIBRARIES
+ KF6::ConfigCore
+ PkgConfig::XKBCommon
+ Qt::Core
+ Qt::Gui
+ Qt::GuiPrivate
+ Qt::Test
+ Qt::WaylandCompositor
+ Wayland::Server
+)
qt6_generate_wayland_protocol_server_sources(mockinputmethodcompositor
FILES
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/plasma-keyboard-6.7.0/autotests/mockinputmethodcompositor.cpp
new/plasma-keyboard-6.7.1/autotests/mockinputmethodcompositor.cpp
--- old/plasma-keyboard-6.7.0/autotests/mockinputmethodcompositor.cpp
2026-06-11 11:36:13.000000000 +0200
+++ new/plasma-keyboard-6.7.1/autotests/mockinputmethodcompositor.cpp
2026-06-23 10:15:21.000000000 +0200
@@ -34,7 +34,7 @@
#include <linux/input-event-codes.h>
#include <sys/mman.h>
#include <unistd.h>
-#include <xkbcommon/xkbcommon.h>
+#include <xkbcommon/xkbcommon-compose.h>
#define PLASMA_KEYBOARD_UNDER_GDB 0
@@ -73,7 +73,7 @@
InputMethodKeyboard(wl_client *client, uint32_t id, int version)
: QtWaylandServer::wl_keyboard(client, id, version)
{
- sendKeymap();
+ initializeKeymap();
m_timer.start();
}
@@ -96,11 +96,15 @@
return m_keymapped;
}
-Q_SIGNALS:
- void keymapDone();
-
-private:
- void sendKeymap()
+ /**
+ * Sets an updated XKB keymap built from the given layout and variant.
+ * Use this to simulate a compositor keymap change (e.g. switching to
us/intl
+ * so that dead keys produce the correct keysyms in the child process).
+ *
+ * @param layout XKB layout name (e.g. "us")
+ * @param variant XKB variant name (e.g. "intl"), or nullptr for none
+ */
+ void setKeymap(const char *layout, const char *variant = nullptr)
{
QXkbCommon::ScopedXKBContext
context(xkb_context_new(XKB_CONTEXT_NO_FLAGS));
if (!context) {
@@ -110,11 +114,13 @@
xkb_rule_names names = {};
names.rules = "evdev";
- names.layout = "us";
+ names.layout = layout;
+ names.variant = variant ? variant : "";
+ names.options = "compose:menu";
QXkbCommon::ScopedXKBKeymap
keymap(xkb_keymap_new_from_names(context.get(), &names,
XKB_KEYMAP_COMPILE_NO_FLAGS));
if (!keymap) {
- qWarning() << "Failed to create xkb keymap";
+ qWarning() << "Failed to create xkb keymap for layout" << layout
<< variant;
return;
}
@@ -143,10 +149,23 @@
qWarning() << "Failed to write keymap terminator";
return;
}
- lseek(fd, 0, SEEK_SET);
+ if (lseek(fd, 0, SEEK_SET) < 0) {
+ close(fd);
+ qWarning() << "Failed to seek keymap file";
+ return;
+ }
send_keymap(WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, fd, mapData.size() + 1);
close(fd);
+ }
+
+Q_SIGNALS:
+ void keymapDone();
+
+private:
+ void initializeKeymap()
+ {
+ setKeymap("us");
m_keymapped = true;
Q_EMIT keymapDone();
}
@@ -176,6 +195,7 @@
Q_SIGNALS:
void keyboardGrabbed();
void commitStringChanged(const QString &commitString);
+ void keysymReceived(uint32_t sym, uint32_t state);
protected:
void zwp_input_method_context_v1_destroy(Resource *resource) override
@@ -206,6 +226,7 @@
{
Q_UNUSED(resource);
qInfo() << "keysym" << serial << time << sym << state << modifiers;
+ Q_EMIT keysymReceived(sym, state);
}
void zwp_input_method_context_v1_grab_keyboard(Resource *resource,
uint32_t keyboard) override
@@ -545,6 +566,21 @@
wl_display_flush_clients(m_compositor->display());
}
+ /**
+ * Sets an updated keymap and waits for it to be processed.
+ *
+ * @param layout XKB layout name (e.g. "us")
+ * @param variant XKB variant name (e.g. "intl"), or nullptr for none
+ */
+ void setKeymap(const char *layout, const char *variant = nullptr)
+ {
+ auto *keyboard = m_inputMethod->context()->keyboard();
+ Q_ASSERT(keyboard);
+ keyboard->setKeymap(layout, variant);
+ wl_display_flush_clients(m_compositor->display());
+ QTest::qWait(200);
+ }
+
void testLongPressShowsOverlayPanel()
{
QSignalSpy overlaySpy(m_inputPanel.get(),
&InputPanelV1::overlayPanelRequested);
@@ -559,6 +595,91 @@
QCOMPARE(commitStringSpy.first().first().toString(),
QStringLiteral("à"));
}
+ /**
+ * Test that a Multi_key compose sequence (Multi_key + t + m → ™) is
handled
+ * locally by the XKB compose state machine in OverlayController. The
+ * intermediate keys must be consumed and not forwarded to the compositor;
+ * only the composed result should arrive via commit_string.
+ */
+ void testComposeSequence()
+ {
+ // Skip if no XKB compose table is available for the current locale.
+ // Without one, OverlayController::m_xkbComposeState is null and the
+ // compose sequence would not be processed locally.
+ {
+ QXkbCommon::ScopedXKBContext
xkbContext(xkb_context_new(XKB_CONTEXT_NO_FLAGS));
+ if (!xkbContext) {
+ QSKIP("Could not create XKB context");
+ }
+ const char *locale = setlocale(LC_CTYPE, nullptr);
+ if (!locale || locale[0] == '\0') {
+ locale = "C";
+ }
+ xkb_compose_table *composeTable =
xkb_compose_table_new_from_locale(xkbContext.get(), locale,
XKB_COMPOSE_COMPILE_NO_FLAGS);
+ if (!composeTable) {
+ QSKIP("No XKB compose table available for the current locale");
+ }
+ xkb_compose_table_unref(composeTable);
+ }
+
+ QSignalSpy overlaySpy(m_inputPanel.get(),
&InputPanelV1::overlayPanelRequested);
+ QSignalSpy commitStringSpy(m_inputMethod->context(),
&InputMethodContext::commitStringChanged);
+ QSignalSpy keysymSpy(m_inputMethod->context(),
&InputMethodContext::keysymReceived);
+
+ // Send the compose sequence: Multi_key → t → m → ™
+ // KEY_COMPOSE (127) maps to Multi_key via the compose:menu keymap
option.
+ sendKey(KEY_COMPOSE, 10);
+ sendKey(KEY_T, 10);
+ sendKey(KEY_M, 10);
+
+ // Exactly one commit_string with the composed character should arrive.
+ QTRY_COMPARE(commitStringSpy.count(), 1);
+ QCOMPARE(commitStringSpy.first().first().toString(),
QStringLiteral("™"));
+
+ // The intermediate keys (t, m) must not have been forwarded via
keysym.
+ // XKB_KEY_t = 0x74, XKB_KEY_m = 0x6d
+ for (const QList<QVariant> &args : keysymSpy) {
+ const uint32_t sym = args.at(0).toUInt();
+ QVERIFY2(sym != 0x74 && sym != 0x6d, "A compose sequence key (t or
m) was incorrectly forwarded via keysym");
+ }
+
+ // No overlay should have appeared during the compose sequence.
+ QTest::qWait(200);
+ QVERIFY(overlaySpy.isEmpty());
+ }
+
+ /**
+ * Test that pressing a dead key (e.g. the grave key `) followed by a
character key (e.g. a) results
+ * in the correct composed character (e.g. à) being committed, without the
dead key
+ * being forwarded as a separate keysym or commit_string.
+ */
+ void testDeadKeySequence()
+ {
+ // Switch to the US intl with dead keys layout for the test.
+ setKeymap("us", "intl");
+
+ QSignalSpy commitStringSpy(m_inputMethod->context(),
&InputMethodContext::commitStringChanged);
+ QSignalSpy keysymSpy(m_inputMethod->context(),
&InputMethodContext::keysymReceived);
+
+ // Send the dead key sequence: ` → a = à
+ sendKey(KEY_GRAVE, 10);
+ sendKey(KEY_A, 10);
+
+ // Exactly one commit_string with the composed character should arrive.
+ QTRY_COMPARE(commitStringSpy.count(), 1);
+ QCOMPARE(commitStringSpy.first().first().toString(),
QStringLiteral("à"));
+
+ // The dead key (`) must not have been forwarded via keysym.
+ // XKB_KEY_grave = 0x60
+ for (const QList<QVariant> &args : keysymSpy) {
+ const uint32_t sym = args.at(0).toUInt();
+ QVERIFY2(sym != 0x60, "The dead key (`) was incorrectly forwarded
via keysym");
+ }
+
+ // Set the keymap back to the default to avoid affecting other tests.
+ setKeymap("us", nullptr);
+ }
+
void cleanupTestCase()
{
if (m_child) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/plasma-keyboard-6.7.0/po/hu/kcm_plasmakeyboard.po
new/plasma-keyboard-6.7.1/po/hu/kcm_plasmakeyboard.po
--- old/plasma-keyboard-6.7.0/po/hu/kcm_plasmakeyboard.po 1970-01-01
01:00:00.000000000 +0100
+++ new/plasma-keyboard-6.7.1/po/hu/kcm_plasmakeyboard.po 2026-06-23
10:15:21.000000000 +0200
@@ -0,0 +1,121 @@
+# Copyright (C) 2026 This file is copyright:
+# This file is distributed under the same license as the plasma-keyboard
package.
+#
+# SPDX-FileCopyrightText: 2026 Kristof Kiszel <[email protected]>
+msgid ""
+msgstr ""
+"Project-Id-Version: plasma-keyboard\n"
+"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
+"POT-Creation-Date: 2026-03-14 00:46+0000\n"
+"PO-Revision-Date: 2026-06-19 22:06+0200\n"
+"Last-Translator: Kristof Kiszel <[email protected]>\n"
+"Language-Team: Hungarian <[email protected]>\n"
+"Language: hu\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Lokalize 26.04.2\n"
+
+#: ui/LocaleSelectorListView.qml:68
+msgid "Filter languages…"
+msgstr "Nyelvek szűrése…"
+
+#: ui/LocaleSelectorListView.qml:69
+msgid "Filter languages"
+msgstr "Nyelvek szűrése"
+
+#: ui/LocaleSelectorListView.qml:82
+msgid ""
+"No languages selected. The default keyboard layout for the system will be "
+"used."
+msgstr ""
+"Nincs kiválasztva nyelv. A rendszer alapértelmezett billentyűzetkiosztása "
+"lesz használva."
+
+#: ui/LocaleSelectorSidebar.qml:25 ui/main_handset.qml:70
+#: ui/main_mediacenter.qml:40
+msgid "Languages"
+msgstr "Nyelvek"
+
+#: ui/main.qml:33
+msgid "Key press feedback:"
+msgstr "Gomblenyomás visszajelzése:"
+
+#: ui/main.qml:34 ui/main_handset.qml:40
+msgid "Sound"
+msgstr "Hang"
+
+#: ui/main.qml:45 ui/main_handset.qml:54
+msgid "Vibration"
+msgstr "Rezgés"
+
+#: ui/main.qml:56
+msgid "General:"
+msgstr "Általános:"
+
+#: ui/main.qml:57 ui/main_handset.qml:90
+msgid "Keyboard navigation"
+msgstr "Billentyűzetnavigáció"
+
+#: ui/main.qml:68 ui/main_handset.qml:104 ui/main_mediacenter.qml:91
+msgid "Auto-capitalization"
+msgstr "Automatikus nagybetű"
+
+#: ui/main.qml:79
+msgid "Alternate characters:"
+msgstr "Alternatív karakterek:"
+
+#: ui/main.qml:80
+msgid "Show popup when holding a key"
+msgstr "Felugró megjelenítése gomb nyomva tartásakor"
+
+#: ui/main.qml:91
+msgid "Hold delay:"
+msgstr "Késleltetés:"
+
+#: ui/main.qml:101
+msgid "milliseconds"
+msgstr "ezredmásodperc"
+
+#: ui/main_handset.qml:29
+msgid "Test the virtual keyboard…"
+msgstr "Virtuális billentyűzet kipróbálása…"
+
+#: ui/main_handset.qml:34
+msgctxt "@title:group"
+msgid "Feedback"
+msgstr "Visszajelzés"
+
+#: ui/main_handset.qml:41
+msgid "Whether to emit a sound on key press"
+msgstr "Adjon-e ki hangot billentyűlenyomáskor"
+
+#: ui/main_handset.qml:55
+msgid "Whether to vibrate on key press"
+msgstr "Rezegjen-e billentyűlenyomáskor"
+
+#: ui/main_handset.qml:76
+msgid "Keyboard Languages"
+msgstr "Billentyűzet nyelvei"
+
+#: ui/main_handset.qml:84
+msgctxt "@title:group"
+msgid "General"
+msgstr "Általános"
+
+#: ui/main_handset.qml:91
+msgid "Whether to use the arrow keys to navigate the keyboard"
+msgstr "Használja-e a nyílgombokat a billentyűzeten navigáláshoz"
+
+#: ui/main_handset.qml:105
+msgid "Automatically capitalize the first letter of sentences"
+msgstr "A mondatok első betűjét automatikusan nagybetűvé alakítja"
+
+#: ui/main_mediacenter.qml:47
+msgid "Key press feedback"
+msgstr "Gomblenyomás visszajelzése"
+
+#: ui/main_mediacenter.qml:82
+msgid "General"
+msgstr "Általános"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/plasma-keyboard-6.7.0/po/ja/kcm_plasmakeyboard.po
new/plasma-keyboard-6.7.1/po/ja/kcm_plasmakeyboard.po
--- old/plasma-keyboard-6.7.0/po/ja/kcm_plasmakeyboard.po 1970-01-01
01:00:00.000000000 +0100
+++ new/plasma-keyboard-6.7.1/po/ja/kcm_plasmakeyboard.po 2026-06-23
10:15:21.000000000 +0200
@@ -0,0 +1,120 @@
+# SPDX-FileCopyrightText: 2026 Mint <[email protected]>
+msgid ""
+msgstr ""
+"Project-Id-Version: plasma-keyboard\n"
+"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
+"POT-Creation-Date: 2026-03-14 00:46+0000\n"
+"PO-Revision-Date: 2026-06-14 15:44+0900\n"
+"Last-Translator: Mint <[email protected]>\n"
+"Language-Team: Japanese <[email protected]>\n"
+"Language: ja\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Accelerator-Marker: &\n"
+"X-Text-Markup: kde4\n"
+"X-Generator: Lokalize 26.04.2\n"
+
+#: ui/LocaleSelectorListView.qml:68
+msgid "Filter languages…"
+msgstr "言語を検索…"
+
+#: ui/LocaleSelectorListView.qml:69
+msgid "Filter languages"
+msgstr "言語の検索"
+
+#: ui/LocaleSelectorListView.qml:82
+msgid ""
+"No languages selected. The default keyboard layout for the system will be "
+"used."
+msgstr ""
+"言語が選択されていません。このシステム標準のキーボードレイアウトが使用されま"
+"す。"
+
+#: ui/LocaleSelectorSidebar.qml:25 ui/main_handset.qml:70
+#: ui/main_mediacenter.qml:40
+msgid "Languages"
+msgstr "言語"
+
+#: ui/main.qml:33
+msgid "Key press feedback:"
+msgstr "キー押下時の反応:"
+
+#: ui/main.qml:34 ui/main_handset.qml:40
+msgid "Sound"
+msgstr "サウンド"
+
+#: ui/main.qml:45 ui/main_handset.qml:54
+msgid "Vibration"
+msgstr "バイブレーション"
+
+#: ui/main.qml:56
+msgid "General:"
+msgstr "全般:"
+
+#: ui/main.qml:57 ui/main_handset.qml:90
+msgid "Keyboard navigation"
+msgstr "物理キーボードで操作"
+
+#: ui/main.qml:68 ui/main_handset.qml:104 ui/main_mediacenter.qml:91
+msgid "Auto-capitalization"
+msgstr "自動大文字変換"
+
+#: ui/main.qml:79
+msgid "Alternate characters:"
+msgstr "代替文字:"
+
+#: ui/main.qml:80
+msgid "Show popup when holding a key"
+msgstr "長押しでポップアップ表示"
+
+#: ui/main.qml:91
+msgid "Hold delay:"
+msgstr "長押しに必要な時間:"
+
+#: ui/main.qml:101
+msgid "milliseconds"
+msgstr "ミリ秒"
+
+#: ui/main_handset.qml:29
+msgid "Test the virtual keyboard…"
+msgstr "仮想キーボードのテスト…"
+
+#: ui/main_handset.qml:34
+msgctxt "@title:group"
+msgid "Feedback"
+msgstr "フィードバック"
+
+#: ui/main_handset.qml:41
+msgid "Whether to emit a sound on key press"
+msgstr "キー押下時にサウンドを再生するかどうか"
+
+#: ui/main_handset.qml:55
+msgid "Whether to vibrate on key press"
+msgstr "キー押下時にバイブレーションするかどうか"
+
+#: ui/main_handset.qml:76
+msgid "Keyboard Languages"
+msgstr "キーボードの言語"
+
+#: ui/main_handset.qml:84
+msgctxt "@title:group"
+msgid "General"
+msgstr "全般"
+
+#: ui/main_handset.qml:91
+msgid "Whether to use the arrow keys to navigate the keyboard"
+msgstr "キーボード内の操作に矢印キーを使用するかどうか"
+
+#: ui/main_handset.qml:105
+msgid "Automatically capitalize the first letter of sentences"
+msgstr "文章の最初の文字を自動で大文字にします"
+
+#: ui/main_mediacenter.qml:47
+msgid "Key press feedback"
+msgstr "キー押下時の反応"
+
+#: ui/main_mediacenter.qml:82
+msgid "General"
+msgstr "全般"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/plasma-keyboard-6.7.0/src/CMakeLists.txt
new/plasma-keyboard-6.7.1/src/CMakeLists.txt
--- old/plasma-keyboard-6.7.0/src/CMakeLists.txt 2026-06-11
11:36:13.000000000 +0200
+++ new/plasma-keyboard-6.7.1/src/CMakeLists.txt 2026-06-23
10:15:21.000000000 +0200
@@ -106,6 +106,7 @@
KF6::ConfigCore
KF6::ConfigGui
KF6::Crash
+ PkgConfig::XKBCommon
Plasma::PlasmaQuick
Qt::DBus
Qt::Gui
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/plasma-keyboard-6.7.0/src/org.kde.plasma.keyboard.metainfo.xml
new/plasma-keyboard-6.7.1/src/org.kde.plasma.keyboard.metainfo.xml
--- old/plasma-keyboard-6.7.0/src/org.kde.plasma.keyboard.metainfo.xml
2026-06-11 11:36:13.000000000 +0200
+++ new/plasma-keyboard-6.7.1/src/org.kde.plasma.keyboard.metainfo.xml
2026-06-23 10:15:21.000000000 +0200
@@ -91,6 +91,7 @@
<p xml:lang="fi">Plasma-näppäimistö tarjoaa virtuaalisen
näyttönäppäimistön kosketusnäytöille, tableteille, muunnettaville laitteille,
puhelimille ja näppäimistöttömille perinteisille tietokoneille.</p>
<p xml:lang="fr">Plasma Keyboard fournit un clavier virtuel à l'écran pour
les écrans tactiles, les tablettes, les ordinateurs convertibles, les
téléphones et les ordinateurs traditionnels sans clavier physique.</p>
<p xml:lang="he">מקלדת פלזמה מספקת מקלדת וירטואלית על גבי המסך למסכי מגע,
מחשבי לוח, מכשירים גמישים, טלפונים ומחשבים מסורתיים בלי מקלדת פיזית.</p>
+ <p xml:lang="hu">A Plasma Billentyűzet egy virtuális képernyő-billentyűzet
érintőképernyőkhöz, tabletekhez, hibrid eszközökhöz, telefonokhoz és fizikai
billentyűzet nélküli, hagyományos számítógépekhez.</p>
<p xml:lang="ia">Claviero de Plasma (Plasma Keyboard) forni un claviero
virtual, sur chermo, per schermos tactile, tablettas, dispositivos
convertibile, telephonos, e computatores traditional sin claviero physic.</p>
<p xml:lang="is">Plasma-lyklaborðið birtir sýndarlyklaborð á skjanum fyrir
snertiskjái, spjaldtölvur, umbreytanleg tæki, snjallsíma og venjulegar tölvur
sem ekki eru með alvöru lyklaborð.</p>
<p xml:lang="it">Plasma Keyboard fornisce una tastiera virtuale su schermo
per touchscreen, tablet, dispositivi convertibili, telefoni e computer
tradizionali privi di tastiera fisica.</p>
@@ -125,6 +126,7 @@
<li xml:lang="fi">Saumaton eheytys Plasma-työtilan ja -sovellusten
kanssa</li>
<li xml:lang="fr">Intégration transparente avec l'espace de travail et
les applications de Plasma</li>
<li xml:lang="he">שילוב חלק בסביבת העבודה והיישומים של פלזמה</li>
+ <li xml:lang="hu">Zökkenőmentes integráció a Plasma munkaterülettel és
az alkalmazásokkal</li>
<li xml:lang="ia">Integration sin solution de continuitate con le spatio
de labor e applicationes de Plasma</li>
<li xml:lang="is">Hnökralaus samþætting við vinnusvæði og forrit í
Plasma</li>
<li xml:lang="it">Integrazione perfetta con l'area di lavoro e le
applicazioni Plasma</li>
@@ -158,6 +160,7 @@
<li xml:lang="fi">Automaattinen näyttäminen tekstisyötettä
tarvittaessa</li>
<li xml:lang="fr">Apparence automatique lorsque la saisie de texte est
nécessaire</li>
<li xml:lang="he">הופעה אוטומטית כשצריך להקליד טקסט</li>
+ <li xml:lang="hu">Automatikus megjelenés, amikor szövegbevitelre van
szükség</li>
<li xml:lang="ia">Apparentia automatic quando le ingresso de testo es
necessari</li>
<li xml:lang="is">Sjálfvirk birting þegar þörf er á að setja inn
texta</li>
<li xml:lang="it">Aspetto automatico quando è necessario l'inserimento
di testo</li>
@@ -191,6 +194,7 @@
<li xml:lang="fi">Useiden asettelujen ja kielten tuki</li>
<li xml:lang="fr">Prise en charge de plusieurs dispositions et
langues</li>
<li xml:lang="he">תמיכה במגוון פריסות ושפות</li>
+ <li xml:lang="hu">Többféle kiosztás és nyelv támogatása</li>
<li xml:lang="ia">Supporto per linguages e dispositiones multiple</li>
<li xml:lang="is">Stuðningur við mörg tungumál og framsetningar</li>
<li xml:lang="it">Supporto per più mappature e lingue</li>
@@ -224,6 +228,7 @@
<li xml:lang="fi">Mukautettava koko ja toiminta eri alustoilla</li>
<li xml:lang="fr">Taille et comportement configurables pour différents
facteurs de forme</li>
<li xml:lang="he">גודל והתנהגות מתכוונים למגוון גודלי תצוגה</li>
+ <li xml:lang="hu">Konfigurálható méret és működés különböző
eszköztípusokhoz</li>
<li xml:lang="ia">Grandor configurabile e comportamento per factores de
forma differente</li>
<li xml:lang="is">Stillanleg stærð og hegðun fyrir mismunandi
skjástærðir</li>
<li xml:lang="it">Dimensioni e comportamento configurabili per diversi
fattori di forma</li>
@@ -263,6 +268,7 @@
<binary>plasma-keyboard</binary>
</provides>
<releases>
+ <release version="6.7.1" date="2026-06-23"/>
<release version="6.7.0" date="2026-06-16"/>
</releases>
</component>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/plasma-keyboard-6.7.0/src/overlay/longpresstrigger.cpp
new/plasma-keyboard-6.7.1/src/overlay/longpresstrigger.cpp
--- old/plasma-keyboard-6.7.0/src/overlay/longpresstrigger.cpp 2026-06-11
11:36:13.000000000 +0200
+++ new/plasma-keyboard-6.7.1/src/overlay/longpresstrigger.cpp 2026-06-23
10:15:21.000000000 +0200
@@ -60,17 +60,36 @@
return result;
}
- // Request timer start for long-press detection.
- // Consume the raw key event to prevent it from being forwarded via
- // wl_keyboard, which would trigger client-side auto-repeat. Instead,
- // the controller commits the base character immediately via
- // commit_string (no repeat) and retracts it if the overlay opens.
- m_timerStarted = true;
- result.action = OverlayAction::StartTimer;
- result.consumeEvent = true;
- result.pendingText = keyEvent->text();
- result.pendingNativeScanCode = keyEvent->nativeScanCode();
- result.timerDurationMs = m_holdThresholdMs;
+ // Characters with diacritic candidates enter the long-press hold timer
+ // (consumed, blocking native auto-repeat). Printable characters
without
+ // diacritics are consumed and committed via commit_string too, but
skip
+ // the pending state so the controller's repeat-suppression check does
+ // not catch them.
+ const QChar baseChar = keyEvent->text().at(0).toLower();
+ if (m_diacriticsMap.contains(baseChar)) {
+ if (keyEvent->isAutoRepeat()) {
+ // Diacritic auto-repeat: let the controller's pending-key
check
+ // suppress it; don't consume here, so the event falls through.
+ return result;
+ }
+ m_timerStarted = true;
+ result.action = OverlayAction::StartTimer;
+ result.consumeEvent = true;
+ result.pendingText = keyEvent->text();
+ result.pendingNativeScanCode = keyEvent->nativeScanCode();
+ result.timerDurationMs = m_holdThresholdMs;
+ } else {
+ // Printable character without diacritics: consume and commit via
+ // commit_string for ordering consistency. Since we are accepting
the key
+ // event, ask the controller to synthesise repeats with its own
internal
+ // timer to retain native key repeat behavior.
+ result.action = OverlayAction::ConsumeEvent;
+ result.consumeEvent = true;
+ result.commitText = keyEvent->text();
+ result.enableRepeat = true;
+ result.repeatScanCode = keyEvent->nativeScanCode();
+ result.pendingNativeScanCode = keyEvent->nativeScanCode();
+ }
// qCDebug(PlasmaKeyboard) << "LongPressTrigger: Requesting timer for"
<< text << "duration" << m_holdThresholdMs << "ms";
break;
@@ -160,10 +179,6 @@
return false;
}
- if (event->isAutoRepeat()) {
- return false;
- }
-
// Only handle simple textual keys without control/meta modifiers
const Qt::KeyboardModifiers mods = event->modifiers();
const bool modifierAllowed = mods == Qt::NoModifier || mods ==
Qt::ShiftModifier;
@@ -171,7 +186,11 @@
return false;
}
- // Check if we have diacritics for this character
+ // Intercept all printable characters so they are consistently committed
via
+ // commit_string, avoiding ordering issues between commit and key event
paths
+ // (e.g. when a password manager injects key events, if they arrive via
multiple
+ // pathways the ordering could be inconsistent). See:
+ // https://invent.kde.org/plasma/plasma-keyboard/-/merge_requests/131
const QChar baseChar = event->text().at(0).toLower();
return baseChar.isPrint();
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/plasma-keyboard-6.7.0/src/overlay/overlaycontroller.cpp
new/plasma-keyboard-6.7.1/src/overlay/overlaycontroller.cpp
--- old/plasma-keyboard-6.7.0/src/overlay/overlaycontroller.cpp 2026-06-11
11:36:13.000000000 +0200
+++ new/plasma-keyboard-6.7.1/src/overlay/overlaycontroller.cpp 2026-06-23
10:15:21.000000000 +0200
@@ -10,18 +10,6 @@
#include "logging.h"
#include "overlaytrigger.h"
-/**
- * Returns true if @p key is in the XKB dead-key range
- * (Qt::Key_Dead_Grave through Qt::Key_Dead_Longsolidusoverlay).
- *
- * Dead keys do not produce text themselves; they modify the next key press
- * to produce a combined character (e.g. dead_acute + e → é).
- */
-static bool isDeadKey(int key)
-{
- return key >= Qt::Key_Dead_Grave && key <= Qt::Key_Dead_Longsolidusoverlay;
-}
-
OverlayController::OverlayController(InputPlugin *inputPlugin, QObject *parent)
: QObject(parent)
, m_inputPlugin(inputPlugin)
@@ -30,6 +18,12 @@
m_holdTimer.setSingleShot(true);
connect(&m_holdTimer, &QTimer::timeout, this,
&OverlayController::handleTimerExpired);
+ m_repeatTimer.setSingleShot(true);
+ connect(&m_repeatTimer, &QTimer::timeout, this,
&OverlayController::handleRepeatTimer);
+
+ m_overlayGraceTimer.setSingleShot(true);
+ connect(&m_overlayGraceTimer, &QTimer::timeout, this,
&OverlayController::handleOverlayGraceTimer);
+
// The settle timer is a single-shot guard that absorbs extra
surrounding_text
// echoes from clients that send more than one event per commit_string.
// 100 ms is well above any realistic Wayland roundtrip but well below the
@@ -37,10 +31,29 @@
static constexpr int SURROUNDING_TEXT_SETTLE_DELAY_MS = 100;
m_surroundingTextSettleTimer.setSingleShot(true);
m_surroundingTextSettleTimer.setInterval(SURROUNDING_TEXT_SETTLE_DELAY_MS);
+
+ // Initialize XKB compose state machine using the system locale.
+ m_xkbContext = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
+ if (m_xkbContext) {
+ const char *locale = setlocale(LC_CTYPE, nullptr);
+ if (!locale || locale[0] == '\0') {
+ locale = "C";
+ }
+ m_xkbComposeTable = xkb_compose_table_new_from_locale(m_xkbContext,
locale, XKB_COMPOSE_COMPILE_NO_FLAGS);
+ if (m_xkbComposeTable) {
+ m_xkbComposeState = xkb_compose_state_new(m_xkbComposeTable,
XKB_COMPOSE_STATE_NO_FLAGS);
+ }
+ }
}
OverlayController::~OverlayController()
{
+ if (m_xkbComposeState)
+ xkb_compose_state_unref(m_xkbComposeState);
+ if (m_xkbComposeTable)
+ xkb_compose_table_unref(m_xkbComposeTable);
+ if (m_xkbContext)
+ xkb_context_unref(m_xkbContext);
}
void OverlayController::registerTrigger(OverlayTrigger *trigger)
@@ -74,7 +87,10 @@
// Compare by native scan code (physical key) rather than Qt key code,
because
// the Qt key code can change if the modifier is released before the
repeat fires
// (e.g. Shift+/ produces Key_Question on press but Key_Slash on repeat).
- if (event->isAutoRepeat() && event->nativeScanCode() ==
m_pendingNativeScanCode) {
+ //
+ // Suppress auto-repeat key events for the pending key (diacritic
long-press)
+ // or for a key being repeated by our internal timer (non-diacritic
ConsumeEvent).
+ if (event->isAutoRepeat() && (event->nativeScanCode() ==
m_pendingNativeScanCode || event->nativeScanCode() == m_repeatNativeScanCode)) {
// qCDebug(PlasmaKeyboard) << "Suppressing repeat press of pending
overlay key" << m_pendingText;
return true;
}
@@ -115,28 +131,47 @@
// Fall through to process the new key
}
- // Handle Compose (Multi_key) to enter compose mode.
- if (event->key() == Qt::Key_Multi_key) {
- qCDebug(PlasmaKeyboard) << "Compose key pressed; entering compose
mode";
- m_composeActive = true;
- return false;
- }
-
- if (m_composeActive) {
- qCDebug(PlasmaKeyboard) << "Compose sequence in progress; passing key
through:" << event->key();
- return false;
- }
-
- // Detect dead key press and enter dead key bypass mode.
- if (isDeadKey(event->key())) {
- qCDebug(PlasmaKeyboard) << "Dead key detected; entering dead key
bypass mode (key =" << event->key() << ")";
- m_deadKeyActive = true;
- return false;
- }
-
- if (m_deadKeyActive) {
- qCDebug(PlasmaKeyboard) << "Dead key sequence in progress; passing key
through. (key =" << event->key() << ")";
- return false;
+ // XKB compose state machine — handles Multi_key sequences and dead keys.
+ // Keys that are part of a sequence are consumed here; the composed result
+ // is committed via commit_string so it never reaches the trigger pipeline.
+ if (m_xkbComposeState) {
+ const xkb_keysym_t keysym =
static_cast<xkb_keysym_t>(event->nativeVirtualKey());
+ if (keysym != XKB_KEY_NoSymbol) {
+ const xkb_compose_feed_result feedResult =
xkb_compose_state_feed(m_xkbComposeState, keysym);
+ if (feedResult == XKB_COMPOSE_FEED_ACCEPTED) {
+ const xkb_compose_status status =
xkb_compose_state_get_status(m_xkbComposeState);
+ switch (status) {
+ case XKB_COMPOSE_COMPOSING:
+ // Sequence started or continuing — cancel any pending
overlay
+ // (it belongs to a key typed before the sequence began).
+ if (m_holdTimer.isActive() || m_overlayVisible) {
+ cancelOverlay();
+ }
+ return true; // Consume; do not forward to compositor.
+ case XKB_COMPOSE_COMPOSED: {
+ if (m_holdTimer.isActive() || m_overlayVisible) {
+ cancelOverlay();
+ }
+ char buf[64] = {};
+ if (xkb_compose_state_get_utf8(m_xkbComposeState, buf,
sizeof(buf)) > 0 && m_inputPlugin) {
+ ++m_pendingSurroundingTextUpdates;
+ m_surroundingTextSettleTimer.start();
+ m_inputPlugin->commit(QString::fromUtf8(buf));
+ }
+ xkb_compose_state_reset(m_xkbComposeState);
+ return true; // Consume the completing key.
+ }
+ case XKB_COMPOSE_CANCELLED:
+ xkb_compose_state_reset(m_xkbComposeState);
+ break; // Fall through — process cancelling key normally.
+ case XKB_COMPOSE_NOTHING:
+ break; // Not in a sequence; fall through.
+ }
+ } else {
+ // qCDebug(PlasmaKeyboard) << "XKB compose feed result:" <<
feedResult << "(keysym" << keysym << "not part of a compose sequence)";
+ }
+ // XKB_COMPOSE_FEED_IGNORED or post-cancel: fall through to
triggers.
+ }
}
// Dispatch to triggers in order
@@ -161,6 +196,22 @@
return false;
}
+ // If the overlay grace timer is running and the held key is released,
+ // stop the grace timer — the overlay stays visible waiting for selection
+ // or cancellation via the normal pathways.
+ if (m_overlayGraceTimer.isActive() && event->nativeScanCode() ==
m_pendingNativeScanCode) {
+ m_overlayGraceTimer.stop();
+ }
+
+ // Check for key release that should stop the internal repeat timer.
+ // This must run before the swallow-release and pending-key checks since
+ // it may share the same scan code.
+ if (m_repeatNativeScanCode != 0 && event->nativeScanCode() ==
m_repeatNativeScanCode) {
+ m_repeatTimer.stop();
+ m_repeatText.clear();
+ m_repeatNativeScanCode = 0;
+ }
+
// Swallow release of a discarded/committed pending key.
// Compare by native scan code (physical key) so that modifier changes
// between press and release don't prevent the match.
@@ -369,23 +420,6 @@
qCDebug(PlasmaKeyboard) << "External cursor move detected while
overlay active; cancelling overlay";
cancelOverlay();
}
-
- // If a Compose (Multi_key) sequence was in progress, an external
surrounding-text
- // update signals that the compositor has processed and committed the
result of a
- // compose sequence (or that the user typed normally while compose mode
was stale).
- // Either way the compose state is done.
- if (m_composeActive) {
- qCDebug(PlasmaKeyboard) << "Compose sequence ended (external
surrounding-text change); clearing compose state";
- m_composeActive = false;
- }
-
- // If a dead key sequence was in progress, the surrounding-text update
means the
- // compositor has committed the composed result (or the original dead key
character).
- // Either way, dead key mode is over.
- if (m_deadKeyActive) {
- qCDebug(PlasmaKeyboard) << "Dead key sequence ended (surrounding-text
change)";
- m_deadKeyActive = false;
- }
}
void OverlayController::openOverlay(const QString &triggerId, const QString
&baseText, const QStringList &candidates)
@@ -409,6 +443,16 @@
Q_EMIT activeTriggerIdChanged();
Q_EMIT pendingTextChanged();
Q_EMIT overlayRequested(triggerId, baseText);
+
+ // Start grace timer for diacritics long-press overlays: if the user keeps
+ // holding the key after the overlay opens, after a grace period the
overlay
+ // closes and the base character starts auto-repeating.
+ //
+ // Only start if there is a physically held pending key (not for
emoji/text-
+ // expansion overlays which don't use the hold timer pathway).
+ if (!m_pendingText.isEmpty() && m_pendingTrigger && !m_pendingKeyReleased)
{
+ m_overlayGraceTimer.start(1000); // 1000 ms grace period after overlay
opens
+ }
}
void OverlayController::handleTimerExpired()
@@ -500,18 +544,86 @@
}
break;
case OverlayAction::ConsumeEvent:
- // Event consumed but no visible action
+ // Commit the base character via commit_string for ordering
consistency, even
+ // if the key is not a diacritic candidate.
+ if (!result.commitText.isEmpty() && m_inputPlugin) {
+ ++m_pendingSurroundingTextUpdates;
+ m_surroundingTextSettleTimer.start();
+ m_inputPlugin->commit(result.commitText);
+ }
+ // If the trigger requested a pending scan code, mark it for
swallowing on release.
+ if (result.consumeEvent && result.pendingNativeScanCode != 0) {
+ m_ignoreReleaseNativeScanCode = result.pendingNativeScanCode;
+ m_swallowNextRelease = true;
+ }
+ // Start internal repeat timer for consumed non-diacritic keys so they
+ // retain auto-repeat even though the raw key events are consumed and
don't reach the client.
+ if (result.enableRepeat && result.repeatScanCode != 0) {
+ m_repeatText = result.commitText;
+ m_repeatNativeScanCode = result.repeatScanCode;
+ // Initial delay before first repeat (matches typical XKB repeat
delay)
+ m_repeatTimer.start(500);
+ }
break;
case OverlayAction::None:
break;
}
}
+void OverlayController::handleRepeatTimer()
+{
+ if (m_repeatText.isEmpty() || !m_inputPlugin) {
+ return;
+ }
+
+ // First tick is the initial repeat delay; switch to the shorter rate.
+ if (m_repeatTimer.interval() > 100) {
+ m_repeatTimer.setInterval(33); // ~30 Hz
+ }
+
+ ++m_pendingSurroundingTextUpdates;
+ m_surroundingTextSettleTimer.start();
+ m_inputPlugin->commit(m_repeatText);
+
+ // The timer is single-shot; restart it for the next tick.
+ m_repeatTimer.start();
+}
+
+void OverlayController::handleOverlayGraceTimer()
+{
+ // If the key was already released while the overlay was visible, don't
+ // start repeating — the overlay is still up waiting for selection.
+ if (m_pendingKeyReleased || m_pendingText.isEmpty()) {
+ return;
+ }
+
+ // Close the overlay.
+ if (m_overlayVisible) {
+ m_overlayVisible = false;
+ Q_EMIT overlayVisibleChanged();
+ Q_EMIT overlayClosed();
+ }
+
+ // Start the internal repeat timer with the base character.
+ m_repeatText = m_pendingText;
+ m_repeatNativeScanCode = m_pendingNativeScanCode;
+ m_repeatTimer.start(500);
+
+ // The raw key press was consumed, so the eventual release must be
swallowed.
+ m_ignoreReleaseNativeScanCode = m_pendingNativeScanCode;
+ m_swallowNextRelease = true;
+}
+
void OverlayController::resetState()
{
if (m_holdTimer.isActive()) {
m_holdTimer.stop();
}
+ m_repeatTimer.stop();
+ m_repeatText.clear();
+ m_repeatNativeScanCode = 0;
+ m_overlayGraceTimer.stop();
+ m_overlayGraceTimer.stop();
const bool wasVisible = m_overlayVisible;
const bool hadPending = !m_pendingText.isEmpty();
@@ -526,8 +638,9 @@
m_candidateModel->clear();
m_pendingSurroundingTextUpdates = 0;
m_surroundingTextSettleTimer.stop();
- m_composeActive = false;
- m_deadKeyActive = false;
+ if (m_xkbComposeState) {
+ xkb_compose_state_reset(m_xkbComposeState);
+ }
if (wasVisible) {
Q_EMIT overlayVisibleChanged();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/plasma-keyboard-6.7.0/src/overlay/overlaycontroller.h
new/plasma-keyboard-6.7.1/src/overlay/overlaycontroller.h
--- old/plasma-keyboard-6.7.0/src/overlay/overlaycontroller.h 2026-06-11
11:36:13.000000000 +0200
+++ new/plasma-keyboard-6.7.1/src/overlay/overlaycontroller.h 2026-06-23
10:15:21.000000000 +0200
@@ -14,6 +14,8 @@
#include <QTimer>
#include <qqmlintegration.h>
+#include <xkbcommon/xkbcommon-compose.h>
+
class InputPlugin;
/**
@@ -187,6 +189,8 @@
private Q_SLOTS:
void handleTimerExpired();
+ void handleRepeatTimer();
+ void handleOverlayGraceTimer();
private:
void executeAction(const OverlayTriggerResult &result, OverlayTrigger
*trigger);
@@ -197,6 +201,8 @@
CandidateModel *m_candidateModel = nullptr;
QTimer m_holdTimer;
+ QTimer m_repeatTimer;
+ QTimer m_overlayGraceTimer;
bool m_overlayVisible = false;
QString m_activeTriggerId;
QString m_pendingText;
@@ -212,31 +218,19 @@
*/
bool m_pendingKeyReleased = false;
+ /** The trigger that is currently timing (for long-press). */
+ OverlayTrigger *m_pendingTrigger = nullptr;
+
/**
- * Set to true when a Compose (Multi_key) key press is detected.
- *
- * While true, all key events bypass the overlay trigger pipeline and are
forwarded
- * directly to the compositor so it can complete the compose sequence
- * (e.g. Multi_key + t + m → ™). The flag is cleared once an external
surrounding-text
- * change arrives (indicating the composed character was committed) or
when the context
- * is reset.
+ * Text being repeated by the internal timer for a consumed key. Empty
when no repeat
+ * is active.
*/
- bool m_composeActive = false;
+ QString m_repeatText;
/**
- * Set to true when a dead key press (Qt::Key_Dead_Grave …
Qt::Key_Dead_Longsolidusoverlay)
- * is detected.
- *
- * While true, the next non-dead-key press bypasses all overlay triggers
and is
- * forwarded directly to the compositor so the XKB compose state can
combine the
- * dead key with the follow-up key (e.g. dead_acute + e → é). The flag is
cleared
- * after forwarding that one follow-up key, or when the context is reset
(e.g. an
- * external surrounding-text change).
+ * Native scan code of the key currently being repeated. 0 when idle.
*/
- bool m_deadKeyActive = false;
-
- /** The trigger that is currently timing (for long-press). */
- OverlayTrigger *m_pendingTrigger = nullptr;
+ quint32 m_repeatNativeScanCode = 0;
/**
* Number of compositor surrounding-text echo events the controller is
still
@@ -275,4 +269,23 @@
* the 200 ms long-press threshold)
*/
QTimer m_surroundingTextSettleTimer;
+
+ /**
+ * XKB compose state machine for handling client-side compose sequences
(e.g.
+ * Multi_key + t + m → ™). The controller processes compose sequences
locally so that
+ * the intermediate keys (e.g. Multi_key, t) can be consumed and not
forwarded to the
+ * client, while only the final composed result (e.g. ™) is sent via
commit_string.
+ */
+ xkb_context *m_xkbContext = nullptr;
+
+ /**
+ * XKB compose table compiled from the system locale, used to initialize
the compose state.
+ */
+ xkb_compose_table *m_xkbComposeTable = nullptr;
+
+ /**
+ * XKB compose state initialized from the compose table, used to track the
current
+ * compose sequence and produce the final composed result.
+ */
+ xkb_compose_state *m_xkbComposeState = nullptr;
};
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/plasma-keyboard-6.7.0/src/overlay/overlaytrigger.h
new/plasma-keyboard-6.7.1/src/overlay/overlaytrigger.h
--- old/plasma-keyboard-6.7.0/src/overlay/overlaytrigger.h 2026-06-11
11:36:13.000000000 +0200
+++ new/plasma-keyboard-6.7.1/src/overlay/overlaytrigger.h 2026-06-23
10:15:21.000000000 +0200
@@ -78,6 +78,25 @@
/** For StartTimer: the pending text to be committed or shown in overlay.
*/
QString pendingText;
+
+ /**
+ * For ConsumeEvent: whether to enable an internal repeat timer for this
key.
+ *
+ * The compositor does not send auto-repeat events (state=2) to the input
+ * method grab when the initial press is consumed, so keys that go through
+ * the commit_string path lose native repeat. Set this to true for
printable
+ * characters that should auto-repeat when held.
+ */
+ bool enableRepeat = false;
+
+ /**
+ * For ConsumeEvent: native scan code used to match the key release that
+ * should stop the repeat timer.
+ *
+ * Same as pendingNativeScanCode but for the controller's internal repeat
+ * timer rather than the long-press hold timer.
+ */
+ quint32 repeatScanCode = 0;
};
/**
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/plasma-keyboard-6.7.0/src/qml/DiacriticsOverlay.qml
new/plasma-keyboard-6.7.1/src/qml/DiacriticsOverlay.qml
--- old/plasma-keyboard-6.7.0/src/qml/DiacriticsOverlay.qml 2026-06-11
11:36:13.000000000 +0200
+++ new/plasma-keyboard-6.7.1/src/qml/DiacriticsOverlay.qml 2026-06-23
10:15:21.000000000 +0200
@@ -71,7 +71,6 @@
case Qt.Key_Return:
if (root.selectedIndex >= 0 && root.selectedIndex <
root.options.length) {
root.characterSelected(root.options[root.selectedIndex]);
- root.close();
} else {
// If no option is selected, close the overlay without
selecting a character
root.close();
@@ -120,7 +119,6 @@
onClicked: {
root.characterSelected(delegate.modelData)
- root.close()
}
contentItem: Column {