diff --git a/input.cpp b/input.cpp
index 65542b77a6..57ba3c1035 100644
--- a/input.cpp
+++ b/input.cpp
@@ -41,6 +41,7 @@ along with this program. If not, see .
// Qt
#include
#include
+#include
// KDE
#include
#if HAVE_XKB
@@ -50,13 +51,15 @@ along with this program. If not, see .
// system
#include
#include
+#include
namespace KWin
{
#if HAVE_XKB
-Xkb::Xkb()
- : m_context(xkb_context_new(static_cast(0)))
+Xkb::Xkb(InputRedirection *input)
+ : m_input(input)
+ , m_context(xkb_context_new(static_cast(0)))
, m_keymap(NULL)
, m_state(NULL)
, m_shiftModifier(0)
@@ -123,6 +126,47 @@ void Xkb::updateKeymap(xkb_keymap *keymap)
m_controlModifier = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_CTRL);
m_altModifier = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_ALT);
m_metaModifier = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_LOGO);
+
+ createKeymapFile();
+}
+
+void Xkb::createKeymapFile()
+{
+#if HAVE_WAYLAND
+ if (!waylandServer()) {
+ return;
+ }
+ // TODO: uninstall keymap on server?
+ if (!m_keymap) {
+ return;
+ }
+
+ ScopedCPointer keymapString(xkb_keymap_get_as_string(m_keymap, XKB_KEYMAP_FORMAT_TEXT_V1));
+ if (keymapString.isNull()) {
+ return;
+ }
+ const uint size = qstrlen(keymapString.data()) + 1;
+
+ QTemporaryFile *tmp = new QTemporaryFile(m_input);
+ if (!tmp->open()) {
+ delete tmp;
+ return;
+ }
+ unlink(tmp->fileName().toUtf8().constData());
+ if (!tmp->resize(size)) {
+ delete tmp;
+ return;
+ }
+ uchar *address = tmp->map(0, size);
+ if (!address) {
+ return;
+ }
+ if (qstrncpy(reinterpret_cast(address), keymapString.data(), size) == nullptr) {
+ delete tmp;
+ return;
+ }
+ waylandServer()->seat()->setKeymap(tmp->handle(), size);
+#endif
}
void Xkb::updateModifiers(uint32_t modsDepressed, uint32_t modsLatched, uint32_t modsLocked, uint32_t group)
@@ -195,7 +239,7 @@ KWIN_SINGLETON_FACTORY(InputRedirection)
InputRedirection::InputRedirection(QObject *parent)
: QObject(parent)
#if HAVE_XKB
- , m_xkb(new Xkb())
+ , m_xkb(new Xkb(this))
#endif
, m_pointerWindow()
, m_shortcuts(new GlobalShortcutsManager(this))
diff --git a/input.h b/input.h
index 81da6465e2..a29d2d9d17 100644
--- a/input.h
+++ b/input.h
@@ -213,7 +213,7 @@ private:
class Xkb
{
public:
- Xkb();
+ Xkb(InputRedirection *input);
~Xkb();
void installKeymap(int fd, uint32_t size);
void updateModifiers(uint32_t modsDepressed, uint32_t modsLatched, uint32_t modsLocked, uint32_t group);
@@ -224,7 +224,9 @@ public:
Qt::KeyboardModifiers modifiers() const;
private:
void updateKeymap(xkb_keymap *keymap);
+ void createKeymapFile();
void updateModifiers();
+ InputRedirection *m_input;
xkb_context *m_context;
xkb_keymap *m_keymap;
xkb_state *m_state;