aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMightyPlaza <[email protected]>2023-08-08 16:52:20 +0000
committerGitHub <[email protected]>2023-08-08 18:52:20 +0200
commit6295cbe9cb39b67e8d2dae1e4edeb281d84f5483 (patch)
treebfa75a2ddfe6ec9c8abae0a30467ab02f7160b89
parentb68292340c910292b6df3d504c9ee706027d8407 (diff)
downloadHyprland-6295cbe9cb39b67e8d2dae1e4edeb281d84f5483.tar.gz
Hyprland-6295cbe9cb39b67e8d2dae1e4edeb281d84f5483.zip
keybinds: Keep aspect ratio (#2907)
-rw-r--r--src/Window.cpp15
-rw-r--r--src/Window.hpp4
-rw-r--r--src/config/ConfigManager.cpp5
-rw-r--r--src/debug/HyprCtl.cpp2
-rw-r--r--src/layout/IHyprLayout.cpp58
-rw-r--r--src/managers/KeybindManager.cpp14
-rw-r--r--src/managers/input/InputManager.hpp17
7 files changed, 76 insertions, 39 deletions
diff --git a/src/Window.cpp b/src/Window.cpp
index f1acc791..f48d27f1 100644
--- a/src/Window.cpp
+++ b/src/Window.cpp
@@ -532,6 +532,8 @@ void CWindow::applyDynamicRule(const SWindowRule& r) {
} catch (std::exception& e) { Debug::log(ERR, "BorderColor rule \"%s\" failed with: %s", r.szRule.c_str(), e.what()); }
} else if (r.szRule == "dimaround") {
m_sAdditionalConfigData.dimAround = true;
+ } else if (r.szRule == "keepaspectratio") {
+ m_sAdditionalConfigData.keepAspectRatio = true;
}
}
@@ -546,12 +548,13 @@ void CWindow::updateDynamicRules() {
m_sAdditionalConfigData.forceNoDim = false;
if (!m_sAdditionalConfigData.forceOpaqueOverridden)
m_sAdditionalConfigData.forceOpaque = false;
- m_sAdditionalConfigData.forceNoAnims = false;
- m_sAdditionalConfigData.animationStyle = std::string("");
- m_sAdditionalConfigData.rounding = -1;
- m_sAdditionalConfigData.dimAround = false;
- m_sAdditionalConfigData.forceRGBX = false;
- m_sAdditionalConfigData.borderSize = -1;
+ m_sAdditionalConfigData.forceNoAnims = false;
+ m_sAdditionalConfigData.animationStyle = std::string("");
+ m_sAdditionalConfigData.rounding = -1;
+ m_sAdditionalConfigData.dimAround = false;
+ m_sAdditionalConfigData.forceRGBX = false;
+ m_sAdditionalConfigData.borderSize = -1;
+ m_sAdditionalConfigData.keepAspectRatio = false;
const auto WINDOWRULES = g_pConfigManager->getMatchingRules(this);
for (auto& r : WINDOWRULES) {
diff --git a/src/Window.hpp b/src/Window.hpp
index bdd079de..d3c34a63 100644
--- a/src/Window.hpp
+++ b/src/Window.hpp
@@ -10,8 +10,7 @@
#include "helpers/Vector2D.hpp"
#include "helpers/WLSurface.hpp"
-enum eIdleInhibitMode
-{
+enum eIdleInhibitMode {
IDLEINHIBIT_NONE = 0,
IDLEINHIBIT_ALWAYS,
IDLEINHIBIT_FULLSCREEN,
@@ -122,6 +121,7 @@ struct SWindowAdditionalConfigData {
CWindowOverridableVar<bool> noMaxSize = false;
CWindowOverridableVar<bool> dimAround = false;
CWindowOverridableVar<bool> forceRGBX = false;
+ CWindowOverridableVar<bool> keepAspectRatio = false;
CWindowOverridableVar<int> borderSize = -1; // -1 means unset, takes precedence over the renderdata one
};
diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp
index 5182942d..461956a2 100644
--- a/src/config/ConfigManager.cpp
+++ b/src/config/ConfigManager.cpp
@@ -887,8 +887,9 @@ bool windowRuleValid(const std::string& RULE) {
RULE.find("maxsize") != 0 && RULE.find("pseudo") != 0 && RULE.find("monitor") != 0 && RULE.find("idleinhibit") != 0 && RULE != "nofocus" && RULE != "noblur" &&
RULE != "noshadow" && RULE != "nodim" && RULE != "noborder" && RULE != "center" && RULE != "opaque" && RULE != "forceinput" && RULE != "fullscreen" &&
RULE != "nofullscreenrequest" && RULE != "nomaximizerequest" && RULE != "fakefullscreen" && RULE != "nomaxsize" && RULE != "pin" && RULE != "noanim" &&
- RULE != "dimaround" && RULE != "windowdance" && RULE != "maximize" && RULE.find("animation") != 0 && RULE.find("rounding") != 0 && RULE.find("workspace") != 0 &&
- RULE.find("bordercolor") != 0 && RULE != "forcergbx" && RULE != "noinitialfocus" && RULE != "stayfocused" && RULE.find("bordersize") != 0);
+ RULE != "dimaround" && RULE != "windowdance" && RULE != "maximize" && RULE != "keepaspectratio" && RULE.find("animation") != 0 && RULE.find("rounding") != 0 &&
+ RULE.find("workspace") != 0 && RULE.find("bordercolor") != 0 && RULE != "forcergbx" && RULE != "noinitialfocus" && RULE != "stayfocused" &&
+ RULE.find("bordersize") != 0);
}
bool layerRuleValid(const std::string& RULE) {
diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp
index 6ad13ce4..2713dee2 100644
--- a/src/debug/HyprCtl.cpp
+++ b/src/debug/HyprCtl.cpp
@@ -1002,6 +1002,8 @@ std::string dispatchSetProp(std::string request) {
PWINDOW->m_sAdditionalConfigData.forceRGBX.forceSetIgnoreLocked(configStringToInt(VAL), lock);
} else if (PROP == "bordersize") {
PWINDOW->m_sSpecialRenderData.borderSize.forceSetIgnoreLocked(configStringToInt(VAL), lock);
+ } else if (PROP == "keepaspectratio") {
+ PWINDOW->m_sAdditionalConfigData.keepAspectRatio.forceSetIgnoreLocked(configStringToInt(VAL), lock);
} else {
return "prop not found";
}
diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp
index baae6616..f39b190a 100644
--- a/src/layout/IHyprLayout.cpp
+++ b/src/layout/IHyprLayout.cpp
@@ -235,7 +235,7 @@ void IHyprLayout::onBeginDragWindow() {
}
}
- if (g_pInputManager->dragMode != MBIND_RESIZE)
+ if (g_pInputManager->dragMode != MBIND_RESIZE && g_pInputManager->dragMode != MBIND_RESIZE_FORCE_RATIO && g_pInputManager->dragMode != MBIND_RESIZE_BLOCK_RATIO)
g_pInputManager->setCursorImageUntilUnset("grab");
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
@@ -314,29 +314,55 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
}
g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goalv());
- } else if (g_pInputManager->dragMode == MBIND_RESIZE) {
+ } else if (g_pInputManager->dragMode == MBIND_RESIZE || g_pInputManager->dragMode == MBIND_RESIZE_FORCE_RATIO || g_pInputManager->dragMode == MBIND_RESIZE_BLOCK_RATIO) {
if (DRAGGINGWINDOW->m_bIsFloating) {
- const auto MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(DRAGGINGWINDOW);
-
- // calc the new size and pos
+ Vector2D MINSIZE = Vector2D(20, 20);
+ Vector2D MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(DRAGGINGWINDOW);
Vector2D newSize = m_vBeginDragSizeXY;
Vector2D newPos = m_vBeginDragPositionXY;
- if (m_eGrabbedCorner == CORNER_BOTTOMRIGHT) {
- newSize = (newSize + DELTA).clamp(Vector2D(20, 20), MAXSIZE);
- } else if (m_eGrabbedCorner == CORNER_TOPLEFT) {
- newSize = (newSize - DELTA).clamp(Vector2D(20, 20), MAXSIZE);
- newPos = newPos - newSize + m_vBeginDragSizeXY;
- } else if (m_eGrabbedCorner == CORNER_TOPRIGHT) {
- newSize = (newSize + Vector2D(DELTA.x, -DELTA.y)).clamp(Vector2D(20, 20), MAXSIZE);
- newPos = newPos + Vector2D(0, (m_vBeginDragSizeXY - newSize).y);
- } else if (m_eGrabbedCorner == CORNER_BOTTOMLEFT) {
- newSize = (newSize + Vector2D(-DELTA.x, DELTA.y)).clamp(Vector2D(20, 20), MAXSIZE);
- newPos = newPos + Vector2D((m_vBeginDragSizeXY - newSize).x, 0);
+ 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);
+
+ if ((m_vBeginDragSizeXY.x >= 1 && m_vBeginDragSizeXY.y >= 1) &&
+ (g_pInputManager->dragMode == MBIND_RESIZE_FORCE_RATIO ||
+ (!(g_pInputManager->dragMode == MBIND_RESIZE_BLOCK_RATIO) && DRAGGINGWINDOW->m_sAdditionalConfigData.keepAspectRatio))) {
+
+ 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);
}
+ 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, (m_vBeginDragSizeXY - newSize).y);
+ else if (m_eGrabbedCorner == CORNER_BOTTOMLEFT)
+ newPos = newPos + Vector2D((m_vBeginDragSizeXY - newSize).x, 0);
+
if (*PANIMATE) {
DRAGGINGWINDOW->m_vRealSize = newSize;
DRAGGINGWINDOW->m_vRealPosition = newPos;
diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp
index 8c0cfab4..9cdf05d0 100644
--- a/src/managers/KeybindManager.cpp
+++ b/src/managers/KeybindManager.cpp
@@ -1942,10 +1942,10 @@ void CKeybindManager::pinActive(std::string args) {
}
void CKeybindManager::mouse(std::string args) {
- const auto TRUEARG = args.substr(1);
+ const auto ARGS = CVarList(args.substr(1), 2, ' ');
const auto PRESSED = args[0] == '1';
- if (TRUEARG == "movewindow") {
+ if (ARGS[0] == "movewindow") {
if (PRESSED) {
g_pKeybindManager->m_bIsMouseBindActive = true;
@@ -1962,13 +1962,19 @@ void CKeybindManager::mouse(std::string args) {
g_pInputManager->dragMode = MBIND_INVALID;
}
}
- } else if (TRUEARG == "resizewindow") {
+ } else if (ARGS[0] == "resizewindow") {
if (PRESSED) {
g_pKeybindManager->m_bIsMouseBindActive = true;
g_pInputManager->currentlyDraggedWindow = g_pCompositor->vectorToWindowIdeal(g_pInputManager->getMouseCoordsInternal());
- g_pInputManager->dragMode = MBIND_RESIZE;
+ try {
+ switch (std::stoi(ARGS[1])) {
+ case 1: g_pInputManager->dragMode = MBIND_RESIZE_FORCE_RATIO; break;
+ case 2: g_pInputManager->dragMode = MBIND_RESIZE_BLOCK_RATIO; break;
+ default: g_pInputManager->dragMode = MBIND_RESIZE;
+ }
+ } catch (std::exception& e) { g_pInputManager->dragMode = MBIND_RESIZE; }
g_pLayoutManager->getCurrentLayout()->onBeginDragWindow();
} else {
g_pKeybindManager->m_bIsMouseBindActive = false;
diff --git a/src/managers/input/InputManager.hpp b/src/managers/input/InputManager.hpp
index 862dc886..1a3eac0c 100644
--- a/src/managers/input/InputManager.hpp
+++ b/src/managers/input/InputManager.hpp
@@ -7,21 +7,20 @@
#include "../../helpers/Timer.hpp"
#include "InputMethodRelay.hpp"
-enum eClickBehaviorMode
-{
+enum eClickBehaviorMode {
CLICKMODE_DEFAULT = 0,
CLICKMODE_KILL
};
-enum eMouseBindMode
-{
- MBIND_INVALID = -1,
- MBIND_MOVE = 0,
- MBIND_RESIZE
+enum eMouseBindMode {
+ MBIND_INVALID = -1,
+ MBIND_MOVE = 0,
+ MBIND_RESIZE = 1,
+ MBIND_RESIZE_BLOCK_RATIO = 2,
+ MBIND_RESIZE_FORCE_RATIO = 3
};
-enum eBorderIconDirection
-{
+enum eBorderIconDirection {
BORDERICON_NONE,
BORDERICON_UP,
BORDERICON_DOWN,