mirror of
https://github.com/hyprwm/Hypr.git
synced 2024-11-22 13:35:57 +01:00
added floating windows 🎉
This commit is contained in:
parent
6898923463
commit
7b7ba35b0c
9 changed files with 212 additions and 64 deletions
|
@ -15,7 +15,7 @@ Hypr is a Linux tiling window manager for Xorg. It's written in XCB with modern
|
|||
## Roadmap (not in order)
|
||||
- [x] Multi-monitor support
|
||||
- [x] Status bar ~ Needs expanding
|
||||
- [ ] Floating windows support (Very basic for now)
|
||||
- [x] Floating windows support
|
||||
- [x] Config system ~ Basic done
|
||||
- [x] Workspaces
|
||||
- [x] Moving windows / user input (e.g. fullscreening) ~ More to be done probably
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "KeybindManager.hpp"
|
||||
#include "utilities/Util.hpp"
|
||||
#include "events/events.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <string.h>
|
||||
|
@ -57,6 +58,8 @@ unsigned int KeybindManager::modToMask(MODS mod) {
|
|||
return XCB_MOD_MASK_4;
|
||||
case MOD_SHIFT:
|
||||
return XCB_MOD_MASK_SHIFT;
|
||||
case MOD_SHIFTSUPER:
|
||||
return XCB_MOD_MASK_4 | XCB_MOD_MASK_SHIFT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -137,9 +140,24 @@ void KeybindManager::toggleActiveWindowFloating(std::string unusedArg) {
|
|||
PWINDOW->setDirty(true);
|
||||
|
||||
// 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->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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -84,6 +84,11 @@ void CStatusBar::setup(int MonitorID) {
|
|||
|
||||
// don't, i use it later
|
||||
//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() {
|
||||
|
|
|
@ -49,6 +49,7 @@ void handleBind(const std::string& command, const std::string& value) {
|
|||
|
||||
if (MOD == "SUPER") mod = MOD_SUPER;
|
||||
else if (MOD == "SHIFT") mod = MOD_SHIFT;
|
||||
else if (MOD == "SUPERSHIFT" || MOD == "SHIFTSUPER") mod = MOD_SHIFTSUPER;
|
||||
|
||||
Dispatcher dispatcher = nullptr;
|
||||
if (HANDLER == "exec") dispatcher = KeybindManager::call;
|
||||
|
|
|
@ -37,9 +37,9 @@ void Events::eventDestroy(xcb_generic_event_t* event) {
|
|||
const auto E = reinterpret_cast<xcb_destroy_notify_event_t*>(event);
|
||||
xcb_kill_client(g_pWindowManager->DisplayConnection, E->window);
|
||||
|
||||
// fix last window
|
||||
// fix last window if tile
|
||||
const auto CLOSEDWINDOW = g_pWindowManager->getWindowFromDrawable(E->window);
|
||||
if (CLOSEDWINDOW) {
|
||||
if (CLOSEDWINDOW && !CLOSEDWINDOW->getIsFloating()) {
|
||||
g_pWindowManager->fixWindowOnClose(CLOSEDWINDOW);
|
||||
|
||||
// delete off of the arr
|
||||
|
@ -47,19 +47,10 @@ void Events::eventDestroy(xcb_generic_event_t* event) {
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
CWindow* Events::remapWindow(int windowID, bool wasfloating) {
|
||||
// Do the setup of the window's params and stuf
|
||||
CWindow window;
|
||||
window.setDrawable(E->window);
|
||||
window.setDrawable(windowID);
|
||||
window.setIsFloating(false);
|
||||
window.setDirty(true);
|
||||
const auto CURRENTSCREEN = g_pWindowManager->getMonitorFromCursor()->ID;
|
||||
|
@ -71,21 +62,21 @@ void Events::eventMapWindow(xcb_generic_event_t* event) {
|
|||
|
||||
// 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]) {
|
||||
if (auto PLASTWINDOW = g_pWindowManager->getWindowFromDrawable(g_pWindowManager->LastWindow); (PLASTWINDOW && PLASTWINDOW->getWorkspaceID() == g_pWindowManager->activeWorkspaces[CURRENTSCREEN]) || wasfloating) {
|
||||
// LastWindow is on our workspace, let's make a new split node
|
||||
|
||||
if (PLASTWINDOW->getIsFloating()) {
|
||||
if (wasfloating || PLASTWINDOW->getIsFloating()) {
|
||||
// find a window manually
|
||||
PLASTWINDOW = g_pWindowManager->findWindowAtCursor();
|
||||
}
|
||||
|
||||
if (PLASTWINDOW) {
|
||||
CWindow newWindowSplitNode;
|
||||
newWindowSplitNode.setPosition(PLASTWINDOW->getPosition());
|
||||
newWindowSplitNode.setSize(PLASTWINDOW->getSize());
|
||||
|
||||
newWindowSplitNode.setChildNodeAID(PLASTWINDOW->getDrawable());
|
||||
newWindowSplitNode.setChildNodeBID(E->window);
|
||||
newWindowSplitNode.setChildNodeBID(windowID);
|
||||
|
||||
newWindowSplitNode.setParentNodeID(PLASTWINDOW->getParentNodeID());
|
||||
|
||||
|
@ -108,6 +99,9 @@ void Events::eventMapWindow(xcb_generic_event_t* event) {
|
|||
PLASTWINDOW->setParentNodeID(newWindowSplitNode.getDrawable());
|
||||
|
||||
g_pWindowManager->addWindowToVectorSafe(newWindowSplitNode);
|
||||
} else {
|
||||
window.setParentNodeID(0);
|
||||
}
|
||||
} else {
|
||||
// LastWindow is not on our workspace, so set the parent to 0.
|
||||
window.setParentNodeID(0);
|
||||
|
@ -117,22 +111,69 @@ void Events::eventMapWindow(xcb_generic_event_t* event) {
|
|||
g_pWindowManager->calculateNewWindowParams(&window);
|
||||
|
||||
// Focus
|
||||
g_pWindowManager->setFocusedWindow(E->window);
|
||||
g_pWindowManager->setFocusedWindow(windowID);
|
||||
|
||||
// Add to arr
|
||||
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: "
|
||||
+ std::to_string(window.getSize().x) + ", H:" + std::to_string(window.getSize().y) + " ID: " + std::to_string(E->window));
|
||||
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));
|
||||
|
||||
// Set map values
|
||||
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) {
|
||||
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 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) {
|
||||
const auto E = reinterpret_cast<xcb_key_press_event_t*>(event);
|
||||
void Events::eventMotionNotify(xcb_generic_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) {
|
||||
|
|
|
@ -10,8 +10,13 @@ namespace Events {
|
|||
EVENT(Destroy);
|
||||
EVENT(MapWindow);
|
||||
EVENT(ButtonPress);
|
||||
EVENT(ButtonRelease);
|
||||
EVENT(Expose);
|
||||
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
|
||||
void redraw();
|
||||
|
|
|
@ -6,7 +6,8 @@ typedef void (*Dispatcher)(std::string);
|
|||
enum MODS {
|
||||
MOD_NONE = 0,
|
||||
MOD_SUPER,
|
||||
MOD_SHIFT
|
||||
MOD_SHIFT,
|
||||
MOD_SHIFTSUPER
|
||||
};
|
||||
|
||||
class Keybind {
|
||||
|
|
|
@ -101,6 +101,7 @@ void CWindowManager::setupManager() {
|
|||
|
||||
xcb_flush(DisplayConnection);
|
||||
|
||||
// MOD + mouse
|
||||
xcb_grab_button(DisplayConnection, 0,
|
||||
Screen->root, XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE,
|
||||
XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, Screen->root, XCB_NONE,
|
||||
|
@ -149,7 +150,7 @@ void CWindowManager::setupManager() {
|
|||
updateBarInfo();
|
||||
|
||||
// start its' update thread
|
||||
//Events::setThread();
|
||||
Events::setThread();
|
||||
|
||||
Debug::log(LOG, "Bar done.");
|
||||
|
||||
|
@ -183,15 +184,23 @@ bool CWindowManager::handleEvent() {
|
|||
Debug::log(LOG, "Event dispatched MAP");
|
||||
break;
|
||||
case XCB_BUTTON_PRESS:
|
||||
Events::eventKeyPress(ev);
|
||||
Events::eventButtonPress(ev);
|
||||
Debug::log(LOG, "Event dispatched BUTTON_PRESS");
|
||||
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:
|
||||
Events::eventExpose(ev);
|
||||
Debug::log(LOG, "Event dispatched EXPOSE");
|
||||
break;
|
||||
case XCB_KEY_PRESS:
|
||||
Events::eventButtonPress(ev);
|
||||
Events::eventKeyPress(ev);
|
||||
Debug::log(LOG, "Event dispatched KEY_PRESS");
|
||||
break;
|
||||
|
||||
|
@ -247,12 +256,11 @@ void CWindowManager::cleanupUnusedWorkspaces() {
|
|||
void CWindowManager::refreshDirtyWindows() {
|
||||
for(auto& window : windows) {
|
||||
if (window.getDirty()) {
|
||||
window.setDirty(false);
|
||||
|
||||
// Check if the window isn't a node
|
||||
if (window.getChildNodeAID() != 0) {
|
||||
window.setDirty(false);
|
||||
if (window.getChildNodeAID() != 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
setEffectiveSizePosUsingConfig(&window);
|
||||
|
||||
|
@ -319,8 +327,6 @@ void CWindowManager::refreshDirtyWindows() {
|
|||
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()));
|
||||
}
|
||||
}
|
||||
|
@ -337,6 +343,12 @@ void CWindowManager::setFocusedWindow(xcb_drawable_t window) {
|
|||
Values[0] = ConfigManager::getInt("col.active_border");
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -404,15 +416,7 @@ void CWindowManager::setEffectiveSizePosUsingConfig(CWindow* pWindow) {
|
|||
CWindow* CWindowManager::findWindowAtCursor() {
|
||||
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 nullptr;
|
||||
}
|
||||
|
||||
Vector2D cursorPos = Vector2D(pointerreply->root_x, pointerreply->root_y);
|
||||
|
||||
free(pointerreply);
|
||||
Vector2D cursorPos = getCursorPos();
|
||||
|
||||
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->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) {
|
||||
|
@ -481,6 +488,9 @@ void CWindowManager::calculateNewFloatingWindow(CWindow* pWindow) {
|
|||
|
||||
pWindow->setPosition(pWindow->getDefaultPosition());
|
||||
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) {
|
||||
|
@ -588,6 +598,11 @@ void CWindowManager::fixWindowOnClose(CWindow* pClosedWindow) {
|
|||
// Get the sibling
|
||||
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->setSize(PPARENT->getSize());
|
||||
|
||||
|
@ -784,16 +799,7 @@ SMonitor* CWindowManager::getMonitorFromWindow(CWindow* pWindow) {
|
|||
}
|
||||
|
||||
SMonitor* CWindowManager::getMonitorFromCursor() {
|
||||
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 nullptr;
|
||||
}
|
||||
|
||||
const auto CURSORPOS = Vector2D(pointerreply->root_x, pointerreply->root_y);
|
||||
free(pointerreply);
|
||||
const auto CURSORPOS = getCursorPos();
|
||||
|
||||
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))
|
||||
|
@ -804,6 +810,21 @@ SMonitor* CWindowManager::getMonitorFromCursor() {
|
|||
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) {
|
||||
|
||||
for (auto& workspace : activeWorkspaces) {
|
||||
|
|
|
@ -24,6 +24,9 @@ public:
|
|||
std::vector<SMonitor> monitors;
|
||||
|
||||
bool modKeyDown = false;
|
||||
int mouseKeyDown = 0;
|
||||
Vector2D mouseLastPos = Vector2D(0, 0);
|
||||
int64_t actingOnWindowFloating = 0;
|
||||
|
||||
uint8_t Depth = 32;
|
||||
xcb_visualtype_t* VisualType;
|
||||
|
@ -64,6 +67,8 @@ public:
|
|||
SMonitor* getMonitorFromWindow(CWindow*);
|
||||
SMonitor* getMonitorFromCursor();
|
||||
|
||||
Vector2D getCursorPos();
|
||||
|
||||
// finds a window that's tiled at cursor.
|
||||
CWindow* findWindowAtCursor();
|
||||
|
||||
|
|
Loading…
Reference in a new issue