mirror of
https://github.com/hyprwm/Hypr.git
synced 2024-11-26 06:45:58 +01:00
keybinds added
This commit is contained in:
parent
f6c856ab62
commit
c5a795155d
8 changed files with 161 additions and 20 deletions
|
@ -1,5 +1,7 @@
|
||||||
#include "KeybindManager.hpp"
|
#include "KeybindManager.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
Keybind* KeybindManager::findKeybindByKey(int mod, xcb_keysym_t keysym) {
|
Keybind* KeybindManager::findKeybindByKey(int mod, xcb_keysym_t keysym) {
|
||||||
for(auto& key : KeybindManager::keybinds) {
|
for(auto& key : KeybindManager::keybinds) {
|
||||||
if (keysym == key.getKeysym() && mod == key.getMod()) {
|
if (keysym == key.getKeysym() && mod == key.getMod()) {
|
||||||
|
@ -8,3 +10,83 @@ Keybind* KeybindManager::findKeybindByKey(int mod, xcb_keysym_t keysym) {
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KeybindManager::reloadAllKeybinds() {
|
||||||
|
KeybindManager::keybinds.clear();
|
||||||
|
|
||||||
|
// todo: config
|
||||||
|
KeybindManager::keybinds.push_back(Keybind(MOD_SUPER, 0x72 /* R */, "krunner", &KeybindManager::call));
|
||||||
|
KeybindManager::keybinds.push_back(Keybind(MOD_SUPER, 0x62 /* G */, "google-chrome-stable", &KeybindManager::call));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int KeybindManager::modToMask(MODS mod) {
|
||||||
|
switch(mod) {
|
||||||
|
case MOD_NONE:
|
||||||
|
return 0;
|
||||||
|
case MOD_SUPER:
|
||||||
|
return XCB_MOD_MASK_4;
|
||||||
|
case MOD_SHIFT:
|
||||||
|
return XCB_MOD_MASK_SHIFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
xcb_keysym_t KeybindManager::getKeysymFromKeycode(xcb_keycode_t keycode) {
|
||||||
|
const auto KEYSYMS = xcb_key_symbols_alloc(WindowManager::DisplayConnection);
|
||||||
|
const auto KEYSYM = (!(KEYSYMS) ? 0 : xcb_key_symbols_get_keysym(KEYSYMS, keycode, 0));
|
||||||
|
xcb_key_symbols_free(KEYSYMS);
|
||||||
|
return KEYSYM;
|
||||||
|
}
|
||||||
|
|
||||||
|
xcb_keycode_t KeybindManager::getKeycodeFromKeysym(xcb_keysym_t keysym) {
|
||||||
|
const auto KEYSYMS = xcb_key_symbols_alloc(WindowManager::DisplayConnection);
|
||||||
|
const auto KEYCODE = (!(KEYSYMS) ? NULL : xcb_key_symbols_get_keycode(KEYSYMS, keysym));
|
||||||
|
xcb_key_symbols_free(KEYSYMS);
|
||||||
|
return KEYCODE ? *KEYCODE : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dispatchers
|
||||||
|
|
||||||
|
void KeybindManager::call(std::string args) {
|
||||||
|
if (fork() == 0) {
|
||||||
|
setsid();
|
||||||
|
if (fork() != 0) {
|
||||||
|
_exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fix the args
|
||||||
|
std::string command = args.substr(0, args.find_first_of(" "));
|
||||||
|
|
||||||
|
int ARGNO = std::count(args.begin(), args.end(), ' ');
|
||||||
|
if(ARGNO > 0)
|
||||||
|
ARGNO -= 1;
|
||||||
|
|
||||||
|
if(ARGNO) {
|
||||||
|
char* argsarr[ARGNO];
|
||||||
|
|
||||||
|
for (int i = 0; i < ARGNO; ++i) {
|
||||||
|
args = args.substr(args.find_first_of(' ') + 1);
|
||||||
|
argsarr[i] = (char*)args.substr(0, args.find_first_of(' ')).c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug::log(LOG, "Executing " + command + " with " + std::to_string(ARGNO) + " args:");
|
||||||
|
for (int i = 0; i < ARGNO; ++i) {
|
||||||
|
Debug::log(NONE, argsarr[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
execvp((char*)command.c_str(), (char**)argsarr);
|
||||||
|
} else {
|
||||||
|
char* argsarr[1];
|
||||||
|
argsarr[0] = "";
|
||||||
|
|
||||||
|
Debug::log(LOG, "Executing " + command + " with 0 args.");
|
||||||
|
|
||||||
|
execvp((char*)command.c_str(), (char**)argsarr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_exit(0);
|
||||||
|
}
|
||||||
|
wait(NULL);
|
||||||
|
}
|
|
@ -1,11 +1,19 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include "utilities/Keybind.hpp"
|
#include "utilities/Keybind.hpp"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "windowManager.hpp"
|
||||||
|
|
||||||
namespace KeybindManager {
|
namespace KeybindManager {
|
||||||
std::vector<Keybind> keybinds;
|
inline std::vector<Keybind> keybinds;
|
||||||
|
|
||||||
|
unsigned int modToMask(MODS);
|
||||||
// -- Methods -- //
|
|
||||||
|
|
||||||
Keybind* findKeybindByKey(int mod, xcb_keysym_t keysym);
|
Keybind* findKeybindByKey(int mod, xcb_keysym_t keysym);
|
||||||
|
void reloadAllKeybinds();
|
||||||
|
xcb_keysym_t getKeysymFromKeycode(xcb_keycode_t keycode);
|
||||||
|
xcb_keycode_t getKeycodeFromKeysym(xcb_keysym_t keysym);
|
||||||
|
|
||||||
|
// Dispatchers
|
||||||
|
void call(std::string args);
|
||||||
};
|
};
|
|
@ -60,3 +60,15 @@ void Events::eventMapWindow(xcb_generic_event_t* event) {
|
||||||
|
|
||||||
WindowManager::setFocusedWindow(E->window);
|
WindowManager::setFocusedWindow(E->window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Events::eventKeyPress(xcb_generic_event_t* event) {
|
||||||
|
const auto E = reinterpret_cast<xcb_key_press_event_t*>(event);
|
||||||
|
|
||||||
|
const auto KEYSYM = KeybindManager::getKeysymFromKeycode(E->detail);
|
||||||
|
|
||||||
|
for (auto& keybind : KeybindManager::keybinds) {
|
||||||
|
if (keybind.getKeysym() != 0 && keybind.getKeysym() == KEYSYM && KeybindManager::modToMask(keybind.getMod()) == E->state) {
|
||||||
|
keybind.getDispatcher()(keybind.getCommand());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,4 +6,5 @@ namespace Events {
|
||||||
EVENT(Leave);
|
EVENT(Leave);
|
||||||
EVENT(Destroy);
|
EVENT(Destroy);
|
||||||
EVENT(MapWindow);
|
EVENT(MapWindow);
|
||||||
|
EVENT(KeyPress);
|
||||||
};
|
};
|
10
src/utilities/Keybind.cpp
Normal file
10
src/utilities/Keybind.cpp
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#include "Keybind.hpp"
|
||||||
|
|
||||||
|
Keybind::Keybind(MODS mod, xcb_keysym_t keysym, std::string comm, Dispatcher disp) {
|
||||||
|
this->m_iMod = mod;
|
||||||
|
this->m_Keysym = keysym;
|
||||||
|
this->m_szCommand = comm;
|
||||||
|
this->m_pDispatcher = disp;
|
||||||
|
}
|
||||||
|
|
||||||
|
Keybind::~Keybind() { }
|
|
@ -1,9 +1,22 @@
|
||||||
|
#pragma once
|
||||||
#include "../defines.hpp"
|
#include "../defines.hpp"
|
||||||
|
|
||||||
class Keybind {
|
typedef void (*Dispatcher)(std::string);
|
||||||
EXPOSED_MEMBER(Mod, int, i);
|
|
||||||
EXPOSED_MEMBER(Keysym, xcb_keysym_t,);
|
enum MODS {
|
||||||
EXPOSED_MEMBER(Command, std::string, sz);
|
MOD_NONE = 0,
|
||||||
EXPOSED_MEMBER(Dispatcher, void*, p);
|
MOD_SUPER,
|
||||||
|
MOD_SHIFT
|
||||||
|
};
|
||||||
|
|
||||||
|
class Keybind {
|
||||||
|
public:
|
||||||
|
Keybind(MODS, xcb_keysym_t, std::string, Dispatcher);
|
||||||
|
~Keybind();
|
||||||
|
|
||||||
|
EXPOSED_MEMBER(Mod, MODS, i);
|
||||||
|
EXPOSED_MEMBER(Keysym, xcb_keysym_t,);
|
||||||
|
EXPOSED_MEMBER(Command, std::string, sz);
|
||||||
|
EXPOSED_MEMBER(Dispatcher, Dispatcher, p);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,23 +2,31 @@
|
||||||
#include "./events/events.hpp"
|
#include "./events/events.hpp"
|
||||||
|
|
||||||
void WindowManager::setupManager() {
|
void WindowManager::setupManager() {
|
||||||
|
KeybindManager::reloadAllKeybinds();
|
||||||
|
|
||||||
WindowManager::Values[0] = XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_PROPERTY_CHANGE;
|
WindowManager::Values[0] = XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_PROPERTY_CHANGE;
|
||||||
xcb_change_window_attributes_checked(WindowManager::DisplayConnection, WindowManager::Screen->root,
|
xcb_change_window_attributes_checked(WindowManager::DisplayConnection, WindowManager::Screen->root,
|
||||||
XCB_CW_EVENT_MASK, WindowManager::Values);
|
XCB_CW_EVENT_MASK, WindowManager::Values);
|
||||||
xcb_ungrab_key(WindowManager::DisplayConnection, XCB_GRAB_ANY, WindowManager::Screen->root, XCB_MOD_MASK_ANY);
|
xcb_ungrab_key(WindowManager::DisplayConnection, XCB_GRAB_ANY, WindowManager::Screen->root, XCB_MOD_MASK_ANY);
|
||||||
/*int key_table_size = sizeof(keys) / sizeof(*keys);
|
|
||||||
for (int i = 0; i < key_table_size; ++i) {
|
for (auto& keybind : KeybindManager::keybinds) {
|
||||||
xcb_keycode_t *keycode = xcb_get_keycodes(keys[i].keysym);
|
xcb_grab_key(WindowManager::DisplayConnection, 1, WindowManager::Screen->root,
|
||||||
if (keycode != NULL) {
|
KeybindManager::modToMask(keybind.getMod()), KeybindManager::getKeycodeFromKeysym(keybind.getKeysym()),
|
||||||
xcb_grab_key(WindowManager::DisplayConnection, 1, WindowManager::Screen->root, keys[i].mod, *keycode,
|
|
||||||
XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
|
XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
xcb_flush(WindowManager::DisplayConnection);
|
xcb_flush(WindowManager::DisplayConnection);
|
||||||
xcb_grab_button(WindowManager::DisplayConnection, 0, WindowManager::Screen->root, XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE, XCB_GRAB_MODE_ASYNC,
|
|
||||||
XCB_GRAB_MODE_ASYNC, WindowManager::Screen->root, XCB_NONE, 1, MOD1);
|
xcb_grab_button(WindowManager::DisplayConnection, 0,
|
||||||
xcb_grab_button(WindowManager::DisplayConnection, 0, WindowManager::Screen->root, XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE, XCB_GRAB_MODE_ASYNC,
|
WindowManager::Screen->root, XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE,
|
||||||
XCB_GRAB_MODE_ASYNC, WindowManager::Screen->root, XCB_NONE, 3, MOD1);*/
|
XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, WindowManager::Screen->root, XCB_NONE,
|
||||||
|
1, KeybindManager::modToMask(MOD_SUPER));
|
||||||
|
|
||||||
|
xcb_grab_button(WindowManager::DisplayConnection, 0,
|
||||||
|
WindowManager::Screen->root, XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE,
|
||||||
|
XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, WindowManager::Screen->root, XCB_NONE,
|
||||||
|
3, KeybindManager::modToMask(MOD_SUPER));
|
||||||
|
|
||||||
xcb_flush(WindowManager::DisplayConnection);
|
xcb_flush(WindowManager::DisplayConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +34,7 @@ bool WindowManager::handleEvent() {
|
||||||
if (xcb_connection_has_error(WindowManager::DisplayConnection))
|
if (xcb_connection_has_error(WindowManager::DisplayConnection))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
xcb_generic_event_t* ev = xcb_wait_for_event(WindowManager::DisplayConnection);
|
const auto ev = xcb_wait_for_event(WindowManager::DisplayConnection);
|
||||||
if (ev != NULL) {
|
if (ev != NULL) {
|
||||||
switch (ev->response_type & ~0x80) {
|
switch (ev->response_type & ~0x80) {
|
||||||
case XCB_ENTER_NOTIFY:
|
case XCB_ENTER_NOTIFY:
|
||||||
|
@ -45,6 +53,11 @@ bool WindowManager::handleEvent() {
|
||||||
Events::eventMapWindow(ev);
|
Events::eventMapWindow(ev);
|
||||||
Debug::log(LOG, "Event dispatched MAP");
|
Debug::log(LOG, "Event dispatched MAP");
|
||||||
break;
|
break;
|
||||||
|
case XCB_KEY_PRESS:
|
||||||
|
case XCB_BUTTON_PRESS:
|
||||||
|
Events::eventKeyPress(ev);
|
||||||
|
Debug::log(LOG, "Event dispatched KEYPRESS");
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Debug::log(WARN, "Unknown event: " + std::to_string(ev->response_type & ~0x80));
|
Debug::log(WARN, "Unknown event: " + std::to_string(ev->response_type & ~0x80));
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "KeybindManager.hpp"
|
||||||
|
|
||||||
|
|
||||||
// temp config values
|
// temp config values
|
||||||
#define BORDERSIZE 1
|
#define BORDERSIZE 1
|
||||||
|
|
Loading…
Reference in a new issue