mirror of
https://github.com/hyprwm/Hyprland
synced 2025-12-28 04:30:06 +01:00
layout: fit floating window on toggle to float (#12139)
This commit is contained in:
parent
83a0a62004
commit
6ade4d58ca
6 changed files with 108 additions and 10 deletions
53
hyprtester/src/tests/main/dwindle.cpp
Normal file
53
hyprtester/src/tests/main/dwindle.cpp
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
#include "../shared.hpp"
|
||||||
|
#include "../../shared.hpp"
|
||||||
|
#include "../../hyprctlCompat.hpp"
|
||||||
|
#include "tests.hpp"
|
||||||
|
|
||||||
|
static int ret = 0;
|
||||||
|
|
||||||
|
static void testFloatClamp() {
|
||||||
|
for (auto const& win : {"a", "b", "c"}) {
|
||||||
|
if (!Tests::spawnKitty(win)) {
|
||||||
|
NLog::log("{}Failed to spawn kitty with win class `{}`", Colors::RED, win);
|
||||||
|
++TESTS_FAILED;
|
||||||
|
ret = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OK(getFromSocket("/keyword dwindle:force_split 2"));
|
||||||
|
OK(getFromSocket("/dispatch focuswindow class:c"));
|
||||||
|
OK(getFromSocket("/dispatch setfloating class:c"));
|
||||||
|
OK(getFromSocket("/dispatch resizewindowpixel exact 1200 900,class:c"));
|
||||||
|
OK(getFromSocket("/dispatch settiled class:c"));
|
||||||
|
OK(getFromSocket("/dispatch setfloating class:c"));
|
||||||
|
|
||||||
|
{
|
||||||
|
auto str = getFromSocket("/clients");
|
||||||
|
EXPECT_CONTAINS(str, "at: 718,178");
|
||||||
|
EXPECT_CONTAINS(str, "size: 1200,900");
|
||||||
|
}
|
||||||
|
|
||||||
|
OK(getFromSocket("/keyword dwindle:force_split 0"));
|
||||||
|
|
||||||
|
// clean up
|
||||||
|
NLog::log("{}Killing all windows", Colors::YELLOW);
|
||||||
|
Tests::killAllWindows();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool test() {
|
||||||
|
NLog::log("{}Testing Dwindle layout", Colors::GREEN);
|
||||||
|
|
||||||
|
// test
|
||||||
|
NLog::log("{}Testing float clamp", Colors::GREEN);
|
||||||
|
testFloatClamp();
|
||||||
|
|
||||||
|
// clean up
|
||||||
|
NLog::log("Cleaning up", Colors::YELLOW);
|
||||||
|
getFromSocket("/dispatch workspace 1");
|
||||||
|
OK(getFromSocket("/reload"));
|
||||||
|
|
||||||
|
return !ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
REGISTER_TEST_FN(test);
|
||||||
|
|
@ -45,11 +45,15 @@ static bool test() {
|
||||||
EXPECT(Tests::windowCount(), 1);
|
EXPECT(Tests::windowCount(), 1);
|
||||||
|
|
||||||
// Give the shell a moment to initialize
|
// Give the shell a moment to initialize
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||||
|
|
||||||
OK(getFromSocket("/dispatch plugin:test:gesture up,4"));
|
OK(getFromSocket("/dispatch plugin:test:gesture up,5"));
|
||||||
|
OK(getFromSocket("/dispatch plugin:test:gesture down,5"));
|
||||||
|
OK(getFromSocket("/dispatch plugin:test:gesture left,5"));
|
||||||
|
OK(getFromSocket("/dispatch plugin:test:gesture right,5"));
|
||||||
|
OK(getFromSocket("/dispatch plugin:test:gesture right,4"));
|
||||||
|
|
||||||
EXPECT(waitForWindowCount(0, "Gesture sent ctrl+d to kitty"), true);
|
EXPECT(waitForWindowCount(0, "Gesture sent paste exit + enter to kitty"), true);
|
||||||
|
|
||||||
EXPECT(Tests::windowCount(), 0);
|
EXPECT(Tests::windowCount(), 0);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -350,7 +350,11 @@ gesture = 3, down, mod:ALT, float
|
||||||
|
|
||||||
gesture = 3, horizontal, mod:ALT, workspace
|
gesture = 3, horizontal, mod:ALT, workspace
|
||||||
|
|
||||||
gesture = 4, up, dispatcher, sendshortcut, ctrl, d, activewindow
|
gesture = 5, up, dispatcher, sendshortcut, , e, activewindow
|
||||||
|
gesture = 5, down, dispatcher, sendshortcut, , x, activewindow
|
||||||
|
gesture = 5, left, dispatcher, sendshortcut, , i, activewindow
|
||||||
|
gesture = 5, right, dispatcher, sendshortcut, , t, activewindow
|
||||||
|
gesture = 4, right, dispatcher, sendshortcut, , return, activewindow
|
||||||
gesture = 4, left, dispatcher, movecursortocorner, 1
|
gesture = 4, left, dispatcher, movecursortocorner, 1
|
||||||
|
|
||||||
windowrule = float, pin, class:wr_kitty
|
windowrule = float, pin, class:wr_kitty
|
||||||
|
|
|
||||||
|
|
@ -257,7 +257,10 @@ CBox CWindow::getWindowBoxUnified(uint64_t properties) {
|
||||||
return {PMONITOR->m_position.x, PMONITOR->m_position.y, PMONITOR->m_size.x, PMONITOR->m_size.y};
|
return {PMONITOR->m_position.x, PMONITOR->m_position.y, PMONITOR->m_size.x, PMONITOR->m_size.y};
|
||||||
}
|
}
|
||||||
|
|
||||||
CBox box = {m_realPosition->value().x, m_realPosition->value().y, m_realSize->value().x, m_realSize->value().y};
|
const auto POS = m_realPosition->value();
|
||||||
|
const auto SIZE = m_realSize->value();
|
||||||
|
|
||||||
|
CBox box{POS, SIZE};
|
||||||
box.addExtents(getWindowExtentsUnified(properties));
|
box.addExtents(getWindowExtentsUnified(properties));
|
||||||
|
|
||||||
return box;
|
return box;
|
||||||
|
|
|
||||||
|
|
@ -790,17 +790,16 @@ void IHyprLayout::changeWindowFloatingMode(PHLWINDOW pWindow) {
|
||||||
CBox wb = {pWindow->m_realPosition->goal() + (pWindow->m_realSize->goal() - pWindow->m_lastFloatingSize) / 2.f, pWindow->m_lastFloatingSize};
|
CBox wb = {pWindow->m_realPosition->goal() + (pWindow->m_realSize->goal() - pWindow->m_lastFloatingSize) / 2.f, pWindow->m_lastFloatingSize};
|
||||||
wb.round();
|
wb.round();
|
||||||
|
|
||||||
if (!(pWindow->m_isFloating && pWindow->m_isPseudotiled) && DELTALESSTHAN(pWindow->m_realSize->value().x, pWindow->m_lastFloatingSize.x, 10) &&
|
if (!(pWindow->m_isFloating && pWindow->m_isPseudotiled) && DELTALESSTHAN(pWindow->m_realSize->goal().x, pWindow->m_lastFloatingSize.x, 10) &&
|
||||||
DELTALESSTHAN(pWindow->m_realSize->value().y, pWindow->m_lastFloatingSize.y, 10)) {
|
DELTALESSTHAN(pWindow->m_realSize->goal().y, pWindow->m_lastFloatingSize.y, 10)) {
|
||||||
wb = {wb.pos() + Vector2D{10, 10}, wb.size() - Vector2D{20, 20}};
|
wb = {wb.pos() + Vector2D{10, 10}, wb.size() - Vector2D{20, 20}};
|
||||||
}
|
}
|
||||||
|
|
||||||
*pWindow->m_realPosition = wb.pos();
|
|
||||||
*pWindow->m_realSize = wb.size();
|
|
||||||
|
|
||||||
pWindow->m_size = wb.size();
|
pWindow->m_size = wb.size();
|
||||||
pWindow->m_position = wb.pos();
|
pWindow->m_position = wb.pos();
|
||||||
|
|
||||||
|
fitFloatingWindowOnMonitor(pWindow, wb);
|
||||||
|
|
||||||
g_pHyprRenderer->damageMonitor(pWindow->m_monitor.lock());
|
g_pHyprRenderer->damageMonitor(pWindow->m_monitor.lock());
|
||||||
|
|
||||||
pWindow->unsetWindowData(PRIORITY_LAYOUT);
|
pWindow->unsetWindowData(PRIORITY_LAYOUT);
|
||||||
|
|
@ -815,6 +814,36 @@ void IHyprLayout::changeWindowFloatingMode(PHLWINDOW pWindow) {
|
||||||
g_pHyprRenderer->damageWindow(pWindow);
|
g_pHyprRenderer->damageWindow(pWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IHyprLayout::fitFloatingWindowOnMonitor(PHLWINDOW w, std::optional<CBox> tb) {
|
||||||
|
if (!w->m_isFloating)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto PMONITOR = w->m_monitor.lock();
|
||||||
|
|
||||||
|
if (!PMONITOR)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto EXTENTS = w->getWindowExtentsUnified(RESERVED_EXTENTS | INPUT_EXTENTS);
|
||||||
|
CBox targetBoxMonLocal = tb.value_or(w->getWindowMainSurfaceBox()).translate(-PMONITOR->m_position).addExtents(EXTENTS);
|
||||||
|
|
||||||
|
if (targetBoxMonLocal.w < PMONITOR->m_size.x) {
|
||||||
|
if (targetBoxMonLocal.x < 0)
|
||||||
|
targetBoxMonLocal.x = 0;
|
||||||
|
else if (targetBoxMonLocal.x + targetBoxMonLocal.w > PMONITOR->m_size.x)
|
||||||
|
targetBoxMonLocal.x = PMONITOR->m_size.x - targetBoxMonLocal.w;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetBoxMonLocal.h < PMONITOR->m_size.y) {
|
||||||
|
if (targetBoxMonLocal.y < 0)
|
||||||
|
targetBoxMonLocal.y = 0;
|
||||||
|
else if (targetBoxMonLocal.y + targetBoxMonLocal.h > PMONITOR->m_size.y)
|
||||||
|
targetBoxMonLocal.y = PMONITOR->m_size.y - targetBoxMonLocal.h;
|
||||||
|
}
|
||||||
|
|
||||||
|
*w->m_realPosition = (targetBoxMonLocal.pos() + PMONITOR->m_position + EXTENTS.topLeft).round();
|
||||||
|
*w->m_realSize = (targetBoxMonLocal.size() - EXTENTS.topLeft - EXTENTS.bottomRight).round();
|
||||||
|
}
|
||||||
|
|
||||||
void IHyprLayout::moveActiveWindow(const Vector2D& delta, PHLWINDOW pWindow) {
|
void IHyprLayout::moveActiveWindow(const Vector2D& delta, PHLWINDOW pWindow) {
|
||||||
const auto PWINDOW = pWindow ? pWindow : g_pCompositor->m_lastWindow.lock();
|
const auto PWINDOW = pWindow ? pWindow : g_pCompositor->m_lastWindow.lock();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -225,6 +225,11 @@ class IHyprLayout {
|
||||||
*/
|
*/
|
||||||
virtual void performSnap(Vector2D& sourcePos, Vector2D& sourceSize, PHLWINDOW DRAGGINGWINDOW, const eMouseBindMode MODE, const int CORNER, const Vector2D& BEGINSIZE);
|
virtual void performSnap(Vector2D& sourcePos, Vector2D& sourceSize, PHLWINDOW DRAGGINGWINDOW, const eMouseBindMode MODE, const int CORNER, const Vector2D& BEGINSIZE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Fits a floating window on its monitor
|
||||||
|
*/
|
||||||
|
virtual void fitFloatingWindowOnMonitor(PHLWINDOW w, std::optional<CBox> targetBox = std::nullopt);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_mouseMoveEventCount;
|
int m_mouseMoveEventCount;
|
||||||
Vector2D m_beginDragXY;
|
Vector2D m_beginDragXY;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue