From 4ffa3ab6a1b8efbd688b19a660363803cb06f390 Mon Sep 17 00:00:00 2001
From: vaxerski <43317083+vaxerski@users.noreply.github.com>
Date: Mon, 22 Nov 2021 18:43:55 +0100
Subject: [PATCH] =?UTF-8?q?many=20fixes=20for=20multi=20monitor,=20added?=
=?UTF-8?q?=20also=20the=20new=20window=20tree=20system=20=20=F0=9F=8E=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
🎉
---
CMakeLists.txt | 1 +
README.md | 2 +-
src/events/events.cpp | 44 ++++++++++++
src/window.cpp | 48 ++++++++++++-
src/window.hpp | 23 +++++-
src/windowManager.cpp | 158 +++++++++++++++++++-----------------------
src/windowManager.hpp | 7 +-
7 files changed, 191 insertions(+), 92 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 419d4f7..34a347c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,6 +5,7 @@ project(Hypr
)
add_compile_options(-std=c++17)
+add_compile_options(-Wall -Wextra)
find_package(Threads REQUIRED)
file(GLOB_RECURSE SRCFILES "src/*.cpp")
diff --git a/README.md b/README.md
index e7e54b7..2bdeb73 100644
--- a/README.md
+++ b/README.md
@@ -20,7 +20,7 @@ Hypr is a Linux tiling window manager for Xorg. It's written in XCB with modern
- [x] Workspaces
- [x] Moving windows / user input (e.g. fullscreening) ~ More to be done probably
- [ ] True lerp animations
-- [ ] Rewriting the window system to be a tree
+- [x] Rewriting the window system to be a tree
diff --git a/src/events/events.cpp b/src/events/events.cpp
index f975e43..f57a840 100644
--- a/src/events/events.cpp
+++ b/src/events/events.cpp
@@ -69,6 +69,50 @@ void Events::eventMapWindow(xcb_generic_event_t* event) {
window.setDefaultPosition(Vector2D(0,0));
window.setDefaultSize(Vector2D(g_pWindowManager->Screen->width_in_pixels/2.f,g_pWindowManager->Screen->height_in_pixels/2.f));
+ // Set the parent
+ // check if lastwindow is on our workspace
+ if (auto PLASTWINDOW = g_pWindowManager->getWindowFromDrawable(g_pWindowManager->LastWindow); PLASTWINDOW
+ && PLASTWINDOW->getWorkspaceID() == g_pWindowManager->activeWorkspaces[CURRENTSCREEN]) {
+ // LastWindow is on our workspace, let's make a new split node
+
+ if (PLASTWINDOW->getIsFloating()) {
+ // find a window manually
+ PLASTWINDOW = g_pWindowManager->findWindowAtCursor();
+ }
+
+ CWindow newWindowSplitNode;
+ newWindowSplitNode.setPosition(PLASTWINDOW->getPosition());
+ newWindowSplitNode.setSize(PLASTWINDOW->getSize());
+
+ newWindowSplitNode.setChildNodeAID(PLASTWINDOW->getDrawable());
+ newWindowSplitNode.setChildNodeBID(E->window);
+
+ newWindowSplitNode.setParentNodeID(PLASTWINDOW->getParentNodeID());
+
+ newWindowSplitNode.setWorkspaceID(window.getWorkspaceID());
+ newWindowSplitNode.setMonitor(window.getMonitor());
+
+ // generates a negative node ID
+ newWindowSplitNode.generateNodeID();
+
+ // update the parent if exists
+ if (const auto PREVPARENT = g_pWindowManager->getWindowFromDrawable(PLASTWINDOW->getParentNodeID()); PREVPARENT) {
+ if (PREVPARENT->getChildNodeAID() == PLASTWINDOW->getDrawable()) {
+ PREVPARENT->setChildNodeAID(newWindowSplitNode.getDrawable());
+ } else {
+ PREVPARENT->setChildNodeBID(newWindowSplitNode.getDrawable());
+ }
+ }
+
+ window.setParentNodeID(newWindowSplitNode.getDrawable());
+ PLASTWINDOW->setParentNodeID(newWindowSplitNode.getDrawable());
+
+ g_pWindowManager->addWindowToVectorSafe(newWindowSplitNode);
+ } else {
+ // LastWindow is not on our workspace, so set the parent to 0.
+ window.setParentNodeID(0);
+ }
+
// Also sets the old one
g_pWindowManager->calculateNewWindowParams(&window);
diff --git a/src/window.cpp b/src/window.cpp
index d6d7de2..a1b6199 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -1,4 +1,48 @@
#include "window.hpp"
+#include "windowManager.hpp"
-CWindow::CWindow() { this->setDirty(true); this->setFullscreen(false); this->setIsFloating(false); }
-CWindow::~CWindow() { }
\ No newline at end of file
+CWindow::CWindow() { this->setDirty(true); this->setFullscreen(false); this->setIsFloating(false); this->setParentNodeID(0); this->setChildNodeAID(0); this->setChildNodeBID(0); }
+CWindow::~CWindow() { }
+
+void CWindow::generateNodeID() {
+
+ int64_t lowest = -1;
+ for (auto& window : g_pWindowManager->windows) {
+ if ((int64_t)window.getDrawable() < lowest) {
+ lowest = (int64_t)window.getDrawable();
+ }
+ }
+
+ m_iDrawable = lowest - 1;
+}
+
+void CWindow::setDirtyRecursive(bool val) {
+ m_bDirty = val;
+
+ if (m_iChildNodeAID != 0) {
+ g_pWindowManager->getWindowFromDrawable(m_iChildNodeAID)->setDirtyRecursive(val);
+ g_pWindowManager->getWindowFromDrawable(m_iChildNodeBID)->setDirtyRecursive(val);
+ }
+}
+
+void CWindow::recalcSizePosRecursive() {
+ if (m_iChildNodeAID != 0) {
+ const auto HORIZONTAL = m_vecSize.x > m_vecSize.y;
+ g_pWindowManager->getWindowFromDrawable(m_iChildNodeAID)->setPosition(m_vecPosition);
+ g_pWindowManager->getWindowFromDrawable(m_iChildNodeBID)->setPosition(m_vecPosition + (HORIZONTAL ? Vector2D(m_vecSize.x / 2.f, 0) : Vector2D(0, m_vecSize.y / 2.f)));
+
+ g_pWindowManager->getWindowFromDrawable(m_iChildNodeAID)->setSize(Vector2D(m_vecSize.x / (HORIZONTAL ? 2 : 1), m_vecSize.y / (HORIZONTAL ? 1 : 2)));
+ g_pWindowManager->getWindowFromDrawable(m_iChildNodeBID)->setSize(Vector2D(m_vecSize.x / (HORIZONTAL ? 2 : 1), m_vecSize.y / (HORIZONTAL ? 1 : 2)));
+
+ g_pWindowManager->getWindowFromDrawable(m_iChildNodeAID)->setDirty(true);
+ g_pWindowManager->getWindowFromDrawable(m_iChildNodeBID)->setDirty(true);
+
+ if (m_iChildNodeAID < 0) {
+ g_pWindowManager->getWindowFromDrawable(m_iChildNodeAID)->recalcSizePosRecursive();
+ }
+
+ if (m_iChildNodeBID < 0) {
+ g_pWindowManager->getWindowFromDrawable(m_iChildNodeBID)->recalcSizePosRecursive();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/window.hpp b/src/window.hpp
index 554d8c1..d808b6d 100644
--- a/src/window.hpp
+++ b/src/window.hpp
@@ -14,17 +14,38 @@ public:
void resize(Vector2D size);
void resize(float percx, float percy);
+ // ------------------------------------- //
+ // Node Stuff //
+ // ------------------------------------- //
+
+ // IDs:
+ // > 0 : Windows
+ // == 0 : None
+ // < 0 : Nodes
+
+ EXPOSED_MEMBER(ParentNodeID, int64_t, i);
+
+ EXPOSED_MEMBER(ChildNodeAID, int64_t, i);
+ EXPOSED_MEMBER(ChildNodeBID, int64_t, i);
+
+ void generateNodeID();
+
+ // ------------------------------------- //
+
std::string getName();
// Tells the window manager to reload the window's params
EXPOSED_MEMBER(Dirty, bool, b);
+ void setDirtyRecursive(bool);
+ void recalcSizePosRecursive();
+
EXPOSED_MEMBER(Size, Vector2D, vec);
EXPOSED_MEMBER(EffectiveSize, Vector2D, vec);
EXPOSED_MEMBER(EffectivePosition, Vector2D, vec);
EXPOSED_MEMBER(Position, Vector2D, vec);
EXPOSED_MEMBER(IsFloating, bool, b);
- EXPOSED_MEMBER(Drawable, xcb_drawable_t, i);
+ EXPOSED_MEMBER(Drawable, int64_t, i); // int64_t because it's my internal ID system too.
// Fullscreen
EXPOSED_MEMBER(Fullscreen, bool, b);
diff --git a/src/windowManager.cpp b/src/windowManager.cpp
index d92648a..cf94b5a 100644
--- a/src/windowManager.cpp
+++ b/src/windowManager.cpp
@@ -55,7 +55,7 @@ void CWindowManager::setupRandrMonitors() {
}
Debug::log(NONE, "Monitor " + monitors[monitors.size() - 1].szName + ": " + std::to_string(monitors[i].vecSize.x) + "x" + std::to_string(monitors[monitors.size() - 1].vecSize.y) +
- ", at " + std::to_string(monitors[monitors.size() - 1].vecPosition.x) + "," + std::to_string(monitors[monitors.size() - 1].vecSize.y));
+ ", at " + std::to_string(monitors[monitors.size() - 1].vecPosition.x) + "," + std::to_string(monitors[monitors.size() - 1].vecPosition.y) + ", ID: " + std::to_string(monitors[monitors.size() - 1].ID));
}
const auto EXTENSIONREPLY = xcb_get_extension_data(DisplayConnection, &xcb_randr_id);
@@ -65,31 +65,29 @@ void CWindowManager::setupRandrMonitors() {
//listen for screen change events
xcb_randr_select_input(DisplayConnection, Screen->root, XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE);
}
-
- // Sort monitors for my convenience thanks
- std::sort(monitors.begin(), monitors.end(), [](SMonitor& a, SMonitor& b) {
- return a.vecPosition.x < b.vecPosition.x;
- });
}
void CWindowManager::setupManager() {
setupRandrMonitors();
- ConfigManager::init();
-
if (monitors.size() == 0) {
// RandR failed!
Debug::log(WARN, "RandR failed!");
- monitors.push_back(SMonitor());
- monitors[0].vecPosition = Vector2D(0, 0);
- monitors[0].vecSize = Vector2D(Screen->width_in_pixels, Screen->height_in_pixels);
- monitors[0].ID = 0;
- monitors[0].szName = "Screen";
+ #define TESTING_MON_AMOUNT 3
+ for (int i = 0; i < TESTING_MON_AMOUNT /* Testing on 3 monitors, RandR shouldnt fail on a real desktop */; ++i) {
+ monitors.push_back(SMonitor());
+ monitors[i].vecPosition = Vector2D(i * Screen->width_in_pixels / TESTING_MON_AMOUNT, 0);
+ monitors[i].vecSize = Vector2D(Screen->width_in_pixels / TESTING_MON_AMOUNT, Screen->height_in_pixels);
+ monitors[i].ID = i;
+ monitors[i].szName = "Screen" + std::to_string(i);
+ }
}
Debug::log(LOG, "RandR done.");
+ ConfigManager::init();
+
Values[0] = XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_PROPERTY_CHANGE;
xcb_change_window_attributes_checked(DisplayConnection, Screen->root,
XCB_CW_EVENT_MASK, Values);
@@ -118,7 +116,7 @@ void CWindowManager::setupManager() {
Debug::log(LOG, "Keys done.");
// Add workspaces to the monitors
- for (int i = 0; i < monitors.size(); ++i) {
+ for (long unsigned int i = 0; i < monitors.size(); ++i) {
CWorkspace protoWorkspace;
protoWorkspace.setID(i + 1);
protoWorkspace.setMonitor(i);
@@ -216,35 +214,6 @@ bool CWindowManager::handleEvent() {
return true;
}
-// TODO: add an empty space check
-void CWindowManager::performSanityCheckForWorkspace(int WorkspaceID) {
- for (auto& windowA : windows) {
- if (windowA.getWorkspaceID() != WorkspaceID)
- continue;
-
- for (auto& windowB : windows) {
- if (windowB.getWorkspaceID() != WorkspaceID)
- continue;
-
- if (windowB.getDrawable() == windowA.getDrawable())
- continue;
-
- // Check if A and B overlap, if don't, continue
- if ((windowA.getPosition().x >= (windowB.getPosition() + windowB.getSize()).x || windowB.getPosition().x >= (windowA.getPosition() + windowA.getSize()).x
- || windowA.getPosition().y >= (windowB.getPosition() + windowB.getSize()).y || windowB.getPosition().y >= (windowA.getPosition() + windowA.getSize()).y)) {
- continue;
- }
-
- // Overlap detected! Fix window B
- if (windowB.getIsFloating()) {
- calculateNewTileSetOldTile(&windowB);
- } else {
- calculateNewFloatingWindow(&windowB);
- }
- }
- }
-}
-
void CWindowManager::cleanupUnusedWorkspaces() {
std::vector temp = workspaces;
@@ -279,6 +248,12 @@ void CWindowManager::refreshDirtyWindows() {
for(auto& window : windows) {
if (window.getDirty()) {
+ // Check if the window isn't a node
+ if (window.getChildNodeAID() != 0) {
+ window.setDirty(false);
+ continue;
+ }
+
setEffectiveSizePosUsingConfig(&window);
// Fullscreen flag
@@ -367,7 +342,7 @@ void CWindowManager::setFocusedWindow(xcb_drawable_t window) {
}
}
-CWindow* CWindowManager::getWindowFromDrawable(xcb_drawable_t window) {
+CWindow* CWindowManager::getWindowFromDrawable(int64_t window) {
for(auto& w : windows) {
if (w.getDrawable() == window) {
return &w;
@@ -420,9 +395,9 @@ void CWindowManager::setEffectiveSizePosUsingConfig(CWindow* pWindow) {
//TODO: make windows with no bar taller, this aint working chief
// do gaps, set top left
- pWindow->setEffectivePosition(pWindow->getEffectivePosition() + Vector2D(DISPLAYLEFT ? ConfigManager::getInt("gaps_out") : ConfigManager::getInt("gaps_in"), DISPLAYTOP ? ConfigManager::getInt("gaps_out") + (MONITOR->ID != statusBar.getMonitorID() ? ConfigManager::getInt("bar_height") : 0) : ConfigManager::getInt("gaps_in")));
+ pWindow->setEffectivePosition(pWindow->getEffectivePosition() + Vector2D(DISPLAYLEFT ? ConfigManager::getInt("gaps_out") : ConfigManager::getInt("gaps_in"), DISPLAYTOP ? ConfigManager::getInt("gaps_out") + (MONITOR->ID == statusBar.getMonitorID() ? ConfigManager::getInt("bar_height") : 0) : ConfigManager::getInt("gaps_in")));
// fix to old size bottom right
- pWindow->setEffectiveSize(pWindow->getEffectiveSize() - Vector2D(DISPLAYLEFT ? ConfigManager::getInt("gaps_out") : ConfigManager::getInt("gaps_in"), DISPLAYTOP ? ConfigManager::getInt("gaps_out") + (MONITOR->ID != statusBar.getMonitorID() ? ConfigManager::getInt("bar_height") : 0) : ConfigManager::getInt("gaps_in")));
+ pWindow->setEffectiveSize(pWindow->getEffectiveSize() - Vector2D(DISPLAYLEFT ? ConfigManager::getInt("gaps_out") : ConfigManager::getInt("gaps_in"), DISPLAYTOP ? ConfigManager::getInt("gaps_out") + (MONITOR->ID == statusBar.getMonitorID() ? ConfigManager::getInt("bar_height") : 0) : ConfigManager::getInt("gaps_in")));
// set bottom right
pWindow->setEffectiveSize(pWindow->getEffectiveSize() - Vector2D(DISPLAYRIGHT ? ConfigManager::getInt("gaps_out") : ConfigManager::getInt("gaps_in"), DISPLAYBOTTOM ? ConfigManager::getInt("gaps_out") : ConfigManager::getInt("gaps_in")));
}
@@ -459,33 +434,45 @@ CWindow* CWindowManager::findWindowAtCursor() {
}
void CWindowManager::calculateNewTileSetOldTile(CWindow* pWindow) {
- auto PLASTWINDOW = getWindowFromDrawable(LastWindow);
+
+ // Get the parent and both children, one of which will be pWindow
+ const auto PPARENT = getWindowFromDrawable(pWindow->getParentNodeID());
- if (PLASTWINDOW && (PLASTWINDOW->getIsFloating() || PLASTWINDOW->getWorkspaceID() != pWindow->getWorkspaceID())) {
- // find a window manually
- PLASTWINDOW = findWindowAtCursor();
+ if (!PPARENT) {
+ // New window on this workspace.
+ // Open a fullscreen window.
+ const auto MONITOR = getMonitorFromCursor();
+ pWindow->setSize(Vector2D(MONITOR->vecSize.x, MONITOR->vecSize.y));
+ pWindow->setPosition(Vector2D(MONITOR->vecPosition.x, MONITOR->vecPosition.y));
+
+ return;
}
- if (PLASTWINDOW) {
- const auto PLASTSIZE = PLASTWINDOW->getSize();
- const auto PLASTPOS = PLASTWINDOW->getPosition();
+ // Get the sibling
+ const auto PSIBLING = getWindowFromDrawable(PPARENT->getChildNodeAID() == pWindow->getDrawable() ? PPARENT->getChildNodeBID() : PPARENT->getChildNodeAID());
+
+ // Should NEVER be null
+ if (PSIBLING) {
+ const auto PLASTSIZE = PPARENT->getSize();
+ const auto PLASTPOS = PPARENT->getPosition();
if (PLASTSIZE.x > PLASTSIZE.y) {
- PLASTWINDOW->setSize(Vector2D(PLASTSIZE.x / 2.f, PLASTSIZE.y));
+ PSIBLING->setPosition(Vector2D(PLASTPOS.x, PLASTPOS.y));
+ PSIBLING->setSize(Vector2D(PLASTSIZE.x / 2.f, PLASTSIZE.y));
pWindow->setSize(Vector2D(PLASTSIZE.x / 2.f, PLASTSIZE.y));
pWindow->setPosition(Vector2D(PLASTPOS.x + PLASTSIZE.x / 2.f, PLASTPOS.y));
} else {
- PLASTWINDOW->setSize(Vector2D(PLASTSIZE.x, PLASTSIZE.y / 2.f));
+ PSIBLING->setPosition(Vector2D(PLASTPOS.x, PLASTPOS.y));
+ PSIBLING->setSize(Vector2D(PLASTSIZE.x, PLASTSIZE.y / 2.f));
pWindow->setSize(Vector2D(PLASTSIZE.x, PLASTSIZE.y / 2.f));
pWindow->setPosition(Vector2D(PLASTPOS.x, PLASTPOS.y + PLASTSIZE.y / 2.f));
}
- PLASTWINDOW->setDirty(true);
+ PSIBLING->setDirty(true);
} else {
- // Open a fullscreen window
- const auto MONITOR = getMonitorFromCursor();
- pWindow->setSize(Vector2D(MONITOR->vecSize.x, MONITOR->vecSize.y));
- pWindow->setPosition(Vector2D(MONITOR->vecPosition.x, MONITOR->vecPosition.y));
+ Debug::log(ERR, "Sibling node was null?? pWindow x,y,w,h: " + std::to_string(pWindow->getPosition().x) + " "
+ + std::to_string(pWindow->getPosition().y) + " " + std::to_string(pWindow->getSize().x) + " "
+ + std::to_string(pWindow->getSize().y));
}
}
@@ -593,32 +580,39 @@ void CWindowManager::fixWindowOnClose(CWindow* pClosedWindow) {
if (!pClosedWindow)
return;
- const auto WORKSPACE = activeWorkspaces[getMonitorFromWindow(pClosedWindow)->ID];
+ // Get the parent and both children, one of which will be pWindow
+ const auto PPARENT = getWindowFromDrawable(pClosedWindow->getParentNodeID());
- // Fix if was fullscreen
- if (pClosedWindow->getFullscreen())
- g_pWindowManager->getWorkspaceByID(WORKSPACE)->setHasFullscreenWindow(false);
+ if (!PPARENT)
+ return; // if there was no parent, we do not need to update anything. it was a fullscreen window, the only one on a given workspace.
- // get the first neighboring window
- CWindow* neighbor = nullptr;
- for(auto& w : windows) {
- if (w.getDrawable() == pClosedWindow->getDrawable())
- continue;
+ // Get the sibling
+ const auto PSIBLING = getWindowFromDrawable(PPARENT->getChildNodeAID() == pClosedWindow->getDrawable() ? PPARENT->getChildNodeBID() : PPARENT->getChildNodeAID());
- if (isNeighbor(&w, pClosedWindow) && canEatWindow(&w, pClosedWindow)) {
- neighbor = &w;
- break;
- }
+ PSIBLING->setPosition(PPARENT->getPosition());
+ PSIBLING->setSize(PPARENT->getSize());
+
+ // make the sibling replace the parent
+ PSIBLING->setParentNodeID(PPARENT->getParentNodeID());
+
+ if (PPARENT->getParentNodeID() != 0
+ && getWindowFromDrawable(PPARENT->getParentNodeID())) {
+ if (getWindowFromDrawable(PPARENT->getParentNodeID())->getChildNodeAID() == PPARENT->getDrawable()) {
+ getWindowFromDrawable(PPARENT->getParentNodeID())->setChildNodeAID(PSIBLING->getDrawable());
+ } else {
+ getWindowFromDrawable(PPARENT->getParentNodeID())->setChildNodeBID(PSIBLING->getDrawable());
+ }
}
- if (!neighbor)
- return; // No neighbor. Don't update, easy.
+ // Make the sibling eat the closed window
+ PSIBLING->setDirtyRecursive(true);
+ PSIBLING->recalcSizePosRecursive();
- // update neighbor to "eat" closed.
- eatWindow(neighbor, pClosedWindow);
+ // Remove the parent
+ removeWindowFromVectorSafe(PPARENT->getDrawable());
- neighbor->setDirty(true);
- setFocusedWindow(neighbor->getDrawable()); // Set focus. :)
+ if (findWindowAtCursor())
+ setFocusedWindow(findWindowAtCursor()->getDrawable()); // Set focus. :)
}
CWindow* CWindowManager::getNeighborInDir(char dir) {
@@ -717,9 +711,6 @@ void CWindowManager::changeWorkspaceByID(int ID) {
activeWorkspaces[workspace.getMonitor()] = workspace.getID();
LastWindow = -1;
- // Perform a sanity check for the new workspace
- performSanityCheckForWorkspace(ID);
-
// Update bar info
updateBarInfo();
@@ -738,9 +729,6 @@ void CWindowManager::changeWorkspaceByID(int ID) {
activeWorkspaces[MONITOR->ID] = workspaces[workspaces.size() - 1].getID();
LastWindow = -1;
- // Perform a sanity check for the new workspace
- performSanityCheckForWorkspace(ID);
-
// Update bar info
updateBarInfo();
diff --git a/src/windowManager.hpp b/src/windowManager.hpp
index 89ae51f..317f50b 100644
--- a/src/windowManager.hpp
+++ b/src/windowManager.hpp
@@ -37,14 +37,13 @@ public:
CStatusBar statusBar;
std::thread* barThread;
- CWindow* getWindowFromDrawable(xcb_drawable_t);
+ CWindow* getWindowFromDrawable(int64_t);
void addWindowToVectorSafe(CWindow);
void removeWindowFromVectorSafe(xcb_drawable_t);
void setupManager();
bool handleEvent();
void refreshDirtyWindows();
- void performSanityCheckForWorkspace(int);
void setFocusedWindow(xcb_drawable_t);
@@ -65,6 +64,9 @@ public:
SMonitor* getMonitorFromWindow(CWindow*);
SMonitor* getMonitorFromCursor();
+ // finds a window that's tiled at cursor.
+ CWindow* findWindowAtCursor();
+
private:
// Internal WM functions that don't have to be exposed
@@ -77,7 +79,6 @@ public:
bool isNeighbor(CWindow* a, CWindow* b);
void calculateNewTileSetOldTile(CWindow* pWindow);
void calculateNewFloatingWindow(CWindow* pWindow);
- CWindow* findWindowAtCursor();
void setEffectiveSizePosUsingConfig(CWindow* pWindow);
void cleanupUnusedWorkspaces();
xcb_visualtype_t* setupColors();