added floating windows 🎉

This commit is contained in:
vaxerski 2021-11-22 21:20:32 +01:00
parent 6898923463
commit 7b7ba35b0c
9 changed files with 212 additions and 64 deletions

View file

@ -15,7 +15,7 @@ Hypr is a Linux tiling window manager for Xorg. It's written in XCB with modern
## Roadmap (not in order) ## Roadmap (not in order)
- [x] Multi-monitor support - [x] Multi-monitor support
- [x] Status bar ~ Needs expanding - [x] Status bar ~ Needs expanding
- [ ] Floating windows support (Very basic for now) - [x] Floating windows support
- [x] Config system ~ Basic done - [x] Config system ~ Basic done
- [x] Workspaces - [x] Workspaces
- [x] Moving windows / user input (e.g. fullscreening) ~ More to be done probably - [x] Moving windows / user input (e.g. fullscreening) ~ More to be done probably

View file

@ -1,5 +1,6 @@
#include "KeybindManager.hpp" #include "KeybindManager.hpp"
#include "utilities/Util.hpp" #include "utilities/Util.hpp"
#include "events/events.hpp"
#include <algorithm> #include <algorithm>
#include <string.h> #include <string.h>
@ -57,6 +58,8 @@ unsigned int KeybindManager::modToMask(MODS mod) {
return XCB_MOD_MASK_4; return XCB_MOD_MASK_4;
case MOD_SHIFT: case MOD_SHIFT:
return XCB_MOD_MASK_SHIFT; return XCB_MOD_MASK_SHIFT;
case MOD_SHIFTSUPER:
return XCB_MOD_MASK_4 | XCB_MOD_MASK_SHIFT;
} }
return 0; return 0;
@ -137,9 +140,24 @@ void KeybindManager::toggleActiveWindowFloating(std::string unusedArg) {
PWINDOW->setDirty(true); PWINDOW->setDirty(true);
// Fix window as if it's closed if we just made it floating // Fix window as if it's closed if we just made it floating
if (PWINDOW->getIsFloating()) if (PWINDOW->getIsFloating()) {
g_pWindowManager->fixWindowOnClose(PWINDOW); g_pWindowManager->fixWindowOnClose(PWINDOW);
g_pWindowManager->calculateNewWindowParams(PWINDOW);
}
else {
// It's remapped again
// SAVE ALL INFO NOW, THE POINTER WILL BE DEAD
const auto RESTOREACSIZE = PWINDOW->getDefaultSize();
const auto RESTOREACPOS = PWINDOW->getDefaultPosition();
const auto RESTOREWINID = PWINDOW->getDrawable();
g_pWindowManager->removeWindowFromVectorSafe(PWINDOW->getDrawable());
const auto PNEWWINDOW = Events::remapWindow(RESTOREWINID, true);
PNEWWINDOW->setDefaultPosition(RESTOREACPOS);
PNEWWINDOW->setDefaultSize(RESTOREACSIZE);
}
g_pWindowManager->calculateNewWindowParams(PWINDOW);
} }
} }

View file

@ -84,6 +84,11 @@ void CStatusBar::setup(int MonitorID) {
// don't, i use it later // don't, i use it later
//xcb_close_font(g_pWindowManager->DisplayConnection, contextBASETEXT->Font); //xcb_close_font(g_pWindowManager->DisplayConnection, contextBASETEXT->Font);
// Set the bar to be top
values[0] = XCB_STACK_MODE_ABOVE;
xcb_configure_window(g_pWindowManager->DisplayConnection, m_iWindowID, XCB_CONFIG_WINDOW_STACK_MODE, values);
} }
void CStatusBar::destroy() { void CStatusBar::destroy() {

View file

@ -49,6 +49,7 @@ void handleBind(const std::string& command, const std::string& value) {
if (MOD == "SUPER") mod = MOD_SUPER; if (MOD == "SUPER") mod = MOD_SUPER;
else if (MOD == "SHIFT") mod = MOD_SHIFT; else if (MOD == "SHIFT") mod = MOD_SHIFT;
else if (MOD == "SUPERSHIFT" || MOD == "SHIFTSUPER") mod = MOD_SHIFTSUPER;
Dispatcher dispatcher = nullptr; Dispatcher dispatcher = nullptr;
if (HANDLER == "exec") dispatcher = KeybindManager::call; if (HANDLER == "exec") dispatcher = KeybindManager::call;

View file

@ -37,9 +37,9 @@ void Events::eventDestroy(xcb_generic_event_t* event) {
const auto E = reinterpret_cast<xcb_destroy_notify_event_t*>(event); const auto E = reinterpret_cast<xcb_destroy_notify_event_t*>(event);
xcb_kill_client(g_pWindowManager->DisplayConnection, E->window); xcb_kill_client(g_pWindowManager->DisplayConnection, E->window);
// fix last window // fix last window if tile
const auto CLOSEDWINDOW = g_pWindowManager->getWindowFromDrawable(E->window); const auto CLOSEDWINDOW = g_pWindowManager->getWindowFromDrawable(E->window);
if (CLOSEDWINDOW) { if (CLOSEDWINDOW && !CLOSEDWINDOW->getIsFloating()) {
g_pWindowManager->fixWindowOnClose(CLOSEDWINDOW); g_pWindowManager->fixWindowOnClose(CLOSEDWINDOW);
// delete off of the arr // delete off of the arr
@ -47,45 +47,36 @@ void Events::eventDestroy(xcb_generic_event_t* event) {
} }
} }
void Events::eventMapWindow(xcb_generic_event_t* event) { CWindow* Events::remapWindow(int windowID, bool wasfloating) {
const auto E = reinterpret_cast<xcb_map_request_event_t*>(event);
// make sure it's not the bar!
if (E->window == g_pWindowManager->statusBar.getWindowID())
return;
// Map the window
xcb_map_window(g_pWindowManager->DisplayConnection, E->window);
// Do the setup of the window's params and stuf // Do the setup of the window's params and stuf
CWindow window; CWindow window;
window.setDrawable(E->window); window.setDrawable(windowID);
window.setIsFloating(false); window.setIsFloating(false);
window.setDirty(true); window.setDirty(true);
const auto CURRENTSCREEN = g_pWindowManager->getMonitorFromCursor()->ID; const auto CURRENTSCREEN = g_pWindowManager->getMonitorFromCursor()->ID;
window.setWorkspaceID(g_pWindowManager->activeWorkspaces[CURRENTSCREEN]); window.setWorkspaceID(g_pWindowManager->activeWorkspaces[CURRENTSCREEN]);
window.setMonitor(CURRENTSCREEN); window.setMonitor(CURRENTSCREEN);
window.setDefaultPosition(Vector2D(0,0)); window.setDefaultPosition(Vector2D(0, 0));
window.setDefaultSize(Vector2D(g_pWindowManager->Screen->width_in_pixels/2.f,g_pWindowManager->Screen->height_in_pixels/2.f)); window.setDefaultSize(Vector2D(g_pWindowManager->Screen->width_in_pixels / 2.f, g_pWindowManager->Screen->height_in_pixels / 2.f));
// Set the parent // Set the parent
// check if lastwindow is on our workspace // check if lastwindow is on our workspace
if (auto PLASTWINDOW = g_pWindowManager->getWindowFromDrawable(g_pWindowManager->LastWindow); PLASTWINDOW if (auto PLASTWINDOW = g_pWindowManager->getWindowFromDrawable(g_pWindowManager->LastWindow); (PLASTWINDOW && PLASTWINDOW->getWorkspaceID() == g_pWindowManager->activeWorkspaces[CURRENTSCREEN]) || wasfloating) {
&& PLASTWINDOW->getWorkspaceID() == g_pWindowManager->activeWorkspaces[CURRENTSCREEN]) { // LastWindow is on our workspace, let's make a new split node
// LastWindow is on our workspace, let's make a new split node
if (PLASTWINDOW->getIsFloating()) { if (wasfloating || PLASTWINDOW->getIsFloating()) {
// find a window manually // find a window manually
PLASTWINDOW = g_pWindowManager->findWindowAtCursor(); PLASTWINDOW = g_pWindowManager->findWindowAtCursor();
} }
if (PLASTWINDOW) {
CWindow newWindowSplitNode; CWindow newWindowSplitNode;
newWindowSplitNode.setPosition(PLASTWINDOW->getPosition()); newWindowSplitNode.setPosition(PLASTWINDOW->getPosition());
newWindowSplitNode.setSize(PLASTWINDOW->getSize()); newWindowSplitNode.setSize(PLASTWINDOW->getSize());
newWindowSplitNode.setChildNodeAID(PLASTWINDOW->getDrawable()); newWindowSplitNode.setChildNodeAID(PLASTWINDOW->getDrawable());
newWindowSplitNode.setChildNodeBID(E->window); newWindowSplitNode.setChildNodeBID(windowID);
newWindowSplitNode.setParentNodeID(PLASTWINDOW->getParentNodeID()); newWindowSplitNode.setParentNodeID(PLASTWINDOW->getParentNodeID());
@ -108,6 +99,9 @@ void Events::eventMapWindow(xcb_generic_event_t* event) {
PLASTWINDOW->setParentNodeID(newWindowSplitNode.getDrawable()); PLASTWINDOW->setParentNodeID(newWindowSplitNode.getDrawable());
g_pWindowManager->addWindowToVectorSafe(newWindowSplitNode); g_pWindowManager->addWindowToVectorSafe(newWindowSplitNode);
} else {
window.setParentNodeID(0);
}
} else { } else {
// LastWindow is not on our workspace, so set the parent to 0. // LastWindow is not on our workspace, so set the parent to 0.
window.setParentNodeID(0); window.setParentNodeID(0);
@ -117,22 +111,69 @@ void Events::eventMapWindow(xcb_generic_event_t* event) {
g_pWindowManager->calculateNewWindowParams(&window); g_pWindowManager->calculateNewWindowParams(&window);
// Focus // Focus
g_pWindowManager->setFocusedWindow(E->window); g_pWindowManager->setFocusedWindow(windowID);
// Add to arr // Add to arr
g_pWindowManager->addWindowToVectorSafe(window); g_pWindowManager->addWindowToVectorSafe(window);
Debug::log(LOG, "Created a new window! X: " + std::to_string(window.getPosition().x) + ", Y: " + std::to_string(window.getPosition().y) + ", W: " Debug::log(LOG, "Created a new window! X: " + std::to_string(window.getPosition().x) + ", Y: " + std::to_string(window.getPosition().y) + ", W: " + std::to_string(window.getSize().x) + ", H:" + std::to_string(window.getSize().y) + " ID: " + std::to_string(windowID));
+ std::to_string(window.getSize().x) + ", H:" + std::to_string(window.getSize().y) + " ID: " + std::to_string(E->window));
// Set map values // Set map values
g_pWindowManager->Values[0] = XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_FOCUS_CHANGE; g_pWindowManager->Values[0] = XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_FOCUS_CHANGE;
xcb_change_window_attributes_checked(g_pWindowManager->DisplayConnection, E->window, XCB_CW_EVENT_MASK, g_pWindowManager->Values); xcb_change_window_attributes_checked(g_pWindowManager->DisplayConnection, windowID, XCB_CW_EVENT_MASK, g_pWindowManager->Values);
g_pWindowManager->setFocusedWindow(E->window); g_pWindowManager->setFocusedWindow(windowID);
float values[1];
values[0] = XCB_STACK_MODE_BELOW;
xcb_configure_window(g_pWindowManager->DisplayConnection, windowID, XCB_CONFIG_WINDOW_STACK_MODE, values);
return g_pWindowManager->getWindowFromDrawable(windowID);
}
void Events::eventMapWindow(xcb_generic_event_t* event) {
const auto E = reinterpret_cast<xcb_map_request_event_t*>(event);
// make sure it's not the bar!
if (E->window == g_pWindowManager->statusBar.getWindowID())
return;
// Map the window
xcb_map_window(g_pWindowManager->DisplayConnection, E->window);
remapWindow(E->window);
} }
void Events::eventButtonPress(xcb_generic_event_t* event) { void Events::eventButtonPress(xcb_generic_event_t* event) {
const auto E = reinterpret_cast<xcb_button_press_event_t*>(event);
// mouse down!
g_pWindowManager->mouseKeyDown = E->detail;
xcb_grab_pointer(g_pWindowManager->DisplayConnection, 0, g_pWindowManager->Screen->root, XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_BUTTON_MOTION | XCB_EVENT_MASK_POINTER_MOTION_HINT,
XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC,
g_pWindowManager->Screen->root, XCB_NONE, XCB_CURRENT_TIME);
if (const auto PLASTWINDOW = g_pWindowManager->getWindowFromDrawable(g_pWindowManager->LastWindow); PLASTWINDOW) {
if (PLASTWINDOW->getIsFloating()) {
g_pWindowManager->actingOnWindowFloating = PLASTWINDOW->getDrawable();
g_pWindowManager->mouseLastPos = g_pWindowManager->getCursorPos();
}
}
}
void Events::eventButtonRelease(xcb_generic_event_t* event) {
const auto E = reinterpret_cast<xcb_button_release_event_t*>(event);
// ungrab the mouse ptr
xcb_ungrab_pointer(g_pWindowManager->DisplayConnection, XCB_CURRENT_TIME);
const auto PACTINGWINDOW = g_pWindowManager->getWindowFromDrawable(g_pWindowManager->actingOnWindowFloating);
if (PACTINGWINDOW)
PACTINGWINDOW->setDirty(true);
g_pWindowManager->actingOnWindowFloating = 0;
g_pWindowManager->mouseKeyDown = 0;
}
void Events::eventKeyPress(xcb_generic_event_t* event) {
const auto E = reinterpret_cast<xcb_key_press_event_t*>(event); const auto E = reinterpret_cast<xcb_key_press_event_t*>(event);
const auto KEYSYM = KeybindManager::getKeysymFromKeycode(E->detail); const auto KEYSYM = KeybindManager::getKeysymFromKeycode(E->detail);
@ -146,10 +187,61 @@ void Events::eventButtonPress(xcb_generic_event_t* event) {
} }
} }
void Events::eventKeyPress(xcb_generic_event_t* event) { void Events::eventMotionNotify(xcb_generic_event_t* event) {
const auto E = reinterpret_cast<xcb_key_press_event_t*>(event); const auto E = reinterpret_cast<xcb_motion_notify_event_t*>(event);
// todo: super resize and move floating if (!g_pWindowManager->mouseKeyDown)
return; // mouse up.
if (!g_pWindowManager->actingOnWindowFloating)
return; // not acting, return.
// means we are holding super
const auto POINTERPOS = g_pWindowManager->getCursorPos();
const auto POINTERDELTA = Vector2D(POINTERPOS) - g_pWindowManager->mouseLastPos;
const auto PACTINGWINDOW = g_pWindowManager->getWindowFromDrawable(g_pWindowManager->actingOnWindowFloating);
if (!PACTINGWINDOW) {
Debug::log(ERR, "ActingWindow not null but doesn't exist?? (Died?)");
g_pWindowManager->actingOnWindowFloating = 0;
return;
}
float Values[2];
if (abs(POINTERDELTA.x) < 1 && abs(POINTERDELTA.y) < 1)
return; // micromovements
if (g_pWindowManager->mouseKeyDown == 1) {
// moving
PACTINGWINDOW->setPosition(PACTINGWINDOW->getPosition() + POINTERDELTA);
PACTINGWINDOW->setEffectivePosition(PACTINGWINDOW->getPosition());
PACTINGWINDOW->setDefaultPosition(PACTINGWINDOW->getPosition());
// update workspace if needed
if (g_pWindowManager->getMonitorFromCursor()) {
const auto WORKSPACE = g_pWindowManager->activeWorkspaces[g_pWindowManager->getMonitorFromCursor()->ID];
PACTINGWINDOW->setWorkspaceID(WORKSPACE);
} else {
PACTINGWINDOW->setWorkspaceID(-1);
}
PACTINGWINDOW->setDirty(true);
} else if (g_pWindowManager->mouseKeyDown == 3) {
// resizing
PACTINGWINDOW->setSize(PACTINGWINDOW->getSize() + POINTERDELTA);
// clamp
PACTINGWINDOW->setSize(Vector2D(std::clamp(PACTINGWINDOW->getSize().x, (double)30, (double)999999), std::clamp(PACTINGWINDOW->getSize().y, (double)30, (double)999999)));
// apply to other
PACTINGWINDOW->setDefaultSize(PACTINGWINDOW->getSize());
PACTINGWINDOW->setEffectiveSize(PACTINGWINDOW->getSize());
PACTINGWINDOW->setDirty(true);
}
g_pWindowManager->mouseLastPos = POINTERPOS;
} }
void Events::eventExpose(xcb_generic_event_t* event) { void Events::eventExpose(xcb_generic_event_t* event) {

View file

@ -10,8 +10,13 @@ namespace Events {
EVENT(Destroy); EVENT(Destroy);
EVENT(MapWindow); EVENT(MapWindow);
EVENT(ButtonPress); EVENT(ButtonPress);
EVENT(ButtonRelease);
EVENT(Expose); EVENT(Expose);
EVENT(KeyPress); EVENT(KeyPress);
EVENT(MotionNotify);
// Bypass some events for floating windows
CWindow* remapWindow(int, bool floating = false);
// A thread to notify xcb to redraw our shiz // A thread to notify xcb to redraw our shiz
void redraw(); void redraw();

View file

@ -6,7 +6,8 @@ typedef void (*Dispatcher)(std::string);
enum MODS { enum MODS {
MOD_NONE = 0, MOD_NONE = 0,
MOD_SUPER, MOD_SUPER,
MOD_SHIFT MOD_SHIFT,
MOD_SHIFTSUPER
}; };
class Keybind { class Keybind {

View file

@ -101,6 +101,7 @@ void CWindowManager::setupManager() {
xcb_flush(DisplayConnection); xcb_flush(DisplayConnection);
// MOD + mouse
xcb_grab_button(DisplayConnection, 0, xcb_grab_button(DisplayConnection, 0,
Screen->root, XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE, Screen->root, XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE,
XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, Screen->root, XCB_NONE, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, Screen->root, XCB_NONE,
@ -149,7 +150,7 @@ void CWindowManager::setupManager() {
updateBarInfo(); updateBarInfo();
// start its' update thread // start its' update thread
//Events::setThread(); Events::setThread();
Debug::log(LOG, "Bar done."); Debug::log(LOG, "Bar done.");
@ -183,15 +184,23 @@ bool CWindowManager::handleEvent() {
Debug::log(LOG, "Event dispatched MAP"); Debug::log(LOG, "Event dispatched MAP");
break; break;
case XCB_BUTTON_PRESS: case XCB_BUTTON_PRESS:
Events::eventKeyPress(ev); Events::eventButtonPress(ev);
Debug::log(LOG, "Event dispatched BUTTON_PRESS"); Debug::log(LOG, "Event dispatched BUTTON_PRESS");
break; break;
case XCB_BUTTON_RELEASE:
Events::eventButtonRelease(ev);
Debug::log(LOG, "Event dispatched BUTTON_RELEASE");
break;
case XCB_MOTION_NOTIFY:
Events::eventMotionNotify(ev);
//Debug::log(LOG, "Event dispatched MOTION_NOTIFY"); // Spam!!
break;
case XCB_EXPOSE: case XCB_EXPOSE:
Events::eventExpose(ev); Events::eventExpose(ev);
Debug::log(LOG, "Event dispatched EXPOSE"); Debug::log(LOG, "Event dispatched EXPOSE");
break; break;
case XCB_KEY_PRESS: case XCB_KEY_PRESS:
Events::eventButtonPress(ev); Events::eventKeyPress(ev);
Debug::log(LOG, "Event dispatched KEY_PRESS"); Debug::log(LOG, "Event dispatched KEY_PRESS");
break; break;
@ -247,12 +256,11 @@ void CWindowManager::cleanupUnusedWorkspaces() {
void CWindowManager::refreshDirtyWindows() { void CWindowManager::refreshDirtyWindows() {
for(auto& window : windows) { for(auto& window : windows) {
if (window.getDirty()) { if (window.getDirty()) {
window.setDirty(false);
// Check if the window isn't a node // Check if the window isn't a node
if (window.getChildNodeAID() != 0) { if (window.getChildNodeAID() != 0)
window.setDirty(false);
continue; continue;
}
setEffectiveSizePosUsingConfig(&window); setEffectiveSizePosUsingConfig(&window);
@ -319,8 +327,6 @@ void CWindowManager::refreshDirtyWindows() {
xcb_change_window_attributes(DisplayConnection, window.getDrawable(), XCB_CW_BORDER_PIXEL, Values); xcb_change_window_attributes(DisplayConnection, window.getDrawable(), XCB_CW_BORDER_PIXEL, Values);
} }
window.setDirty(false);
Debug::log(LOG, "Refreshed dirty window, with an ID of " + std::to_string(window.getDrawable())); Debug::log(LOG, "Refreshed dirty window, with an ID of " + std::to_string(window.getDrawable()));
} }
} }
@ -337,6 +343,12 @@ void CWindowManager::setFocusedWindow(xcb_drawable_t window) {
Values[0] = ConfigManager::getInt("col.active_border"); Values[0] = ConfigManager::getInt("col.active_border");
xcb_change_window_attributes(DisplayConnection, window, XCB_CW_BORDER_PIXEL, Values); xcb_change_window_attributes(DisplayConnection, window, XCB_CW_BORDER_PIXEL, Values);
float values[1];
if (g_pWindowManager->getWindowFromDrawable(window) && g_pWindowManager->getWindowFromDrawable(window)->getIsFloating()) {
values[0] = XCB_STACK_MODE_ABOVE;
xcb_configure_window(g_pWindowManager->DisplayConnection, window, XCB_CONFIG_WINDOW_STACK_MODE, values);
}
LastWindow = window; LastWindow = window;
} }
} }
@ -404,15 +416,7 @@ void CWindowManager::setEffectiveSizePosUsingConfig(CWindow* pWindow) {
CWindow* CWindowManager::findWindowAtCursor() { CWindow* CWindowManager::findWindowAtCursor() {
const auto POINTERCOOKIE = xcb_query_pointer(DisplayConnection, Screen->root); const auto POINTERCOOKIE = xcb_query_pointer(DisplayConnection, Screen->root);
xcb_query_pointer_reply_t* pointerreply = xcb_query_pointer_reply(DisplayConnection, POINTERCOOKIE, NULL); Vector2D cursorPos = getCursorPos();
if (!pointerreply) {
Debug::log(ERR, "Couldn't query pointer.");
return nullptr;
}
Vector2D cursorPos = Vector2D(pointerreply->root_x, pointerreply->root_y);
free(pointerreply);
const auto WORKSPACE = activeWorkspaces[getMonitorFromCursor()->ID]; const auto WORKSPACE = activeWorkspaces[getMonitorFromCursor()->ID];
@ -473,6 +477,9 @@ void CWindowManager::calculateNewTileSetOldTile(CWindow* pWindow) {
+ std::to_string(pWindow->getPosition().y) + " " + std::to_string(pWindow->getSize().x) + " " + std::to_string(pWindow->getPosition().y) + " " + std::to_string(pWindow->getSize().x) + " "
+ std::to_string(pWindow->getSize().y)); + std::to_string(pWindow->getSize().y));
} }
Values[0] = XCB_STACK_MODE_BELOW;
xcb_configure_window(DisplayConnection, pWindow->getDrawable(), XCB_CONFIG_WINDOW_STACK_MODE, Values);
} }
void CWindowManager::calculateNewFloatingWindow(CWindow* pWindow) { void CWindowManager::calculateNewFloatingWindow(CWindow* pWindow) {
@ -481,6 +488,9 @@ void CWindowManager::calculateNewFloatingWindow(CWindow* pWindow) {
pWindow->setPosition(pWindow->getDefaultPosition()); pWindow->setPosition(pWindow->getDefaultPosition());
pWindow->setSize(pWindow->getDefaultSize()); pWindow->setSize(pWindow->getDefaultSize());
Values[0] = XCB_STACK_MODE_ABOVE;
xcb_configure_window(DisplayConnection, pWindow->getDrawable(), XCB_CONFIG_WINDOW_STACK_MODE, Values);
} }
void CWindowManager::calculateNewWindowParams(CWindow* pWindow) { void CWindowManager::calculateNewWindowParams(CWindow* pWindow) {
@ -588,6 +598,11 @@ void CWindowManager::fixWindowOnClose(CWindow* pClosedWindow) {
// Get the sibling // Get the sibling
const auto PSIBLING = getWindowFromDrawable(PPARENT->getChildNodeAID() == pClosedWindow->getDrawable() ? PPARENT->getChildNodeBID() : PPARENT->getChildNodeAID()); const auto PSIBLING = getWindowFromDrawable(PPARENT->getChildNodeAID() == pClosedWindow->getDrawable() ? PPARENT->getChildNodeBID() : PPARENT->getChildNodeAID());
if (!PSIBLING) {
Debug::log(ERR, "No sibling found in fixOnClose! (Corrupted tree...?)");
return;
}
PSIBLING->setPosition(PPARENT->getPosition()); PSIBLING->setPosition(PPARENT->getPosition());
PSIBLING->setSize(PPARENT->getSize()); PSIBLING->setSize(PPARENT->getSize());
@ -784,16 +799,7 @@ SMonitor* CWindowManager::getMonitorFromWindow(CWindow* pWindow) {
} }
SMonitor* CWindowManager::getMonitorFromCursor() { SMonitor* CWindowManager::getMonitorFromCursor() {
const auto POINTERCOOKIE = xcb_query_pointer(DisplayConnection, Screen->root); const auto CURSORPOS = getCursorPos();
xcb_query_pointer_reply_t* pointerreply = xcb_query_pointer_reply(DisplayConnection, POINTERCOOKIE, NULL);
if (!pointerreply) {
Debug::log(ERR, "Couldn't query pointer.");
return nullptr;
}
const auto CURSORPOS = Vector2D(pointerreply->root_x, pointerreply->root_y);
free(pointerreply);
for (auto& monitor : monitors) { for (auto& monitor : monitors) {
if (VECINRECT(CURSORPOS, monitor.vecPosition.x, monitor.vecPosition.y, monitor.vecPosition.x + monitor.vecSize.x, monitor.vecPosition.y + monitor.vecSize.y)) if (VECINRECT(CURSORPOS, monitor.vecPosition.x, monitor.vecPosition.y, monitor.vecPosition.x + monitor.vecSize.x, monitor.vecPosition.y + monitor.vecSize.y))
@ -804,6 +810,21 @@ SMonitor* CWindowManager::getMonitorFromCursor() {
return nullptr; return nullptr;
} }
Vector2D CWindowManager::getCursorPos() {
const auto POINTERCOOKIE = xcb_query_pointer(DisplayConnection, Screen->root);
xcb_query_pointer_reply_t* pointerreply = xcb_query_pointer_reply(DisplayConnection, POINTERCOOKIE, NULL);
if (!pointerreply) {
Debug::log(ERR, "Couldn't query pointer.");
return Vector2D(0,0);
}
const auto CURSORPOS = Vector2D(pointerreply->root_x, pointerreply->root_y);
free(pointerreply);
return CURSORPOS;
}
bool CWindowManager::isWorkspaceVisible(int workspaceID) { bool CWindowManager::isWorkspaceVisible(int workspaceID) {
for (auto& workspace : activeWorkspaces) { for (auto& workspace : activeWorkspaces) {

View file

@ -24,6 +24,9 @@ public:
std::vector<SMonitor> monitors; std::vector<SMonitor> monitors;
bool modKeyDown = false; bool modKeyDown = false;
int mouseKeyDown = 0;
Vector2D mouseLastPos = Vector2D(0, 0);
int64_t actingOnWindowFloating = 0;
uint8_t Depth = 32; uint8_t Depth = 32;
xcb_visualtype_t* VisualType; xcb_visualtype_t* VisualType;
@ -64,6 +67,8 @@ public:
SMonitor* getMonitorFromWindow(CWindow*); SMonitor* getMonitorFromWindow(CWindow*);
SMonitor* getMonitorFromCursor(); SMonitor* getMonitorFromCursor();
Vector2D getCursorPos();
// finds a window that's tiled at cursor. // finds a window that's tiled at cursor.
CWindow* findWindowAtCursor(); CWindow* findWindowAtCursor();