summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBossCode45 <human.cyborg42@gmail.com>2023-08-15 21:27:51 +1200
committerBossCode45 <human.cyborg42@gmail.com>2023-08-15 21:27:51 +1200
commitea569d9c9c61eb26f7d325b41d8ac839dc470eec (patch)
tree33c15ab71f81e6647d904f3133b16afd87c836ed
parent37a2725da41e363fcdca12d0374b192cd03905d0 (diff)
downloadYATwm-ea569d9c9c61eb26f7d325b41d8ac839dc470eec.tar.gz
YATwm-ea569d9c9c61eb26f7d325b41d8ac839dc470eec.zip
feat: Made the bind modes work
Numlock still seems to mess with keybindings. Also switched from storing keybinds with KeySym to KeyCode
-rw-r--r--commands.cpp10
-rw-r--r--keybinds.cpp86
-rw-r--r--keybinds.h8
-rw-r--r--util.cpp8
-rw-r--r--util.h2
5 files changed, 98 insertions, 16 deletions
diff --git a/commands.cpp b/commands.cpp
index af523ad..54fe891 100644
--- a/commands.cpp
+++ b/commands.cpp
@@ -1,5 +1,6 @@
#include "commands.h"
#include "error.h"
+#include "util.h"
#include <cctype>
#include <iostream>
@@ -11,7 +12,7 @@
#include <regex>
#include <cstring>
-using std::cout, std::endl, std::string, std::vector, std::tolower;
+using std::cout, std::endl, std::string, std::vector;
const void CommandsModule::echo(const CommandArg* argv)
{
@@ -135,13 +136,6 @@ vector<string> CommandsModule::splitCommand(string command)
return v;
}
-string lowercase(string s)
-{
- string s2 = s;
- std::transform(s2.begin(), s2.end(), s2.begin(), [](unsigned char c){ return std::tolower(c); });
- return s2;
-}
-
CommandArg* CommandsModule::getCommandArgs(vector<string>& split, const CommandArgType* argTypes, const int argc)
{
CommandArg* args = new CommandArg[argc];
diff --git a/keybinds.cpp b/keybinds.cpp
index b51bf6e..88a43fe 100644
--- a/keybinds.cpp
+++ b/keybinds.cpp
@@ -1,5 +1,6 @@
#include <X11/X.h>
#include <X11/Xlib.h>
+#include <cctype>
#include <iostream>
#include <sstream>
#include <utility>
@@ -30,6 +31,14 @@ KeybindsModule::KeybindsModule(CommandsModule& commandsModule, Config& cfg, Glob
{
commandsModule.addCommand("bind", &KeybindsModule::bind, 2, {STR, STR_REST}, this);
commandsModule.addCommand("quitkey", &KeybindsModule::quitKey, 1, {STR}, this);
+ commandsModule.addCommand("bindmode", &KeybindsModule::bindMode, 1, {STR}, this);
+
+ bindModes = {
+ {"normal", &KeybindsModule::normalBindMode},
+ {"emacs", &KeybindsModule::emacsBindMode}
+ };
+ bindFunc = &KeybindsModule::normalBindMode;
+
this->updateMousePos = updateMousePos;
keyMaps.insert({0, std::map<Keybind, KeyFunction>()});
}
@@ -47,8 +56,7 @@ void KeybindsModule::changeMap(int newMapID)
for(std::pair<Keybind, KeyFunction> pair : getKeymap(currentMapID))
{
Keybind bind = pair.first;
- KeyCode c = XKeysymToKeycode(globals.dpy, bind.key);
- XGrabKey(globals.dpy, c, bind.modifiers, globals.root, false, GrabModeAsync, GrabModeAsync);
+ XGrabKey(globals.dpy, bind.key, bind.modifiers, globals.root, false, GrabModeAsync, GrabModeAsync);
}
}
else
@@ -66,7 +74,7 @@ const void KeybindsModule::handleKeypress(XKeyEvent e)
updateMousePos();
const unsigned int masks = ShiftMask | ControlMask | Mod1Mask | Mod4Mask;
- Keybind k = {XLookupKeysym(&e, 0), e.state & masks};
+ Keybind k = {(KeyCode)e.keycode, e.state & masks};
if(k == exitBind)
{
changeMap(0);
@@ -91,7 +99,28 @@ const void KeybindsModule::handleKeypress(XKeyEvent e)
}
}
-Keybind KeybindsModule::getKeybind(string bindString)
+bool isUpper(const std::string& s) {
+ return std::all_of(s.begin(), s.end(), [](unsigned char c){ return std::isupper(c); });
+}
+
+const void KeybindsModule::bindMode(const CommandArg* argv)
+{
+ if(bindModes.count(argv[0].str) < 1)
+ {
+ throw Err(CFG_ERR_KEYBIND, "Bind mode: " + string(argv[0].str) + " does not exist");
+ }
+ else
+ {
+ bindFunc = bindModes.find(argv[0].str)->second;
+ }
+}
+
+Keybind KeybindsModule::getKeybind(std::string bindString)
+{
+ return (this->*bindFunc)(bindString);
+}
+
+const Keybind KeybindsModule::normalBindMode(string bindString)
{
std::vector<string> keys = split(bindString, '+');
Keybind bind;
@@ -116,15 +145,58 @@ Keybind KeybindsModule::getKeybind(string bindString)
}
else
{
+ if(isUpper(key))
+ {
+ bind.modifiers |= ShiftMask;
+ }
+ KeySym s = XStringToKeysym(key.c_str());
+ if(s == NoSymbol)
+ {
+ throw Err(CFG_ERR_KEYBIND, "Keybind '" + bindString + "' is invalid!");
+ }
+ bind.key = XKeysymToKeycode(globals.dpy, s);
+ }
+ }
+ if(!bind.key)
+ throw Err(CFG_ERR_KEYBIND, "Keybind '" + bindString + "' is invalid!");
+ return bind;
+}
+
+const Keybind KeybindsModule::emacsBindMode(string bindString)
+{
+ std::vector<string> keys = split(bindString, '-');
+ Keybind bind;
+ bind.modifiers = 0;
+ for(string key : keys)
+ {
+ if(key == "s")
+ {
+ bind.modifiers |= Mod4Mask >> 3 * cfg.swapSuperAlt;
+ }
+ else if(key == "M")
+ {
+ bind.modifiers |= Mod1Mask << 3 * cfg.swapSuperAlt;
+ }
+ else if(key == "C")
+ {
+ bind.modifiers |= ControlMask;
+ }
+ else
+ {
+ if(isUpper(key))
+ {
+ bind.modifiers |= ShiftMask;
+ }
KeySym s = XStringToKeysym(key.c_str());
- bind.key = s;
- if(bind.key == NoSymbol)
+ if(s == NoSymbol)
{
throw Err(CFG_ERR_KEYBIND, "Keybind '" + bindString + "' is invalid!");
- continue;
}
+ bind.key = XKeysymToKeycode(globals.dpy, s);
}
}
+ if(!bind.key)
+ throw Err(CFG_ERR_KEYBIND, "Keybind '" + bindString + "' is invalid!");
return bind;
}
diff --git a/keybinds.h b/keybinds.h
index 5c220c2..a742240 100644
--- a/keybinds.h
+++ b/keybinds.h
@@ -13,7 +13,7 @@
#include "util.h"
struct Keybind {
- KeySym key;
+ KeyCode key;
unsigned int modifiers;
bool operator<(const Keybind &o) const;
bool operator==(const Keybind &o) const;
@@ -28,6 +28,7 @@ struct KeyFunction
#define getKeymap(X) \
keyMaps.find(X)->second
+
class KeybindsModule
{
public:
@@ -35,12 +36,17 @@ public:
~KeybindsModule() = default;
const void bind(const CommandArg* argv);
const void quitKey(const CommandArg* argv);
+ const void bindMode(const CommandArg* argv);
const void handleKeypress(XKeyEvent e);
const void clearKeybinds();
private:
Keybind getKeybind(std::string bindString);
void changeMap(int newMapID);
std::map<int, std::map<Keybind, KeyFunction>> keyMaps;
+ const Keybind emacsBindMode(std::string bindString);
+ const Keybind normalBindMode(std::string bindString);
+ std::map<std::string, const Keybind(KeybindsModule::*)(std::string bindString)> bindModes;
+ const Keybind(KeybindsModule::* bindFunc)(std::string bindString);
// Modifier keys to ignore when canceling a keymap
KeyCode ignoredKeys[8] = {50, 37, 133, 64, 62, 105, 134, 108};
int currentMapID = 0;
diff --git a/util.cpp b/util.cpp
index 7fe5641..58116d0 100644
--- a/util.cpp
+++ b/util.cpp
@@ -1,6 +1,7 @@
#include "util.h"
#include <sstream>
+#include <algorithm>
using std::string;
@@ -22,3 +23,10 @@ string getEventName(int e)
{
return evNames[e];
}
+
+string lowercase(string s)
+{
+ string s2 = s;
+ std::transform(s2.begin(), s2.end(), s2.begin(), [](unsigned char c){ return std::tolower(c); });
+ return s2;
+}
diff --git a/util.h b/util.h
index d29d596..66ecf76 100644
--- a/util.h
+++ b/util.h
@@ -10,6 +10,8 @@ std::string getEventName(int e);
std::vector<std::string> split (const std::string &s, char delim);
+std::string lowercase(std::string s);
+
struct Globals {
Display*& dpy;