From 1e4b54f3f0f3beaba57dea6fdf2b0b7ca63e56bf Mon Sep 17 00:00:00 2001 From: vaxerski <43317083+vaxerski@users.noreply.github.com> Date: Thu, 25 Nov 2021 17:44:46 +0100 Subject: [PATCH] Added move to workspace and fixed floating windows being wonky a bit --- README.md | 2 +- example/hypr.conf | 10 +++++++ src/KeybindManager.cpp | 9 ++++++ src/KeybindManager.hpp | 1 + src/config/ConfigManager.cpp | 1 + src/events/events.cpp | 12 ++++---- src/events/events.hpp | 4 +-- src/windowManager.cpp | 58 +++++++++++++++++++++++++++++++++--- src/windowManager.hpp | 1 + 9 files changed, 85 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 4860e44..ce1c613 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Hypr is a Linux tiling window manager for Xorg. It's written in XCB with modern - [ ] Replace default X11 cursor with the pointer - [x] Fix ghost windows once and for all - [ ] Fix windows minimizing themselves to tray not being able to come back without pkill -- [ ] Moving windows between workspaces without floating +- [x] Moving windows between workspaces without floating - [x] EWMH ~ Basic, idk if i'll add more. - [ ] Docks / Fullscreen Apps etc. auto-detection - [ ] Fix animation flicker (if possible) diff --git a/example/hypr.conf b/example/hypr.conf index 3e8e95a..290706d 100644 --- a/example/hypr.conf +++ b/example/hypr.conf @@ -45,4 +45,14 @@ bind=SUPER,7,workspace,7 bind=SUPER,8,workspace,8 bind=SUPER,9,workspace,9 +bind=SUPERSHIFT,1,movetoworkspace,1 +bind=SUPERSHIFT,2,movetoworkspace,2 +bind=SUPERSHIFT,3,movetoworkspace,3 +bind=SUPERSHIFT,4,movetoworkspace,4 +bind=SUPERSHIFT,5,movetoworkspace,5 +bind=SUPERSHIFT,6,movetoworkspace,6 +bind=SUPERSHIFT,7,movetoworkspace,7 +bind=SUPERSHIFT,8,movetoworkspace,8 +bind=SUPERSHIFT,9,movetoworkspace,9 + bind=SUPER,SPACE,togglefloating, diff --git a/src/KeybindManager.cpp b/src/KeybindManager.cpp index 97e321b..fc989bf 100644 --- a/src/KeybindManager.cpp +++ b/src/KeybindManager.cpp @@ -108,6 +108,15 @@ void KeybindManager::movewindow(std::string arg) { g_pWindowManager->moveActiveWindowTo(arg[0]); } +void KeybindManager::movetoworkspace(std::string arg) { + try { + g_pWindowManager->moveActiveWindowToWorkspace(stoi(arg)); + } catch (...) { + Debug::log(ERR, "Invalid arg in movetoworkspace, arg: " + arg); + } + +} + void KeybindManager::changeworkspace(std::string arg) { int ID = -1; try { diff --git a/src/KeybindManager.hpp b/src/KeybindManager.hpp index 0a7e7c2..f8e1c45 100644 --- a/src/KeybindManager.hpp +++ b/src/KeybindManager.hpp @@ -24,4 +24,5 @@ namespace KeybindManager { void changeworkspace(std::string args); void toggleActiveWindowFullscreen(std::string args); void toggleActiveWindowFloating(std::string args); + void movetoworkspace(std::string args); }; \ No newline at end of file diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index a67ac08..9366909 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -67,6 +67,7 @@ void handleBind(const std::string& command, const std::string& value) { if (HANDLER == "killactive") dispatcher = KeybindManager::killactive; if (HANDLER == "fullscreen") dispatcher = KeybindManager::toggleActiveWindowFullscreen; if (HANDLER == "movewindow") dispatcher = KeybindManager::movewindow; + if (HANDLER == "movetoworkspace") dispatcher = KeybindManager::movetoworkspace; if (HANDLER == "workspace") dispatcher = KeybindManager::changeworkspace; if (HANDLER == "togglefloating") dispatcher = KeybindManager::toggleActiveWindowFloating; diff --git a/src/events/events.cpp b/src/events/events.cpp index db52292..adbdb6f 100644 --- a/src/events/events.cpp +++ b/src/events/events.cpp @@ -40,7 +40,7 @@ void Events::eventDestroy(xcb_generic_event_t* event) { g_pWindowManager->closeWindowAllChecks(E->window); } -CWindow* Events::remapFloatingWindow(int windowID) { +CWindow* Events::remapFloatingWindow(int windowID, int forcemonitor) { CWindow window; window.setDrawable(windowID); window.setIsFloating(true); @@ -49,7 +49,7 @@ CWindow* Events::remapFloatingWindow(int windowID) { Debug::log(ERR, "Monitor was null! (remapWindow)"); // rip! we cannot continue. } - const auto CURRENTSCREEN = g_pWindowManager->getMonitorFromCursor()->ID; + const auto CURRENTSCREEN = forcemonitor != -1 ? forcemonitor : g_pWindowManager->getMonitorFromCursor()->ID; window.setWorkspaceID(g_pWindowManager->activeWorkspaces[CURRENTSCREEN]); window.setMonitor(CURRENTSCREEN); @@ -58,12 +58,12 @@ CWindow* Events::remapFloatingWindow(int windowID) { const auto GEOMETRY = xcb_get_geometry_reply(g_pWindowManager->DisplayConnection, GEOMETRYCOOKIE, 0); if (GEOMETRY) { - window.setDefaultPosition(Vector2D(GEOMETRY->x, GEOMETRY->y)); + window.setDefaultPosition(g_pWindowManager->monitors[CURRENTSCREEN].vecPosition); window.setDefaultSize(Vector2D(GEOMETRY->width, GEOMETRY->height)); } else { Debug::log(ERR, "Geometry failed in remap."); - window.setDefaultPosition(Vector2D(0, 0)); + window.setDefaultPosition(g_pWindowManager->monitors[CURRENTSCREEN].vecPosition); window.setDefaultSize(Vector2D(g_pWindowManager->Screen->width_in_pixels / 2.f, g_pWindowManager->Screen->height_in_pixels / 2.f)); } @@ -91,7 +91,7 @@ CWindow* Events::remapFloatingWindow(int windowID) { return g_pWindowManager->getWindowFromDrawable(windowID); } -CWindow* Events::remapWindow(int windowID, bool wasfloating) { +CWindow* Events::remapWindow(int windowID, bool wasfloating, int forcemonitor) { // Do the setup of the window's params and stuf CWindow window; window.setDrawable(windowID); @@ -101,7 +101,7 @@ CWindow* Events::remapWindow(int windowID, bool wasfloating) { Debug::log(ERR, "Monitor was null! (remapWindow)"); // rip! we cannot continue. } - const auto CURRENTSCREEN = g_pWindowManager->getMonitorFromCursor()->ID; + const auto CURRENTSCREEN = forcemonitor != -1 ? forcemonitor : g_pWindowManager->getMonitorFromCursor()->ID; window.setWorkspaceID(g_pWindowManager->activeWorkspaces[CURRENTSCREEN]); window.setMonitor(CURRENTSCREEN); diff --git a/src/events/events.hpp b/src/events/events.hpp index b2b3369..08c35f5 100644 --- a/src/events/events.hpp +++ b/src/events/events.hpp @@ -16,8 +16,8 @@ namespace Events { EVENT(MotionNotify); // Bypass some events for floating windows - CWindow* remapWindow(int, bool floating = false); - CWindow* remapFloatingWindow(int); + CWindow* remapWindow(int, bool floating = false, int forcemonitor = -1); + CWindow* remapFloatingWindow(int, int forcemonitor = -1); // A thread to notify xcb to redraw our shiz void redraw(); diff --git a/src/windowManager.cpp b/src/windowManager.cpp index 91a4717..1a5840b 100644 --- a/src/windowManager.cpp +++ b/src/windowManager.cpp @@ -95,9 +95,10 @@ void CWindowManager::setupManager() { EWMH::setupInitEWMH(); setupRandrMonitors(); - if (monitors.size() == 0) { + if (monitors.size() == 0 || true) { // RandR failed! Debug::log(WARN, "RandR failed!"); + monitors.clear(); #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) { @@ -507,7 +508,7 @@ void CWindowManager::removeWindowFromVectorSafe(int64_t window) { void CWindowManager::setEffectiveSizePosUsingConfig(CWindow* pWindow) { - if (!pWindow) + if (!pWindow || pWindow->getIsFloating()) return; const auto MONITOR = getMonitorFromWindow(pWindow); @@ -560,7 +561,7 @@ void CWindowManager::calculateNewTileSetOldTile(CWindow* pWindow) { if (!PPARENT) { // New window on this workspace. // Open a fullscreen window. - const auto MONITOR = getMonitorFromCursor(); + const auto MONITOR = getMonitorFromWindow(pWindow); if (!MONITOR) { Debug::log(ERR, "Monitor was nullptr! (calculateNewTileSetOldTile)"); return; @@ -607,7 +608,7 @@ void CWindowManager::calculateNewFloatingWindow(CWindow* pWindow) { if (!pWindow) return; - //pWindow->setPosition(pWindow->getDefaultPosition()); + pWindow->setPosition(pWindow->getDefaultPosition()); pWindow->setSize(pWindow->getDefaultSize()); pWindow->setEffectivePosition(pWindow->getPosition() + Vector2D(10,10)); @@ -826,6 +827,55 @@ void CWindowManager::warpCursorTo(Vector2D to) { free(pointerreply); } +void CWindowManager::moveActiveWindowToWorkspace(int workspace) { + + const auto PWINDOW = getWindowFromDrawable(LastWindow); + + if (!PWINDOW) + return; + + const auto SAVEDDEFAULTSIZE = PWINDOW->getDefaultSize(); + const auto SAVEDFLOATSTATUS = PWINDOW->getIsFloating(); + const auto SAVEDDRAWABLE = PWINDOW->getDrawable(); + + closeWindowAllChecks(SAVEDDRAWABLE); + + // PWINDOW is dead! + + changeWorkspaceByID(workspace); + + // Find new mon + int NEWMONITOR = 0; + for (long unsigned int i = 0; i < activeWorkspaces.size(); ++i) { + if (activeWorkspaces[i] == workspace) { + NEWMONITOR = i; + } + } + + // Find the first window on the new workspace + xcb_drawable_t newLastWindow = 0; + for (auto& w : windows) { + if (w.getDrawable() > 0 && w.getWorkspaceID() == workspace && !w.getIsFloating()) { + newLastWindow = w.getDrawable(); + break; + } + } + + if (newLastWindow) { + setFocusedWindow(newLastWindow); + } + + + CWindow* PNEWWINDOW = nullptr; + if (SAVEDFLOATSTATUS) + PNEWWINDOW = Events::remapFloatingWindow(SAVEDDRAWABLE, NEWMONITOR); + else + PNEWWINDOW = Events::remapWindow(SAVEDDRAWABLE, false, NEWMONITOR); + + + PNEWWINDOW->setDefaultSize(SAVEDDEFAULTSIZE); +} + void CWindowManager::moveActiveWindowTo(char dir) { const auto CURRENTWINDOW = getWindowFromDrawable(LastWindow); diff --git a/src/windowManager.hpp b/src/windowManager.hpp index 4bcfc38..16b7aed 100644 --- a/src/windowManager.hpp +++ b/src/windowManager.hpp @@ -61,6 +61,7 @@ public: void closeWindowAllChecks(int64_t); void moveActiveWindowTo(char); + void moveActiveWindowToWorkspace(int); void warpCursorTo(Vector2D); void changeWorkspaceByID(int);