mirror of
https://github.com/hyprwm/hyprlock.git
synced 2025-05-12 13:20:36 +01:00

nix: add hyprwayland-scanner dep flake.lock: update --------- Co-authored-by: Mihai Fufezan <mihai@fufexan.net>
138 lines
5.5 KiB
C++
138 lines
5.5 KiB
C++
#include "Seat.hpp"
|
|
#include "hyprlock.hpp"
|
|
#include "../helpers/Log.hpp"
|
|
#include "../config/ConfigManager.hpp"
|
|
#include <chrono>
|
|
#include <sys/mman.h>
|
|
|
|
CSeatManager::~CSeatManager() {
|
|
if (m_pXKBState)
|
|
xkb_state_unref(m_pXKBState);
|
|
if (m_pXKBKeymap)
|
|
xkb_keymap_unref(m_pXKBKeymap);
|
|
if (m_pXKBContext)
|
|
xkb_context_unref(m_pXKBContext);
|
|
}
|
|
|
|
void CSeatManager::registerSeat(SP<CCWlSeat> seat) {
|
|
m_pSeat = seat;
|
|
|
|
m_pXKBContext = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
|
if (!m_pXKBContext)
|
|
Debug::log(ERR, "Failed to create xkb context");
|
|
|
|
m_pSeat->setCapabilities([this](CCWlSeat* r, wl_seat_capability caps) {
|
|
if (caps & WL_SEAT_CAPABILITY_POINTER) {
|
|
m_pPointer = makeShared<CCWlPointer>(r->sendGetPointer());
|
|
|
|
m_pPointer->setMotion([](CCWlPointer* r, uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) {
|
|
if (std::chrono::system_clock::now() > g_pHyprlock->m_tGraceEnds)
|
|
return;
|
|
|
|
if (!g_pHyprlock->isUnlocked() && g_pHyprlock->m_vLastEnterCoords.distance({wl_fixed_to_double(surface_x), wl_fixed_to_double(surface_y)}) > 5) {
|
|
Debug::log(LOG, "In grace and cursor moved more than 5px, unlocking!");
|
|
g_pHyprlock->unlock();
|
|
}
|
|
});
|
|
|
|
m_pPointer->setEnter([this](CCWlPointer* r, uint32_t serial, wl_proxy* surf, wl_fixed_t surface_x, wl_fixed_t surface_y) {
|
|
if (!m_pCursorShape)
|
|
return;
|
|
|
|
static auto* const PHIDE = (Hyprlang::INT* const*)g_pConfigManager->getValuePtr("general:hide_cursor");
|
|
|
|
m_pCursorShape->lastCursorSerial = serial;
|
|
|
|
if (**PHIDE)
|
|
m_pCursorShape->hideCursor();
|
|
else
|
|
m_pCursorShape->setShape(wpCursorShapeDeviceV1Shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_DEFAULT);
|
|
|
|
g_pHyprlock->m_vLastEnterCoords = {wl_fixed_to_double(surface_x), wl_fixed_to_double(surface_y)};
|
|
});
|
|
}
|
|
|
|
if (caps & WL_SEAT_CAPABILITY_KEYBOARD) {
|
|
m_pKeeb = makeShared<CCWlKeyboard>(r->sendGetKeyboard());
|
|
|
|
m_pKeeb->setKeymap([this](CCWlKeyboard*, wl_keyboard_keymap_format format, int32_t fd, uint32_t size) {
|
|
if (!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(nullptr, size, PROT_READ, MAP_PRIVATE, fd, 0);
|
|
if (buf == MAP_FAILED) {
|
|
Debug::log(ERR, "Failed to mmap xkb keymap: {}", errno);
|
|
return;
|
|
}
|
|
|
|
m_pXKBKeymap = xkb_keymap_new_from_buffer(m_pXKBContext, buf, size - 1, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
|
|
|
munmap((void*)buf, size);
|
|
close(fd);
|
|
|
|
if (!m_pXKBKeymap) {
|
|
Debug::log(ERR, "Failed to compile xkb keymap");
|
|
return;
|
|
}
|
|
|
|
m_pXKBState = xkb_state_new(m_pXKBKeymap);
|
|
if (!m_pXKBState) {
|
|
Debug::log(ERR, "Failed to create xkb state");
|
|
return;
|
|
}
|
|
|
|
const auto PCOMOPOSETABLE = xkb_compose_table_new_from_locale(m_pXKBContext, setlocale(LC_CTYPE, nullptr), XKB_COMPOSE_COMPILE_NO_FLAGS);
|
|
|
|
if (!PCOMOPOSETABLE) {
|
|
Debug::log(ERR, "Failed to create xkb compose table");
|
|
return;
|
|
}
|
|
|
|
m_pXKBComposeState = xkb_compose_state_new(PCOMOPOSETABLE, XKB_COMPOSE_STATE_NO_FLAGS);
|
|
});
|
|
|
|
m_pKeeb->setKey([](CCWlKeyboard* r, uint32_t serial, uint32_t time, uint32_t key, wl_keyboard_key_state state) {
|
|
g_pHyprlock->onKey(key, state == WL_KEYBOARD_KEY_STATE_PRESSED);
|
|
});
|
|
|
|
m_pKeeb->setModifiers([this](CCWlKeyboard* r, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) {
|
|
if (!m_pXKBState)
|
|
return;
|
|
|
|
if (group != g_pHyprlock->m_uiActiveLayout) {
|
|
g_pHyprlock->m_uiActiveLayout = group;
|
|
for (auto& t : g_pHyprlock->getTimers()) {
|
|
if (t->canForceUpdate()) {
|
|
t->call(t);
|
|
t->cancel();
|
|
}
|
|
}
|
|
}
|
|
|
|
xkb_state_update_mask(m_pXKBState, mods_depressed, mods_latched, mods_locked, 0, 0, group);
|
|
g_pHyprlock->m_bCapsLock = xkb_state_mod_name_is_active(m_pXKBState, XKB_MOD_NAME_CAPS, XKB_STATE_MODS_LOCKED);
|
|
g_pHyprlock->m_bNumLock = xkb_state_mod_name_is_active(m_pXKBState, XKB_MOD_NAME_NUM, XKB_STATE_MODS_LOCKED);
|
|
});
|
|
|
|
m_pKeeb->setRepeatInfo([](CCWlKeyboard* r, int32_t rate, int32_t delay) {
|
|
g_pHyprlock->m_iKeebRepeatRate = rate;
|
|
g_pHyprlock->m_iKeebRepeatDelay = delay;
|
|
});
|
|
}
|
|
});
|
|
|
|
m_pSeat->setName([](CCWlSeat* r, const char* name) { Debug::log(LOG, "Exposed seat name: {}", name ? name : "nullptr"); });
|
|
}
|
|
|
|
void CSeatManager::registerCursorShape(SP<CCWpCursorShapeManagerV1> shape) {
|
|
m_pCursorShape = std::make_unique<CCursorShape>(shape);
|
|
}
|
|
|
|
bool CSeatManager::registered() {
|
|
return m_pSeat;
|
|
}
|