layout/algos: use binds:window_direction_monitor_fallback for moves (#13508)
ref https://github.com/hyprwm/Hyprland/discussions/13473
This commit is contained in:
parent
ff20cbf89c
commit
be03497b82
6 changed files with 153 additions and 9 deletions
|
|
@ -255,6 +255,126 @@ static void testMultimonBAF() {
|
||||||
Tests::killAllWindows();
|
Tests::killAllWindows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void testMultimonFocus() {
|
||||||
|
NLog::log("{}Testing multimon focus and move", Colors::YELLOW);
|
||||||
|
|
||||||
|
OK(getFromSocket("/keyword input:follow_mouse 0"));
|
||||||
|
OK(getFromSocket("/dispatch focusmonitor HEADLESS-3"));
|
||||||
|
OK(getFromSocket("/dispatch workspace 8"));
|
||||||
|
OK(getFromSocket("/dispatch focusmonitor HEADLESS-2"));
|
||||||
|
OK(getFromSocket("/dispatch workspace 7"));
|
||||||
|
|
||||||
|
for (auto const& win : {"a", "b"}) {
|
||||||
|
if (!Tests::spawnKitty(win)) {
|
||||||
|
NLog::log("{}Failed to spawn kitty with win class `{}`", Colors::RED, win);
|
||||||
|
++TESTS_FAILED;
|
||||||
|
ret = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OK(getFromSocket("/dispatch focuswindow class:a"));
|
||||||
|
OK(getFromSocket("/dispatch movefocus r"));
|
||||||
|
|
||||||
|
{
|
||||||
|
auto str = getFromSocket("/activeworkspace");
|
||||||
|
EXPECT_CONTAINS(str, "workspace ID 7 ");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto str = getFromSocket("/activewindow");
|
||||||
|
EXPECT_CONTAINS(str, "class: b");
|
||||||
|
}
|
||||||
|
|
||||||
|
OK(getFromSocket("/dispatch movefocus r"));
|
||||||
|
|
||||||
|
{
|
||||||
|
auto str = getFromSocket("/activeworkspace");
|
||||||
|
EXPECT_CONTAINS(str, "workspace ID 8 ");
|
||||||
|
}
|
||||||
|
|
||||||
|
Tests::spawnKitty("c");
|
||||||
|
|
||||||
|
{
|
||||||
|
auto str = getFromSocket("/activewindow");
|
||||||
|
EXPECT_CONTAINS(str, "class: c");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto str = getFromSocket("/activeworkspace");
|
||||||
|
EXPECT_CONTAINS(str, "workspace ID 8 ");
|
||||||
|
}
|
||||||
|
|
||||||
|
OK(getFromSocket("/dispatch movefocus l"));
|
||||||
|
|
||||||
|
{
|
||||||
|
auto str = getFromSocket("/activewindow");
|
||||||
|
EXPECT_CONTAINS(str, "class: b");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto str = getFromSocket("/activeworkspace");
|
||||||
|
EXPECT_CONTAINS(str, "workspace ID 7 ");
|
||||||
|
}
|
||||||
|
|
||||||
|
OK(getFromSocket("/dispatch movewindow r"));
|
||||||
|
|
||||||
|
{
|
||||||
|
auto str = getFromSocket("/activewindow");
|
||||||
|
EXPECT_CONTAINS(str, "class: b");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto str = getFromSocket("/activeworkspace");
|
||||||
|
EXPECT_CONTAINS(str, "workspace ID 8 ");
|
||||||
|
}
|
||||||
|
|
||||||
|
OK(getFromSocket("/dispatch movefocus r"));
|
||||||
|
|
||||||
|
{
|
||||||
|
auto str = getFromSocket("/activewindow");
|
||||||
|
EXPECT_CONTAINS(str, "class: c");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto str = getFromSocket("/activeworkspace");
|
||||||
|
EXPECT_CONTAINS(str, "workspace ID 8 ");
|
||||||
|
}
|
||||||
|
|
||||||
|
OK(getFromSocket("/dispatch movefocus l"));
|
||||||
|
|
||||||
|
OK(getFromSocket("/keyword general:no_focus_fallback true"));
|
||||||
|
OK(getFromSocket("/keyword binds:window_direction_monitor_fallback false"));
|
||||||
|
|
||||||
|
OK(getFromSocket("/dispatch movefocus l"));
|
||||||
|
|
||||||
|
{
|
||||||
|
auto str = getFromSocket("/activewindow");
|
||||||
|
EXPECT_CONTAINS(str, "class: b");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto str = getFromSocket("/activeworkspace");
|
||||||
|
EXPECT_CONTAINS(str, "workspace ID 8 ");
|
||||||
|
}
|
||||||
|
|
||||||
|
OK(getFromSocket("/dispatch movewindow l"));
|
||||||
|
|
||||||
|
{
|
||||||
|
auto str = getFromSocket("/activewindow");
|
||||||
|
EXPECT_CONTAINS(str, "class: b");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto str = getFromSocket("/activeworkspace");
|
||||||
|
EXPECT_CONTAINS(str, "workspace ID 8 ");
|
||||||
|
}
|
||||||
|
|
||||||
|
OK(getFromSocket("/reload"));
|
||||||
|
|
||||||
|
Tests::killAllWindows();
|
||||||
|
}
|
||||||
|
|
||||||
static bool test() {
|
static bool test() {
|
||||||
NLog::log("{}Testing workspaces", Colors::GREEN);
|
NLog::log("{}Testing workspaces", Colors::GREEN);
|
||||||
|
|
||||||
|
|
@ -594,6 +714,7 @@ static bool test() {
|
||||||
Tests::killAllWindows();
|
Tests::killAllWindows();
|
||||||
|
|
||||||
testMultimonBAF();
|
testMultimonBAF();
|
||||||
|
testMultimonFocus();
|
||||||
|
|
||||||
// destroy the headless output
|
// destroy the headless output
|
||||||
OK(getFromSocket("/output remove HEADLESS-3"));
|
OK(getFromSocket("/output remove HEADLESS-3"));
|
||||||
|
|
|
||||||
|
|
@ -549,6 +549,8 @@ std::optional<Vector2D> CDwindleAlgorithm::predictSizeForNewTarget() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDwindleAlgorithm::moveTargetInDirection(SP<ITarget> t, Math::eDirection dir, bool silent) {
|
void CDwindleAlgorithm::moveTargetInDirection(SP<ITarget> t, Math::eDirection dir, bool silent) {
|
||||||
|
static auto PMONITORFALLBACK = CConfigValue<Hyprlang::INT>("binds:window_direction_monitor_fallback");
|
||||||
|
|
||||||
const auto PNODE = getNodeFromTarget(t);
|
const auto PNODE = getNodeFromTarget(t);
|
||||||
const Vector2D originalPos = t->position().middle();
|
const Vector2D originalPos = t->position().middle();
|
||||||
|
|
||||||
|
|
@ -557,12 +559,15 @@ void CDwindleAlgorithm::moveTargetInDirection(SP<ITarget> t, Math::eDirection di
|
||||||
|
|
||||||
const auto FOCAL_POINT = focalPointForDir(t, dir);
|
const auto FOCAL_POINT = focalPointForDir(t, dir);
|
||||||
|
|
||||||
|
const auto PMONITORFOCAL = g_pCompositor->getMonitorFromVector(FOCAL_POINT.value_or(t->position().middle()));
|
||||||
|
|
||||||
|
if (PMONITORFOCAL != m_parent->space()->workspace()->m_monitor && !*PMONITORFALLBACK)
|
||||||
|
return; // noop
|
||||||
|
|
||||||
t->window()->setAnimationsToMove();
|
t->window()->setAnimationsToMove();
|
||||||
|
|
||||||
removeTarget(t);
|
removeTarget(t);
|
||||||
|
|
||||||
const auto PMONITORFOCAL = g_pCompositor->getMonitorFromVector(FOCAL_POINT.value_or(t->position().middle()));
|
|
||||||
|
|
||||||
if (PMONITORFOCAL != m_parent->space()->workspace()->m_monitor) {
|
if (PMONITORFOCAL != m_parent->space()->workspace()->m_monitor) {
|
||||||
// move with a focal point
|
// move with a focal point
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -403,7 +403,9 @@ void CMasterAlgorithm::swapTargets(SP<ITarget> a, SP<ITarget> b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMasterAlgorithm::moveTargetInDirection(SP<ITarget> t, Math::eDirection dir, bool silent) {
|
void CMasterAlgorithm::moveTargetInDirection(SP<ITarget> t, Math::eDirection dir, bool silent) {
|
||||||
const auto PWINDOW2 = g_pCompositor->getWindowInDirection(t->window(), dir);
|
static auto PMONITORFALLBACK = CConfigValue<Hyprlang::INT>("binds:window_direction_monitor_fallback");
|
||||||
|
|
||||||
|
const auto PWINDOW2 = g_pCompositor->getWindowInDirection(t->window(), dir);
|
||||||
|
|
||||||
if (!t->window())
|
if (!t->window())
|
||||||
return;
|
return;
|
||||||
|
|
@ -424,6 +426,9 @@ void CMasterAlgorithm::moveTargetInDirection(SP<ITarget> t, Math::eDirection dir
|
||||||
t->window()->setAnimationsToMove();
|
t->window()->setAnimationsToMove();
|
||||||
|
|
||||||
if (t->window()->m_workspace != targetWs) {
|
if (t->window()->m_workspace != targetWs) {
|
||||||
|
if (!*PMONITORFALLBACK)
|
||||||
|
return; // noop
|
||||||
|
|
||||||
t->assignToSpace(targetWs->m_space, focalPointForDir(t, dir));
|
t->assignToSpace(targetWs->m_space, focalPointForDir(t, dir));
|
||||||
} else if (PWINDOW2) {
|
} else if (PWINDOW2) {
|
||||||
// if same monitor, switch windows
|
// if same monitor, switch windows
|
||||||
|
|
|
||||||
|
|
@ -202,6 +202,11 @@ void CMonocleAlgorithm::swapTargets(SP<ITarget> a, SP<ITarget> b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMonocleAlgorithm::moveTargetInDirection(SP<ITarget> t, Math::eDirection dir, bool silent) {
|
void CMonocleAlgorithm::moveTargetInDirection(SP<ITarget> t, Math::eDirection dir, bool silent) {
|
||||||
|
static auto PMONITORFALLBACK = CConfigValue<Hyprlang::INT>("binds:window_direction_monitor_fallback");
|
||||||
|
|
||||||
|
if (!*PMONITORFALLBACK)
|
||||||
|
return; // noop
|
||||||
|
|
||||||
// try to find a monitor in the specified direction, thats the logical thing
|
// try to find a monitor in the specified direction, thats the logical thing
|
||||||
if (!t || !t->space() || !t->space()->workspace())
|
if (!t || !t->space() || !t->space()->workspace())
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -848,7 +848,9 @@ void CScrollingAlgorithm::moveTargetInDirection(SP<ITarget> t, Math::eDirection
|
||||||
}
|
}
|
||||||
|
|
||||||
void CScrollingAlgorithm::moveTargetTo(SP<ITarget> t, Math::eDirection dir, bool silent) {
|
void CScrollingAlgorithm::moveTargetTo(SP<ITarget> t, Math::eDirection dir, bool silent) {
|
||||||
const auto DATA = dataFor(t);
|
static auto PMONITORFALLBACK = CConfigValue<Hyprlang::INT>("binds:window_direction_monitor_fallback");
|
||||||
|
|
||||||
|
const auto DATA = dataFor(t);
|
||||||
|
|
||||||
if (!DATA)
|
if (!DATA)
|
||||||
return;
|
return;
|
||||||
|
|
@ -953,6 +955,10 @@ void CScrollingAlgorithm::moveTargetTo(SP<ITarget> t, Math::eDirection dir, bool
|
||||||
if (!commenceDir()) {
|
if (!commenceDir()) {
|
||||||
// dir wasn't commenced, move to a workspace if possible
|
// dir wasn't commenced, move to a workspace if possible
|
||||||
// with the original dir
|
// with the original dir
|
||||||
|
|
||||||
|
if (!*PMONITORFALLBACK)
|
||||||
|
return; // noop
|
||||||
|
|
||||||
const auto MONINDIR = g_pCompositor->getMonitorInDirection(m_parent->space()->workspace()->m_monitor.lock(), dir);
|
const auto MONINDIR = g_pCompositor->getMonitorInDirection(m_parent->space()->workspace()->m_monitor.lock(), dir);
|
||||||
if (MONINDIR && MONINDIR != m_parent->space()->workspace()->m_monitor && MONINDIR->m_activeWorkspace) {
|
if (MONINDIR && MONINDIR != m_parent->space()->workspace()->m_monitor && MONINDIR->m_activeWorkspace) {
|
||||||
t->assignToSpace(MONINDIR->m_activeWorkspace->m_space, focalPointForDir(t, dir));
|
t->assignToSpace(MONINDIR->m_activeWorkspace->m_space, focalPointForDir(t, dir));
|
||||||
|
|
|
||||||
|
|
@ -1468,9 +1468,10 @@ SDispatchResult CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SDispatchResult CKeybindManager::moveFocusTo(std::string args) {
|
SDispatchResult CKeybindManager::moveFocusTo(std::string args) {
|
||||||
static auto PFULLCYCLE = CConfigValue<Hyprlang::INT>("binds:movefocus_cycles_fullscreen");
|
static auto PFULLCYCLE = CConfigValue<Hyprlang::INT>("binds:movefocus_cycles_fullscreen");
|
||||||
static auto PGROUPCYCLE = CConfigValue<Hyprlang::INT>("binds:movefocus_cycles_groupfirst");
|
static auto PGROUPCYCLE = CConfigValue<Hyprlang::INT>("binds:movefocus_cycles_groupfirst");
|
||||||
Math::eDirection dir = Math::fromChar(args[0]);
|
static auto PMONITORFALLBACK = CConfigValue<Hyprlang::INT>("binds:window_direction_monitor_fallback");
|
||||||
|
Math::eDirection dir = Math::fromChar(args[0]);
|
||||||
|
|
||||||
if (dir == Math::DIRECTION_DEFAULT) {
|
if (dir == Math::DIRECTION_DEFAULT) {
|
||||||
Log::logger->log(Log::ERR, "Cannot move focus in direction {}, unsupported direction. Supported: l,r,u/t,d/b", args[0]);
|
Log::logger->log(Log::ERR, "Cannot move focus in direction {}, unsupported direction. Supported: l,r,u/t,d/b", args[0]);
|
||||||
|
|
@ -1479,7 +1480,8 @@ SDispatchResult CKeybindManager::moveFocusTo(std::string args) {
|
||||||
|
|
||||||
const auto PLASTWINDOW = Desktop::focusState()->window();
|
const auto PLASTWINDOW = Desktop::focusState()->window();
|
||||||
if (!PLASTWINDOW || !PLASTWINDOW->aliveAndVisible()) {
|
if (!PLASTWINDOW || !PLASTWINDOW->aliveAndVisible()) {
|
||||||
tryMoveFocusToMonitor(g_pCompositor->getMonitorInDirection(dir));
|
if (*PMONITORFALLBACK)
|
||||||
|
tryMoveFocusToMonitor(g_pCompositor->getMonitorInDirection(dir));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1509,7 +1511,7 @@ SDispatchResult CKeybindManager::moveFocusTo(std::string args) {
|
||||||
|
|
||||||
Log::logger->log(Log::DEBUG, "No window found in direction {}, looking for a monitor", Math::toString(dir));
|
Log::logger->log(Log::DEBUG, "No window found in direction {}, looking for a monitor", Math::toString(dir));
|
||||||
|
|
||||||
if (tryMoveFocusToMonitor(g_pCompositor->getMonitorInDirection(dir)))
|
if (*PMONITORFALLBACK && tryMoveFocusToMonitor(g_pCompositor->getMonitorInDirection(dir)))
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
static auto PNOFALLBACK = CConfigValue<Hyprlang::INT>("general:no_focus_fallback");
|
static auto PNOFALLBACK = CConfigValue<Hyprlang::INT>("general:no_focus_fallback");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue