mirror of
https://github.com/hyprwm/Hyprland.git
synced 2024-09-11 13:25:42 +03:00
input basics
This commit is contained in:
parent
52090853da
commit
cf51ab71a2
@ -9,7 +9,7 @@ message(STATUS "Configuring Hyprland!")
|
||||
|
||||
include_directories(.)
|
||||
add_compile_options(-std=c++20 -DWLR_USE_UNSTABLE )
|
||||
add_compile_options(-Wall -Wextra -Wno-unused-parameter)
|
||||
add_compile_options(-Wall -Wextra -Wno-unused-parameter -Wno-unused-value)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
|
11
example/hyprland.conf
Normal file
11
example/hyprland.conf
Normal file
@ -0,0 +1,11 @@
|
||||
# This is an example Hyprland config file.
|
||||
# Syntax is the same as in Hypr, but settings might differ.
|
||||
#
|
||||
# Refer to the wiki for more information.
|
||||
|
||||
general {
|
||||
max_fps=240
|
||||
gaps_in=5
|
||||
gaps_out=20
|
||||
border_size=1
|
||||
}
|
@ -40,16 +40,16 @@ CCompositor::CCompositor() {
|
||||
m_sWLRXDGActivation - wlr_xdg_activation_v1_create(m_sWLDisplay);
|
||||
m_sWLROutputLayout = wlr_output_layout_create();
|
||||
|
||||
wl_signal_add(&m_sWLRXDGActivation->events.request_activate, &Events::listener_activate);
|
||||
wl_signal_add(&m_sWLROutputLayout->events.change, &Events::listener_change);
|
||||
wl_signal_add(&m_sWLRBackend->events.new_output, &Events::listener_newOutput);
|
||||
wl_signal_add(&m_sWLRXDGActivation->events.request_activate, &Events::listen_activate);
|
||||
wl_signal_add(&m_sWLROutputLayout->events.change, &Events::listen_change);
|
||||
wl_signal_add(&m_sWLRBackend->events.new_output, &Events::listen_newOutput);
|
||||
|
||||
m_sWLRIdle = wlr_idle_create(m_sWLDisplay);
|
||||
m_sWLRLayerShell = wlr_layer_shell_v1_create(m_sWLDisplay);
|
||||
m_sWLRXDGShell = wlr_xdg_shell_create(m_sWLDisplay);
|
||||
|
||||
wl_signal_add(&m_sWLRLayerShell->events.new_surface, &Events::listener_newLayerSurface);
|
||||
wl_signal_add(&m_sWLRXDGShell->events.new_surface, &Events::listener_newXDGSurface);
|
||||
wl_signal_add(&m_sWLRLayerShell->events.new_surface, &Events::listen_newLayerSurface);
|
||||
wl_signal_add(&m_sWLRXDGShell->events.new_surface, &Events::listen_newXDGSurface);
|
||||
|
||||
wlr_server_decoration_manager_set_default_mode(wlr_server_decoration_manager_create(m_sWLDisplay), WLR_SERVER_DECORATION_MANAGER_MODE_SERVER);
|
||||
wlr_xdg_decoration_manager_v1_create(m_sWLDisplay);
|
||||
@ -67,22 +67,26 @@ CCompositor::CCompositor() {
|
||||
|
||||
m_sWLRPresentation = wlr_presentation_create(m_sWLDisplay, m_sWLRBackend);
|
||||
|
||||
wl_signal_add(&m_sWLRCursor->events.motion, &Events::listener_mouseMove);
|
||||
wl_signal_add(&m_sWLRCursor->events.motion_absolute, &Events::listener_mouseMoveAbsolute);
|
||||
wl_signal_add(&m_sWLRCursor->events.button, &Events::listener_mouseButton);
|
||||
wl_signal_add(&m_sWLRCursor->events.axis, &Events::listener_mouseAxis);
|
||||
wl_signal_add(&m_sWLRCursor->events.frame, &Events::listener_mouseFrame);
|
||||
wl_signal_add(&m_sWLRBackend->events.new_input, &Events::listener_newInput);
|
||||
wl_signal_add(&m_sWLRVKeyboardMgr->events.new_virtual_keyboard, &Events::listener_newKeyboard);
|
||||
wl_signal_add(&m_sWLRSeat->events.request_set_cursor, &Events::listener_requestMouse);
|
||||
wl_signal_add(&m_sWLRSeat->events.request_set_selection, &Events::listener_requestSetSel);
|
||||
wl_signal_add(&m_sWLRSeat->events.request_set_primary_selection, &Events::listener_requestSetPrimarySel);
|
||||
wl_signal_add(&m_sWLROutputMgr->events.apply, &Events::listener_outputMgrApply);
|
||||
wl_signal_add(&m_sWLROutputMgr->events.test, &Events::listener_outputMgrTest);
|
||||
wl_signal_add(&m_sWLRCursor->events.motion, &Events::listen_mouseMove);
|
||||
wl_signal_add(&m_sWLRCursor->events.motion_absolute, &Events::listen_mouseMoveAbsolute);
|
||||
wl_signal_add(&m_sWLRCursor->events.button, &Events::listen_mouseButton);
|
||||
wl_signal_add(&m_sWLRCursor->events.axis, &Events::listen_mouseAxis);
|
||||
wl_signal_add(&m_sWLRCursor->events.frame, &Events::listen_mouseFrame);
|
||||
wl_signal_add(&m_sWLRBackend->events.new_input, &Events::listen_newInput);
|
||||
wl_signal_add(&m_sWLRVKeyboardMgr->events.new_virtual_keyboard, &Events::listen_newKeyboard);
|
||||
wl_signal_add(&m_sWLRSeat->events.request_set_cursor, &Events::listen_requestMouse);
|
||||
wl_signal_add(&m_sWLRSeat->events.request_set_selection, &Events::listen_requestSetSel);
|
||||
wl_signal_add(&m_sWLRSeat->events.request_set_primary_selection, &Events::listen_requestSetPrimarySel);
|
||||
wl_signal_add(&m_sWLROutputMgr->events.apply, &Events::listen_outputMgrApply);
|
||||
wl_signal_add(&m_sWLROutputMgr->events.test, &Events::listen_outputMgrTest);
|
||||
|
||||
// TODO: XWayland
|
||||
}
|
||||
|
||||
CCompositor::~CCompositor() {
|
||||
|
||||
}
|
||||
|
||||
void CCompositor::startCompositor() {
|
||||
m_szWLDisplaySocket = wl_display_add_socket_auto(m_sWLDisplay);
|
||||
|
||||
@ -95,6 +99,7 @@ void CCompositor::startCompositor() {
|
||||
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
Debug::log(LOG, "Running on WAYLAND_DISPLAY: %s", m_szWLDisplaySocket);
|
||||
|
||||
if (!wlr_backend_start(m_sWLRBackend)) {
|
||||
Debug::log(CRIT, "Backend did not start!");
|
||||
@ -103,6 +108,15 @@ void CCompositor::startCompositor() {
|
||||
|
||||
wlr_xcursor_manager_set_cursor_image(m_sWLRXCursorMgr, "left_ptr", m_sWLRCursor);
|
||||
|
||||
Debug::log(LOG, "Creating the config manager!");
|
||||
g_pConfigManager = std::make_unique<CConfigManager>();
|
||||
|
||||
Debug::log(LOG, "Creating the ManagerThread!");
|
||||
g_pManagerThread = std::make_unique<CManagerThread>();
|
||||
|
||||
Debug::log(LOG, "Creating the InputManager!");
|
||||
g_pInputManager = std::make_unique<CInputManager>();
|
||||
|
||||
// This blocks until we are done.
|
||||
Debug::log(LOG, "Hyprland is ready, running the event loop!");
|
||||
wl_display_run(m_sWLDisplay);
|
||||
|
@ -5,6 +5,9 @@
|
||||
#include "defines.hpp"
|
||||
#include "debug/Log.hpp"
|
||||
#include "events/Events.hpp"
|
||||
#include "config/ConfigManager.hpp"
|
||||
#include "ManagerThread.hpp"
|
||||
#include "input/InputManager.hpp"
|
||||
|
||||
class CCompositor {
|
||||
public:
|
||||
|
22
src/ManagerThread.cpp
Normal file
22
src/ManagerThread.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
#include "ManagerThread.hpp"
|
||||
|
||||
CManagerThread::CManagerThread() {
|
||||
m_tMainThread = new std::thread([=]() {
|
||||
// Call the handle method.
|
||||
this->handle();
|
||||
});
|
||||
|
||||
m_tMainThread->detach(); // detach and continue.
|
||||
}
|
||||
|
||||
CManagerThread::~CManagerThread() {
|
||||
//
|
||||
}
|
||||
|
||||
void CManagerThread::handle() {
|
||||
while (3.1415f) {
|
||||
g_pConfigManager->tick();
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(1000000 / g_pConfigManager->getInt("max_fps")));
|
||||
}
|
||||
}
|
19
src/ManagerThread.hpp
Normal file
19
src/ManagerThread.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "defines.hpp"
|
||||
#include <thread>
|
||||
#include "Compositor.hpp"
|
||||
|
||||
class CManagerThread {
|
||||
public:
|
||||
CManagerThread();
|
||||
~CManagerThread();
|
||||
|
||||
private:
|
||||
|
||||
void handle();
|
||||
|
||||
std::thread* m_tMainThread;
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CManagerThread> g_pManagerThread;
|
201
src/config/ConfigManager.cpp
Normal file
201
src/config/ConfigManager.cpp
Normal file
@ -0,0 +1,201 @@
|
||||
#include "ConfigManager.hpp"
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
CConfigManager::CConfigManager() {
|
||||
configValues["general:max_fps"].intValue = 240;
|
||||
|
||||
configValues["general:border_size"].intValue = 1;
|
||||
configValues["general:gaps_in"].intValue = 5;
|
||||
configValues["general:gaps_out"].intValue = 20;
|
||||
|
||||
loadConfigLoadVars();
|
||||
|
||||
isFirstLaunch = false;
|
||||
}
|
||||
|
||||
void CConfigManager::configSetValueSafe(const std::string& COMMAND, const std::string& VALUE) {
|
||||
if (configValues.find(COMMAND) == configValues.end()) {
|
||||
parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">: No such field.";
|
||||
return;
|
||||
}
|
||||
|
||||
auto& CONFIGENTRY = configValues.at(COMMAND);
|
||||
if (CONFIGENTRY.intValue != -1) {
|
||||
try {
|
||||
if (VALUE.find("0x") == 0) {
|
||||
// Values with 0x are hex
|
||||
const auto VALUEWITHOUTHEX = VALUE.substr(2);
|
||||
CONFIGENTRY.intValue = stol(VALUEWITHOUTHEX, nullptr, 16);
|
||||
} else
|
||||
CONFIGENTRY.intValue = stol(VALUE);
|
||||
} catch (...) {
|
||||
Debug::log(WARN, "Error reading value of %s", COMMAND.c_str());
|
||||
parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">.";
|
||||
}
|
||||
} else if (CONFIGENTRY.floatValue != -1) {
|
||||
try {
|
||||
CONFIGENTRY.floatValue = stof(VALUE);
|
||||
} catch (...) {
|
||||
Debug::log(WARN, "Error reading value of %s", COMMAND.c_str());
|
||||
parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">.";
|
||||
}
|
||||
} else if (CONFIGENTRY.strValue != "") {
|
||||
try {
|
||||
CONFIGENTRY.strValue = VALUE;
|
||||
} catch (...) {
|
||||
Debug::log(WARN, "Error reading value of %s", COMMAND.c_str());
|
||||
parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CConfigManager::handleRawExec(const std::string& command, const std::string& args) {
|
||||
// Exec in the background dont wait for it.
|
||||
if (fork() == 0) {
|
||||
execl("/bin/sh", "/bin/sh", "-c", args.c_str(), nullptr);
|
||||
|
||||
_exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
void CConfigManager::parseLine(std::string& line) {
|
||||
// first check if its not a comment
|
||||
const auto COMMENTSTART = line.find_first_of('#');
|
||||
if (COMMENTSTART == 0)
|
||||
return;
|
||||
|
||||
// now, cut the comment off
|
||||
if (COMMENTSTART != std::string::npos)
|
||||
line = line.substr(0, COMMENTSTART);
|
||||
|
||||
// remove shit at the beginning
|
||||
while (line[0] == ' ' || line[0] == '\t') {
|
||||
line = line.substr(1);
|
||||
}
|
||||
|
||||
if (line.find(" {") != std::string::npos) {
|
||||
auto cat = line.substr(0, line.find(" {"));
|
||||
transform(cat.begin(), cat.end(), cat.begin(), ::tolower);
|
||||
currentCategory = cat;
|
||||
return;
|
||||
}
|
||||
|
||||
if (line.find("}") != std::string::npos && currentCategory != "") {
|
||||
currentCategory = "";
|
||||
return;
|
||||
}
|
||||
|
||||
// And parse
|
||||
// check if command
|
||||
const auto EQUALSPLACE = line.find_first_of('=');
|
||||
|
||||
if (EQUALSPLACE == std::string::npos)
|
||||
return;
|
||||
|
||||
const auto COMMAND = line.substr(0, EQUALSPLACE);
|
||||
const auto VALUE = line.substr(EQUALSPLACE + 1);
|
||||
|
||||
if (COMMAND == "exec") {
|
||||
handleRawExec(COMMAND, VALUE);
|
||||
return;
|
||||
} else if (COMMAND == "exec-once") {
|
||||
if (isFirstLaunch) {
|
||||
handleRawExec(COMMAND, VALUE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
configSetValueSafe(currentCategory + (currentCategory == "" ? "" : ":") + COMMAND, VALUE);
|
||||
}
|
||||
|
||||
void CConfigManager::loadConfigLoadVars() {
|
||||
Debug::log(LOG, "Reloading the config!");
|
||||
parseError = ""; // reset the error
|
||||
currentCategory = ""; // reset the category
|
||||
|
||||
const char* const ENVHOME = getenv("HOME");
|
||||
const std::string CONFIGPATH = ENVHOME + (ISDEBUG ? (std::string) "/.config/hypr/hyprlandd.conf" : (std::string) "/.config/hypr/hyprland.conf");
|
||||
|
||||
std::ifstream ifs;
|
||||
ifs.open(CONFIGPATH.c_str());
|
||||
|
||||
if (!ifs.good()) {
|
||||
Debug::log(WARN, "Config reading error. (No file?)");
|
||||
parseError = "The config could not be read. (No file?)";
|
||||
|
||||
ifs.close();
|
||||
return;
|
||||
}
|
||||
|
||||
std::string line = "";
|
||||
int linenum = 1;
|
||||
if (ifs.is_open()) {
|
||||
while (std::getline(ifs, line)) {
|
||||
// Read line by line.
|
||||
try {
|
||||
parseLine(line);
|
||||
} catch (...) {
|
||||
Debug::log(ERR, "Error reading line from config. Line:");
|
||||
Debug::log(NONE, "%s", line.c_str());
|
||||
|
||||
parseError = "Config error at line " + std::to_string(linenum) + ": Line parsing error.";
|
||||
}
|
||||
|
||||
if (parseError != "" && parseError.find("Config error at line") != 0) {
|
||||
parseError = "Config error at line " + std::to_string(linenum) + ": " + parseError;
|
||||
}
|
||||
|
||||
++linenum;
|
||||
}
|
||||
|
||||
ifs.close();
|
||||
}
|
||||
}
|
||||
|
||||
void CConfigManager::tick() {
|
||||
const char* const ENVHOME = getenv("HOME");
|
||||
|
||||
const std::string CONFIGPATH = ENVHOME + (ISDEBUG ? (std::string) "/.config/hypr/hyprd.conf" : (std::string) "/.config/hypr/hypr.conf");
|
||||
|
||||
struct stat fileStat;
|
||||
int err = stat(CONFIGPATH.c_str(), &fileStat);
|
||||
if (err != 0) {
|
||||
Debug::log(WARN, "Error at ticking config, error %i", errno);
|
||||
}
|
||||
|
||||
// check if we need to reload cfg
|
||||
if (fileStat.st_mtime != lastModifyTime) {
|
||||
lastModifyTime = fileStat.st_mtime;
|
||||
|
||||
loadConfigLoadVars();
|
||||
}
|
||||
}
|
||||
|
||||
std::mutex configmtx;
|
||||
SConfigValue CConfigManager::getConfigValueSafe(std::string val) {
|
||||
std::lock_guard<std::mutex> lg(configmtx);
|
||||
|
||||
SConfigValue copy = configValues[val];
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
int CConfigManager::getInt(std::string v) {
|
||||
return getConfigValueSafe(v).intValue;
|
||||
}
|
||||
|
||||
float CConfigManager::getFloat(std::string v) {
|
||||
return getConfigValueSafe(v).floatValue;
|
||||
}
|
||||
|
||||
std::string CConfigManager::getString(std::string v) {
|
||||
return getConfigValueSafe(v).strValue;
|
||||
}
|
43
src/config/ConfigManager.hpp
Normal file
43
src/config/ConfigManager.hpp
Normal file
@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include "../debug/Log.hpp"
|
||||
#include <unordered_map>
|
||||
#include "../defines.hpp"
|
||||
#include <vector>
|
||||
|
||||
struct SConfigValue {
|
||||
int64_t intValue = -1;
|
||||
float floatValue = -1;
|
||||
std::string strValue = "";
|
||||
};
|
||||
|
||||
class CConfigManager {
|
||||
public:
|
||||
CConfigManager();
|
||||
|
||||
void tick();
|
||||
|
||||
int getInt(std::string);
|
||||
float getFloat(std::string);
|
||||
std::string getString(std::string);
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, SConfigValue> configValues;
|
||||
time_t lastModifyTime = 0; // for reloading the config if changed
|
||||
|
||||
std::string currentCategory = ""; // For storing the category of the current item
|
||||
|
||||
std::string parseError = ""; // For storing a parse error to display later
|
||||
|
||||
bool isFirstLaunch = true; // For exec-once
|
||||
|
||||
// internal methods
|
||||
void loadConfigLoadVars();
|
||||
SConfigValue getConfigValueSafe(std::string);
|
||||
void parseLine(std::string&);
|
||||
void configSetValueSafe(const std::string&, const std::string&);
|
||||
void handleRawExec(const std::string&, const std::string&);
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CConfigManager> g_pConfigManager;
|
@ -2,6 +2,7 @@
|
||||
#include "../defines.hpp"
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
void Debug::log(LogLevel level, const char* fmt, ...) {
|
||||
va_list args;
|
||||
@ -37,5 +38,8 @@ void Debug::log(LogLevel level, const char* fmt, ...) {
|
||||
|
||||
ofs.close();
|
||||
|
||||
// log it to the stdout too.
|
||||
std::cout << buf << "\n";
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
@ -8,4 +8,4 @@
|
||||
|
||||
#define RIP(format, ... ) { fprintf(stderr, format "\n", ##__VA_ARGS__); exit(EXIT_FAILURE); }
|
||||
|
||||
#define LISTENER(name) inline wl_listener listener_##name = {.notify = ##name};
|
||||
#define LISTENER(name) void listener_##name(wl_listener*, void*); inline wl_listener listen_##name = { .notify = listener_##name };
|
@ -1,5 +1,70 @@
|
||||
#include "Events.hpp"
|
||||
#include "../input/InputManager.hpp"
|
||||
|
||||
void Events::listener_activate(wl_listener* listener, void* data) {
|
||||
|
||||
}
|
||||
|
||||
void Events::listener_change(wl_listener* listener, void* data) {
|
||||
|
||||
}
|
||||
|
||||
void Events::listener_mouseAxis(wl_listener* listener, void* data) {
|
||||
|
||||
}
|
||||
|
||||
void Events::listener_mouseButton(wl_listener* listener, void* data) {
|
||||
|
||||
}
|
||||
|
||||
void Events::listener_mouseFrame(wl_listener* listener, void* data) {
|
||||
|
||||
}
|
||||
|
||||
void Events::listener_mouseMove(wl_listener* listener, void* data) {
|
||||
g_pInputManager->onMouseMoved((wlr_event_pointer_motion*)data);
|
||||
}
|
||||
|
||||
void Events::listener_mouseMoveAbsolute(wl_listener* listener, void* data) {
|
||||
|
||||
}
|
||||
|
||||
void Events::listener_newInput(wl_listener* listener, void* data) {
|
||||
|
||||
}
|
||||
|
||||
void Events::listener_newKeyboard(wl_listener* listener, void* data) {
|
||||
|
||||
}
|
||||
|
||||
void Events::listener_newLayerSurface(wl_listener* listener, void* data) {
|
||||
|
||||
}
|
||||
|
||||
void Events::listener_newOutput(wl_listener* listener, void* data) {
|
||||
|
||||
}
|
||||
|
||||
void Events::listener_newXDGSurface(wl_listener* listener, void* data) {
|
||||
|
||||
}
|
||||
|
||||
void Events::listener_outputMgrApply(wl_listener* listener, void* data) {
|
||||
|
||||
}
|
||||
|
||||
void Events::listener_outputMgrTest(wl_listener* listener, void* data) {
|
||||
|
||||
}
|
||||
|
||||
void Events::listener_requestMouse(wl_listener* listener, void* data) {
|
||||
|
||||
}
|
||||
|
||||
void Events::listener_requestSetPrimarySel(wl_listener* listener, void* data) {
|
||||
|
||||
}
|
||||
|
||||
void Events::listener_requestSetSel(wl_listener* listener, void* data) {
|
||||
|
||||
}
|
@ -16,4 +16,8 @@ double Vector2D::normalize() {
|
||||
y /= max;
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
Vector2D Vector2D::floor() {
|
||||
return Vector2D((int)x, (int)y);
|
||||
}
|
@ -26,4 +26,15 @@ class Vector2D {
|
||||
Vector2D operator/(float a) {
|
||||
return Vector2D(this->x / a, this->y / a);
|
||||
}
|
||||
|
||||
bool operator==(Vector2D& a) {
|
||||
return a.x == x && a.y == y;
|
||||
}
|
||||
|
||||
bool operator!=(Vector2D& a) {
|
||||
return a.x != x || a.y != y;
|
||||
}
|
||||
|
||||
|
||||
Vector2D floor();
|
||||
};
|
@ -1,5 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
// because C/C++ VS Code intellisense is stupid with includes, we will suppress them here.
|
||||
// This suppresses all "include file not found" errors.
|
||||
#ifdef __INTELLISENSE__
|
||||
#pragma diag_suppress 1696
|
||||
#endif
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <getopt.h>
|
||||
#include <libinput.h>
|
||||
@ -11,6 +17,8 @@
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <wayland-server-core.h>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
|
||||
|
||||
#if true
|
||||
|
17
src/input/InputManager.cpp
Normal file
17
src/input/InputManager.cpp
Normal file
@ -0,0 +1,17 @@
|
||||
#include "InputManager.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
|
||||
void CInputManager::onMouseMoved(wlr_event_pointer_motion* e) {
|
||||
// TODO: sensitivity
|
||||
|
||||
float sensitivity = 0.25f;
|
||||
|
||||
m_vMouseCoords = m_vMouseCoords + Vector2D(e->delta_x * sensitivity, e->delta_y * sensitivity);
|
||||
|
||||
if (m_vMouseCoords.floor() != m_vWLRMouseCoords) {
|
||||
Vector2D delta = m_vMouseCoords - m_vWLRMouseCoords;
|
||||
m_vWLRMouseCoords = m_vMouseCoords.floor();
|
||||
|
||||
wlr_cursor_move(g_pCompositor->m_sWLRCursor, e->device, delta.floor().x, delta.floor().y);
|
||||
}
|
||||
}
|
17
src/input/InputManager.hpp
Normal file
17
src/input/InputManager.hpp
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "../defines.hpp"
|
||||
|
||||
class CInputManager {
|
||||
public:
|
||||
|
||||
void onMouseMoved(wlr_event_pointer_motion*);
|
||||
void onMouseButton(int);
|
||||
|
||||
private:
|
||||
Vector2D m_vMouseCoords = Vector2D(0,0);
|
||||
Vector2D m_vWLRMouseCoords = Vector2D(0,0);
|
||||
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CInputManager> g_pInputManager;
|
@ -1,6 +1,7 @@
|
||||
#include "defines.hpp"
|
||||
#include "debug/Log.hpp"
|
||||
#include "Compositor.hpp"
|
||||
#include "config/ConfigManager.hpp"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user