Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use xkbcommon for keyboard event handling #43

Merged
merged 1 commit into from
Oct 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ add_compile_options(-Wall -Wextra -Wno-unused-parameter -Wno-unused-value -Wno-m
find_package(Threads REQUIRED)

find_package(PkgConfig REQUIRED)
pkg_check_modules(deps REQUIRED IMPORTED_TARGET wayland-client wayland-protocols cairo pango pangocairo libjpeg)
pkg_check_modules(deps REQUIRED IMPORTED_TARGET wayland-client wayland-protocols xkbcommon cairo pango pangocairo libjpeg)

file(GLOB_RECURSE SRCFILES "src/*.cpp")

Expand Down
2 changes: 2 additions & 0 deletions nix/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
libselinux,
libsepol,
libthai,
libxkbcommon,
pango,
pcre,
utillinux,
Expand Down Expand Up @@ -50,6 +51,7 @@ stdenv.mkDerivation {
wayland-scanner
wlroots
libXdmcp
libxkbcommon
utillinux
];

Expand Down
47 changes: 44 additions & 3 deletions src/events/Events.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,18 +246,59 @@ void Events::handlePointerButton(void* data, struct wl_pointer* wl_pointer, uint
g_pHyprpicker->finish();
}

void Events::handleKeyboardKeymap(void* data, wl_keyboard* wl_keyboard, uint format, int fd, uint size) {}
void Events::handleKeyboardKeymap(void* data, wl_keyboard* wl_keyboard, uint format, int fd, uint size) {
if (!g_pHyprpicker->m_pXKBContext)
return;

if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
Debug::log(ERR, "Could not recognise keymap format");
return;
}

const char* buf = (const char*)mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
if (buf == MAP_FAILED) {
Debug::log(ERR, "Failed to mmap xkb keymap: %d", errno);
return;
}

g_pHyprpicker->m_pXKBKeymap = xkb_keymap_new_from_buffer(g_pHyprpicker->m_pXKBContext, buf, size - 1, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);

munmap((void*)buf, size);
close(fd);

if (!g_pHyprpicker->m_pXKBKeymap) {
Debug::log(ERR, "Failed to compile xkb keymap");
return;
}

g_pHyprpicker->m_pXKBState = xkb_state_new(g_pHyprpicker->m_pXKBKeymap);
if (!g_pHyprpicker->m_pXKBState) {
Debug::log(ERR, "Failed to create xkb state");
return;
}
}

void Events::handleKeyboardKey(void* data, struct wl_keyboard* keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state) {
if (key == 1) // escape
if (state != WL_KEYBOARD_KEY_STATE_PRESSED)
return;

if (g_pHyprpicker->m_pXKBState) {
if (xkb_state_key_get_one_sym(g_pHyprpicker->m_pXKBState, key + 8) == XKB_KEY_Escape)
g_pHyprpicker->finish();
} else if (key == 1) // Assume keycode 1 is escape
g_pHyprpicker->finish();
}

void Events::handleKeyboardEnter(void* data, wl_keyboard* wl_keyboard, uint serial, wl_surface* surface, wl_array* keys) {}

void Events::handleKeyboardLeave(void* data, wl_keyboard* wl_keyboard, uint serial, wl_surface* surface) {}

void Events::handleKeyboardModifiers(void* data, wl_keyboard* wl_keyboard, uint serial, uint mods_depressed, uint mods_latched, uint mods_locked, uint group) {}
void Events::handleKeyboardModifiers(void* data, wl_keyboard* wl_keyboard, uint serial, uint mods_depressed, uint mods_latched, uint mods_locked, uint group) {
if (!g_pHyprpicker->m_pXKBState)
return;

xkb_state_update_mask(g_pHyprpicker->m_pXKBState, mods_depressed, mods_latched, mods_locked, 0, 0, group);
}

void Events::handleFrameDone(void* data, struct wl_callback* callback, uint32_t time) {
CLayerSurface* pLS = (CLayerSurface*)data;
Expand Down
4 changes: 4 additions & 0 deletions src/hyprpicker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ void sigHandler(int sig) {
}

void CHyprpicker::init() {
m_pXKBContext = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
if (!m_pXKBContext)
Debug::log(ERR, "Failed to create xkb context");

m_pWLDisplay = wl_display_connect(nullptr);

if (!m_pWLDisplay) {
Expand Down
4 changes: 4 additions & 0 deletions src/hyprpicker.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ class CHyprpicker {
zwlr_layer_shell_v1* m_pLayerShell;
zwlr_screencopy_manager_v1* m_pSCMgr;

xkb_context* m_pXKBContext = nullptr;
xkb_keymap* m_pXKBKeymap = nullptr;
xkb_state* m_pXKBState = nullptr;

eOutputMode m_bSelectedOutputMode = OUTPUT_HEX;

bool m_bFancyOutput = true;
Expand Down
1 change: 1 addition & 0 deletions src/includes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ extern "C" {
#include <sys/mman.h>
#include <unistd.h>
#include <wayland-client.h>
#include <xkbcommon/xkbcommon.h>

#include <algorithm>
#include <filesystem>
Expand Down