Add a keyboard tab to the debug console

Summary:
A little bit debug information about the current keyboard state is
useful. Thus a new tab is added to show information about xkbcommon.

It shows:
* layouts in the keymap
* currently active layout
* supported modifiers in key map
* currently active modifiers in state
* supported leds in key map
* currently active leds in state

Whenever a key is pressed/released the complete ui is updated to reflect
the latest state. That is pressing/releasing a modifier is directly
reflected in the ui.

This UI can extended as needed for further debug information about the
keymap state.

Reviewers: #kwin, #plasma_on_wayland

Subscribers: plasma-devel, kwin

Tags: #plasma_on_wayland, #kwin

Differential Revision: https://phabricator.kde.org/D3379
This commit is contained in:
Martin Gräßlin 2016-11-16 11:18:36 +01:00
parent 346619aa36
commit 327ccffcf4
4 changed files with 200 additions and 0 deletions

View file

@ -49,6 +49,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <QMetaProperty>
#include <QMetaType>
// xkb
#include <xkbcommon/xkbcommon.h>
#include <functional>
namespace KWin
{
@ -503,6 +508,10 @@ DebugConsole::DebugConsole()
m_inputFilter.reset(new DebugConsoleFilter(m_ui->inputTextEdit));
input()->prepandInputEventFilter(m_inputFilter.data());
}
if (index == 5) {
updateKeyboardTab();
connect(input(), &InputRedirection::keyStateChanged, this, &DebugConsole::updateKeyboardTab);
}
}
);
@ -556,6 +565,47 @@ void DebugConsole::initGLTab()
m_ui->openGLExtensionsLabel->setText(extensionsString(openGLExtensions()));
}
template <typename T>
QString keymapComponentToString(xkb_keymap *map, const T &count, std::function<const char*(xkb_keymap*,T)> f)
{
QString text = QStringLiteral("<ul>");
for (T i = 0; i < count; i++) {
text.append(QStringLiteral("<li>%1</li>").arg(QString::fromLocal8Bit(f(map, i))));
}
text.append(QStringLiteral("</ul>"));
return text;
}
template <typename T>
QString stateActiveComponents(xkb_state *state, const T &count, std::function<int(xkb_state*,T)> f, std::function<const char*(xkb_keymap*,T)> name)
{
QString text = QStringLiteral("<ul>");
xkb_keymap *map = xkb_state_get_keymap(state);
for (T i = 0; i < count; i++) {
if (f(state, i) == 1) {
text.append(QStringLiteral("<li>%1</li>").arg(QString::fromLocal8Bit(name(map, i))));
}
}
text.append(QStringLiteral("</ul>"));
return text;
}
void DebugConsole::updateKeyboardTab()
{
auto xkb = input()->keyboard()->xkb();
xkb_keymap *map = xkb->keymap();
xkb_state *state = xkb->state();
m_ui->layoutsLabel->setText(keymapComponentToString<xkb_layout_index_t>(map, xkb_keymap_num_layouts(map), &xkb_keymap_layout_get_name));
m_ui->currentLayoutLabel->setText(xkb_keymap_layout_get_name(map, xkb->currentLayout()));
m_ui->modifiersLabel->setText(keymapComponentToString<xkb_mod_index_t>(map, xkb_keymap_num_mods(map), &xkb_keymap_mod_get_name));
m_ui->ledsLabel->setText(keymapComponentToString<xkb_led_index_t>(map, xkb_keymap_num_leds(map), &xkb_keymap_led_get_name));
m_ui->activeLedsLabel->setText(stateActiveComponents<xkb_led_index_t>(state, xkb_keymap_num_leds(map), &xkb_state_led_index_is_active, &xkb_keymap_led_get_name));
using namespace std::placeholders;
auto modActive = std::bind(xkb_state_mod_index_is_active, _1, _2, XKB_STATE_MODS_EFFECTIVE);
m_ui->activeModifiersLabel->setText(stateActiveComponents<xkb_mod_index_t>(state, xkb_keymap_num_mods(map), modActive, &xkb_keymap_mod_get_name));
}
void DebugConsole::showEvent(QShowEvent *event)
{
QWidget::showEvent(event);

View file

@ -106,6 +106,7 @@ protected:
private:
void initGLTab();
void updateKeyboardTab();
QScopedPointer<Ui::DebugConsole> m_ui;
QScopedPointer<DebugConsoleFilter> m_inputFilter;

View file

@ -302,6 +302,143 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="keyboard">
<attribute name="title">
<string>Keyboard</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_11">
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents_2">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>564</width>
<height>495</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_13">
<item>
<widget class="QGroupBox" name="layoutBox">
<property name="title">
<string>Keymap Layouts</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_12">
<item>
<widget class="QLabel" name="layoutsLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_9">
<property name="text">
<string>Current Layout:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="currentLayoutLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="modifiersBox">
<property name="title">
<string>Modifiers</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="modifiersLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="activeModifiersBox">
<property name="title">
<string>Active Modifiers</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_16">
<item>
<widget class="QLabel" name="activeModifiersLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="ledsBox">
<property name="title">
<string>LEDs</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_14">
<item>
<widget class="QLabel" name="ledsLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="activeLedsBox">
<property name="title">
<string>Active LEDs</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_15">
<item>
<widget class="QLabel" name="activeLedsLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>

View file

@ -82,6 +82,18 @@ public:
return m_leds;
}
xkb_keymap *keymap() const {
return m_keymap;
}
xkb_state *state() const {
return m_state;
}
quint32 currentLayout() const {
return m_currentLayout;
}
private:
xkb_keymap *loadKeymapFromConfig();
xkb_keymap *loadDefaultKeymap();