diff options
| author | BossCode45 <human.cyborg42@gmail.com> | 2023-05-26 21:46:19 +1200 |
|---|---|---|
| committer | BossCode45 <human.cyborg42@gmail.com> | 2023-05-26 21:46:19 +1200 |
| commit | 27137ec9d29c36df8117869773203b243849896c (patch) | |
| tree | 8f457bcc0862ecd176f5fc748b06f66e46082a2e | |
| parent | da3b5b2131d2b4ff5cb127e92090fca568376835 (diff) | |
| download | YATwm-27137ec9d29c36df8117869773203b243849896c.tar.gz YATwm-27137ec9d29c36df8117869773203b243849896c.zip | |
feat: Made keybinds work (I hope)
Note: the config file reloading keybinds isn't quite working, though, need to ungrab the keys
| -rw-r--r-- | commands.cpp | 2 | ||||
| -rw-r--r-- | commands.h | 2 | ||||
| -rw-r--r-- | config.cpp | 11 | ||||
| -rw-r--r-- | config.h | 4 | ||||
| -rw-r--r-- | error.h | 7 | ||||
| -rw-r--r-- | keybinds.cpp | 66 | ||||
| -rw-r--r-- | keybinds.h | 34 | ||||
| -rw-r--r-- | main.cpp | 64 |
8 files changed, 118 insertions, 72 deletions
diff --git a/commands.cpp b/commands.cpp index 3e78463..322d160 100644 --- a/commands.cpp +++ b/commands.cpp @@ -104,7 +104,7 @@ CommandArg* CommandsModule::getCommandArgs(vector<string>& split, const CommandA { case STR: args[i-1].str = (char*)split[i].c_str(); break; case NUM: args[i-1].num = std::stoi(split[i]); break; - case DIR: args[i-1].dir = LEFT; break; + case MOVDIR: args[i-1].dir = LEFT; break; case STR_REST: { string rest = ""; @@ -18,7 +18,7 @@ enum CommandArgType { STR, NUM, - DIR, + MOVDIR, STR_REST, NUM_ARR_REST }; @@ -1,5 +1,6 @@ #include "config.h" #include "commands.h" +#include "error.h" #include <X11/Xlib.h> @@ -66,6 +67,7 @@ const void Config::focChange(const CommandArg* argv) } const void Config::reload(const CommandArg* argv) { + // Note: this is kinda broken cos it doesn't ungrab keys, i'll do that later. cout << "Reloading config" << endl; reloadFile(); } @@ -116,14 +118,14 @@ Config::Config(CommandsModule& commandsModule) commandsModule.addCommand("addworkspace", &Config::addWorkspaceCmd, 2, addWorkspaceArgs, this); } -void Config::reloadFile() +Err Config::reloadFile() { if(!loaded) - return; - loadFromFile(file); + return {CFG_ERR_NON_FATAL, "Not loaded config yet"}; + return loadFromFile(file); } -void Config::loadFromFile(string path) +Err Config::loadFromFile(string path) { file = path; //Set defaults @@ -152,6 +154,7 @@ void Config::loadFromFile(string path) line++; } loaded = true; + return {NOERR, ""}; } Config::~Config() @@ -23,8 +23,8 @@ class Config ~Config(); void free(); - void loadFromFile(std::string path); - void reloadFile(); + Err loadFromFile(std::string path); + Err reloadFile(); // Startup std::string* startupBash; int startupBashc; @@ -17,5 +17,10 @@ typedef unsigned int ErrCode; struct Err { ErrCode code; - std::string errorMessage; + std::string message; + Err(ErrCode code, std::string message) + { + this->code = code; + this->message = message; + } }; diff --git a/keybinds.cpp b/keybinds.cpp index 57f7003..ee6892a 100644 --- a/keybinds.cpp +++ b/keybinds.cpp @@ -1,21 +1,41 @@ +#include <X11/X.h> +#include <X11/Xlib.h> #include <iostream> +#include <sstream> +#include <vector> +#include "error.h" #include "keybinds.h" +#include "util.h" -using std::string, std::cin, std::cout, std::endl; +using std::string, std::cout, std::endl; -KeybindsModule::KeybindsModule(CommandsModule& commandsModule) +KeybindsModule::KeybindsModule(CommandsModule& commandsModule, Display* dpy, Window root) :commandsModule(commandsModule) { + this->dpy = dpy; + this->root = root; CommandArgType* bindArgs = new CommandArgType[2]; bindArgs[0] = STR; bindArgs[1] = STR_REST; commandsModule.addCommand("bind", &KeybindsModule::bind, 2, bindArgs, this); commandsModule.addCommand("exit", &KeybindsModule::exit, 0, {}, this); - commandsModule.addCommand("readBinds", &KeybindsModule::readBinds, 0, {}, this); exitNow = false; } +const void KeybindsModule::handleKeypress(XKeyEvent e) +{ + if(e.same_screen!=1) return; + //updateMousePos(); + for(Keybind bind : binds) + { + if(bind.modifiers == e.state && bind.key == e.keycode) + { + commandsModule.runCommand(bind.command); + } + } +} + const void KeybindsModule::bind(const CommandArg* argv) { Err e = commandsModule.checkCommand(argv[1].str); @@ -24,18 +44,38 @@ const void KeybindsModule::bind(const CommandArg* argv) e.message = "Binding fail - " + e.message; throw e; } - binds.insert({argv[0].str, argv[1].str}); -} -const void KeybindsModule::readBinds(const CommandArg* argv) -{ - cout << "Reading binds" << endl; - while(exitNow == false) + std::vector<string> keys = split(argv[0].str, '+'); + Keybind bind; + for(string key : keys) { - string key; - cout << "> "; - std::getline(std::cin, key); - commandsModule.runCommand(binds.find(key)->second); + if(key == "mod") + { + bind.modifiers |= Mod1Mask; + } + else if(key == "alt") + { + bind.modifiers |= Mod1Mask; + } + else if(key == "shift") + { + bind.modifiers |= ShiftMask; + } + else if(key == "control") + { + bind.modifiers |= ControlMask; + } + else + { + bind.key = XKeysymToKeycode(dpy, XStringToKeysym(key.c_str())); + if(bind.key == NoSymbol) + { + throw Err(CFG_ERR_KEYBIND, "Keybind '" + string(argv[0].str) + "' is invalid!"); + continue; + } + } } + XGrabKey(dpy, bind.key, bind.modifiers, root, false, GrabModeAsync, GrabModeAsync); + binds.push_back(bind); } const void KeybindsModule::exit(const CommandArg* argv) @@ -1,19 +1,31 @@ #pragma once -#include <unordered_map> +#include <X11/X.h> +#include <X11/Xlib.h> +#include <map> #include <string> +#include <X11/keysym.h> +#include <vector> #include "commands.h" +struct Keybind { + KeyCode key; + unsigned int modifiers; + std::string command; +}; + class KeybindsModule { - public: - KeybindsModule(CommandsModule& commandsModule); - ~KeybindsModule() = default; - const void bind(const CommandArg* argv); - const void readBinds(const CommandArg* argv); - const void exit(const CommandArg* argv); - private: - std::unordered_map<std::string, std::string> binds; - bool exitNow; - CommandsModule& commandsModule; +public: + KeybindsModule(CommandsModule& commandsModule, Display* dpy, Window root); + ~KeybindsModule() = default; + const void bind(const CommandArg* argv); + const void exit(const CommandArg* argv); + const void handleKeypress(XKeyEvent e); +private: + std::vector<Keybind> binds; + bool exitNow; + CommandsModule& commandsModule; + Display* dpy; + Window root; }; @@ -26,6 +26,7 @@ #include <fcntl.h> #include "commands.h" +#include "keybinds.h" #include "structs.h" #include "config.h" #include "util.h" @@ -43,11 +44,13 @@ std::ofstream yatlog; #define log(x) yatlog << x << std::endl +Display* dpy; +Window root; + CommandsModule commandsModule; Config cfg(commandsModule); +KeybindsModule keybindsModule(commandsModule, dpy, root); -Display* dpy; -Window root; int sW, sH; int bH; TileDir nextDir = horizontal; @@ -81,7 +84,6 @@ void updateMousePos(); void focusRoot(int root); void handleConfigErrs(Err cfgErr); -void keyPress(XKeyEvent e); void configureRequest(XConfigureRequestEvent e); void mapRequest(XMapRequestEvent e); void destroyNotify(XDestroyWindowEvent e); @@ -164,11 +166,11 @@ void handleConfigErrs(Err cfgErr) { if(cfgErr.code!=NOERR) { - if(cfgErr.code == ERR_CFG_FATAL) + if(cfgErr.code == CFG_ERR_FATAL) { - log("YATwm fatal error (Code " << cfgErr.code << ")\n" << cfgErr.errorMessage); + log("YATwm fatal error (Code " << cfgErr.code << ")\n" << cfgErr.message); std::string title = "YATwm fatal config error (Code " + std::to_string(cfgErr.code) + ")"; - std::string body = cfgErr.errorMessage; + std::string body = cfgErr.message; NotifyNotification* n = notify_notification_new(title.c_str(), body.c_str(), 0); @@ -180,7 +182,7 @@ void handleConfigErrs(Err cfgErr) } else { - log("YATwm non fatal error (Code " << cfgErr.code << ")\n" << cfgErr.errorMessage); + log("YATwm non fatal error (Code " << cfgErr.code << ")\n" << cfgErr.message); std::string title = "YATwm non fatal config error (Code " + std::to_string(cfgErr.code) + ")"; std::string body = "Check logs for more information"; NotifyNotification* n = notify_notification_new(title.c_str(), @@ -254,11 +256,12 @@ const void kill(const CommandArg* argv) XKillClient(dpy, w); } } -const void changeWS(const CommandArg* argv) +// Took this out as it is used commonly +void cWS(int newWS) { int prevWS = currWS; - currWS = argv[0].num; + currWS = newWS; if(prevWS == currWS) return; untileRoots(); @@ -267,17 +270,17 @@ const void changeWS(const CommandArg* argv) for(int i = 0; i < cfg.maxMonitors; i++) { - if(nscreens > cfg.screenPreferences[argv[0].num - 1][i]) + if(nscreens > cfg.screenPreferences[newWS - 1][i]) { - int screen = cfg.screenPreferences[argv[0].num - 1][i]; + int screen = cfg.screenPreferences[newWS - 1][i]; //log("Found screen (screen " << screenPreferences[arg.num - 1][i] << ")"); - prevWS = focusedWorkspaces[cfg.screenPreferences[argv[0].num - 1][i]]; + prevWS = focusedWorkspaces[cfg.screenPreferences[newWS - 1][i]]; //log("Changed prevWS"); - focusedWorkspaces[cfg.screenPreferences[argv[0].num - 1][i]] = argv[0].num; + focusedWorkspaces[cfg.screenPreferences[newWS - 1][i]] = newWS; //log("Changed focusedWorkspaces"); - if(focusedScreen != cfg.screenPreferences[argv[0].num - 1][i]) + if(focusedScreen != cfg.screenPreferences[newWS - 1][i]) { - focusedScreen = cfg.screenPreferences[argv[0].num - 1][i]; + focusedScreen = cfg.screenPreferences[newWS - 1][i]; XWarpPointer(dpy, root, root, 0, 0, 0, 0, screens[screen].x + screens[screen].w/2, screens[screen].y + screens[screen].h/2); } //log("Changed focusedScreen"); @@ -301,6 +304,10 @@ const void changeWS(const CommandArg* argv) //EWMH setCurrentDesktop(currWS); } +const void changeWS(const CommandArg* argv) +{ + cWS(argv[0].num); +} const void wToWS(const CommandArg* argv) { Window focusedWindow; @@ -513,7 +520,7 @@ const void reload(const CommandArg* argv) detectScreens(); //Load config again - Err cfgErr = cfg.reload(); + Err cfgErr = cfg.reloadFile(); //Error check handleConfigErrs(cfgErr); @@ -546,22 +553,6 @@ const void nextMonitor(const CommandArg* argv) focusRoot(focusedWorkspaces[focusedScreen]); } -void keyPress(XKeyEvent e) -{ - if(e.same_screen!=1) return; - updateMousePos(); - //cout << "Keypress recieved\n"; - KeySym keysym = XLookupKeysym(&e, 0); - //cout << "\t" << XKeysymToString(keysym) << " super: " << ((e.state & Mod4Mask) == Mod4Mask) << " alt: " << ((e.state & Mod1Mask) == Mod1Mask) << " shift: " << ((e.state & ShiftMask) == ShiftMask) << std::endl; - for(int i = 0; i < cfg.bindsc; i++) - { - if(cfg.binds[i].keysym == keysym && (e.state & cfg.binds[i].modifiers) == cfg.binds[i].modifiers) - { - cfg.binds[i].func(cfg.binds[i].args); - } - } -} - void configureRequest(XConfigureRequestEvent e) { XWindowChanges changes; @@ -811,7 +802,7 @@ void clientMessage(XClientMessageEvent e) log("Client message: " << name); if(e.message_type == XInternAtom(dpy, "_NET_CURRENT_DESKTOP", false)) { - changeWS({.num = (int)((long)e.data.l[0] + 1)}); + cWS(e.data.l[0] + 1); /* //Change desktop int nextWS = (long)e.data.l[0] + 1; @@ -966,11 +957,6 @@ int main(int argc, char** argv) XSetErrorHandler(OnXError); XSelectInput(dpy, root, SubstructureRedirectMask | SubstructureNotifyMask | KeyPressMask | EnterWindowMask); - for(int i = 0; i < cfg.bindsc; i++) - { - XGrabKey(dpy, XKeysymToKeycode(dpy, cfg.binds[i].keysym), cfg.binds[i].modifiers, root, false, GrabModeAsync, GrabModeAsync); - //log("Grabbing " << XKeysymToString(cfg.binds[i].keysym)); - } XDefineCursor(dpy, root, XCreateFontCursor(dpy, XC_top_left_arrow)); //EWMH initEWMH(&dpy, &root, cfg.numWS,cfg. workspaceNames); @@ -1004,7 +990,7 @@ int main(int argc, char** argv) switch(e.type) { case KeyPress: - keyPress(e.xkey); + keybindsModule.keyPress(e.xkey); break; case ConfigureRequest: configureRequest(e.xconfigurerequest); |
