diff options
| author | BossCode45 <human.cyborg42@gmail.com> | 2022-09-18 14:38:41 +1200 |
|---|---|---|
| committer | BossCode45 <human.cyborg42@gmail.com> | 2022-09-18 14:38:41 +1200 |
| commit | a34c161a6643f184348f42235bcda46352b68da0 (patch) | |
| tree | b74a27a55b64c91dbec16df42d62894f8adeadc5 | |
| parent | 598f8cc9e8d7acc2adb1671adc591c3ad7008712 (diff) | |
| download | YATwm-a34c161a6643f184348f42235bcda46352b68da0.tar.gz YATwm-a34c161a6643f184348f42235bcda46352b68da0.zip | |
Starting work on multiple monitors
| -rw-r--r-- | config.h | 36 | ||||
| -rw-r--r-- | ewmh.cpp | 2 | ||||
| -rw-r--r-- | ewmh.h | 2 | ||||
| -rw-r--r-- | logs.txt | 19 | ||||
| -rw-r--r-- | main.cpp | 133 | ||||
| -rw-r--r-- | makefile | 2 | ||||
| -rw-r--r-- | notes.org | 24 | ||||
| -rw-r--r-- | structs.h | 8 | ||||
| -rw-r--r-- | test | 2 |
9 files changed, 174 insertions, 54 deletions
@@ -5,16 +5,19 @@ #include <string> //Startup -std::string startup[] = {"picom -fD 3", "feh --bg-scale /usr/share/backgrounds/vapor_trails_blue.png", "~/.config/polybar/launch.sh", "emacs --daemon"}; +const std::string startup[] = {"picom -fD 3", "feh --bg-scale /usr/share/backgrounds/vapor_trails_blue.png", "~/.config/polybar/launch.sh", "emacs --daemon"}; //Main config -int gaps = 3; -int outerGaps = 3; -std::string logFile = "/tmp/yatlog"; +const int gaps = 3; +const int outerGaps = 3; +const std::string logFile = "/tmp/yatlog.txt"; //WS config const int numWS = 10; -std::string workspaceNames[] = {"1: ", "2: 拾", "3: ", "4: ", "5: ", "6: ", "7: 拾", "8: ", "9: ", "10: "}; +const std::string workspaceNames[] = {"1: ", "2: 拾", "3: ", "4: ", "5: ", "6: ", "7: 拾", "8: ", "9: ", "10: "}; +//If you have more then 2 monitors change the number below +const int maxMonitors = 2; +const int screenPreferences[][maxMonitors] = {{0}, {0}, {0}, {0}, {0}, {1, 0}, {1, 0}, {1, 0}, {1, 0}, {1, 0}}; //Keys //The types and perhaps functions likely to be moved to seperate header file later @@ -35,8 +38,8 @@ typedef union struct Key { - unsigned int modifiers; - KeySym keysym; + const unsigned int modifiers; + const KeySym keysym; void (*function)(const KeyArg arg); const KeyArg arg; }; @@ -52,25 +55,28 @@ KEYCOM(changeWS); KEYCOM(wToWS); KEYCOM(focChange); KEYCOM(wMove); +KEYCOM(bashSpawn); +KEYCOM(screenTest); +//Super key mod +#define MOD Mod4Mask +//Alt key mod +//#define MOD Mod1Mask +#define SHIFT ShiftMask const char* alacritty[] = {"alacritty", NULL}; const char* rofi[] = {"rofi", "-i", "-show", "drun", NULL}; const char* qutebrowser[] = {"qutebrowser", NULL}; - const char* i3lock[] = {"i3lock", "-eti", "/usr/share/backgrounds/lockscreen.png", NULL}; const char* suspend[] = {"systemctl", "suspend", NULL}; -//Super key mod -//#define MOD Mod4Mask -//Alt key mod -#define MOD Mod1Mask -#define SHIFT ShiftMask +const char* monConfig[] = {"~/.i3_commands/monitor-config.sh"}; + #define WSKEY(K, X) \ {MOD, K, changeWS, {.num = X}}, \ {MOD|SHIFT, K, wToWS, {.num = X}} -static Key keyBinds[] = { +const Key keyBinds[] = { //Modifiers //Key //Func //Args //General {MOD, XK_e, exit, {NULL}}, @@ -82,6 +88,8 @@ static Key keyBinds[] = { {MOD, XK_x, spawn, {.str = i3lock}}, {MOD|SHIFT, XK_x, spawn, {.str = i3lock}}, {MOD|SHIFT, XK_x, spawn, {.str = suspend}}, + {MOD, XK_m, bashSpawn, {.str = monConfig}}, + {MOD|SHIFT, XK_t, screenTest, {NULL}}, //Focus {MOD, XK_h, focChange, {.dir = Left}}, {MOD, XK_j, focChange, {.dir = Down}}, @@ -5,7 +5,7 @@ Display** dpy_; Window* root_; -void initEWMH(Display** dpy, Window* root, int numWS, std::string workspaceNames[]) +void initEWMH(Display** dpy, Window* root, int numWS, const std::string workspaceNames[]) { dpy_ = dpy; root_ = root; @@ -8,7 +8,7 @@ #include "structs.h" -void initEWMH(Display** dpy, Window* root, int numWS, std::string workspaceNames[]); +void initEWMH(Display** dpy, Window* root, int numWS, const std::string workspaceNames[]); void updateClientList(std::map<int, Client> clients); diff --git a/logs.txt b/logs.txt deleted file mode 100644 index ff03f10..0000000 --- a/logs.txt +++ /dev/null @@ -1,19 +0,0 @@ ---- -Bars launched... -Successfully wrote command 'quit' to PID 196086 ---- -Bars launched... -Successfully wrote command 'quit' to PID 204881 ---- -Bars launched... -Successfully wrote command 'quit' to PID 207764 ---- -Bars launched... ---- -Bars launched... ---- -Bars launched... -Successfully wrote command 'quit' to PID 215833 -Successfully wrote command 'quit' to PID 215841 ---- -Bars launched... @@ -3,6 +3,7 @@ #include <X11/Xatom.h> #include <X11/Xutil.h> +#include <X11/extensions/Xrandr.h> #include <chrono> #include <cstdio> #include <cstdlib> @@ -48,6 +49,12 @@ map<int, Frame> frames; int currFrameID = 1; map<Window, int> frameIDS; +ScreenInfo* screens; +int* focusedWorkspaces; +int focusedScreen; +int nscreens; +int mX, mY; + #define getClient(c) clients.find(c)->second #define getFrame(f) frames.find(f)->second @@ -55,6 +62,11 @@ Window bar; int currWS = 1; + +// Usefull functions +int FFCF(int sID); +void detectScreens(); + void keyPress(XKeyEvent e); void configureRequest(XConfigureRequestEvent e); void mapRequest(XMapRequestEvent e); @@ -63,9 +75,39 @@ void clientMessage(XClientMessageEvent e); static int OnXError(Display* display, XErrorEvent* e); +void tileRoots(); +void untileRoots(); void tile(int frameID, int x, int y, int w, int h); void untile(int frameID); +// Usefull functions +int FFCF(int sID) +{ + if(frames.find(sID)->second.isClient) + return sID; + return FFCF(frames.find(sID)->second.subFrameIDs[0]); +} +void detectScreens() +{ + delete[] screens; + delete[] focusedWorkspaces; + log("Detecting screens: "); + XRRMonitorInfo* monitors = XRRGetMonitors(dpy, root, true, &nscreens); + log("\t"<<nscreens << " monitors"); + screens = new ScreenInfo[nscreens]; + focusedWorkspaces = new int[nscreens]; + for(int i = 0; i < nscreens; i++) + { + char* name = XGetAtomName(dpy, monitors[i].name); + screens[i] = {name, monitors[i].x, monitors[i].y, monitors[i].width, monitors[i].height}; + log("\tMonitor " << i + 1 << " - " << screens[i].name); + log("\t\tx: " << screens[i].x << ", y: " << screens[i].y); + log("\t\tw: " << screens[i].w << ", h: " << screens[i].h); + XFree(name); + } + XFree(monitors); +} + //Keybind commands void exit(const KeyArg arg) { @@ -183,12 +225,6 @@ void wToWS(const KeyArg arg) tile(currWS, outerGaps, outerGaps, sW - outerGaps*2, sH - outerGaps*2 - bH); XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); } -int FFCF(int sID) -{ - if(frames.find(sID)->second.isClient) - return sID; - return FFCF(frames.find(sID)->second.subFrameIDs[0]); -} int dirFind(int fID, MoveDir dir) { vector<int>& pSF = frames.find(frames.find(fID)->second.pID)->second.subFrameIDs; @@ -328,6 +364,22 @@ void wMove(const KeyArg arg) } XSetInputFocus(dpy, focusedWindow, RevertToPointerRoot, CurrentTime); } +void bashSpawn(const KeyArg arg) +{ + if(fork() == 0) + { + int null = open("log.txt", O_WRONLY); + dup2(null, 1); + dup2(null, 2); + system(arg.str[0]); + exit(0); + } + +} +void screenTest(const KeyArg arg) +{ + detectScreens(); +} void keyPress(XKeyEvent e) { @@ -335,7 +387,7 @@ void keyPress(XKeyEvent e) KeySym keysym = XLookupKeysym(&e, 0); for(int i = 0; i < sizeof(keyBinds)/sizeof(keyBinds[0]); i++) { - if(keyBinds[i].keysym == keysym && (e.state & keyBinds[i].modifiers) == keyBinds[i].modifiers) + if(keyBinds[i].keysym == keysym && e.state == keyBinds[i].modifiers) { keyBinds[i].function(keyBinds[i].arg); } @@ -361,9 +413,40 @@ void mapRequest(XMapRequestEvent e) XTextProperty name; XGetWMName(dpy, e.window, &name); + XWindowAttributes attr; + XGetWindowAttributes(dpy, e.window, &attr); log("Mapping window: " << name.value); log("\tWindow ID: " << e.window); - + + Window focusedWindow; + int revertToReturn; + XGetInputFocus(dpy, &focusedWindow, &revertToReturn); + if(focusedWindow && focusedWindow != root) + { + //Use focused to determine monitors + XWindowAttributes focAttr; + XGetWindowAttributes(dpy, focusedWindow, &focAttr); + log("\tFocused is at x: " << focAttr.x << ", y: " << focAttr.y); + } + else + { + Window rootRet, childRet; + int rX, rY, cX, cY; + unsigned int maskRet; + XQueryPointer(dpy, root, &rootRet, &childRet, &rX, &rY, &cX, &cY, &maskRet); + if(mX == rX && mY == rY) + { + //Use focused screen + log("\tFocused screen is: " << focusedScreen); + } + else + { + //Use mouse + log("\tMouse is at x: " << rX << ", y: " << rY); + mX = rX; + mY = rY; + } + } unsigned char* data; Atom type; @@ -371,8 +454,6 @@ void mapRequest(XMapRequestEvent e) if (status == Success && ((Atom*)data)[0] == XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DOCK", false)) { log("\tWindow was bar"); - XWindowAttributes attr; - XGetWindowAttributes(dpy, e.window, &attr); bH = attr.height; bar = e.window; XFree(data); @@ -382,9 +463,6 @@ void mapRequest(XMapRequestEvent e) - Window focusedWindow; - int revertToReturn; - XGetInputFocus(dpy, &focusedWindow, &revertToReturn); XSetInputFocus(dpy, e.window, RevertToNone, CurrentTime); XSelectInput(dpy, e.window, EnterWindowMask); @@ -515,9 +593,11 @@ void destroyNotify(XDestroyWindowEvent e) } void clientMessage(XClientMessageEvent e) { - log("Client message: " << XGetAtomName(dpy, e.message_type)); + char* name = XGetAtomName(dpy, e.message_type); + log("Client message: " << name); if(e.message_type == XInternAtom(dpy, "_NET_CURRENT_DESKTOP", false)) { + //Change desktop int nextWS = (long)e.data.l[0] + 1; int prevWS = currWS; currWS = nextWS; @@ -531,8 +611,8 @@ void clientMessage(XClientMessageEvent e) //EWMH setCurrentDesktop(currWS); - } + XFree(name); } static int OnXError(Display* display, XErrorEvent* e) @@ -541,6 +621,20 @@ static int OnXError(Display* display, XErrorEvent* e) return 0; } +void tileRoots() +{ + for(int i = 0; i < nscreens; i++) + { + tile(focusedWorkspaces[i], screens[i].x + outerGaps, screens[i].y + outerGaps, screens[i].w - outerGaps*2, screens[i].h - outerGaps*2 - bH); + } +} +void untileRoots() +{ + for(int i = 0; i < nscreens; i++) + { + untile(focusedWorkspaces[i]); + } +} void tile(int frameID, int x, int y, int w, int h) { for(int fID : frames.find(frameID)->second.floatingFrameIDs) @@ -606,6 +700,7 @@ void untile(int frameID) int main(int argc, char** argv) { + mX = mY = 0; dpy = XOpenDisplay(nullptr); root = Window(DefaultRootWindow(dpy)); @@ -613,7 +708,11 @@ int main(int argc, char** argv) auto timeUnformatted = std::chrono::system_clock::now(); std::time_t time = std::chrono::system_clock::to_time_t(timeUnformatted); - log("\nYAT STARTING: " << std::ctime(&time) << "--------------------------------------" ); + log("\nYAT STARTING: " << std::ctime(&time) << "--------------------------------------"); + + screens = new ScreenInfo[1]; + focusedWorkspaces = new int[1]; + detectScreens(); int screenNum = DefaultScreen(dpy); sW = DisplayWidth(dpy, screenNum); @@ -669,7 +768,7 @@ int main(int argc, char** argv) case DestroyNotify: destroyNotify(e.xdestroywindow); case EnterNotify: - //cout << e.xcrossing.window << "\n"; + log(e.xcrossing.x); if(e.xcrossing.window == root) break; XSetInputFocus(dpy, e.xcrossing.window, RevertToNone, CurrentTime); @@ -1,7 +1,7 @@ .PHONY: clean CXX := g++ CXXFLAGS := #-g -fsanitize=address -fno-omit-frame-pointer -LINKFLAGS := -lX11 +LINKFLAGS := -lX11 -lXrandr OBJS_DIR := . OUT_DIR := . SOURCE_DIR := . diff --git a/notes.org b/notes.org new file mode 100644 index 0000000..e67a9a0 --- /dev/null +++ b/notes.org @@ -0,0 +1,24 @@ +#+TITLE: Notes for myself to read + +* Multiple monitors +** How I tell which monitor +- First I should check the currently focsued window +- Seccondly I should get the current mouseX and mouseY + - If the mouseX and mouseY match the old ones then use the focusedScreen + - If not then use mouseX and mouseY +** When to update mouseX and mouseY +Whenever I change focus or focused screen or map a new window +** When to change focusedScreen +It should get changed when I change workspace to one that should go on a different screen +** How to tell which monitor to focus when changing workspace +There should be an array with the priorities. + +* Fullscreen windows +This should be another thing like floating windows except each workspace only gets one +I should check it first when tiling and if it exists then draw it to the size of the screeen then return + +* General EWMH things +I should really figure out what all the client messages mean + +* The eventual program to communicate with YAT +Use a unix socket @@ -2,6 +2,8 @@ #include <X11/Xlib.h> +#include <X11/extensions/Xrandr.h> +#include <string> #include <vector> #define noID -1 @@ -36,3 +38,9 @@ struct Frame bool isRoot; std::vector<int> floatingFrameIDs; }; + +struct ScreenInfo +{ + std::string name; + int x, y, w, h; +}; @@ -2,7 +2,7 @@ make -Xephyr :100 -screen 1600x900 & +Xephyr -screen 1600x900+160+0 :100 & sleep 0.1 |
