summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBossCode45 <human.cyborg42@gmail.com>2023-05-26 21:46:19 +1200
committerBossCode45 <human.cyborg42@gmail.com>2023-05-26 21:46:19 +1200
commit27137ec9d29c36df8117869773203b243849896c (patch)
tree8f457bcc0862ecd176f5fc748b06f66e46082a2e
parentda3b5b2131d2b4ff5cb127e92090fca568376835 (diff)
downloadYATwm-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.cpp2
-rw-r--r--commands.h2
-rw-r--r--config.cpp11
-rw-r--r--config.h4
-rw-r--r--error.h7
-rw-r--r--keybinds.cpp66
-rw-r--r--keybinds.h34
-rw-r--r--main.cpp64
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 = "";
diff --git a/commands.h b/commands.h
index f9a0999..2e364ac 100644
--- a/commands.h
+++ b/commands.h
@@ -18,7 +18,7 @@ enum CommandArgType
{
STR,
NUM,
- DIR,
+ MOVDIR,
STR_REST,
NUM_ARR_REST
};
diff --git a/config.cpp b/config.cpp
index 101af24..6d8215c 100644
--- a/config.cpp
+++ b/config.cpp
@@ -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()
diff --git a/config.h b/config.h
index 3956492..a31c1df 100644
--- a/config.h
+++ b/config.h
@@ -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;
diff --git a/error.h b/error.h
index 630fc7f..f0a67a5 100644
--- a/error.h
+++ b/error.h
@@ -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)
diff --git a/keybinds.h b/keybinds.h
index d26b7a1..c0cc955 100644
--- a/keybinds.h
+++ b/keybinds.h
@@ -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;
};
diff --git a/main.cpp b/main.cpp
index 1433e70..e4a4bcc 100644
--- a/main.cpp
+++ b/main.cpp
@@ -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);