From 6d305f396d9e7a64599407c546ac72de69670783 Mon Sep 17 00:00:00 2001 From: BossCode45 Date: Sun, 11 May 2025 18:17:27 +1200 Subject: feat: A few minor bug fixes Fixed keybinding errors Hopefully fixed multiple monitor status bar workspaces Refactored EWMH module --- YATwm.nix | 6 +-- compile_commands.json | 132 +++++++++++++++++++++++++------------------------- config | 10 +++- flake.nix | 2 +- makefile | 4 +- src/IPC.cpp | 17 ++++--- src/IPC.h | 8 +-- src/commands.cpp | 19 ++++++-- src/debug.h | 10 ++++ src/ewmh.cpp | 113 +++++++++++++++++++++++++----------------- src/ewmh.h | 27 ++++++++--- src/keybinds.cpp | 43 ++++++++++------ src/main.cpp | 82 ++++++++++++++++++------------- test | 2 +- 14 files changed, 284 insertions(+), 191 deletions(-) create mode 100644 src/debug.h diff --git a/YATwm.nix b/YATwm.nix index be7cd2d..a2a6878 100644 --- a/YATwm.nix +++ b/YATwm.nix @@ -11,12 +11,12 @@ stdenv.mkDerivation { pname = "YATwm"; - version = "0.0.1"; + version = "0.0.2"; src = fetchgit { url = "https://git.tehbox.org/cgit/boss/YATwm.git/"; - rev = "v0.0.1"; - hash = "sha256-A4Yra/903rOeEbXfFia/A2HRPrFyE1b05mzHWlDImCY="; + rev = "v0.0.2"; + hash = "sha256-k75sJip3YMiTZdFlVu+qfAz3URO4cjVtd/PvsaMvBNg="; }; installPhase = '' diff --git a/compile_commands.json b/compile_commands.json index 5d777ae..f3595d5 100644 --- a/compile_commands.json +++ b/compile_commands.json @@ -1,13 +1,13 @@ [ { "arguments": [ - "/nix/store/888bkaqdpfpx72dd8bdc69qsqlgbhcvf-gcc-wrapper-13.3.0/bin/g++", + "/nix/store/mzfk1sdv6bxvdh9slvddpj734ck99idi-gcc-wrapper-13.3.0/bin/g++", "-std=c++17", - "-I/nix/store/xq34vhc04n55v53xj9hbn0h0vj2ywcv6-libnotify-0.8.3-dev/include", - "-I/nix/store/089kvf479gh1jnapqi296pjn2yvmyplj-gdk-pixbuf-2.42.12-dev/include/gdk-pixbuf-2.0", - "-I/nix/store/5dd834gbg319lfmfwgv54mswcq9k4k57-glib-2.82.1-dev/include", - "-I/nix/store/5dd834gbg319lfmfwgv54mswcq9k4k57-glib-2.82.1-dev/include/glib-2.0", - "-I/nix/store/8mmkgqj0r37s2rlxjvpj8dya7k9gcg77-glib-2.82.1/lib/glib-2.0/include", + "-I/nix/store/lx8rjaxiazr2p6wrfx3hrnydbknlkzlj-libnotify-0.8.3-dev/include", + "-I/nix/store/ji6inyc1hiid4kj2cid3dnrd2qhfmvda-gdk-pixbuf-2.42.12-dev/include/gdk-pixbuf-2.0", + "-I/nix/store/g8psrwxldnl8hnksf0rind77ja4pjwxc-glib-2.82.1-dev/include", + "-I/nix/store/g8psrwxldnl8hnksf0rind77ja4pjwxc-glib-2.82.1-dev/include/glib-2.0", + "-I/nix/store/26hcp8h792wl0h52c5r94qakhvk6q717-glib-2.82.1/lib/glib-2.0/include", "-c", "-o", "build/keybinds.o", @@ -19,31 +19,13 @@ }, { "arguments": [ - "/nix/store/888bkaqdpfpx72dd8bdc69qsqlgbhcvf-gcc-wrapper-13.3.0/bin/g++", + "/nix/store/mzfk1sdv6bxvdh9slvddpj734ck99idi-gcc-wrapper-13.3.0/bin/g++", "-std=c++17", - "-I/nix/store/xq34vhc04n55v53xj9hbn0h0vj2ywcv6-libnotify-0.8.3-dev/include", - "-I/nix/store/089kvf479gh1jnapqi296pjn2yvmyplj-gdk-pixbuf-2.42.12-dev/include/gdk-pixbuf-2.0", - "-I/nix/store/5dd834gbg319lfmfwgv54mswcq9k4k57-glib-2.82.1-dev/include", - "-I/nix/store/5dd834gbg319lfmfwgv54mswcq9k4k57-glib-2.82.1-dev/include/glib-2.0", - "-I/nix/store/8mmkgqj0r37s2rlxjvpj8dya7k9gcg77-glib-2.82.1/lib/glib-2.0/include", - "-c", - "-o", - "build/main.o", - "src/main.cpp" - ], - "directory": "/home/boss/Documents/Coding/WM/YATwm", - "file": "/home/boss/Documents/Coding/WM/YATwm/src/main.cpp", - "output": "/home/boss/Documents/Coding/WM/YATwm/build/main.o" - }, - { - "arguments": [ - "/nix/store/888bkaqdpfpx72dd8bdc69qsqlgbhcvf-gcc-wrapper-13.3.0/bin/g++", - "-std=c++17", - "-I/nix/store/xq34vhc04n55v53xj9hbn0h0vj2ywcv6-libnotify-0.8.3-dev/include", - "-I/nix/store/089kvf479gh1jnapqi296pjn2yvmyplj-gdk-pixbuf-2.42.12-dev/include/gdk-pixbuf-2.0", - "-I/nix/store/5dd834gbg319lfmfwgv54mswcq9k4k57-glib-2.82.1-dev/include", - "-I/nix/store/5dd834gbg319lfmfwgv54mswcq9k4k57-glib-2.82.1-dev/include/glib-2.0", - "-I/nix/store/8mmkgqj0r37s2rlxjvpj8dya7k9gcg77-glib-2.82.1/lib/glib-2.0/include", + "-I/nix/store/lx8rjaxiazr2p6wrfx3hrnydbknlkzlj-libnotify-0.8.3-dev/include", + "-I/nix/store/ji6inyc1hiid4kj2cid3dnrd2qhfmvda-gdk-pixbuf-2.42.12-dev/include/gdk-pixbuf-2.0", + "-I/nix/store/g8psrwxldnl8hnksf0rind77ja4pjwxc-glib-2.82.1-dev/include", + "-I/nix/store/g8psrwxldnl8hnksf0rind77ja4pjwxc-glib-2.82.1-dev/include/glib-2.0", + "-I/nix/store/26hcp8h792wl0h52c5r94qakhvk6q717-glib-2.82.1/lib/glib-2.0/include", "-c", "-o", "build/ewmh.o", @@ -55,31 +37,31 @@ }, { "arguments": [ - "/nix/store/888bkaqdpfpx72dd8bdc69qsqlgbhcvf-gcc-wrapper-13.3.0/bin/g++", + "/nix/store/mzfk1sdv6bxvdh9slvddpj734ck99idi-gcc-wrapper-13.3.0/bin/g++", "-std=c++17", - "-I/nix/store/xq34vhc04n55v53xj9hbn0h0vj2ywcv6-libnotify-0.8.3-dev/include", - "-I/nix/store/089kvf479gh1jnapqi296pjn2yvmyplj-gdk-pixbuf-2.42.12-dev/include/gdk-pixbuf-2.0", - "-I/nix/store/5dd834gbg319lfmfwgv54mswcq9k4k57-glib-2.82.1-dev/include", - "-I/nix/store/5dd834gbg319lfmfwgv54mswcq9k4k57-glib-2.82.1-dev/include/glib-2.0", - "-I/nix/store/8mmkgqj0r37s2rlxjvpj8dya7k9gcg77-glib-2.82.1/lib/glib-2.0/include", + "-I/nix/store/lx8rjaxiazr2p6wrfx3hrnydbknlkzlj-libnotify-0.8.3-dev/include", + "-I/nix/store/ji6inyc1hiid4kj2cid3dnrd2qhfmvda-gdk-pixbuf-2.42.12-dev/include/gdk-pixbuf-2.0", + "-I/nix/store/g8psrwxldnl8hnksf0rind77ja4pjwxc-glib-2.82.1-dev/include", + "-I/nix/store/g8psrwxldnl8hnksf0rind77ja4pjwxc-glib-2.82.1-dev/include/glib-2.0", + "-I/nix/store/26hcp8h792wl0h52c5r94qakhvk6q717-glib-2.82.1/lib/glib-2.0/include", "-c", "-o", - "build/IPC.o", - "src/IPC.cpp" + "build/config.o", + "src/config.cpp" ], "directory": "/home/boss/Documents/Coding/WM/YATwm", - "file": "/home/boss/Documents/Coding/WM/YATwm/src/IPC.cpp", - "output": "/home/boss/Documents/Coding/WM/YATwm/build/IPC.o" + "file": "/home/boss/Documents/Coding/WM/YATwm/src/config.cpp", + "output": "/home/boss/Documents/Coding/WM/YATwm/build/config.o" }, { "arguments": [ - "/nix/store/888bkaqdpfpx72dd8bdc69qsqlgbhcvf-gcc-wrapper-13.3.0/bin/g++", + "/nix/store/mzfk1sdv6bxvdh9slvddpj734ck99idi-gcc-wrapper-13.3.0/bin/g++", "-std=c++17", - "-I/nix/store/xq34vhc04n55v53xj9hbn0h0vj2ywcv6-libnotify-0.8.3-dev/include", - "-I/nix/store/089kvf479gh1jnapqi296pjn2yvmyplj-gdk-pixbuf-2.42.12-dev/include/gdk-pixbuf-2.0", - "-I/nix/store/5dd834gbg319lfmfwgv54mswcq9k4k57-glib-2.82.1-dev/include", - "-I/nix/store/5dd834gbg319lfmfwgv54mswcq9k4k57-glib-2.82.1-dev/include/glib-2.0", - "-I/nix/store/8mmkgqj0r37s2rlxjvpj8dya7k9gcg77-glib-2.82.1/lib/glib-2.0/include", + "-I/nix/store/lx8rjaxiazr2p6wrfx3hrnydbknlkzlj-libnotify-0.8.3-dev/include", + "-I/nix/store/ji6inyc1hiid4kj2cid3dnrd2qhfmvda-gdk-pixbuf-2.42.12-dev/include/gdk-pixbuf-2.0", + "-I/nix/store/g8psrwxldnl8hnksf0rind77ja4pjwxc-glib-2.82.1-dev/include", + "-I/nix/store/g8psrwxldnl8hnksf0rind77ja4pjwxc-glib-2.82.1-dev/include/glib-2.0", + "-I/nix/store/26hcp8h792wl0h52c5r94qakhvk6q717-glib-2.82.1/lib/glib-2.0/include", "-c", "-o", "build/commands.o", @@ -91,38 +73,56 @@ }, { "arguments": [ - "/nix/store/888bkaqdpfpx72dd8bdc69qsqlgbhcvf-gcc-wrapper-13.3.0/bin/g++", + "/nix/store/mzfk1sdv6bxvdh9slvddpj734ck99idi-gcc-wrapper-13.3.0/bin/g++", "-std=c++17", - "-I/nix/store/xq34vhc04n55v53xj9hbn0h0vj2ywcv6-libnotify-0.8.3-dev/include", - "-I/nix/store/089kvf479gh1jnapqi296pjn2yvmyplj-gdk-pixbuf-2.42.12-dev/include/gdk-pixbuf-2.0", - "-I/nix/store/5dd834gbg319lfmfwgv54mswcq9k4k57-glib-2.82.1-dev/include", - "-I/nix/store/5dd834gbg319lfmfwgv54mswcq9k4k57-glib-2.82.1-dev/include/glib-2.0", - "-I/nix/store/8mmkgqj0r37s2rlxjvpj8dya7k9gcg77-glib-2.82.1/lib/glib-2.0/include", + "-I/nix/store/lx8rjaxiazr2p6wrfx3hrnydbknlkzlj-libnotify-0.8.3-dev/include", + "-I/nix/store/ji6inyc1hiid4kj2cid3dnrd2qhfmvda-gdk-pixbuf-2.42.12-dev/include/gdk-pixbuf-2.0", + "-I/nix/store/g8psrwxldnl8hnksf0rind77ja4pjwxc-glib-2.82.1-dev/include", + "-I/nix/store/g8psrwxldnl8hnksf0rind77ja4pjwxc-glib-2.82.1-dev/include/glib-2.0", + "-I/nix/store/26hcp8h792wl0h52c5r94qakhvk6q717-glib-2.82.1/lib/glib-2.0/include", "-c", "-o", - "build/util.o", - "src/util.cpp" + "build/main.o", + "src/main.cpp" ], "directory": "/home/boss/Documents/Coding/WM/YATwm", - "file": "/home/boss/Documents/Coding/WM/YATwm/src/util.cpp", - "output": "/home/boss/Documents/Coding/WM/YATwm/build/util.o" + "file": "/home/boss/Documents/Coding/WM/YATwm/src/main.cpp", + "output": "/home/boss/Documents/Coding/WM/YATwm/build/main.o" }, { "arguments": [ - "/nix/store/888bkaqdpfpx72dd8bdc69qsqlgbhcvf-gcc-wrapper-13.3.0/bin/g++", + "/nix/store/mzfk1sdv6bxvdh9slvddpj734ck99idi-gcc-wrapper-13.3.0/bin/g++", "-std=c++17", - "-I/nix/store/xq34vhc04n55v53xj9hbn0h0vj2ywcv6-libnotify-0.8.3-dev/include", - "-I/nix/store/089kvf479gh1jnapqi296pjn2yvmyplj-gdk-pixbuf-2.42.12-dev/include/gdk-pixbuf-2.0", - "-I/nix/store/5dd834gbg319lfmfwgv54mswcq9k4k57-glib-2.82.1-dev/include", - "-I/nix/store/5dd834gbg319lfmfwgv54mswcq9k4k57-glib-2.82.1-dev/include/glib-2.0", - "-I/nix/store/8mmkgqj0r37s2rlxjvpj8dya7k9gcg77-glib-2.82.1/lib/glib-2.0/include", + "-I/nix/store/lx8rjaxiazr2p6wrfx3hrnydbknlkzlj-libnotify-0.8.3-dev/include", + "-I/nix/store/ji6inyc1hiid4kj2cid3dnrd2qhfmvda-gdk-pixbuf-2.42.12-dev/include/gdk-pixbuf-2.0", + "-I/nix/store/g8psrwxldnl8hnksf0rind77ja4pjwxc-glib-2.82.1-dev/include", + "-I/nix/store/g8psrwxldnl8hnksf0rind77ja4pjwxc-glib-2.82.1-dev/include/glib-2.0", + "-I/nix/store/26hcp8h792wl0h52c5r94qakhvk6q717-glib-2.82.1/lib/glib-2.0/include", "-c", "-o", - "build/config.o", - "src/config.cpp" + "build/IPC.o", + "src/IPC.cpp" ], "directory": "/home/boss/Documents/Coding/WM/YATwm", - "file": "/home/boss/Documents/Coding/WM/YATwm/src/config.cpp", - "output": "/home/boss/Documents/Coding/WM/YATwm/build/config.o" + "file": "/home/boss/Documents/Coding/WM/YATwm/src/IPC.cpp", + "output": "/home/boss/Documents/Coding/WM/YATwm/build/IPC.o" + }, + { + "arguments": [ + "/nix/store/mzfk1sdv6bxvdh9slvddpj734ck99idi-gcc-wrapper-13.3.0/bin/g++", + "-std=c++17", + "-I/nix/store/lx8rjaxiazr2p6wrfx3hrnydbknlkzlj-libnotify-0.8.3-dev/include", + "-I/nix/store/ji6inyc1hiid4kj2cid3dnrd2qhfmvda-gdk-pixbuf-2.42.12-dev/include/gdk-pixbuf-2.0", + "-I/nix/store/g8psrwxldnl8hnksf0rind77ja4pjwxc-glib-2.82.1-dev/include", + "-I/nix/store/g8psrwxldnl8hnksf0rind77ja4pjwxc-glib-2.82.1-dev/include/glib-2.0", + "-I/nix/store/26hcp8h792wl0h52c5r94qakhvk6q717-glib-2.82.1/lib/glib-2.0/include", + "-c", + "-o", + "build/util.o", + "src/util.cpp" + ], + "directory": "/home/boss/Documents/Coding/WM/YATwm", + "file": "/home/boss/Documents/Coding/WM/YATwm/src/util.cpp", + "output": "/home/boss/Documents/Coding/WM/YATwm/build/util.o" } ] diff --git a/config b/config index 5771451..21074d2 100644 --- a/config +++ b/config @@ -2,8 +2,14 @@ # Keybinds: bindmode emacs -quitkey s-g +quitkey C-s-g swapmods + + +bind "s-[" spawn playerctl -p firefox play-pause +bind "s-]" spawn playerctl -p spotify play-pause +bind "s-S--" bashSpawn emacsclient -c + bind "s-0" changeWS 10 bind "s-1" changeWS 1 bind "s-2" changeWS 2 @@ -16,7 +22,7 @@ bind "s-8" changeWS 8 bind "s-9" changeWS 9 bind "s-E" exit bind "s-R" reload -bind "s-RET" spawn alacritty +bind "s-RET" bashSpawn alacritty bind "s-S-0" wToWS 10 bind "s-S-1" wToWS 1 bind "s-S-2" wToWS 2 diff --git a/flake.nix b/flake.nix index 8d97f64..ad2cdb8 100644 --- a/flake.nix +++ b/flake.nix @@ -18,7 +18,7 @@ pkgs.clang-tools ]; }; - packages.x86_64-linux.YATwm = (pkgs.callPackage ./YATwm.nix {inherit inputs;}); + packages.x86_64-linux.YATwm = (pkgs.callPackage ./YATwm.nix {inherit inputs;}); packages.x86_64-linux.default = self.packages.x86_64-linux.YATwm; nixosModules.YATwm = import ./nix/module.nix; nixosModules.default = self.nixosModules.YATwm; diff --git a/makefile b/makefile index 991a02a..85d29d7 100644 --- a/makefile +++ b/makefile @@ -32,10 +32,10 @@ remove: r #Files to be compiled $(OBJS_DIR)/main.o: $(SOURCE_FILES) $(SOURCE_HEADERS) $(OBJS_DIR)/ewmh.o: $(SOURCE_DIR)/ewmh.cpp $(SOURCE_DIR)/ewmh.h -$(OBJS_DIR)/command.o: $(SOURCE_DIR)/commands.cpp $(SOURCE_DIR)/commands.h $(SOURCE_DIR)/util.h $(SOURCE_DIR)/error.h +$(OBJS_DIR)/command.o: $(SOURCE_DIR)/commands.cpp $(SOURCE_DIR)/commands.h $(SOURCE_DIR)/util.h $(SOURCE_DIR)/debug.h $(SOURCE_DIR)/error.h $(OBJS_DIR)/util.o: $(SOURCE_DIR)/util.cpp $(SOURCE_DIR)/util.h $(OBJS_DIR)/config.o: $(SOURCE_DIR)/config.cpp $(SOURCE_DIR)/config.h -$(OBJS_DIR)/keybinds.o: $(SOURCE_DIR)/keybinds.cpp $(SOURCE_DIR)/keybinds.h +$(OBJS_DIR)/keybinds.o: $(SOURCE_DIR)/keybinds.cpp $(SOURCE_DIR)/keybinds.h $(SOURCE_DIR)/debug.h $(OBJS_DIR)/ipc.o: $(SOURCE_DIR)/ipc.cpp $(SOURCE_DIR)/ipc.h $(SOURCE_DIR)/commands.h $(SOURCE_DIR)/ewmh.h clean: diff --git a/src/IPC.cpp b/src/IPC.cpp index 3ed1bb6..4f9754e 100644 --- a/src/IPC.cpp +++ b/src/IPC.cpp @@ -12,13 +12,16 @@ using std::cout, std::endl; static const char* path = "/tmp/YATwm.sock"; -IPCServerModule::IPCServerModule(CommandsModule& commandsModule, Config& cfg, Globals& globals) - :commandsModule(commandsModule), - cfg(cfg), - globals(globals) +IPCServerModule::IPCServerModule(Globals& globals, Config& cfg, CommandsModule& commandsModule, EWMHModule& ewmh) + :globals(globals) + ,cfg(cfg) + ,commandsModule(commandsModule) + ,ewmh(ewmh) { } + + void IPCServerModule::init() { sockfd = socket(AF_UNIX, SOCK_STREAM, 0); @@ -32,7 +35,7 @@ void IPCServerModule::init() cout << "ERROR " << errno << endl; } cout << "SOCKETED" << endl; - setIPCPath((unsigned char*)path, strlen(path)); + ewmh.setIPCPath((unsigned char*)path, strlen(path)); ready = true; } @@ -85,10 +88,10 @@ void IPCServerModule::quitIPC() int IPCServerModule::getFD() { if(!ready) - return -1; + return 0; if(sockfd > 0) return sockfd; - return -1; + return 0; } IPCClientModule::IPCClientModule() diff --git a/src/IPC.h b/src/IPC.h index e0bbcee..09d176a 100644 --- a/src/IPC.h +++ b/src/IPC.h @@ -5,20 +5,22 @@ #include "commands.h" #include "config.h" +#include "ewmh.h" #include "util.h" class IPCServerModule { public: - IPCServerModule(CommandsModule& commandsModule, Config& cfg, Globals& globals); + IPCServerModule(Globals& globals, Config& cfg, CommandsModule& commandsModule, EWMHModule& ewmh); void init(); void doListen(); void quitIPC(); int getFD(); private: - CommandsModule& commandsModule; - Config& cfg; Globals& globals; + Config& cfg; + CommandsModule& commandsModule; + EWMHModule& ewmh; int sockfd; int len; bool first = true; diff --git a/src/commands.cpp b/src/commands.cpp index caa82eb..460c45b 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -12,6 +12,8 @@ #include #include +#include "debug.h" + using std::cout, std::endl, std::string, std::vector; const void CommandsModule::echo(const CommandArg* argv) @@ -181,7 +183,12 @@ CommandArg* CommandsModule::getCommandArgs(vector& split, const CommandA { switch(argTypes[i-1]) { - case STR: args[i-1].str = (char*)split[i].c_str(); break; + case STR: + { + args[i-1].str = new char[split[i].length() + 1]; + strncpy(args[i-1].str, split[i].c_str(), split[i].length() + 1); + break; + } case NUM: { try @@ -194,6 +201,7 @@ CommandArg* CommandsModule::getCommandArgs(vector& split, const CommandA delete[] args; throw Err(CMD_ERR_WRONG_ARGS, split[i] + " is not a number!"); } + break; } case MOVDIR: { @@ -221,8 +229,8 @@ CommandArg* CommandsModule::getCommandArgs(vector& split, const CommandA if(j != split.size() - 1) rest += " "; } - args[i-1].str = new char[rest.size()]; - strncpy(args[i-1].str, rest.c_str(), rest.size()); + args[i-1].str = new char[rest.size() + 1]; + strncpy(args[i-1].str, rest.c_str(), rest.size() + 1); return args; } case NUM_ARR_REST: @@ -252,6 +260,7 @@ CommandArg* CommandsModule::getCommandArgs(vector& split, const CommandA void CommandsModule::runCommand(string command) { + debug(cout << command << endl); vector split = splitCommand(command); vector::const_iterator start = split.begin(); int count = 0; @@ -303,7 +312,7 @@ void CommandsModule::runCommand(vector split) { for(int i = 0; i < cmd->argc; i++) { - if(cmd->argTypes[i] == STR_REST) + if(cmd->argTypes[i] == STR_REST || cmd->argTypes[i] == STR) delete[] args[i].str; } delete[] args; @@ -311,7 +320,7 @@ void CommandsModule::runCommand(vector split) } for(int i = 0; i < cmd->argc; i++) { - if(cmd->argTypes[i] == STR_REST) + if(cmd->argTypes[i] == STR_REST || cmd->argTypes[i] == STR) delete[] args[i].str; } delete[] args; diff --git a/src/debug.h b/src/debug.h new file mode 100644 index 0000000..907498b --- /dev/null +++ b/src/debug.h @@ -0,0 +1,10 @@ +#pragma once + +// Toggles global debug +// #define ENABLE_DEBUG + +#ifdef ENABLE_DEBUG +#define debug(x) (x) +#else +#define debug(x) +#endif diff --git a/src/ewmh.cpp b/src/ewmh.cpp index a3cc505..6bbf575 100644 --- a/src/ewmh.cpp +++ b/src/ewmh.cpp @@ -1,99 +1,124 @@ #include "ewmh.h" +#include "util.h" #include #include #include -#include -#include +#include #include -Display** dpy_; -Window* root_; +#include -void initEWMH(Display** dpy, Window* root, int numWS, std::vector workspaces) +EWMHModule::EWMHModule(Globals& globals, Config& cfg) + :globals(globals) + ,cfg(cfg) { - dpy_ = dpy; - root_ = root; +} - Atom supported[] = {XInternAtom(*dpy_, "_NET_NUMBER_OF_DESKTOPS", false), XInternAtom(*dpy_, "_NET_DESKTOP_NAMES", false), XInternAtom(*dpy_, "_NET_CLIENT_LIST", false), XInternAtom(*dpy_, "_NET_CURRENT_DESKTOP", false)}; - int wsNamesLen = numWS; //For null bytes - for(int i = 0; i < numWS; i++) +void EWMHModule::init() +{ + Atom supported[] = {XInternAtom(globals.dpy, "_NET_NUMBER_OF_DESKTOPS", false), XInternAtom(globals.dpy, "_NET_DESKTOP_NAMES", false), XInternAtom(globals.dpy, "_NET_CLIENT_LIST", false), XInternAtom(globals.dpy, "_NET_CURRENT_DESKTOP", false), XInternAtom(globals.dpy, "_NET_DESKTOP_VIEWPORT", false)}; + int wsNamesLen = cfg.numWS; //For null bytes + for(int i = 0; i < cfg.numWS; i++) { - wsNamesLen += workspaces[i].name.length(); + wsNamesLen += cfg.workspaces[i].name.length(); } - char wsNames[wsNamesLen]; + char *wsNames = new char[wsNamesLen]; int pos = 0; - for(int i = 0; i < numWS; i++) + for(int i = 0; i < cfg.numWS; i++) { - for(char toAdd : workspaces[i].name) + for(char toAdd : cfg.workspaces[i].name) { wsNames[pos++] = toAdd; } wsNames[pos++] = '\0'; } - unsigned long numDesktops = numWS; - Atom netSupportedAtom = XInternAtom(*dpy_, "_NET_SUPPORTED", false); - Atom netNumDesktopsAtom = XInternAtom(*dpy_, "_NET_NUMBER_OF_DESKTOPS", false); - Atom netDesktopNamesAtom = XInternAtom(*dpy_, "_NET_DESKTOP_NAMES", false); - Atom XA_UTF8STRING = XInternAtom(*dpy_, "UTF8_STRING", false); - XChangeProperty(*dpy_, *root_, netSupportedAtom, XA_ATOM, 32, PropModeReplace, (unsigned char*)supported, 3); - XChangeProperty(*dpy_, *root_, netDesktopNamesAtom, XA_UTF8STRING, 8, PropModeReplace, (unsigned char*)&wsNames, wsNamesLen); - XChangeProperty(*dpy_, *root_, netNumDesktopsAtom, XA_CARDINAL, 32, PropModeReplace, (unsigned char*)&numDesktops, 1); - + unsigned long numDesktops = cfg.numWS; + Atom netSupportedAtom = XInternAtom(globals.dpy, "_NET_SUPPORTED", false); + Atom netNumDesktopsAtom = XInternAtom(globals.dpy, "_NET_NUMBER_OF_DESKTOPS", false); + Atom netDesktopNamesAtom = XInternAtom(globals.dpy, "_NET_DESKTOP_NAMES", false); + Atom XA_UTF8STRING = XInternAtom(globals.dpy, "UTF8_STRING", false); + XChangeProperty(globals.dpy, globals.root, netSupportedAtom, XA_ATOM, 32, PropModeReplace, (unsigned char*)supported, 5); + XChangeProperty(globals.dpy, globals.root, netDesktopNamesAtom, XA_UTF8STRING, 8, PropModeReplace, (unsigned char*)wsNames, wsNamesLen); + XChangeProperty(globals.dpy, globals.root, netNumDesktopsAtom, XA_CARDINAL, 32, PropModeReplace, (unsigned char*)&numDesktops, 1); + delete[] wsNames; } -void updateClientList(std::map clients) +void EWMHModule::updateClientList(std::map clients) { - Atom netClientList = XInternAtom(*dpy_, "_NET_CLIENT_LIST", false); - XDeleteProperty(*dpy_, *root_, netClientList); + Atom netClientList = XInternAtom(globals.dpy, "_NET_CLIENT_LIST", false); + XDeleteProperty(globals.dpy, globals.root, netClientList); std::map::iterator cItr; for(cItr = clients.begin(); cItr != clients.end(); cItr++) { - XChangeProperty(*dpy_, *root_, netClientList, XA_WINDOW, 32, PropModeAppend, (unsigned char*)&cItr->second.w, 1); + XChangeProperty(globals.dpy, globals.root, netClientList, XA_WINDOW, 32, PropModeAppend, (unsigned char*)&cItr->second.w, 1); } } -void setWindowDesktop(Window w, int desktop) +void EWMHModule::updateScreens(ScreenInfo* screens, int nscreens) +{ + uint16_t *desktopViewports = new uint16_t[cfg.numWS*2]; + + for(int i = 0; i < cfg.numWS; i++) + { + for(int j = 0; j < cfg.workspaces[i].screenPreferencesc; j++) + { + if(cfg.workspaces[i].screenPreferences[j] < nscreens) + { + desktopViewports[i*2] = (uint16_t)screens[cfg.workspaces[i].screenPreferences[j]].x; + desktopViewports[i*2 + 1] = (uint16_t)screens[cfg.workspaces[i].screenPreferences[j]].y; + break; + } + } + } + + Atom netDesktopViewport = XInternAtom(globals.dpy, "_NET_DESKTOP_VIEWPORT", false); + XChangeProperty(globals.dpy, globals.root, netDesktopViewport, XA_CARDINAL, 16, PropModeReplace, (unsigned char*)desktopViewports, cfg.numWS*2); + + delete[] desktopViewports; +} + +void EWMHModule::setWindowDesktop(Window w, int desktop) { unsigned long currDesktop = desktop - 1; - Atom netWMDesktop = XInternAtom(*dpy_, "_NET_WM_DESKTOP", false); - XChangeProperty(*dpy_, w, netWMDesktop, XA_CARDINAL, 32, PropModeReplace, (unsigned char*)&currDesktop, 1); + Atom netWMDesktop = XInternAtom(globals.dpy, "_NET_WM_DESKTOP", false); + XChangeProperty(globals.dpy, w, netWMDesktop, XA_CARDINAL, 32, PropModeReplace, (unsigned char*)&currDesktop, 1); } -void setCurrentDesktop(int desktop) +void EWMHModule::setCurrentDesktop(int desktop) { unsigned long currDesktop = desktop - 1; - Atom netCurrentDesktop = XInternAtom(*dpy_, "_NET_CURRENT_DESKTOP", false); - XChangeProperty(*dpy_, *root_, netCurrentDesktop, XA_CARDINAL, 32, PropModeReplace, (unsigned char*)&currDesktop, 1); + Atom netCurrentDesktop = XInternAtom(globals.dpy, "_NET_CURRENT_DESKTOP", false); + XChangeProperty(globals.dpy, globals.root, netCurrentDesktop, XA_CARDINAL, 32, PropModeReplace, (unsigned char*)&currDesktop, 1); } -void setFullscreen(Window w, bool fullscreen) +void EWMHModule::setFullscreen(Window w, bool fullscreen) { - Atom netWMState = XInternAtom(*dpy_, "_NET_WM_STATE", false); + Atom netWMState = XInternAtom(globals.dpy, "_NET_WM_STATE", false); Atom netWMStateVal; if(fullscreen) - netWMStateVal = XInternAtom(*dpy_, "_NET_WM_STATE_FULLSCREEN", false); + netWMStateVal = XInternAtom(globals.dpy, "_NET_WM_STATE_FULLSCREEN", false); else - netWMStateVal = XInternAtom(*dpy_, "", false); - XChangeProperty(*dpy_, w, netWMState, XA_ATOM, 32, PropModeReplace, (unsigned char*)&netWMStateVal, 1); + netWMStateVal = XInternAtom(globals.dpy, "", false); + XChangeProperty(globals.dpy, w, netWMState, XA_ATOM, 32, PropModeReplace, (unsigned char*)&netWMStateVal, 1); } -void setIPCPath(unsigned char* path, int len) +void EWMHModule::setIPCPath(unsigned char* path, int len) { - Atom socketPathAtom = XInternAtom(*dpy_, "YATWM_SOCKET_PATH", false); - XChangeProperty(*dpy_, *root_, socketPathAtom, XA_STRING, 8, PropModeReplace, path, len); + Atom socketPathAtom = XInternAtom(globals.dpy, "YATWM_SOCKET_PATH", false); + XChangeProperty(globals.dpy, globals.root, socketPathAtom, XA_STRING, 8, PropModeReplace, path, len); } -int getProp(Window w, char* propName, Atom* type, unsigned char** data) +int EWMHModule::getProp(Window w, char* propName, Atom* type, unsigned char** data) { - Atom prop_type = XInternAtom(*dpy_, propName, false); + Atom prop_type = XInternAtom(globals.dpy, propName, false); int format; unsigned long length; unsigned long after; - int status = XGetWindowProperty(*dpy_, w, prop_type, + int status = XGetWindowProperty(globals.dpy, w, prop_type, 0L, 1L, False, AnyPropertyType, type, &format, &length, &after, data); diff --git a/src/ewmh.h b/src/ewmh.h index 9473d5d..cb1284a 100644 --- a/src/ewmh.h +++ b/src/ewmh.h @@ -9,17 +9,30 @@ #include "structs.h" #include "config.h" +#include "util.h" -void initEWMH(Display** dpy, Window* root, int numWS, std::vector workspaces); +class EWMHModule +{ +public: + EWMHModule(Globals& globals, Config& cfg); + + void init(); -void updateClientList(std::map clients); + void updateClientList(std::map clients); -void setWindowDesktop(Window w, int desktop); + void updateScreens(ScreenInfo* screens, int nscreens); -void setCurrentDesktop(int desktop); + void setWindowDesktop(Window w, int desktop); -void setFullscreen(Window w, bool fullscreen); + void setCurrentDesktop(int desktop); -void setIPCPath(unsigned char* path, int len); + void setFullscreen(Window w, bool fullscreen); -int getProp(Window w, char* propName, Atom* type, unsigned char** data); + void setIPCPath(unsigned char* path, int len); + + int getProp(Window w, char* propName, Atom* type, unsigned char** data); + +private: + Globals& globals; + Config& cfg; +}; diff --git a/src/keybinds.cpp b/src/keybinds.cpp index 1f60a75..828b7f6 100644 --- a/src/keybinds.cpp +++ b/src/keybinds.cpp @@ -12,6 +12,10 @@ #include "keybinds.h" #include "util.h" +// #define ENABLE_DEBUG + +#include "debug.h" + using std::string, std::cout, std::endl; bool Keybind::operator<(const Keybind &o) const { @@ -69,9 +73,6 @@ void KeybindsModule::changeMap(int newMapID) const void KeybindsModule::handleKeypress(XKeyEvent e) { if(e.same_screen!=1) return; - // cout << "Key Pressed" << endl; - // cout << "\tState: " << e.state << endl; - // cout << "\tCode: " << XKeysymToString(XKeycodeToKeysym(globals.dpy, e.keycode, 0)) << endl; updateMousePos(); const unsigned int masks = ShiftMask | ControlMask | Mod1Mask | Mod4Mask; @@ -82,9 +83,14 @@ const void KeybindsModule::handleKeypress(XKeyEvent e) } else if(getKeymap(currentMapID).count(k) > 0) { + debug(cout << "Key Pressed" << endl); + debug(cout << "\tState: " << e.state << endl); + debug(cout << "\tCode: " << XKeysymToString(XKeycodeToKeysym(globals.dpy, e.keycode, 0)) << endl); + KeyFunction& c = getKeymap(currentMapID).find(k)->second; - if(getKeymap(c.mapID).size() == 0) + if(c.mapID == -1) { + debug(cout << '\t' << c.command << endl); commandsModule.runCommand(c.command); changeMap(0); } @@ -168,7 +174,7 @@ const Keybind KeybindsModule::emacsBindMode(string bindString) Keybind bind; bind.modifiers = 0; - //cout << "Adding keybind: '" << bindString << "'" << endl; + debug(cout << "Adding keybind: '" << bindString << "'" << endl); const std::regex keyRegex("^((?:[CMSs]-)*)([^\\s]|(?:SPC|ESC|RET))$"); std::smatch keyMatch; @@ -179,34 +185,34 @@ const Keybind KeybindsModule::emacsBindMode(string bindString) { if(modifier == "s") { - //cout << "\tModifier: s" << endl; + debug(cout << "\tModifier: s" << endl); bind.modifiers |= cfg.swapSuperAlt?Mod1Mask:Mod4Mask; } else if(modifier == "M") { - //cout << "\tModifier: M" << endl; + debug(cout << "\tModifier: M" << endl); bind.modifiers |= cfg.swapSuperAlt?Mod4Mask:Mod1Mask; } else if(modifier == "C") { - //cout << "\tModifier: C" << endl; + debug(cout << "\tModifier: C" << endl); bind.modifiers |= ControlMask; } else if(modifier == "S") { - //cout << "\tModifier: S" << endl; + debug(cout << "\tModifier: S" << endl); bind.modifiers |= ShiftMask; } } } KeySym keySym = XStringToKeysym(keyMatch[2].str().c_str()); - //cout << "\tKey: " << keyMatch[2].str() << endl; + debug(cout << "\tKey: " << keyMatch[2].str() << endl); - if(isUpper(keyMatch[2].str().c_str()) && keySym != NoSymbol) + if(keySym != NoSymbol && isUpper(keyMatch[2].str().c_str())) { bind.modifiers |= ShiftMask; } - if(keySym == NoSymbol) + else if(keySym == NoSymbol) { if(keyMatch[2].str() == "RET") keySym = XK_Return; @@ -218,10 +224,16 @@ const Keybind KeybindsModule::emacsBindMode(string bindString) keySym = XK_minus; else if(keyMatch[2].str() == "+") keySym = XK_plus; + else if(keyMatch[2].str() == "[") + keySym = XK_bracketleft; + else if(keyMatch[2].str() == "]") + keySym = XK_bracketright; else throw Err(CFG_ERR_KEYBIND, "Keybind '" + bindString + "' is invalid"); } bind.key = XKeysymToKeycode(globals.dpy, keySym); + + debug(cout << "\tState: " << bind.modifiers << endl); return bind; } @@ -258,9 +270,10 @@ const void KeybindsModule::bind(const CommandArg* argv) Keybind bind = getKeybind(keys[keys.size() - 1]); if(getKeymap(currentBindingMap).count(bind) <= 0) { - KeyFunction function = {argv[1].str, nextKeymapID}; - keyMaps.insert({nextKeymapID, std::map()}); - nextKeymapID++; + KeyFunction function = {argv[1].str, -1}; + debug(cout << "\tCommand: " << argv[1].str << endl); + // keyMaps.insert({nextKeymapID, std::map()}); + // nextKeymapID++; getKeymap(currentBindingMap).insert({bind, function}); if(currentBindingMap == currentMapID) { diff --git a/src/main.cpp b/src/main.cpp index 45e4eba..badcccd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,7 +8,6 @@ #include #include -#include #include #include #include @@ -17,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -54,6 +52,9 @@ char nowString[80]; updateTime(); \ yatlog << nowString << x << std::endl + +const char* version = "YATwm for X - v0.0.2"; + Display* dpy; Window root; @@ -64,7 +65,8 @@ void updateMousePos(); CommandsModule commandsModule; Config cfg(commandsModule); KeybindsModule keybindsModule(commandsModule, cfg, globals, &updateMousePos); -IPCServerModule ipc(commandsModule, cfg, globals); +EWMHModule ewmh(globals, cfg); +IPCServerModule ipc(globals, cfg, commandsModule, ewmh); int sW, sH; int bH; @@ -113,7 +115,7 @@ static int OnXError(Display* display, XErrorEvent* e); // Tiling // Call this one to tile everything (it does all the fancy stuff trust me just call this one) void tileRoots(); -// Call this one to until everything (it handles multiple monitors) +// Call this one to untile everything (it handles multiple monitors) void untileRoots(); // This is to be called by tileRoots, it takes in the x, y, w, and h of where it's allowed to tile windows to, and returns the ID of a fullscreen client if one is found, or noID (-1) if none are found int tile(int frameID, int x, int y, int w, int h); @@ -154,6 +156,8 @@ void detectScreens() } } XFree(monitors); + + ewmh.updateScreens(screens, nscreens); } void updateMousePos() { @@ -271,7 +275,7 @@ void cWS(int newWS) focusWindow(getFrame(currWS).rootData->focus); //EWMH - setCurrentDesktop(currWS); + ewmh.setCurrentDesktop(currWS); } void focusWindow(Window w) { @@ -393,7 +397,7 @@ const void wToWS(const CommandArg* argv) frames.find(argv[0].num)->second.subFrameIDs.push_back(fID); //EWMH - setWindowDesktop(focusedWindow, argv[0].num); + ewmh.setWindowDesktop(focusedWindow, argv[0].num); XUnmapWindow(dpy, focusedWindow); //tile(currWS, outerGaps, outerGaps, sW - outerGaps*2, sH - outerGaps*2 - bH); @@ -611,7 +615,7 @@ const void fullscreen(const CommandArg* arg) int cID = getFrame(fID).cID; getClient(cID).fullscreen ^= true; tileRoots(); - setFullscreen(focusedWindow, getClient(cID).fullscreen); + ewmh.setFullscreen(focusedWindow, getClient(cID).fullscreen); } void configureRequest(XConfigureRequestEvent e) @@ -697,7 +701,7 @@ void mapRequest(XMapRequestEvent e) unsigned char* data; Atom type; - int status = getProp(e.window, "_NET_WM_WINDOW_TYPE", &type, &data); + int status = ewmh.getProp(e.window, "_NET_WM_WINDOW_TYPE", &type, &data); if (status == Success && type != None && ((Atom*)data)[0] == XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DOCK", false)) { log("\tWindow was bar"); @@ -730,15 +734,15 @@ void mapRequest(XMapRequestEvent e) //Add ID to frameIDS map frameIDS.insert(pair(e.window, f.ID)); - status = getProp(e.window, "_NET_WM_STATE", &type, &data); + status = ewmh.getProp(e.window, "_NET_WM_STATE", &type, &data); if(status == Success && type!=None && (((Atom*)data)[0] == XInternAtom(dpy, "_NET_WM_STATE_MODAL", false) || ((Atom*)data)[0] == XInternAtom(dpy, "_NET_WM_STATE_ABOVE", false))) { cout << "Floating" << endl; clients.find(c.ID)->second.floating = true; frames.find(pID)->second.rootData->floatingFrameIDs.push_back(f.ID); frames.insert(pair(f.ID, f)); - setWindowDesktop(e.window, currWS); - updateClientList(clients); + ewmh.setWindowDesktop(e.window, currWS); + ewmh.updateClientList(clients); XFree(data); //tile(currWS, outerGaps, outerGaps, sW - outerGaps*2, sH - outerGaps*2 - bH); tileRoots(); @@ -785,8 +789,8 @@ void mapRequest(XMapRequestEvent e) //Add to frames map frames.insert(pair(f.ID, f)); - setWindowDesktop(e.window, currWS); - updateClientList(clients); + ewmh.setWindowDesktop(e.window, currWS); + ewmh.updateClientList(clients); //tile(currWS, outerGaps, outerGaps, sW - outerGaps*2, sH - outerGaps*2 - bH); focusWindow(e.window); @@ -839,7 +843,7 @@ void destroyNotify(XDestroyWindowEvent e) //tile(currWS, outerGaps, outerGaps, sW - outerGaps*2, sH - outerGaps*2 - bH); tileRoots(); - updateClientList(clients); + ewmh.updateClientList(clients); } void enterNotify(XEnterWindowEvent e) { @@ -902,7 +906,7 @@ void clientMessage(XClientMessageEvent e) int fID = getFrameID(e.window); int cID = getFrame(fID).cID; getClient(cID).fullscreen = (Atom) e.data.l[0] > 0; - setFullscreen(e.window, (Atom) e.data.l[0] > 0); + ewmh.setFullscreen(e.window, (Atom) e.data.l[0] > 0); tileRoots(); } XFree(prop1); @@ -976,7 +980,7 @@ int tile(int frameID, int x, int y, int w, int h) return fullscreenClientID; continue; } - Client c = clients.find(f.cID)->second; + Client c = getClient(f.cID); if(c.fullscreen) return c.ID; wX += cfg.gaps; @@ -1019,25 +1023,24 @@ void untile(int frameID) void printVersion() { - const char* version = - "YATwm for X\n" - "version 0.0.1"; cout << version << endl; } int main(int argc, char** argv) { int versionFlag = 0; + int noSocketFlag = 0; bool immediateExit = false; string configLocation = ""; while(1) { static option long_options[] = {{"version", no_argument, &versionFlag, 1}, {"config", required_argument, NULL, 'c'}, + {"nosocket", no_argument, &noSocketFlag, 1}, {0, 0, 0, 0}}; int optionIndex; - char c = getopt_long(argc, argv, "c:v", long_options, &optionIndex); + char c = getopt_long(argc, argv, "c:nv", long_options, &optionIndex); if(c == -1) break; @@ -1055,6 +1058,8 @@ int main(int argc, char** argv) case 'v': versionFlag = 1; break; + case 'n': + noSocketFlag = 1; case '?': //Error?? break; @@ -1130,21 +1135,25 @@ int main(int argc, char** argv) cout << "Registered commands" << endl; - if(configLocation != "") - cfgErr = cfg.loadFromFile(configLocation); - else + // if(configLocation != "") + // cfgErr = cfg.loadFromFile(configLocation); + if(configLocation == "") { char* confDir = getenv("XDG_CONFIG_HOME"); if(confDir != NULL) - cfgErr = cfg.loadFromFile(string(confDir) + "/YATwm/config"); + configLocation = string(confDir) + "/YATwm/config"; + // cfgErr = cfg.loadFromFile(string(confDir) + "/YATwm/config"); else { string home = getenv("HOME"); - cfgErr = cfg.loadFromFile(home + "/.config/YATwm/config"); + configLocation = home + "/.config/YATwm/config"; + // cfgErr = cfg.loadFromFile(home + "/.config/YATwm/config"); } } - cout << "Done config" << endl; + cfgErr = cfg.loadFromFile(configLocation); + + cout << "Loaded config" << endl; //Log yatlog.open(cfg.logFile, std::ios_base::app); @@ -1152,6 +1161,9 @@ int main(int argc, char** argv) //Print starting message log("-------- YATWM STARTING --------"); + log(version); + log("Running from command: " << argv[0]); + log("Reading config from file: " << configLocation); //Notifications notify_init("YATwm"); @@ -1172,10 +1184,11 @@ int main(int argc, char** argv) XDefineCursor(dpy, root, XCreateFontCursor(dpy, XC_top_left_arrow)); //EWMH - initEWMH(&dpy, &root, cfg.workspaces.size(), cfg.workspaces); - setCurrentDesktop(1); + ewmh.init(); + ewmh.setCurrentDesktop(1); - ipc.init(); + if(!noSocketFlag) + ipc.init(); for(int i = 1; i < cfg.numWS + 1; i++) { @@ -1192,18 +1205,15 @@ int main(int argc, char** argv) fd_set fdset; int x11fd = ConnectionNumber(dpy); - FD_ZERO(&fdset); - FD_SET(x11fd, &fdset); - FD_SET(ipc.getFD(), &fdset); - log("Begin mainloop"); while(keepGoing) { FD_ZERO(&fdset); FD_SET(x11fd, &fdset); - FD_SET(ipc.getFD(), &fdset); + if(!noSocketFlag) + FD_SET(ipc.getFD(), &fdset); int ready = select(std::max(x11fd, ipc.getFD()) + 1, &fdset, NULL, NULL, NULL); - if(FD_ISSET(ipc.getFD(), &fdset)) + if(!noSocketFlag && FD_ISSET(ipc.getFD(), &fdset)) { ipc.doListen(); } @@ -1248,5 +1258,7 @@ int main(int argc, char** argv) //Kill children ipc.quitIPC(); + delete[] screens; + delete[] focusedWorkspaces; XCloseDisplay(dpy); } diff --git a/test b/test index f821b7f..bafbb1d 100644 --- a/test +++ b/test @@ -7,6 +7,6 @@ Xephyr -screen 1600x900+2080+90 :1 & sleep 0.1 -DISPLAY=:1 ./YATwm -c config +DISPLAY=:1 ./YATwm -nc config pkill Xephyr -- cgit v1.2.3-70-g09d2