diff --git a/example/hypr.conf b/example/hypr.conf index f659887..c51a1d9 100644 --- a/example/hypr.conf +++ b/example/hypr.conf @@ -35,4 +35,4 @@ bind=SUPER,7,workspace,7 bind=SUPER,8,workspace,8 bind=SUPER,9,workspace,9 - +bind=SUPER,SPACE,togglefloating, diff --git a/src/KeybindManager.cpp b/src/KeybindManager.cpp index 5aba8da..88d3d29 100644 --- a/src/KeybindManager.cpp +++ b/src/KeybindManager.cpp @@ -40,6 +40,8 @@ uint32_t KeybindManager::getKeyCodeFromName(std::string name) { return 0xff52; } else if (name == "down") { return 0xff54; + } else if (name == "space") { + return 0x20; } } @@ -147,4 +149,17 @@ void KeybindManager::toggleActiveWindowFullscreen(std::string unusedArg) { WINDOW->setFullscreen(!WINDOW->getFullscreen()); g_pWindowManager->activeWorkspace->setHasFullscreenWindow(WINDOW->getFullscreen()); } +} + +void KeybindManager::toggleActiveWindowFloating(std::string unusedArg) { + if (const auto PWINDOW = g_pWindowManager->getWindowFromDrawable(g_pWindowManager->LastWindow); PWINDOW) { + PWINDOW->setIsFloating(!PWINDOW->getIsFloating()); + PWINDOW->setDirty(true); + + // Fix window as if it's closed if we just made it floating + if (PWINDOW->getIsFloating()) + g_pWindowManager->fixWindowOnClose(PWINDOW); + + g_pWindowManager->calculateNewWindowParams(PWINDOW); + } } \ No newline at end of file diff --git a/src/KeybindManager.hpp b/src/KeybindManager.hpp index 2dd444f..0a7e7c2 100644 --- a/src/KeybindManager.hpp +++ b/src/KeybindManager.hpp @@ -15,13 +15,13 @@ namespace KeybindManager { xcb_keysym_t getKeysymFromKeycode(xcb_keycode_t keycode); xcb_keycode_t getKeycodeFromKeysym(xcb_keysym_t keysym); + uint32_t getKeyCodeFromName(std::string); + // Dispatchers void call(std::string args); void killactive(std::string args); void movewindow(std::string args); void changeworkspace(std::string args); void toggleActiveWindowFullscreen(std::string args); - - - uint32_t getKeyCodeFromName(std::string); + void toggleActiveWindowFloating(std::string args); }; \ No newline at end of file diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 8f88c51..2f3ae33 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -48,6 +48,7 @@ void handleBind(const std::string& command, const std::string& value) { if (HANDLER == "fullscreen") dispatcher = KeybindManager::toggleActiveWindowFullscreen; if (HANDLER == "movewindow") dispatcher = KeybindManager::call; if (HANDLER == "workspace") dispatcher = KeybindManager::changeworkspace; + if (HANDLER == "togglefloating") dispatcher = KeybindManager::toggleActiveWindowFloating; if (dispatcher) KeybindManager::keybinds.push_back(Keybind(mod, KEY, COMMAND, dispatcher)); diff --git a/src/events/events.cpp b/src/events/events.cpp index 9812921..d572803 100644 --- a/src/events/events.cpp +++ b/src/events/events.cpp @@ -66,6 +66,9 @@ void Events::eventMapWindow(xcb_generic_event_t* event) { window.setDirty(true); window.setWorkspaceID(g_pWindowManager->activeWorkspace->getID()); + window.setDefaultPosition(Vector2D(0,0)); + window.setDefaultSize(Vector2D(g_pWindowManager->Screen->width_in_pixels/2.f,g_pWindowManager->Screen->height_in_pixels/2.f)); + // Also sets the old one g_pWindowManager->calculateNewWindowParams(&window); diff --git a/src/window.cpp b/src/window.cpp index 6462e01..d6d7de2 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -1,4 +1,4 @@ #include "window.hpp" -CWindow::CWindow() { this->setDirty(true); } +CWindow::CWindow() { this->setDirty(true); this->setFullscreen(false); this->setIsFloating(false); } CWindow::~CWindow() { } \ No newline at end of file diff --git a/src/window.hpp b/src/window.hpp index c006464..4c9cde8 100644 --- a/src/window.hpp +++ b/src/window.hpp @@ -31,6 +31,10 @@ public: // Workspace pointer EXPOSED_MEMBER(WorkspaceID, int, i); + + // For floating + EXPOSED_MEMBER(DefaultSize, Vector2D, vec); + EXPOSED_MEMBER(DefaultPosition, Vector2D, vec); private: diff --git a/src/windowManager.cpp b/src/windowManager.cpp index 36b9802..2675c7d 100644 --- a/src/windowManager.cpp +++ b/src/windowManager.cpp @@ -294,8 +294,41 @@ void CWindowManager::setEffectiveSizePosUsingConfig(CWindow* pWindow) { pWindow->setEffectiveSize(pWindow->getEffectiveSize() - Vector2D(DISPLAYRIGHT ? ConfigManager::getInt("gaps_out") : ConfigManager::getInt("gaps_in"), DISPLAYBOTTOM ? ConfigManager::getInt("gaps_out") : ConfigManager::getInt("gaps_in"))); } +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); + + for (auto& window : windows) { + if (window.getWorkspaceID() == activeWorkspace->getID() && !window.getIsFloating()) { + + if (cursorPos.x >= window.getPosition().x + && cursorPos.x <= window.getPosition().x + window.getSize().x + && cursorPos.y >= window.getPosition().y + && cursorPos.y <= window.getPosition().y + window.getSize().y) { + + return &window; + } + } + } +} + void CWindowManager::calculateNewTileSetOldTile(CWindow* pWindow) { - const auto PLASTWINDOW = getWindowFromDrawable(LastWindow); + auto PLASTWINDOW = getWindowFromDrawable(LastWindow); + + if (PLASTWINDOW && PLASTWINDOW->getIsFloating()) { + // find a window manually + PLASTWINDOW = findWindowAtCursor(); + } + if (PLASTWINDOW) { const auto PLASTSIZE = PLASTWINDOW->getSize(); const auto PLASTPOS = PLASTWINDOW->getPosition(); @@ -318,6 +351,14 @@ void CWindowManager::calculateNewTileSetOldTile(CWindow* pWindow) { } } +void CWindowManager::calculateNewFloatingWindow(CWindow* pWindow) { + if (!pWindow) + return; + + pWindow->setPosition(pWindow->getDefaultPosition()); + pWindow->setSize(pWindow->getDefaultSize()); +} + void CWindowManager::calculateNewWindowParams(CWindow* pWindow) { // And set old one's if needed. if (!pWindow) @@ -325,6 +366,8 @@ void CWindowManager::calculateNewWindowParams(CWindow* pWindow) { if (!pWindow->getIsFloating()) { calculateNewTileSetOldTile(pWindow); + } else { + calculateNewFloatingWindow(pWindow); } pWindow->setDirty(true); @@ -385,7 +428,7 @@ bool CWindowManager::canEatWindow(CWindow* a, CWindow* toEat) { }; for (auto& w : windows) { - if (w.getDrawable() == a->getDrawable() || w.getDrawable() == toEat->getDrawable() || w.getWorkspaceID() != toEat->getWorkspaceID()) + if (w.getDrawable() == a->getDrawable() || w.getDrawable() == toEat->getDrawable() || w.getWorkspaceID() != toEat->getWorkspaceID() || w.getIsFloating()) continue; if (doOverlap(&w)) diff --git a/src/windowManager.hpp b/src/windowManager.hpp index a5bd97b..f2a43d8 100644 --- a/src/windowManager.hpp +++ b/src/windowManager.hpp @@ -62,6 +62,8 @@ private: bool canEatWindow(CWindow* a, CWindow* toEat); 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();