summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBossCode45 <human.cyborg42@gmail.com>2022-09-18 14:38:41 +1200
committerBossCode45 <human.cyborg42@gmail.com>2022-09-18 14:38:41 +1200
commita34c161a6643f184348f42235bcda46352b68da0 (patch)
treeb74a27a55b64c91dbec16df42d62894f8adeadc5
parent598f8cc9e8d7acc2adb1671adc591c3ad7008712 (diff)
downloadYATwm-a34c161a6643f184348f42235bcda46352b68da0.tar.gz
YATwm-a34c161a6643f184348f42235bcda46352b68da0.zip
Starting work on multiple monitors
-rw-r--r--config.h36
-rw-r--r--ewmh.cpp2
-rw-r--r--ewmh.h2
-rw-r--r--logs.txt19
-rw-r--r--main.cpp133
-rw-r--r--makefile2
-rw-r--r--notes.org24
-rw-r--r--structs.h8
-rw-r--r--test2
9 files changed, 174 insertions, 54 deletions
diff --git a/config.h b/config.h
index 72be653..d5d7ba5 100644
--- a/config.h
+++ b/config.h
@@ -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}},
diff --git a/ewmh.cpp b/ewmh.cpp
index c1e5e75..eec5de9 100644
--- a/ewmh.cpp
+++ b/ewmh.cpp
@@ -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;
diff --git a/ewmh.h b/ewmh.h
index d7b0741..7b1b5f4 100644
--- a/ewmh.h
+++ b/ewmh.h
@@ -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...
diff --git a/main.cpp b/main.cpp
index 950b26d..6553889 100644
--- a/main.cpp
+++ b/main.cpp
@@ -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);
diff --git a/makefile b/makefile
index 45b40df..e2d98b5 100644
--- a/makefile
+++ b/makefile
@@ -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
diff --git a/structs.h b/structs.h
index c238413..f58a8cd 100644
--- a/structs.h
+++ b/structs.h
@@ -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;
+};
diff --git a/test b/test
index 5427e8e..6a49b10 100644
--- a/test
+++ b/test
@@ -2,7 +2,7 @@
make
-Xephyr :100 -screen 1600x900 &
+Xephyr -screen 1600x900+160+0 :100 &
sleep 0.1