Hyprland/src/layout/IHyprLayout.cpp

934 lines
40 KiB
C++
Raw Normal View History

2022-06-30 12:09:05 +02:00
#include "IHyprLayout.hpp"
#include "../defines.hpp"
#include "../Compositor.hpp"
#include "../render/decorations/CHyprGroupBarDecoration.hpp"
#include "../config/ConfigValue.hpp"
2024-03-20 01:44:51 +00:00
#include "../desktop/Window.hpp"
2024-05-10 23:28:33 +01:00
#include "../protocols/XDGShell.hpp"
#include "../protocols/core/Compositor.hpp"
#include "../xwayland/XSurface.hpp"
2022-06-30 12:09:05 +02:00
void IHyprLayout::onWindowCreated(PHLWINDOW pWindow, eDirection direction) {
CBox desiredGeometry = {};
g_pXWaylandManager->getGeometryForWindow(pWindow, &desiredGeometry);
2022-08-05 17:52:14 +02:00
if (desiredGeometry.width <= 5 || desiredGeometry.height <= 5) {
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
pWindow->m_vLastFloatingSize = PMONITOR->vecSize / 2.f;
} else
pWindow->m_vLastFloatingSize = Vector2D(desiredGeometry.width, desiredGeometry.height);
2022-08-05 17:52:14 +02:00
pWindow->m_vPseudoSize = pWindow->m_vLastFloatingSize;
if (!g_pXWaylandManager->shouldBeFloated(pWindow)) // do not apply group rules to child windows
pWindow->applyGroupRules();
bool autoGrouped = IHyprLayout::onWindowCreatedAutoGroup(pWindow);
if (autoGrouped)
return;
if (pWindow->m_bIsFloating)
onWindowCreatedFloating(pWindow);
else
onWindowCreatedTiling(pWindow, direction);
2022-06-30 12:09:05 +02:00
}
void IHyprLayout::onWindowRemoved(PHLWINDOW pWindow) {
internal: refactor fullscreen states (#7104) * refactor fullscreen modified: src/Compositor.cpp modified: src/Compositor.hpp modified: src/config/ConfigManager.cpp modified: src/config/ConfigManager.hpp modified: src/debug/HyprCtl.cpp modified: src/desktop/LayerSurface.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/desktop/Workspace.cpp modified: src/desktop/Workspace.hpp modified: src/events/Windows.cpp modified: src/helpers/Monitor.cpp modified: src/layout/DwindleLayout.cpp modified: src/layout/DwindleLayout.hpp modified: src/layout/IHyprLayout.cpp modified: src/layout/IHyprLayout.hpp modified: src/layout/MasterLayout.cpp modified: src/layout/MasterLayout.hpp modified: src/managers/KeybindManager.cpp modified: src/managers/KeybindManager.hpp modified: src/managers/input/IdleInhibitor.cpp modified: src/managers/input/InputManager.cpp modified: src/managers/input/Swipe.cpp modified: src/protocols/ForeignToplevelWlr.cpp modified: src/render/Renderer.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp * clean up modified: src/config/ConfigManager.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.hpp modified: src/desktop/Workspace.cpp modified: src/events/Windows.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/input/Swipe.cpp * fix mapWindow fullscreen modified: src/events/Windows.cpp * fix typo modified: src/desktop/Workspace.cpp * add fullscreenstate modified: src/config/ConfigManager.cpp modified: src/events/Windows.cpp * change syncFullscreen to lower modified: src/config/ConfigManager.hpp * initialize fs state modified: src/desktop/Window.hpp
2024-07-31 17:55:52 +00:00
if (pWindow->isFullscreen())
g_pCompositor->setWindowFullscreenInternal(pWindow, FSMODE_NONE);
2022-12-07 18:55:56 +00:00
if (!pWindow->m_sGroupData.pNextWindow.expired()) {
if (pWindow->m_sGroupData.pNextWindow.lock() == pWindow)
pWindow->m_sGroupData.pNextWindow.reset();
2023-02-19 21:07:32 +00:00
else {
// find last window and update
PHLWINDOW PWINDOWPREV = pWindow->getGroupPrevious();
const auto WINDOWISVISIBLE = pWindow->getGroupCurrent() == pWindow;
2023-02-19 21:07:32 +00:00
if (WINDOWISVISIBLE)
PWINDOWPREV->setGroupCurrent(pWindow->m_sGroupData.head ? pWindow->m_sGroupData.pNextWindow.lock() : PWINDOWPREV);
2023-02-19 21:07:32 +00:00
PWINDOWPREV->m_sGroupData.pNextWindow = pWindow->m_sGroupData.pNextWindow;
2023-02-19 21:07:32 +00:00
pWindow->m_sGroupData.pNextWindow.reset();
2023-02-19 21:07:32 +00:00
if (pWindow->m_sGroupData.head) {
std::swap(PWINDOWPREV->m_sGroupData.pNextWindow->m_sGroupData.head, pWindow->m_sGroupData.head);
std::swap(PWINDOWPREV->m_sGroupData.pNextWindow->m_sGroupData.locked, pWindow->m_sGroupData.locked);
2023-02-19 21:07:32 +00:00
}
if (pWindow == m_pLastTiledWindow)
m_pLastTiledWindow.reset();
2023-02-19 21:07:32 +00:00
2023-02-19 23:26:36 +00:00
pWindow->setHidden(false);
decos: groupbar mouse interaction (#3102) * allow groupbar clicking modified: src/Window.cpp modified: src/Window.hpp modified: src/managers/input/InputManager.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp modified: src/render/decorations/CHyprGroupBarDecoration.hpp * remove setting pos inside insertWindowToGroup() modified: src/Window.cpp modified: src/layout/DwindleLayout.cpp modified: src/layout/MasterLayout.cpp modified: src/managers/KeybindManager.cpp * add group window by index and group size functions modified: src/Window.cpp modified: src/Window.hpp modified: src/managers/input/InputManager.cpp * allow dragging into groupbar modified: src/Window.cpp modified: src/layout/DwindleLayout.cpp modified: src/layout/MasterLayout.cpp * allow dragging from groupbar modified: src/managers/KeybindManager.cpp * try groupbar clicking before border resize modified: src/managers/input/InputManager.cpp * block grabbing groupbar on floating (crash) remove later when crashing is fixed modified: src/managers/KeybindManager.cpp * remove redundant { } modified: src/layout/DwindleLayout.cpp modified: src/layout/MasterLayout.cpp * implement getWindowDecorationBox() modified: src/Window.cpp modified: src/Window.hpp modified: src/layout/DwindleLayout.cpp modified: src/layout/MasterLayout.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/input/InputManager.cpp modified: src/render/decorations/CHyprDropShadowDecoration.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp modified: src/render/decorations/IHyprWindowDecoration.cpp modified: src/render/decorations/IHyprWindowDecoration.hpp * fix crash when moveoutofgroup in floating windows also removes dragging from floating windows limitation modified: src/layout/IHyprLayout.cpp modified: src/managers/KeybindManager.cpp * use CRegion in getWindowDecorationBox() modified: src/helpers/Region.cpp modified: src/helpers/Region.hpp modified: src/layout/DwindleLayout.cpp modified: src/layout/MasterLayout.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/input/InputManager.cpp modified: src/render/decorations/IHyprWindowDecoration.cpp modified: src/render/decorations/IHyprWindowDecoration.hpp * add groupbar scrolling modified: src/config/ConfigManager.cpp modified: src/managers/input/InputManager.cpp * change name to getWindowDecorationRegion() modified: src/layout/DwindleLayout.cpp modified: src/layout/MasterLayout.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/input/InputManager.cpp modified: src/render/decorations/IHyprWindowDecoration.cpp modified: src/render/decorations/IHyprWindowDecoration.hpp * make dragging from group less hacky for floating modified: src/managers/KeybindManager.cpp
2023-08-30 15:39:22 +00:00
pWindow->updateWindowDecos();
PWINDOWPREV->getGroupCurrent()->updateWindowDecos();
decos: groupbar mouse interaction (#3102) * allow groupbar clicking modified: src/Window.cpp modified: src/Window.hpp modified: src/managers/input/InputManager.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp modified: src/render/decorations/CHyprGroupBarDecoration.hpp * remove setting pos inside insertWindowToGroup() modified: src/Window.cpp modified: src/layout/DwindleLayout.cpp modified: src/layout/MasterLayout.cpp modified: src/managers/KeybindManager.cpp * add group window by index and group size functions modified: src/Window.cpp modified: src/Window.hpp modified: src/managers/input/InputManager.cpp * allow dragging into groupbar modified: src/Window.cpp modified: src/layout/DwindleLayout.cpp modified: src/layout/MasterLayout.cpp * allow dragging from groupbar modified: src/managers/KeybindManager.cpp * try groupbar clicking before border resize modified: src/managers/input/InputManager.cpp * block grabbing groupbar on floating (crash) remove later when crashing is fixed modified: src/managers/KeybindManager.cpp * remove redundant { } modified: src/layout/DwindleLayout.cpp modified: src/layout/MasterLayout.cpp * implement getWindowDecorationBox() modified: src/Window.cpp modified: src/Window.hpp modified: src/layout/DwindleLayout.cpp modified: src/layout/MasterLayout.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/input/InputManager.cpp modified: src/render/decorations/CHyprDropShadowDecoration.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp modified: src/render/decorations/IHyprWindowDecoration.cpp modified: src/render/decorations/IHyprWindowDecoration.hpp * fix crash when moveoutofgroup in floating windows also removes dragging from floating windows limitation modified: src/layout/IHyprLayout.cpp modified: src/managers/KeybindManager.cpp * use CRegion in getWindowDecorationBox() modified: src/helpers/Region.cpp modified: src/helpers/Region.hpp modified: src/layout/DwindleLayout.cpp modified: src/layout/MasterLayout.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/input/InputManager.cpp modified: src/render/decorations/IHyprWindowDecoration.cpp modified: src/render/decorations/IHyprWindowDecoration.hpp * add groupbar scrolling modified: src/config/ConfigManager.cpp modified: src/managers/input/InputManager.cpp * change name to getWindowDecorationRegion() modified: src/layout/DwindleLayout.cpp modified: src/layout/MasterLayout.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/input/InputManager.cpp modified: src/render/decorations/IHyprWindowDecoration.cpp modified: src/render/decorations/IHyprWindowDecoration.hpp * make dragging from group less hacky for floating modified: src/managers/KeybindManager.cpp
2023-08-30 15:39:22 +00:00
g_pCompositor->updateWindowAnimatedDecorationValues(pWindow);
2023-02-19 21:07:32 +00:00
return;
}
}
2022-06-30 12:09:05 +02:00
if (pWindow->m_bIsFloating) {
onWindowRemovedFloating(pWindow);
} else {
onWindowRemovedTiling(pWindow);
}
if (pWindow == m_pLastTiledWindow)
m_pLastTiledWindow.reset();
2022-06-30 12:09:05 +02:00
}
void IHyprLayout::onWindowRemovedFloating(PHLWINDOW pWindow) {
2022-06-30 12:09:05 +02:00
return; // no-op
}
void IHyprLayout::onWindowCreatedFloating(PHLWINDOW pWindow) {
CBox desiredGeometry = {0};
2022-06-30 12:09:05 +02:00
g_pXWaylandManager->getGeometryForWindow(pWindow, &desiredGeometry);
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
if (pWindow->m_bIsX11) {
Vector2D xy = {desiredGeometry.x, desiredGeometry.y};
xy = g_pXWaylandManager->xwaylandToWaylandCoords(xy);
desiredGeometry.x = xy.x;
desiredGeometry.y = xy.y;
}
static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
2022-06-30 12:09:05 +02:00
if (!PMONITOR) {
Debug::log(ERR, "{:m} has an invalid monitor in onWindowCreatedFloating!!!", pWindow);
2022-06-30 12:09:05 +02:00
return;
}
if (desiredGeometry.width <= 5 || desiredGeometry.height <= 5) {
const auto PWINDOWSURFACE = pWindow->m_pWLSurface->resource();
pWindow->m_vRealSize = PWINDOWSURFACE->current.size;
2022-07-28 15:40:06 +02:00
if ((desiredGeometry.width <= 1 || desiredGeometry.height <= 1) && pWindow->m_bIsX11 &&
pWindow->isX11OverrideRedirect()) { // XDG windows should be fine. TODO: check for weird atoms?
pWindow->setHidden(true);
2022-07-28 15:40:06 +02:00
return;
}
2022-09-25 20:07:48 +02:00
// reject any windows with size <= 5x5
if (pWindow->m_vRealSize.goal().x <= 5 || pWindow->m_vRealSize.goal().y <= 5)
pWindow->m_vRealSize = PMONITOR->vecSize / 2.f;
2022-06-30 12:09:05 +02:00
if (pWindow->m_bIsX11 && pWindow->isX11OverrideRedirect()) {
if (pWindow->m_pXWaylandSurface->geometry.x != 0 && pWindow->m_pXWaylandSurface->geometry.y != 0)
pWindow->m_vRealPosition = g_pXWaylandManager->xwaylandToWaylandCoords(pWindow->m_pXWaylandSurface->geometry.pos());
else
pWindow->m_vRealPosition = Vector2D(PMONITOR->vecPosition.x + (PMONITOR->vecSize.x - pWindow->m_vRealSize.goal().x) / 2.f,
PMONITOR->vecPosition.y + (PMONITOR->vecSize.y - pWindow->m_vRealSize.goal().y) / 2.f);
} else {
pWindow->m_vRealPosition = Vector2D(PMONITOR->vecPosition.x + (PMONITOR->vecSize.x - pWindow->m_vRealSize.goal().x) / 2.f,
PMONITOR->vecPosition.y + (PMONITOR->vecSize.y - pWindow->m_vRealSize.goal().y) / 2.f);
}
2022-06-30 12:09:05 +02:00
} else {
// we respect the size.
pWindow->m_vRealSize = Vector2D(desiredGeometry.width, desiredGeometry.height);
// check if it's on the correct monitor!
Vector2D middlePoint = Vector2D(desiredGeometry.x, desiredGeometry.y) + Vector2D(desiredGeometry.width, desiredGeometry.height) / 2.f;
2022-09-13 22:23:48 +02:00
// check if it's visible on any monitor (only for XDG)
bool visible = pWindow->m_bIsX11;
if (!visible) {
visible = g_pCompositor->isPointOnAnyMonitor(Vector2D(desiredGeometry.x, desiredGeometry.y)) &&
g_pCompositor->isPointOnAnyMonitor(Vector2D(desiredGeometry.x + desiredGeometry.width, desiredGeometry.y)) &&
g_pCompositor->isPointOnAnyMonitor(Vector2D(desiredGeometry.x, desiredGeometry.y + desiredGeometry.height)) &&
g_pCompositor->isPointOnAnyMonitor(Vector2D(desiredGeometry.x + desiredGeometry.width, desiredGeometry.y + desiredGeometry.height));
}
2022-06-30 12:09:05 +02:00
// TODO: detect a popup in a more consistent way.
if ((desiredGeometry.x == 0 && desiredGeometry.y == 0) || !visible || !pWindow->m_bIsX11) {
2024-05-10 23:28:33 +01:00
// if the pos isn't set, fall back to the center placement if it's not a child, otherwise middle of parent if available
if (!pWindow->m_bIsX11 && pWindow->m_pXDGSurface->toplevel->parent && validMapped(pWindow->m_pXDGSurface->toplevel->parent->window))
pWindow->m_vRealPosition = pWindow->m_pXDGSurface->toplevel->parent->window->m_vRealPosition.goal() +
pWindow->m_pXDGSurface->toplevel->parent->window->m_vRealSize.goal() / 2.F - desiredGeometry.size() / 2.F;
else
pWindow->m_vRealPosition = PMONITOR->vecPosition + PMONITOR->vecSize / 2.F - desiredGeometry.size() / 2.F;
2022-06-30 12:09:05 +02:00
} else {
// if it is, we respect where it wants to put itself, but apply monitor offset if outside
// most of these are popups
2023-07-01 16:28:17 +02:00
if (const auto POPENMON = g_pCompositor->getMonitorFromVector(middlePoint); POPENMON->ID != PMONITOR->ID)
2022-06-30 12:09:05 +02:00
pWindow->m_vRealPosition = Vector2D(desiredGeometry.x, desiredGeometry.y) - POPENMON->vecPosition + PMONITOR->vecPosition;
2023-07-01 16:28:17 +02:00
else
2022-06-30 12:09:05 +02:00
pWindow->m_vRealPosition = Vector2D(desiredGeometry.x, desiredGeometry.y);
}
}
if (*PXWLFORCESCALEZERO && pWindow->m_bIsX11)
pWindow->m_vRealSize = pWindow->m_vRealSize.goal() / PMONITOR->scale;
if (pWindow->m_bX11DoesntWantBorders || (pWindow->m_bIsX11 && pWindow->isX11OverrideRedirect())) {
pWindow->m_vRealPosition.warp();
pWindow->m_vRealSize.warp();
2022-06-30 12:09:05 +02:00
}
if (!pWindow->isX11OverrideRedirect()) {
g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goal());
2022-06-30 12:09:05 +02:00
g_pCompositor->changeWindowZOrder(pWindow, true);
} else {
pWindow->m_vPendingReportedSize = pWindow->m_vRealSize.goal();
pWindow->m_vReportedSize = pWindow->m_vPendingReportedSize;
}
2022-06-30 12:09:05 +02:00
}
bool IHyprLayout::onWindowCreatedAutoGroup(PHLWINDOW pWindow) {
static auto PAUTOGROUP = CConfigValue<Hyprlang::INT>("group:auto_group");
const PHLWINDOW OPENINGON = g_pCompositor->m_pLastWindow.lock() && g_pCompositor->m_pLastWindow->m_pWorkspace == pWindow->m_pWorkspace ?
g_pCompositor->m_pLastWindow.lock() :
g_pCompositor->getFirstWindowOnWorkspace(pWindow->workspaceID());
const bool FLOATEDINTOTILED = pWindow->m_bIsFloating && !OPENINGON->m_bIsFloating;
const bool SWALLOWING = pWindow->m_pSwallowed || pWindow->m_bGroupSwallowed;
if ((*PAUTOGROUP || SWALLOWING) // continue if auto_group is enabled or if dealing with window swallowing.
&& OPENINGON // this shouldn't be 0, but honestly, better safe than sorry.
&& OPENINGON != pWindow // prevent freeze when the "group set" window rule makes the new window to be already a group.
&& OPENINGON->m_sGroupData.pNextWindow.lock() // check if OPENINGON is a group.
&& pWindow->canBeGroupedInto(OPENINGON) // check if the new window can be grouped into OPENINGON.
&& !g_pXWaylandManager->shouldBeFloated(pWindow) // don't group child windows. Fix for floated groups. Tiled groups don't need this because we check if !FLOATEDINTOTILED.
&& !FLOATEDINTOTILED) { // don't group a new floated window into a tiled group (for convenience).
pWindow->m_bIsFloating = OPENINGON->m_bIsFloating; // match the floating state. Needed to autogroup a new tiled window into a floated group.
static auto USECURRPOS = CConfigValue<Hyprlang::INT>("group:insert_after_current");
(*USECURRPOS ? OPENINGON : OPENINGON->getGroupTail())->insertWindowToGroup(pWindow);
OPENINGON->setGroupCurrent(pWindow);
pWindow->updateWindowDecos();
recalculateWindow(pWindow);
if (!pWindow->getDecorationByType(DECORATION_GROUPBAR))
pWindow->addWindowDeco(std::make_unique<CHyprGroupBarDecoration>(pWindow));
return true;
}
return false;
}
2022-06-30 12:09:05 +02:00
void IHyprLayout::onBeginDragWindow() {
const auto DRAGGINGWINDOW = g_pInputManager->currentlyDraggedWindow.lock();
2022-06-30 12:09:05 +02:00
m_iMouseMoveEventCount = 1;
m_vBeginDragSizeXY = Vector2D();
2022-06-30 12:09:05 +02:00
// Window will be floating. Let's check if it's valid. It should be, but I don't like crashing.
if (!validMapped(DRAGGINGWINDOW)) {
2022-06-30 12:09:05 +02:00
Debug::log(ERR, "Dragging attempted on an invalid window!");
g_pKeybindManager->changeMouseBindMode(MBIND_INVALID);
2022-06-30 12:09:05 +02:00
return;
}
internal: refactor fullscreen states (#7104) * refactor fullscreen modified: src/Compositor.cpp modified: src/Compositor.hpp modified: src/config/ConfigManager.cpp modified: src/config/ConfigManager.hpp modified: src/debug/HyprCtl.cpp modified: src/desktop/LayerSurface.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/desktop/Workspace.cpp modified: src/desktop/Workspace.hpp modified: src/events/Windows.cpp modified: src/helpers/Monitor.cpp modified: src/layout/DwindleLayout.cpp modified: src/layout/DwindleLayout.hpp modified: src/layout/IHyprLayout.cpp modified: src/layout/IHyprLayout.hpp modified: src/layout/MasterLayout.cpp modified: src/layout/MasterLayout.hpp modified: src/managers/KeybindManager.cpp modified: src/managers/KeybindManager.hpp modified: src/managers/input/IdleInhibitor.cpp modified: src/managers/input/InputManager.cpp modified: src/managers/input/Swipe.cpp modified: src/protocols/ForeignToplevelWlr.cpp modified: src/render/Renderer.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp * clean up modified: src/config/ConfigManager.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.hpp modified: src/desktop/Workspace.cpp modified: src/events/Windows.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/input/Swipe.cpp * fix mapWindow fullscreen modified: src/events/Windows.cpp * fix typo modified: src/desktop/Workspace.cpp * add fullscreenstate modified: src/config/ConfigManager.cpp modified: src/events/Windows.cpp * change syncFullscreen to lower modified: src/config/ConfigManager.hpp * initialize fs state modified: src/desktop/Window.hpp
2024-07-31 17:55:52 +00:00
if (DRAGGINGWINDOW->isFullscreen()) {
Debug::log(LOG, "Dragging a fullscreen window");
internal: refactor fullscreen states (#7104) * refactor fullscreen modified: src/Compositor.cpp modified: src/Compositor.hpp modified: src/config/ConfigManager.cpp modified: src/config/ConfigManager.hpp modified: src/debug/HyprCtl.cpp modified: src/desktop/LayerSurface.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/desktop/Workspace.cpp modified: src/desktop/Workspace.hpp modified: src/events/Windows.cpp modified: src/helpers/Monitor.cpp modified: src/layout/DwindleLayout.cpp modified: src/layout/DwindleLayout.hpp modified: src/layout/IHyprLayout.cpp modified: src/layout/IHyprLayout.hpp modified: src/layout/MasterLayout.cpp modified: src/layout/MasterLayout.hpp modified: src/managers/KeybindManager.cpp modified: src/managers/KeybindManager.hpp modified: src/managers/input/IdleInhibitor.cpp modified: src/managers/input/InputManager.cpp modified: src/managers/input/Swipe.cpp modified: src/protocols/ForeignToplevelWlr.cpp modified: src/render/Renderer.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp * clean up modified: src/config/ConfigManager.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.hpp modified: src/desktop/Workspace.cpp modified: src/events/Windows.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/input/Swipe.cpp * fix mapWindow fullscreen modified: src/events/Windows.cpp * fix typo modified: src/desktop/Workspace.cpp * add fullscreenstate modified: src/config/ConfigManager.cpp modified: src/events/Windows.cpp * change syncFullscreen to lower modified: src/config/ConfigManager.hpp * initialize fs state modified: src/desktop/Window.hpp
2024-07-31 17:55:52 +00:00
g_pCompositor->setWindowFullscreenInternal(DRAGGINGWINDOW, FSMODE_NONE);
2022-06-30 12:09:05 +02:00
}
const auto PWORKSPACE = DRAGGINGWINDOW->m_pWorkspace;
2022-06-30 12:09:05 +02:00
if (PWORKSPACE->m_bHasFullscreenWindow && (!DRAGGINGWINDOW->m_bCreatedOverFullscreen || !DRAGGINGWINDOW->m_bIsFloating)) {
Debug::log(LOG, "Rejecting drag on a fullscreen workspace. (window under fullscreen)");
g_pKeybindManager->changeMouseBindMode(MBIND_INVALID);
2022-06-30 12:09:05 +02:00
return;
}
DRAGGINGWINDOW->m_bDraggingTiled = false;
m_vDraggingWindowOriginalFloatSize = DRAGGINGWINDOW->m_vLastFloatingSize;
2022-06-30 12:09:05 +02:00
if (!DRAGGINGWINDOW->m_bIsFloating) {
2022-09-19 19:04:48 +01:00
if (g_pInputManager->dragMode == MBIND_MOVE) {
DRAGGINGWINDOW->m_vLastFloatingSize = (DRAGGINGWINDOW->m_vRealSize.goal() * 0.8489).clamp(Vector2D{5, 5}, Vector2D{}).floor();
2022-06-30 12:09:05 +02:00
changeWindowFloatingMode(DRAGGINGWINDOW);
DRAGGINGWINDOW->m_bIsFloating = true;
2022-06-30 12:09:05 +02:00
DRAGGINGWINDOW->m_bDraggingTiled = true;
2022-08-05 17:52:14 +02:00
DRAGGINGWINDOW->m_vRealPosition = g_pInputManager->getMouseCoordsInternal() - DRAGGINGWINDOW->m_vRealSize.goal() / 2.f;
2022-06-30 12:09:05 +02:00
}
}
m_vBeginDragXY = g_pInputManager->getMouseCoordsInternal();
m_vBeginDragPositionXY = DRAGGINGWINDOW->m_vRealPosition.goal();
m_vBeginDragSizeXY = DRAGGINGWINDOW->m_vRealSize.goal();
m_vLastDragXY = m_vBeginDragXY;
2022-06-30 12:09:05 +02:00
// get the grab corner
static auto RESIZECORNER = CConfigValue<Hyprlang::INT>("general:resize_corner");
if (*RESIZECORNER != 0 && *RESIZECORNER <= 4 && DRAGGINGWINDOW->m_bIsFloating) {
switch (*RESIZECORNER) {
case 1:
m_eGrabbedCorner = CORNER_TOPLEFT;
g_pInputManager->setCursorImageUntilUnset("nw-resize");
break;
case 2:
m_eGrabbedCorner = CORNER_TOPRIGHT;
g_pInputManager->setCursorImageUntilUnset("ne-resize");
break;
case 3:
m_eGrabbedCorner = CORNER_BOTTOMRIGHT;
g_pInputManager->setCursorImageUntilUnset("se-resize");
break;
case 4:
m_eGrabbedCorner = CORNER_BOTTOMLEFT;
g_pInputManager->setCursorImageUntilUnset("sw-resize");
break;
}
} else if (m_vBeginDragXY.x < m_vBeginDragPositionXY.x + m_vBeginDragSizeXY.x / 2.0) {
2023-02-26 03:56:23 +02:00
if (m_vBeginDragXY.y < m_vBeginDragPositionXY.y + m_vBeginDragSizeXY.y / 2.0) {
m_eGrabbedCorner = CORNER_TOPLEFT;
2023-02-26 03:56:23 +02:00
g_pInputManager->setCursorImageUntilUnset("nw-resize");
} else {
m_eGrabbedCorner = CORNER_BOTTOMLEFT;
2023-02-26 03:56:23 +02:00
g_pInputManager->setCursorImageUntilUnset("sw-resize");
}
} else {
2023-02-26 03:56:23 +02:00
if (m_vBeginDragXY.y < m_vBeginDragPositionXY.y + m_vBeginDragSizeXY.y / 2.0) {
m_eGrabbedCorner = CORNER_TOPRIGHT;
2023-02-26 03:56:23 +02:00
g_pInputManager->setCursorImageUntilUnset("ne-resize");
} else {
m_eGrabbedCorner = CORNER_BOTTOMRIGHT;
2023-02-26 03:56:23 +02:00
g_pInputManager->setCursorImageUntilUnset("se-resize");
}
}
2023-08-08 16:52:20 +00:00
if (g_pInputManager->dragMode != MBIND_RESIZE && g_pInputManager->dragMode != MBIND_RESIZE_FORCE_RATIO && g_pInputManager->dragMode != MBIND_RESIZE_BLOCK_RATIO)
2023-02-26 23:08:20 +00:00
g_pInputManager->setCursorImageUntilUnset("grab");
2022-06-30 12:09:05 +02:00
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
2022-07-21 19:44:34 +02:00
g_pKeybindManager->shadowKeybinds();
2023-07-13 18:20:40 +00:00
g_pCompositor->focusWindow(DRAGGINGWINDOW);
g_pCompositor->changeWindowZOrder(DRAGGINGWINDOW, true);
2022-06-30 12:09:05 +02:00
}
void IHyprLayout::onEndDragWindow() {
const auto DRAGGINGWINDOW = g_pInputManager->currentlyDraggedWindow.lock();
2022-06-30 12:09:05 +02:00
m_iMouseMoveEventCount = 1;
if (!validMapped(DRAGGINGWINDOW)) {
2023-02-18 23:35:31 +01:00
if (DRAGGINGWINDOW) {
g_pInputManager->unsetCursorImage();
g_pInputManager->currentlyDraggedWindow.reset();
2023-02-18 23:35:31 +01:00
}
2022-06-30 12:09:05 +02:00
return;
2023-02-18 23:35:31 +01:00
}
g_pInputManager->unsetCursorImage();
g_pInputManager->currentlyDraggedWindow.reset();
g_pInputManager->m_bWasDraggingWindow = true;
2023-01-02 12:06:06 +01:00
if (g_pInputManager->dragMode == MBIND_MOVE) {
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
const auto MOUSECOORDS = g_pInputManager->getMouseCoordsInternal();
PHLWINDOW pWindow = g_pCompositor->vectorToWindowUnified(MOUSECOORDS, RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING, DRAGGINGWINDOW);
if (pWindow) {
if (pWindow->checkInputOnDecos(INPUT_TYPE_DRAG_END, MOUSECOORDS, DRAGGINGWINDOW))
return;
const bool FLOATEDINTOTILED = !pWindow->m_bIsFloating && !DRAGGINGWINDOW->m_bDraggingTiled;
static auto PDRAGINTOGROUP = CConfigValue<Hyprlang::INT>("group:drag_into_group");
if (pWindow->m_sGroupData.pNextWindow.lock() && DRAGGINGWINDOW->canBeGroupedInto(pWindow) && *PDRAGINTOGROUP == 1 && !FLOATEDINTOTILED) {
if (DRAGGINGWINDOW->m_bDraggingTiled) {
changeWindowFloatingMode(DRAGGINGWINDOW);
DRAGGINGWINDOW->m_vLastFloatingSize = m_vDraggingWindowOriginalFloatSize;
DRAGGINGWINDOW->m_bDraggingTiled = false;
}
if (DRAGGINGWINDOW->m_sGroupData.pNextWindow) {
std::vector<PHLWINDOW> members;
PHLWINDOW curr = DRAGGINGWINDOW->getGroupHead();
do {
members.push_back(curr);
curr = curr->m_sGroupData.pNextWindow.lock();
} while (curr != members[0]);
for (auto it = members.begin(); it != members.end(); ++it) {
(*it)->m_bIsFloating = pWindow->m_bIsFloating; // match the floating state of group members
if (pWindow->m_bIsFloating)
(*it)->m_vRealSize = pWindow->m_vRealSize.goal(); // match the size of group members
}
}
DRAGGINGWINDOW->m_bIsFloating = pWindow->m_bIsFloating; // match the floating state of the window
if (pWindow->m_bIsFloating)
g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, pWindow->m_vRealSize.goal()); // match the size of the window
static auto USECURRPOS = CConfigValue<Hyprlang::INT>("group:insert_after_current");
(*USECURRPOS ? pWindow : pWindow->getGroupTail())->insertWindowToGroup(DRAGGINGWINDOW);
pWindow->setGroupCurrent(DRAGGINGWINDOW);
DRAGGINGWINDOW->updateWindowDecos();
if (!DRAGGINGWINDOW->getDecorationByType(DECORATION_GROUPBAR))
DRAGGINGWINDOW->addWindowDeco(std::make_unique<CHyprGroupBarDecoration>(DRAGGINGWINDOW));
}
}
2022-06-30 12:09:05 +02:00
}
if (DRAGGINGWINDOW->m_bDraggingTiled) {
DRAGGINGWINDOW->m_bIsFloating = false;
g_pInputManager->refocus();
changeWindowFloatingMode(DRAGGINGWINDOW);
DRAGGINGWINDOW->m_vLastFloatingSize = m_vDraggingWindowOriginalFloatSize;
}
2022-06-30 12:09:05 +02:00
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
2023-08-05 18:53:13 +00:00
g_pCompositor->focusWindow(DRAGGINGWINDOW);
g_pInputManager->m_bWasDraggingWindow = false;
2022-06-30 12:09:05 +02:00
}
input: add snapping to floating windows (#8088) * add snapping to floating windows Works for both moving and resizing of windows. It comes with 3 options: `general:snap:enabled` - whether it's enabled, off by default `general:snap:window_gap` - minimum gap in pixels between windows before snapping. Setting to 0 effectively turns off this method of snapping. `general:snap:monitor_gap` - minimum gap in pixels between window and monitor edges before snapping. Again, setting it to 0 effectively turns it off. * snap: add more ignore criteria and change if clause into a guard * snap: refactor code * snap: new refactoring approach and account for border size * snap: do corner snapping after all edge snapping is done The approach of performing corner snaps after each individual edge snap results in far fewer scenarios where snapping can occur. After trying it out for a while, I found that I prefer an approach that's more prone to snapping. * snap: combine snapWindows and snapMonitor into a single function * snap: add forced aspect ratio functionality * snap: avoid directly referring to border_size config value * snap: address vaxerski feedback - add new line between functions - use std::function typedef for SnapFn and make snap functions static - avoid uninitialized variable declarations. - change ignore condition m_bIsX11 to isX11OverrideRedirect() - use braces for CBox and Vector2D declarations. - add SNAP_INVALID to eSnapEdge enum - use bitshift notation for eSnapEdge and eRectCorner - make performSnap a non-member function. * snap: add corner-snapping to forced aspect ratio mode
2024-10-21 11:08:25 -04:00
static inline bool canSnap(const double sideA, const double sideB, const double gap) {
return std::abs(sideA - sideB) < gap;
}
static void snapMoveLeft(double& pos, double& len, const double p) {
pos = p;
}
static void snapMoveRight(double& pos, double& len, const double p) {
pos = p - len;
}
static void snapResizeLeft(double& pos, double& len, const double p) {
len += pos - p;
pos = p;
}
static void snapResizeRight(double& pos, double& len, const double p) {
len = p - pos;
}
typedef std::function<void(double&, double&, const double)> SnapFn;
static void performSnap(Vector2D& pos, Vector2D& size, PHLWINDOW DRAGGINGWINDOW, const eMouseBindMode mode, const int corner, const Vector2D& beginSize) {
static auto SNAPWINDOWGAP = CConfigValue<Hyprlang::INT>("general:snap:window_gap");
static auto SNAPMONITORGAP = CConfigValue<Hyprlang::INT>("general:snap:monitor_gap");
const SnapFn snapRight = (mode == MBIND_MOVE) ? snapMoveRight : snapResizeRight;
const SnapFn snapLeft = (mode == MBIND_MOVE) ? snapMoveLeft : snapResizeLeft;
const SnapFn snapDown = snapRight;
const SnapFn snapUp = snapLeft;
int snaps = 0;
if (*SNAPWINDOWGAP) {
const auto PID = DRAGGINGWINDOW->getPID();
const auto WSID = DRAGGINGWINDOW->workspaceID();
const int BORD = DRAGGINGWINDOW->getRealBorderSize();
for (auto& other : g_pCompositor->m_vWindows) {
if (other->workspaceID() != WSID || other->getPID() == PID || !other->m_bIsMapped || other->m_bFadingOut || other->isX11OverrideRedirect())
continue;
const int bord = std::max(BORD, other->getRealBorderSize());
const double gap = *SNAPWINDOWGAP + bord;
const CBox box = other->getWindowMainSurfaceBox();
const CBox ob = {box.x, box.y, box.x + box.w, box.y + box.h};
const CBox bb = {ob.x - bord, ob.y - bord, ob.w + bord, ob.h + bord};
const Vector2D end = {pos.x + size.x, pos.y + size.y};
// only snap windows if their ranges intersect in the opposite axis
if (pos.y <= bb.h && bb.y <= end.y) {
if (corner & (CORNER_TOPLEFT | CORNER_BOTTOMLEFT) && canSnap(pos.x, bb.w, gap)) {
snapLeft(pos.x, size.x, bb.w);
snaps |= SNAP_LEFT;
} else if (corner & (CORNER_TOPRIGHT | CORNER_BOTTOMRIGHT) && canSnap(end.x, bb.x, gap)) {
snapRight(pos.x, size.x, bb.x);
snaps |= SNAP_RIGHT;
}
}
if (pos.x <= bb.w && bb.x <= end.x) {
if (corner & (CORNER_TOPLEFT | CORNER_TOPRIGHT) && canSnap(pos.y, bb.h, gap)) {
snapUp(pos.y, size.y, bb.h);
snaps |= SNAP_UP;
} else if (corner & (CORNER_BOTTOMLEFT | CORNER_BOTTOMRIGHT) && canSnap(end.y, bb.y, gap)) {
snapDown(pos.y, size.y, bb.y);
snaps |= SNAP_DOWN;
}
}
// corner snapping
if (pos.x == bb.w || bb.x == pos.x + size.x) {
if (corner & (CORNER_TOPLEFT | CORNER_TOPRIGHT) && canSnap(pos.y, ob.y, gap)) {
snapUp(pos.y, size.y, ob.y);
snaps |= SNAP_UP;
} else if (corner & (CORNER_BOTTOMLEFT | CORNER_BOTTOMRIGHT) && canSnap(end.y, ob.h, gap)) {
snapDown(pos.y, size.y, ob.h);
snaps |= SNAP_DOWN;
}
}
if (pos.y == bb.h || bb.y == pos.y + size.y) {
if (corner & (CORNER_TOPLEFT | CORNER_BOTTOMLEFT) && canSnap(pos.x, ob.x, gap)) {
snapLeft(pos.x, size.x, ob.x);
snaps |= SNAP_LEFT;
} else if (corner & (CORNER_TOPRIGHT | CORNER_BOTTOMRIGHT) && canSnap(end.x, ob.w, gap)) {
snapRight(pos.x, size.x, ob.w);
snaps |= SNAP_RIGHT;
}
}
}
}
if (*SNAPMONITORGAP) {
const auto MON = g_pCompositor->getMonitorFromID(DRAGGINGWINDOW->m_iMonitorID);
const CBox mon = {MON->vecPosition.x, MON->vecPosition.y, MON->vecPosition.x + MON->vecSize.x, MON->vecPosition.y + MON->vecSize.y};
const double gap = *SNAPMONITORGAP;
if (canSnap(pos.x, mon.x, gap)) {
snapLeft(pos.x, size.x, mon.x);
snaps |= SNAP_LEFT;
}
if (canSnap(pos.x + size.x, mon.w, gap)) {
snapRight(pos.x, size.x, mon.w);
snaps |= SNAP_RIGHT;
}
if (canSnap(pos.y, mon.y, gap)) {
snapUp(pos.y, size.y, mon.y);
snaps |= SNAP_UP;
}
if (canSnap(pos.y + size.y, mon.h, gap)) {
snapDown(pos.y, size.y, mon.h);
snaps |= SNAP_DOWN;
}
}
if (mode == MBIND_RESIZE_FORCE_RATIO) {
const double RATIO = beginSize.y / beginSize.x;
if ((corner & (CORNER_TOPLEFT | CORNER_BOTTOMLEFT) && snaps & SNAP_LEFT) || (corner & (CORNER_TOPRIGHT | CORNER_BOTTOMRIGHT) && snaps & SNAP_RIGHT)) {
const double sizeY = size.x * RATIO;
if (corner & (CORNER_TOPLEFT | CORNER_TOPRIGHT))
pos.y += size.y - sizeY;
size.y = sizeY;
} else if ((corner & (CORNER_TOPLEFT | CORNER_TOPRIGHT) && snaps & SNAP_UP) || (corner & (CORNER_BOTTOMLEFT | CORNER_BOTTOMRIGHT) && snaps & SNAP_DOWN)) {
const double sizeX = size.y / RATIO;
if (corner & (CORNER_TOPLEFT | CORNER_BOTTOMLEFT))
pos.x += size.x - sizeX;
size.x = sizeX;
}
}
}
2022-06-30 12:09:05 +02:00
void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
if (g_pInputManager->currentlyDraggedWindow.expired())
return;
const auto DRAGGINGWINDOW = g_pInputManager->currentlyDraggedWindow.lock();
2022-06-30 12:09:05 +02:00
// Window invalid or drag begin size 0,0 meaning we rejected it.
if ((!validMapped(DRAGGINGWINDOW) || m_vBeginDragSizeXY == Vector2D())) {
g_pKeybindManager->changeMouseBindMode(MBIND_INVALID);
2022-06-30 12:09:05 +02:00
return;
}
static auto TIMER = std::chrono::high_resolution_clock::now(), MSTIMER = TIMER;
2022-12-09 17:08:04 +00:00
const auto SPECIAL = DRAGGINGWINDOW->onSpecialWorkspace();
2022-06-30 12:09:05 +02:00
const auto DELTA = Vector2D(mousePos.x - m_vBeginDragXY.x, mousePos.y - m_vBeginDragXY.y);
const auto TICKDELTA = Vector2D(mousePos.x - m_vLastDragXY.x, mousePos.y - m_vLastDragXY.y);
2022-08-16 21:56:54 +02:00
static auto PANIMATEMOUSE = CConfigValue<Hyprlang::INT>("misc:animate_mouse_windowdragging");
static auto PANIMATE = CConfigValue<Hyprlang::INT>("misc:animate_manual_resizes");
input: add snapping to floating windows (#8088) * add snapping to floating windows Works for both moving and resizing of windows. It comes with 3 options: `general:snap:enabled` - whether it's enabled, off by default `general:snap:window_gap` - minimum gap in pixels between windows before snapping. Setting to 0 effectively turns off this method of snapping. `general:snap:monitor_gap` - minimum gap in pixels between window and monitor edges before snapping. Again, setting it to 0 effectively turns it off. * snap: add more ignore criteria and change if clause into a guard * snap: refactor code * snap: new refactoring approach and account for border size * snap: do corner snapping after all edge snapping is done The approach of performing corner snaps after each individual edge snap results in far fewer scenarios where snapping can occur. After trying it out for a while, I found that I prefer an approach that's more prone to snapping. * snap: combine snapWindows and snapMonitor into a single function * snap: add forced aspect ratio functionality * snap: avoid directly referring to border_size config value * snap: address vaxerski feedback - add new line between functions - use std::function typedef for SnapFn and make snap functions static - avoid uninitialized variable declarations. - change ignore condition m_bIsX11 to isX11OverrideRedirect() - use braces for CBox and Vector2D declarations. - add SNAP_INVALID to eSnapEdge enum - use bitshift notation for eSnapEdge and eRectCorner - make performSnap a non-member function. * snap: add corner-snapping to forced aspect ratio mode
2024-10-21 11:08:25 -04:00
static auto SNAPENABLED = CConfigValue<Hyprlang::INT>("general:snap:enabled");
const auto TIMERDELTA = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - TIMER).count();
const auto MSDELTA = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - MSTIMER).count();
const auto MSMONITOR = 1000.0 / g_pHyprRenderer->m_pMostHzMonitor->refreshRate;
static int totalMs = 0;
bool canSkipUpdate = true;
MSTIMER = std::chrono::high_resolution_clock::now();
if (m_iMouseMoveEventCount == 1)
totalMs = 0;
if (MSMONITOR > 16.0) {
totalMs += MSDELTA < MSMONITOR ? MSDELTA : std::round(totalMs * 1.0 / m_iMouseMoveEventCount);
m_iMouseMoveEventCount += 1;
// check if time-window is enough to skip update on 60hz monitor
canSkipUpdate = std::clamp(MSMONITOR - TIMERDELTA, 0.0, MSMONITOR) > totalMs * 1.0 / m_iMouseMoveEventCount;
}
if ((abs(TICKDELTA.x) < 1.f && abs(TICKDELTA.y) < 1.f) || (TIMERDELTA < MSMONITOR && canSkipUpdate && (g_pInputManager->dragMode != MBIND_MOVE || *PANIMATEMOUSE)))
2022-06-30 12:09:05 +02:00
return;
TIMER = std::chrono::high_resolution_clock::now();
2022-06-30 12:09:05 +02:00
m_vLastDragXY = mousePos;
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
2022-09-19 19:04:48 +01:00
if (g_pInputManager->dragMode == MBIND_MOVE) {
2022-10-19 21:17:49 +01:00
input: add snapping to floating windows (#8088) * add snapping to floating windows Works for both moving and resizing of windows. It comes with 3 options: `general:snap:enabled` - whether it's enabled, off by default `general:snap:window_gap` - minimum gap in pixels between windows before snapping. Setting to 0 effectively turns off this method of snapping. `general:snap:monitor_gap` - minimum gap in pixels between window and monitor edges before snapping. Again, setting it to 0 effectively turns it off. * snap: add more ignore criteria and change if clause into a guard * snap: refactor code * snap: new refactoring approach and account for border size * snap: do corner snapping after all edge snapping is done The approach of performing corner snaps after each individual edge snap results in far fewer scenarios where snapping can occur. After trying it out for a while, I found that I prefer an approach that's more prone to snapping. * snap: combine snapWindows and snapMonitor into a single function * snap: add forced aspect ratio functionality * snap: avoid directly referring to border_size config value * snap: address vaxerski feedback - add new line between functions - use std::function typedef for SnapFn and make snap functions static - avoid uninitialized variable declarations. - change ignore condition m_bIsX11 to isX11OverrideRedirect() - use braces for CBox and Vector2D declarations. - add SNAP_INVALID to eSnapEdge enum - use bitshift notation for eSnapEdge and eRectCorner - make performSnap a non-member function. * snap: add corner-snapping to forced aspect ratio mode
2024-10-21 11:08:25 -04:00
Vector2D newPos = m_vBeginDragPositionXY + DELTA;
Vector2D newSize = DRAGGINGWINDOW->m_vRealSize.goal();
if (*SNAPENABLED && !DRAGGINGWINDOW->m_bDraggingTiled)
performSnap(newPos, newSize, DRAGGINGWINDOW, MBIND_MOVE, -1, m_vBeginDragSizeXY);
CBox wb = {newPos, newSize};
wb.round();
if (*PANIMATEMOUSE)
DRAGGINGWINDOW->m_vRealPosition = wb.pos();
else
DRAGGINGWINDOW->m_vRealPosition.setValueAndWarp(wb.pos());
2022-06-30 12:09:05 +02:00
g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goal());
2023-08-08 16:52:20 +00:00
} else if (g_pInputManager->dragMode == MBIND_RESIZE || g_pInputManager->dragMode == MBIND_RESIZE_FORCE_RATIO || g_pInputManager->dragMode == MBIND_RESIZE_BLOCK_RATIO) {
2022-06-30 12:09:05 +02:00
if (DRAGGINGWINDOW->m_bIsFloating) {
core: Improve handling of window properties (#6776) * add mWindowProperties modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp * support int values modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp * create m_sWindowData modified: src/Compositor.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp modified: src/layout/DwindleLayout.cpp modified: src/layout/IHyprLayout.cpp modified: src/layout/MasterLayout.cpp modified: src/managers/AnimationManager.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/XWaylandManager.cpp modified: src/render/OpenGL.cpp modified: src/render/Renderer.cpp modified: src/render/decorations/CHyprBorderDecoration.cpp modified: src/render/decorations/CHyprDropShadowDecoration.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp * simplify some properties modified: src/Compositor.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/managers/KeybindManager.cpp * store multiple values in CWindowOverridableVar modified: src/Compositor.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp modified: src/layout/IHyprLayout.cpp modified: src/managers/AnimationManager.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/XWaylandManager.cpp modified: src/render/OpenGL.cpp modified: src/render/Renderer.cpp modified: src/render/decorations/CHyprBorderDecoration.cpp modified: src/render/decorations/CHyprDropShadowDecoration.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp * clean up modified: src/Compositor.cpp modified: src/Compositor.hpp modified: src/config/ConfigManager.cpp modified: src/config/ConfigManager.hpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp modified: src/layout/DwindleLayout.cpp modified: src/layout/IHyprLayout.cpp modified: src/layout/IHyprLayout.hpp modified: src/layout/MasterLayout.cpp modified: src/managers/KeybindManager.cpp * use SET_PROP priority for exec rules modified: src/config/ConfigManager.hpp modified: src/desktop/Window.cpp * add default value modified: src/Compositor.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp modified: src/layout/IHyprLayout.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/XWaylandManager.cpp modified: src/render/OpenGL.cpp modified: src/render/Renderer.cpp modified: src/render/decorations/CHyprBorderDecoration.cpp modified: src/render/decorations/CHyprDropShadowDecoration.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp * add setprop toggle modified: src/config/ConfigManager.hpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp * add setprop toggle modified: src/debug/HyprCtl.cpp * make window rules functional modified: src/config/ConfigManager.cpp modified: src/desktop/Window.cpp * minor fixes modified: src/Compositor.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.hpp * properly clean layout data modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp modified: src/layout/DwindleLayout.cpp modified: src/layout/IHyprLayout.cpp modified: src/layout/IHyprLayout.hpp modified: src/layout/MasterLayout.cpp * remove newline modified: src/events/Windows.cpp * fixes modified: src/config/ConfigManager.hpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp * use CamelCase modified: src/Compositor.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp modified: src/layout/IHyprLayout.cpp modified: src/managers/AnimationManager.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/XWaylandManager.cpp modified: src/render/OpenGL.cpp modified: src/render/Renderer.cpp modified: src/render/decorations/CHyprBorderDecoration.cpp modified: src/render/decorations/CHyprDropShadowDecoration.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp
2024-07-11 14:10:42 +00:00
Vector2D MINSIZE = g_pXWaylandManager->getMinSizeForWindow(DRAGGINGWINDOW).clamp(DRAGGINGWINDOW->m_sWindowData.minSize.valueOr(Vector2D(20, 20)));
Vector2D MAXSIZE;
if (DRAGGINGWINDOW->m_sWindowData.maxSize.hasValue())
MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(DRAGGINGWINDOW).clamp({}, DRAGGINGWINDOW->m_sWindowData.maxSize.value());
else
MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(DRAGGINGWINDOW).clamp({}, Vector2D(std::numeric_limits<double>::max(), std::numeric_limits<double>::max()));
Vector2D newSize = m_vBeginDragSizeXY;
Vector2D newPos = m_vBeginDragPositionXY;
2023-08-08 16:52:20 +00:00
if (m_eGrabbedCorner == CORNER_BOTTOMRIGHT)
newSize = newSize + DELTA;
else if (m_eGrabbedCorner == CORNER_TOPLEFT)
newSize = newSize - DELTA;
else if (m_eGrabbedCorner == CORNER_TOPRIGHT)
newSize = newSize + Vector2D(DELTA.x, -DELTA.y);
else if (m_eGrabbedCorner == CORNER_BOTTOMLEFT)
newSize = newSize + Vector2D(-DELTA.x, DELTA.y);
input: add snapping to floating windows (#8088) * add snapping to floating windows Works for both moving and resizing of windows. It comes with 3 options: `general:snap:enabled` - whether it's enabled, off by default `general:snap:window_gap` - minimum gap in pixels between windows before snapping. Setting to 0 effectively turns off this method of snapping. `general:snap:monitor_gap` - minimum gap in pixels between window and monitor edges before snapping. Again, setting it to 0 effectively turns it off. * snap: add more ignore criteria and change if clause into a guard * snap: refactor code * snap: new refactoring approach and account for border size * snap: do corner snapping after all edge snapping is done The approach of performing corner snaps after each individual edge snap results in far fewer scenarios where snapping can occur. After trying it out for a while, I found that I prefer an approach that's more prone to snapping. * snap: combine snapWindows and snapMonitor into a single function * snap: add forced aspect ratio functionality * snap: avoid directly referring to border_size config value * snap: address vaxerski feedback - add new line between functions - use std::function typedef for SnapFn and make snap functions static - avoid uninitialized variable declarations. - change ignore condition m_bIsX11 to isX11OverrideRedirect() - use braces for CBox and Vector2D declarations. - add SNAP_INVALID to eSnapEdge enum - use bitshift notation for eSnapEdge and eRectCorner - make performSnap a non-member function. * snap: add corner-snapping to forced aspect ratio mode
2024-10-21 11:08:25 -04:00
eMouseBindMode mode = g_pInputManager->dragMode;
if (DRAGGINGWINDOW->m_sWindowData.keepAspectRatio.valueOrDefault() && mode != MBIND_RESIZE_BLOCK_RATIO)
mode = MBIND_RESIZE_FORCE_RATIO;
if (m_vBeginDragSizeXY.x >= 1 && m_vBeginDragSizeXY.y >= 1 && mode == MBIND_RESIZE_FORCE_RATIO) {
2023-08-08 16:52:20 +00:00
const float RATIO = m_vBeginDragSizeXY.y / m_vBeginDragSizeXY.x;
if (MINSIZE.x * RATIO > MINSIZE.y)
MINSIZE = Vector2D(MINSIZE.x, MINSIZE.x * RATIO);
else
MINSIZE = Vector2D(MINSIZE.y / RATIO, MINSIZE.y);
if (MAXSIZE.x * RATIO < MAXSIZE.y)
MAXSIZE = Vector2D(MAXSIZE.x, MAXSIZE.x * RATIO);
else
MAXSIZE = Vector2D(MAXSIZE.y / RATIO, MAXSIZE.y);
if (newSize.x * RATIO > newSize.y)
newSize = Vector2D(newSize.x, newSize.x * RATIO);
else
newSize = Vector2D(newSize.y / RATIO, newSize.y);
}
2023-08-08 16:52:20 +00:00
newSize = newSize.clamp(MINSIZE, MAXSIZE);
if (m_eGrabbedCorner == CORNER_TOPLEFT)
newPos = newPos - newSize + m_vBeginDragSizeXY;
else if (m_eGrabbedCorner == CORNER_TOPRIGHT)
newPos = newPos + Vector2D(0.0, (m_vBeginDragSizeXY - newSize).y);
2023-08-08 16:52:20 +00:00
else if (m_eGrabbedCorner == CORNER_BOTTOMLEFT)
newPos = newPos + Vector2D((m_vBeginDragSizeXY - newSize).x, 0.0);
2023-08-08 16:52:20 +00:00
input: add snapping to floating windows (#8088) * add snapping to floating windows Works for both moving and resizing of windows. It comes with 3 options: `general:snap:enabled` - whether it's enabled, off by default `general:snap:window_gap` - minimum gap in pixels between windows before snapping. Setting to 0 effectively turns off this method of snapping. `general:snap:monitor_gap` - minimum gap in pixels between window and monitor edges before snapping. Again, setting it to 0 effectively turns it off. * snap: add more ignore criteria and change if clause into a guard * snap: refactor code * snap: new refactoring approach and account for border size * snap: do corner snapping after all edge snapping is done The approach of performing corner snaps after each individual edge snap results in far fewer scenarios where snapping can occur. After trying it out for a while, I found that I prefer an approach that's more prone to snapping. * snap: combine snapWindows and snapMonitor into a single function * snap: add forced aspect ratio functionality * snap: avoid directly referring to border_size config value * snap: address vaxerski feedback - add new line between functions - use std::function typedef for SnapFn and make snap functions static - avoid uninitialized variable declarations. - change ignore condition m_bIsX11 to isX11OverrideRedirect() - use braces for CBox and Vector2D declarations. - add SNAP_INVALID to eSnapEdge enum - use bitshift notation for eSnapEdge and eRectCorner - make performSnap a non-member function. * snap: add corner-snapping to forced aspect ratio mode
2024-10-21 11:08:25 -04:00
if (*SNAPENABLED) {
performSnap(newPos, newSize, DRAGGINGWINDOW, mode, m_eGrabbedCorner, m_vBeginDragSizeXY);
newSize = newSize.clamp(MINSIZE, MAXSIZE);
}
CBox wb = {newPos, newSize};
wb.round();
if (*PANIMATE) {
DRAGGINGWINDOW->m_vRealSize = wb.size();
DRAGGINGWINDOW->m_vRealPosition = wb.pos();
2022-08-16 21:56:54 +02:00
} else {
DRAGGINGWINDOW->m_vRealSize.setValueAndWarp(wb.size());
DRAGGINGWINDOW->m_vRealPosition.setValueAndWarp(wb.pos());
2022-08-16 21:56:54 +02:00
}
2022-09-25 20:07:48 +02:00
g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goal());
2022-06-30 12:09:05 +02:00
} else {
resizeActiveWindow(TICKDELTA, m_eGrabbedCorner, DRAGGINGWINDOW);
2022-06-30 12:09:05 +02:00
}
}
// get middle point
Vector2D middle = DRAGGINGWINDOW->m_vRealPosition.value() + DRAGGINGWINDOW->m_vRealSize.value() / 2.f;
2022-06-30 12:09:05 +02:00
// and check its monitor
const auto PMONITOR = g_pCompositor->getMonitorFromVector(middle);
2022-12-09 17:08:04 +00:00
if (PMONITOR && !SPECIAL) {
2022-06-30 12:09:05 +02:00
DRAGGINGWINDOW->m_iMonitorID = PMONITOR->ID;
DRAGGINGWINDOW->moveToWorkspace(PMONITOR->activeWorkspace);
2023-03-18 16:30:29 +00:00
DRAGGINGWINDOW->updateGroupOutputs();
2022-09-25 20:07:48 +02:00
DRAGGINGWINDOW->updateToplevel();
2022-06-30 12:09:05 +02:00
}
2022-08-05 19:23:53 +02:00
DRAGGINGWINDOW->updateWindowDecos();
2022-06-30 12:09:05 +02:00
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
}
void IHyprLayout::changeWindowFloatingMode(PHLWINDOW pWindow) {
2022-06-30 12:09:05 +02:00
internal: refactor fullscreen states (#7104) * refactor fullscreen modified: src/Compositor.cpp modified: src/Compositor.hpp modified: src/config/ConfigManager.cpp modified: src/config/ConfigManager.hpp modified: src/debug/HyprCtl.cpp modified: src/desktop/LayerSurface.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/desktop/Workspace.cpp modified: src/desktop/Workspace.hpp modified: src/events/Windows.cpp modified: src/helpers/Monitor.cpp modified: src/layout/DwindleLayout.cpp modified: src/layout/DwindleLayout.hpp modified: src/layout/IHyprLayout.cpp modified: src/layout/IHyprLayout.hpp modified: src/layout/MasterLayout.cpp modified: src/layout/MasterLayout.hpp modified: src/managers/KeybindManager.cpp modified: src/managers/KeybindManager.hpp modified: src/managers/input/IdleInhibitor.cpp modified: src/managers/input/InputManager.cpp modified: src/managers/input/Swipe.cpp modified: src/protocols/ForeignToplevelWlr.cpp modified: src/render/Renderer.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp * clean up modified: src/config/ConfigManager.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.hpp modified: src/desktop/Workspace.cpp modified: src/events/Windows.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/input/Swipe.cpp * fix mapWindow fullscreen modified: src/events/Windows.cpp * fix typo modified: src/desktop/Workspace.cpp * add fullscreenstate modified: src/config/ConfigManager.cpp modified: src/events/Windows.cpp * change syncFullscreen to lower modified: src/config/ConfigManager.hpp * initialize fs state modified: src/desktop/Window.hpp
2024-07-31 17:55:52 +00:00
if (pWindow->isFullscreen()) {
Debug::log(LOG, "changeWindowFloatingMode: fullscreen");
internal: refactor fullscreen states (#7104) * refactor fullscreen modified: src/Compositor.cpp modified: src/Compositor.hpp modified: src/config/ConfigManager.cpp modified: src/config/ConfigManager.hpp modified: src/debug/HyprCtl.cpp modified: src/desktop/LayerSurface.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/desktop/Workspace.cpp modified: src/desktop/Workspace.hpp modified: src/events/Windows.cpp modified: src/helpers/Monitor.cpp modified: src/layout/DwindleLayout.cpp modified: src/layout/DwindleLayout.hpp modified: src/layout/IHyprLayout.cpp modified: src/layout/IHyprLayout.hpp modified: src/layout/MasterLayout.cpp modified: src/layout/MasterLayout.hpp modified: src/managers/KeybindManager.cpp modified: src/managers/KeybindManager.hpp modified: src/managers/input/IdleInhibitor.cpp modified: src/managers/input/InputManager.cpp modified: src/managers/input/Swipe.cpp modified: src/protocols/ForeignToplevelWlr.cpp modified: src/render/Renderer.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp * clean up modified: src/config/ConfigManager.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.hpp modified: src/desktop/Workspace.cpp modified: src/events/Windows.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/input/Swipe.cpp * fix mapWindow fullscreen modified: src/events/Windows.cpp * fix typo modified: src/desktop/Workspace.cpp * add fullscreenstate modified: src/config/ConfigManager.cpp modified: src/events/Windows.cpp * change syncFullscreen to lower modified: src/config/ConfigManager.hpp * initialize fs state modified: src/desktop/Window.hpp
2024-07-31 17:55:52 +00:00
g_pCompositor->setWindowFullscreenInternal(pWindow, FSMODE_NONE);
2022-06-30 12:09:05 +02:00
}
2022-09-10 13:11:02 +02:00
pWindow->m_bPinned = false;
2022-06-30 12:09:05 +02:00
const auto TILED = isWindowTiled(pWindow);
2022-12-09 18:51:44 +00:00
// event
g_pEventManager->postEvent(SHyprIPCEvent{"changefloatingmode", std::format("{:x},{}", (uintptr_t)pWindow.get(), (int)TILED)});
EMIT_HOOK_EVENT("changeFloatingMode", pWindow);
2022-12-09 18:51:44 +00:00
2022-06-30 12:09:05 +02:00
if (!TILED) {
const auto PNEWMON = g_pCompositor->getMonitorFromVector(pWindow->m_vRealPosition.value() + pWindow->m_vRealSize.value() / 2.f);
2022-06-30 12:09:05 +02:00
pWindow->m_iMonitorID = PNEWMON->ID;
pWindow->moveToWorkspace(PNEWMON->activeSpecialWorkspace ? PNEWMON->activeSpecialWorkspace : PNEWMON->activeWorkspace);
2023-03-18 16:30:29 +00:00
pWindow->updateGroupOutputs();
2022-06-30 12:09:05 +02:00
const auto PWORKSPACE = PNEWMON->activeSpecialWorkspace ? PNEWMON->activeSpecialWorkspace : PNEWMON->activeWorkspace;
if (PWORKSPACE->m_bHasFullscreenWindow)
internal: refactor fullscreen states (#7104) * refactor fullscreen modified: src/Compositor.cpp modified: src/Compositor.hpp modified: src/config/ConfigManager.cpp modified: src/config/ConfigManager.hpp modified: src/debug/HyprCtl.cpp modified: src/desktop/LayerSurface.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/desktop/Workspace.cpp modified: src/desktop/Workspace.hpp modified: src/events/Windows.cpp modified: src/helpers/Monitor.cpp modified: src/layout/DwindleLayout.cpp modified: src/layout/DwindleLayout.hpp modified: src/layout/IHyprLayout.cpp modified: src/layout/IHyprLayout.hpp modified: src/layout/MasterLayout.cpp modified: src/layout/MasterLayout.hpp modified: src/managers/KeybindManager.cpp modified: src/managers/KeybindManager.hpp modified: src/managers/input/IdleInhibitor.cpp modified: src/managers/input/InputManager.cpp modified: src/managers/input/Swipe.cpp modified: src/protocols/ForeignToplevelWlr.cpp modified: src/render/Renderer.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp * clean up modified: src/config/ConfigManager.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.hpp modified: src/desktop/Workspace.cpp modified: src/events/Windows.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/input/Swipe.cpp * fix mapWindow fullscreen modified: src/events/Windows.cpp * fix typo modified: src/desktop/Workspace.cpp * add fullscreenstate modified: src/config/ConfigManager.cpp modified: src/events/Windows.cpp * change syncFullscreen to lower modified: src/config/ConfigManager.hpp * initialize fs state modified: src/desktop/Window.hpp
2024-07-31 17:55:52 +00:00
g_pCompositor->setWindowFullscreenInternal(g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID), FSMODE_NONE);
2022-06-30 12:09:05 +02:00
// save real pos cuz the func applies the default 5,5 mid
const auto PSAVEDPOS = pWindow->m_vRealPosition.goal();
const auto PSAVEDSIZE = pWindow->m_vRealSize.goal();
2022-06-30 12:09:05 +02:00
// if the window is pseudo, update its size
if (!pWindow->m_bDraggingTiled)
pWindow->m_vPseudoSize = pWindow->m_vRealSize.goal();
2022-06-30 12:09:05 +02:00
2022-08-05 17:52:14 +02:00
pWindow->m_vLastFloatingSize = PSAVEDSIZE;
// move to narnia because we don't wanna find our own node. onWindowCreatedTiling should apply the coords back.
pWindow->m_vPosition = Vector2D(-999999, -999999);
onWindowCreatedTiling(pWindow);
2022-06-30 12:09:05 +02:00
pWindow->m_vRealPosition.setValue(PSAVEDPOS);
pWindow->m_vRealSize.setValue(PSAVEDSIZE);
// fix pseudo leaving artifacts
g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID));
if (pWindow == g_pCompositor->m_pLastWindow)
m_pLastTiledWindow = pWindow;
2022-06-30 12:09:05 +02:00
} else {
onWindowRemovedTiling(pWindow);
g_pCompositor->changeWindowZOrder(pWindow, true);
CBox wb = {pWindow->m_vRealPosition.goal() + (pWindow->m_vRealSize.goal() - pWindow->m_vLastFloatingSize) / 2.f, pWindow->m_vLastFloatingSize};
wb.round();
if (!(pWindow->m_bIsFloating && pWindow->m_bIsPseudotiled) && DELTALESSTHAN(pWindow->m_vRealSize.value().x, pWindow->m_vLastFloatingSize.x, 10) &&
DELTALESSTHAN(pWindow->m_vRealSize.value().y, pWindow->m_vLastFloatingSize.y, 10)) {
wb = {wb.pos() + Vector2D{10, 10}, wb.size() - Vector2D{20, 20}};
}
pWindow->m_vRealPosition = wb.pos();
pWindow->m_vRealSize = wb.size();
pWindow->m_vSize = wb.pos();
pWindow->m_vPosition = wb.size();
g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID));
2022-08-05 18:08:23 +02:00
core: Improve handling of window properties (#6776) * add mWindowProperties modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp * support int values modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp * create m_sWindowData modified: src/Compositor.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp modified: src/layout/DwindleLayout.cpp modified: src/layout/IHyprLayout.cpp modified: src/layout/MasterLayout.cpp modified: src/managers/AnimationManager.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/XWaylandManager.cpp modified: src/render/OpenGL.cpp modified: src/render/Renderer.cpp modified: src/render/decorations/CHyprBorderDecoration.cpp modified: src/render/decorations/CHyprDropShadowDecoration.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp * simplify some properties modified: src/Compositor.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/managers/KeybindManager.cpp * store multiple values in CWindowOverridableVar modified: src/Compositor.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp modified: src/layout/IHyprLayout.cpp modified: src/managers/AnimationManager.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/XWaylandManager.cpp modified: src/render/OpenGL.cpp modified: src/render/Renderer.cpp modified: src/render/decorations/CHyprBorderDecoration.cpp modified: src/render/decorations/CHyprDropShadowDecoration.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp * clean up modified: src/Compositor.cpp modified: src/Compositor.hpp modified: src/config/ConfigManager.cpp modified: src/config/ConfigManager.hpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp modified: src/layout/DwindleLayout.cpp modified: src/layout/IHyprLayout.cpp modified: src/layout/IHyprLayout.hpp modified: src/layout/MasterLayout.cpp modified: src/managers/KeybindManager.cpp * use SET_PROP priority for exec rules modified: src/config/ConfigManager.hpp modified: src/desktop/Window.cpp * add default value modified: src/Compositor.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp modified: src/layout/IHyprLayout.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/XWaylandManager.cpp modified: src/render/OpenGL.cpp modified: src/render/Renderer.cpp modified: src/render/decorations/CHyprBorderDecoration.cpp modified: src/render/decorations/CHyprDropShadowDecoration.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp * add setprop toggle modified: src/config/ConfigManager.hpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp * add setprop toggle modified: src/debug/HyprCtl.cpp * make window rules functional modified: src/config/ConfigManager.cpp modified: src/desktop/Window.cpp * minor fixes modified: src/Compositor.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.hpp * properly clean layout data modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp modified: src/layout/DwindleLayout.cpp modified: src/layout/IHyprLayout.cpp modified: src/layout/IHyprLayout.hpp modified: src/layout/MasterLayout.cpp * remove newline modified: src/events/Windows.cpp * fixes modified: src/config/ConfigManager.hpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp * use CamelCase modified: src/Compositor.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp modified: src/layout/IHyprLayout.cpp modified: src/managers/AnimationManager.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/XWaylandManager.cpp modified: src/render/OpenGL.cpp modified: src/render/Renderer.cpp modified: src/render/decorations/CHyprBorderDecoration.cpp modified: src/render/decorations/CHyprDropShadowDecoration.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp
2024-07-11 14:10:42 +00:00
pWindow->unsetWindowData(PRIORITY_LAYOUT);
pWindow->updateWindowData();
if (pWindow == m_pLastTiledWindow)
m_pLastTiledWindow.reset();
2022-06-30 12:09:05 +02:00
}
2022-08-11 19:29:39 +02:00
g_pCompositor->updateWindowAnimatedDecorationValues(pWindow);
pWindow->updateToplevel();
2022-06-30 12:09:05 +02:00
}
void IHyprLayout::moveActiveWindow(const Vector2D& delta, PHLWINDOW pWindow) {
const auto PWINDOW = pWindow ? pWindow : g_pCompositor->m_pLastWindow.lock();
2022-06-30 12:09:05 +02:00
if (!validMapped(PWINDOW))
2022-06-30 12:09:05 +02:00
return;
if (!PWINDOW->m_bIsFloating) {
Debug::log(LOG, "Dwindle cannot move a tiled window in moveActiveWindow!");
return;
}
PWINDOW->setAnimationsToMove();
PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition.goal() + delta;
2022-06-30 12:09:05 +02:00
g_pHyprRenderer->damageWindow(PWINDOW);
2022-09-25 20:07:48 +02:00
}
void IHyprLayout::onWindowFocusChange(PHLWINDOW pNewFocus) {
m_pLastTiledWindow = pNewFocus && !pNewFocus->m_bIsFloating ? pNewFocus : m_pLastTiledWindow;
}
PHLWINDOW IHyprLayout::getNextWindowCandidate(PHLWINDOW pWindow) {
// although we don't expect nullptrs here, let's verify jic
if (!pWindow)
return nullptr;
const auto PWORKSPACE = pWindow->m_pWorkspace;
// first of all, if this is a fullscreen workspace,
if (PWORKSPACE->m_bHasFullscreenWindow)
return g_pCompositor->getFullscreenWindowOnWorkspace(pWindow->workspaceID());
if (pWindow->m_bIsFloating) {
2022-11-27 12:11:45 +00:00
// find whether there is a floating window below this one
for (auto const& w : g_pCompositor->m_vWindows) {
if (w->m_bIsMapped && !w->isHidden() && w->m_bIsFloating && !w->isX11OverrideRedirect() && w->m_pWorkspace == pWindow->m_pWorkspace && !w->m_bX11ShouldntFocus &&
core: Improve handling of window properties (#6776) * add mWindowProperties modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp * support int values modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp * create m_sWindowData modified: src/Compositor.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp modified: src/layout/DwindleLayout.cpp modified: src/layout/IHyprLayout.cpp modified: src/layout/MasterLayout.cpp modified: src/managers/AnimationManager.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/XWaylandManager.cpp modified: src/render/OpenGL.cpp modified: src/render/Renderer.cpp modified: src/render/decorations/CHyprBorderDecoration.cpp modified: src/render/decorations/CHyprDropShadowDecoration.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp * simplify some properties modified: src/Compositor.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/managers/KeybindManager.cpp * store multiple values in CWindowOverridableVar modified: src/Compositor.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp modified: src/layout/IHyprLayout.cpp modified: src/managers/AnimationManager.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/XWaylandManager.cpp modified: src/render/OpenGL.cpp modified: src/render/Renderer.cpp modified: src/render/decorations/CHyprBorderDecoration.cpp modified: src/render/decorations/CHyprDropShadowDecoration.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp * clean up modified: src/Compositor.cpp modified: src/Compositor.hpp modified: src/config/ConfigManager.cpp modified: src/config/ConfigManager.hpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp modified: src/layout/DwindleLayout.cpp modified: src/layout/IHyprLayout.cpp modified: src/layout/IHyprLayout.hpp modified: src/layout/MasterLayout.cpp modified: src/managers/KeybindManager.cpp * use SET_PROP priority for exec rules modified: src/config/ConfigManager.hpp modified: src/desktop/Window.cpp * add default value modified: src/Compositor.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp modified: src/layout/IHyprLayout.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/XWaylandManager.cpp modified: src/render/OpenGL.cpp modified: src/render/Renderer.cpp modified: src/render/decorations/CHyprBorderDecoration.cpp modified: src/render/decorations/CHyprDropShadowDecoration.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp * add setprop toggle modified: src/config/ConfigManager.hpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp * add setprop toggle modified: src/debug/HyprCtl.cpp * make window rules functional modified: src/config/ConfigManager.cpp modified: src/desktop/Window.cpp * minor fixes modified: src/Compositor.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.hpp * properly clean layout data modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp modified: src/layout/DwindleLayout.cpp modified: src/layout/IHyprLayout.cpp modified: src/layout/IHyprLayout.hpp modified: src/layout/MasterLayout.cpp * remove newline modified: src/events/Windows.cpp * fixes modified: src/config/ConfigManager.hpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp * use CamelCase modified: src/Compositor.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp modified: src/layout/IHyprLayout.cpp modified: src/managers/AnimationManager.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/XWaylandManager.cpp modified: src/render/OpenGL.cpp modified: src/render/Renderer.cpp modified: src/render/decorations/CHyprBorderDecoration.cpp modified: src/render/decorations/CHyprDropShadowDecoration.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp
2024-07-11 14:10:42 +00:00
!w->m_sWindowData.noFocus.valueOrDefault() && w != pWindow) {
if (VECINRECT((pWindow->m_vSize / 2.f + pWindow->m_vPosition), w->m_vPosition.x, w->m_vPosition.y, w->m_vPosition.x + w->m_vSize.x,
w->m_vPosition.y + w->m_vSize.y)) {
return w;
2022-11-27 12:11:45 +00:00
}
}
}
// let's try the last tiled window.
if (m_pLastTiledWindow.lock() && m_pLastTiledWindow->m_pWorkspace == pWindow->m_pWorkspace)
return m_pLastTiledWindow.lock();
// if we don't, let's try to find any window that is in the middle
if (const auto PWINDOWCANDIDATE = g_pCompositor->vectorToWindowUnified(pWindow->middle(), RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING);
PWINDOWCANDIDATE && PWINDOWCANDIDATE != pWindow)
return PWINDOWCANDIDATE;
// if not, floating window
for (auto const& w : g_pCompositor->m_vWindows) {
if (w->m_bIsMapped && !w->isHidden() && w->m_bIsFloating && !w->isX11OverrideRedirect() && w->m_pWorkspace == pWindow->m_pWorkspace && !w->m_bX11ShouldntFocus &&
core: Improve handling of window properties (#6776) * add mWindowProperties modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp * support int values modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp * create m_sWindowData modified: src/Compositor.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp modified: src/layout/DwindleLayout.cpp modified: src/layout/IHyprLayout.cpp modified: src/layout/MasterLayout.cpp modified: src/managers/AnimationManager.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/XWaylandManager.cpp modified: src/render/OpenGL.cpp modified: src/render/Renderer.cpp modified: src/render/decorations/CHyprBorderDecoration.cpp modified: src/render/decorations/CHyprDropShadowDecoration.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp * simplify some properties modified: src/Compositor.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/managers/KeybindManager.cpp * store multiple values in CWindowOverridableVar modified: src/Compositor.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp modified: src/layout/IHyprLayout.cpp modified: src/managers/AnimationManager.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/XWaylandManager.cpp modified: src/render/OpenGL.cpp modified: src/render/Renderer.cpp modified: src/render/decorations/CHyprBorderDecoration.cpp modified: src/render/decorations/CHyprDropShadowDecoration.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp * clean up modified: src/Compositor.cpp modified: src/Compositor.hpp modified: src/config/ConfigManager.cpp modified: src/config/ConfigManager.hpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp modified: src/layout/DwindleLayout.cpp modified: src/layout/IHyprLayout.cpp modified: src/layout/IHyprLayout.hpp modified: src/layout/MasterLayout.cpp modified: src/managers/KeybindManager.cpp * use SET_PROP priority for exec rules modified: src/config/ConfigManager.hpp modified: src/desktop/Window.cpp * add default value modified: src/Compositor.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp modified: src/layout/IHyprLayout.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/XWaylandManager.cpp modified: src/render/OpenGL.cpp modified: src/render/Renderer.cpp modified: src/render/decorations/CHyprBorderDecoration.cpp modified: src/render/decorations/CHyprDropShadowDecoration.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp * add setprop toggle modified: src/config/ConfigManager.hpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp * add setprop toggle modified: src/debug/HyprCtl.cpp * make window rules functional modified: src/config/ConfigManager.cpp modified: src/desktop/Window.cpp * minor fixes modified: src/Compositor.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.hpp * properly clean layout data modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp modified: src/layout/DwindleLayout.cpp modified: src/layout/IHyprLayout.cpp modified: src/layout/IHyprLayout.hpp modified: src/layout/MasterLayout.cpp * remove newline modified: src/events/Windows.cpp * fixes modified: src/config/ConfigManager.hpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp * use CamelCase modified: src/Compositor.cpp modified: src/debug/HyprCtl.cpp modified: src/desktop/Window.cpp modified: src/desktop/Window.hpp modified: src/events/Windows.cpp modified: src/layout/IHyprLayout.cpp modified: src/managers/AnimationManager.cpp modified: src/managers/KeybindManager.cpp modified: src/managers/XWaylandManager.cpp modified: src/render/OpenGL.cpp modified: src/render/Renderer.cpp modified: src/render/decorations/CHyprBorderDecoration.cpp modified: src/render/decorations/CHyprDropShadowDecoration.cpp modified: src/render/decorations/CHyprGroupBarDecoration.cpp
2024-07-11 14:10:42 +00:00
!w->m_sWindowData.noFocus.valueOrDefault() && w != pWindow)
return w;
}
// if there is no candidate, too bad
return nullptr;
}
// if it was a tiled window, we first try to find the window that will replace it.
auto pWindowCandidate = g_pCompositor->vectorToWindowUnified(pWindow->middle(), RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING);
if (!pWindowCandidate)
pWindowCandidate = g_pCompositor->getTopLeftWindowOnWorkspace(pWindow->workspaceID());
if (!pWindowCandidate)
pWindowCandidate = g_pCompositor->getFirstWindowOnWorkspace(pWindow->workspaceID());
if (!pWindowCandidate || pWindow == pWindowCandidate || !pWindowCandidate->m_bIsMapped || pWindowCandidate->isHidden() || pWindowCandidate->m_bX11ShouldntFocus ||
pWindowCandidate->isX11OverrideRedirect() || pWindowCandidate->m_iMonitorID != g_pCompositor->m_pLastMonitor->ID)
return nullptr;
return pWindowCandidate;
}
bool IHyprLayout::isWindowReachable(PHLWINDOW pWindow) {
return pWindow && (!pWindow->isHidden() || pWindow->m_sGroupData.pNextWindow);
}
void IHyprLayout::bringWindowToTop(PHLWINDOW pWindow) {
if (pWindow == nullptr)
return;
if (pWindow->isHidden() && pWindow->m_sGroupData.pNextWindow) {
// grouped, change the current to this window
pWindow->setGroupCurrent(pWindow);
}
}
void IHyprLayout::requestFocusForWindow(PHLWINDOW pWindow) {
bringWindowToTop(pWindow);
g_pCompositor->focusWindow(pWindow);
g_pCompositor->warpCursorTo(pWindow->middle());
}
Vector2D IHyprLayout::predictSizeForNewWindowFloating(PHLWINDOW pWindow) { // get all rules, see if we have any size overrides.
Vector2D sizeOverride = {};
if (g_pCompositor->m_pLastMonitor) {
for (auto const& r : g_pConfigManager->getMatchingRules(pWindow, true, true)) {
if (r.szRule.starts_with("size")) {
try {
const auto VALUE = r.szRule.substr(r.szRule.find(' ') + 1);
const auto SIZEXSTR = VALUE.substr(0, VALUE.find(' '));
const auto SIZEYSTR = VALUE.substr(VALUE.find(' ') + 1);
const auto MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(pWindow);
const auto SIZEX = SIZEXSTR == "max" ?
std::clamp(MAXSIZE.x, 20.0, g_pCompositor->m_pLastMonitor->vecSize.x) :
(!SIZEXSTR.contains('%') ? std::stoi(SIZEXSTR) : std::stof(SIZEXSTR.substr(0, SIZEXSTR.length() - 1)) * 0.01 * g_pCompositor->m_pLastMonitor->vecSize.x);
const auto SIZEY = SIZEYSTR == "max" ?
std::clamp(MAXSIZE.y, 20.0, g_pCompositor->m_pLastMonitor->vecSize.y) :
(!SIZEYSTR.contains('%') ? std::stoi(SIZEYSTR) : std::stof(SIZEYSTR.substr(0, SIZEYSTR.length() - 1)) * 0.01 * g_pCompositor->m_pLastMonitor->vecSize.y);
sizeOverride = {SIZEX, SIZEY};
} catch (...) { Debug::log(LOG, "Rule size failed, rule: {} -> {}", r.szRule, r.szValue); }
break;
}
}
}
return sizeOverride;
}
Vector2D IHyprLayout::predictSizeForNewWindow(PHLWINDOW pWindow) {
bool shouldBeFloated = g_pXWaylandManager->shouldBeFloated(pWindow, true);
if (!shouldBeFloated) {
for (auto const& r : g_pConfigManager->getMatchingRules(pWindow, true, true)) {
if (r.szRule.starts_with("float")) {
shouldBeFloated = true;
break;
}
}
}
Vector2D sizePredicted = {};
if (!shouldBeFloated)
sizePredicted = predictSizeForNewWindowTiled();
else
sizePredicted = predictSizeForNewWindowFloating(pWindow);
2024-05-10 23:28:33 +01:00
Vector2D maxSize = pWindow->m_pXDGSurface->toplevel->pending.maxSize;
if ((maxSize.x > 0 && maxSize.x < sizePredicted.x) || (maxSize.y > 0 && maxSize.y < sizePredicted.y))
sizePredicted = {};
return sizePredicted;
}
IHyprLayout::~IHyprLayout() {}