Skip to content

Commit 7054e2d

Browse files
committed
wayland: input method protocol
1 parent f7597cd commit 7054e2d

23 files changed

+2420
-0
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ boption(SCREENCOPY " Screencopy" ON REQUIRES WAYLAND)
6060
boption(SCREENCOPY_ICC " Image Copy Capture" ON REQUIRES WAYLAND)
6161
boption(SCREENCOPY_WLR " Wlroots Screencopy" ON REQUIRES WAYLAND)
6262
boption(SCREENCOPY_HYPRLAND_TOPLEVEL " Hyprland Toplevel Export" ON REQUIRES WAYLAND)
63+
boption(INPUT_METHOD " Input Method" ON REQUIRES WAYLAND)
6364
boption(X11 "X11" ON)
6465
boption(I3 "I3/Sway" ON)
6566
boption(I3_IPC " I3/Sway IPC" ON REQUIRES I3)

src/wayland/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,11 @@ if (HYPRLAND)
114114
add_subdirectory(hyprland)
115115
endif()
116116

117+
if (INPUT_METHOD)
118+
add_subdirectory(input_method)
119+
list(APPEND WAYLAND_MODULES Quickshell.Wayland._InputMethod)
120+
endif()
121+
117122
add_subdirectory(idle_inhibit)
118123
list(APPEND WAYLAND_MODULES Quickshell.Wayland._IdleInhibitor)
119124

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
set(INPUT_METHOD_PRINT_KETS OFF)
2+
3+
qt_add_library(quickshell-wayland-input-method STATIC
4+
input_method.cpp
5+
keyboard_grab.cpp
6+
virtual_keyboard.cpp
7+
key_map_state.cpp
8+
manager.cpp
9+
qml.cpp
10+
qml_helpers.cpp
11+
c_helpers.cpp
12+
types.cpp
13+
)
14+
15+
target_compile_definitions(quickshell-wayland-input-method PRIVATE INPUT_METHOD_PRINT=0)
16+
17+
qt_add_qml_module(quickshell-wayland-input-method
18+
URI Quickshell.Wayland._InputMethod
19+
VERSION 0.1
20+
DEPENDENCIES QtQml
21+
)
22+
23+
qs_add_module_deps_light(quickshell-wayland-input-method
24+
Quickshell Quickshell.Wayland
25+
)
26+
27+
install_qml_module(quickshell-wayland-input-method)
28+
29+
wl_proto(zwp-input-method input-method-unstable-v2 "${CMAKE_CURRENT_SOURCE_DIR}")
30+
wl_proto(zwp-virtual-keyboard virtual-keyboard-unstable-v1 "${CMAKE_CURRENT_SOURCE_DIR}")
31+
wl_proto(zwp-text-input text-input-unstable-v3 "${WAYLAND_PROTOCOLS}/unstable/text-input")
32+
33+
target_link_libraries(quickshell-wayland-input-method PRIVATE
34+
Qt::Quick Qt::WaylandClient Qt::WaylandClientPrivate wayland-client
35+
zwp-input-method zwp-virtual-keyboard zwp-text-input
36+
)
37+
38+
qs_module_pch(quickshell-wayland-input-method SET large)
39+
40+
target_link_libraries(quickshell PRIVATE quickshell-wayland-input-methodplugin)
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#include "c_helpers.hpp"
2+
#include <cstddef>
3+
#include <cstdio>
4+
#include <cstring>
5+
#include <utility>
6+
7+
#include <qdebug.h>
8+
#include <qlogging.h>
9+
#include <sys/mman.h>
10+
#include <sys/shm.h>
11+
#include <unistd.h>
12+
13+
namespace qs::wayland::input_method::impl {
14+
15+
void FreeDeleter::operator()(const char* p) const {
16+
std::free(const_cast<std::remove_const_t<char>*>(p)); // NOLINT
17+
}
18+
19+
SharedMemory::SharedMemory(const char* shmName, int oFlag, size_t size)
20+
: mShmName(shmName)
21+
, mSize(size)
22+
, fd(shm_open(this->mShmName, oFlag, 0))
23+
, map(nullptr) {
24+
if (this->fd == -1) {
25+
perror("");
26+
qDebug() << "Virtual keyboard failed to open shared memory";
27+
return;
28+
}
29+
if (ftruncate(this->fd, static_cast<int>(size)) == -1) {
30+
this->fd = -1;
31+
perror("");
32+
qDebug() << "Virtual keyboard failed to resize shared memory to" << size;
33+
return;
34+
}
35+
this->map = static_cast<char*>(mmap(nullptr, this->mSize, PROT_WRITE, MAP_SHARED, this->fd, 0));
36+
if (this->map == MAP_FAILED) {
37+
perror("");
38+
qDebug() << "Virtual keyboard failed to open shared memory";
39+
return;
40+
}
41+
}
42+
SharedMemory::~SharedMemory() {
43+
if (this->fd != -1) {
44+
close(this->fd);
45+
shm_unlink(this->mShmName);
46+
}
47+
if (this->map != nullptr) {
48+
munmap(this->map, this->mSize);
49+
}
50+
}
51+
SharedMemory::SharedMemory(SharedMemory&& other) noexcept
52+
: mShmName(std::exchange(other.mShmName, nullptr))
53+
, mSize(std::exchange(other.mSize, 0))
54+
, fd(std::exchange(other.fd, -1))
55+
, map(std::exchange(other.map, nullptr)) {}
56+
SharedMemory& SharedMemory::operator=(SharedMemory&& other) noexcept {
57+
this->mShmName = std::exchange(other.mShmName, nullptr);
58+
this->mSize = std::exchange(other.mSize, 0);
59+
this->fd = std::exchange(other.fd, -1);
60+
this->map = std::exchange(other.map, nullptr);
61+
return *this;
62+
}
63+
64+
SharedMemory::operator bool() const { return fd != -1 && map != MAP_FAILED; }
65+
[[nodiscard]] int SharedMemory::get() const { return fd; }
66+
67+
void SharedMemory::write(const char* string) {
68+
if (!this->map) return;
69+
strcpy(this->map, string);
70+
}
71+
72+
} // namespace qs::wayland::input_method::impl
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#pragma once
2+
3+
#include <memory>
4+
5+
#include <sys/mman.h>
6+
7+
namespace qs::wayland::input_method::impl {
8+
9+
struct FreeDeleter {
10+
void operator()(const char* p) const;
11+
};
12+
// Dont use this for literals, only c strings that were allocated
13+
using uniqueCString = std::unique_ptr<const char, FreeDeleter>;
14+
15+
// this is a bit half baked but works for what I need it for
16+
/// Handles the lifetime of a memory mapped shm
17+
class SharedMemory {
18+
public:
19+
SharedMemory(const char* shmName, int oFlag, size_t size);
20+
~SharedMemory();
21+
SharedMemory(const SharedMemory&) = delete;
22+
SharedMemory(SharedMemory&& other) noexcept;
23+
SharedMemory& operator=(const SharedMemory&) = delete;
24+
SharedMemory& operator=(SharedMemory&& other) noexcept;
25+
26+
[[nodiscard]] operator bool() const;
27+
[[nodiscard]] int get() const;
28+
29+
void write(const char* string);
30+
31+
private:
32+
const char* mShmName;
33+
size_t mSize;
34+
int fd;
35+
char* map = nullptr;
36+
};
37+
38+
} // namespace qs::wayland::input_method::impl

0 commit comments

Comments
 (0)