Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: cursor warps maintain relative position within a window #6338

Merged
merged 5 commits into from
Jun 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/config/ConfigManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,7 @@ CConfigManager::CConfigManager() {
m_pConfig->addConfigValue("cursor:hotspot_padding", Hyprlang::INT{1});
m_pConfig->addConfigValue("cursor:inactive_timeout", Hyprlang::INT{0});
m_pConfig->addConfigValue("cursor:no_warps", Hyprlang::INT{0});
m_pConfig->addConfigValue("cursor:persistent_warps", Hyprlang::INT{0});
m_pConfig->addConfigValue("cursor:default_monitor", {STRVAL_EMPTY});
m_pConfig->addConfigValue("cursor:zoom_factor", {1.f});
m_pConfig->addConfigValue("cursor:zoom_rigid", Hyprlang::INT{0});
Expand Down
13 changes: 12 additions & 1 deletion src/desktop/Window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1356,7 +1356,7 @@ void CWindow::activate(bool force) {
g_pCompositor->changeWindowZOrder(m_pSelf.lock(), true);

g_pCompositor->focusWindow(m_pSelf.lock());
g_pCompositor->warpCursorTo(middle());
warpCursor();
}

void CWindow::onUpdateState() {
Expand Down Expand Up @@ -1530,3 +1530,14 @@ void CWindow::onX11Configure(CBox box) {

g_pHyprRenderer->damageWindow(m_pSelf.lock());
}

void CWindow::warpCursor() {
static auto PERSISTENTWARPS = CConfigValue<Hyprlang::INT>("cursor:persistent_warps");
const auto coords = m_vRelativeCursorCoordsOnLastWarp;
m_vRelativeCursorCoordsOnLastWarp.x = -1; // reset m_vRelativeCursorCoordsOnLastWarp

if (*PERSISTENTWARPS && coords.x > 0 && coords.y > 0 && coords < m_vSize) // don't warp cursor outside the window
g_pCompositor->warpCursorTo(m_vPosition + coords);
else
g_pCompositor->warpCursorTo(middle());
}
8 changes: 6 additions & 2 deletions src/desktop/Window.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,11 @@ class CWindow {
Vector2D m_vFloatingOffset = Vector2D(0, 0);

// this is used for pseudotiling
bool m_bIsPseudotiled = false;
Vector2D m_vPseudoSize = Vector2D(1280, 720);
bool m_bIsPseudotiled = false;
Vector2D m_vPseudoSize = Vector2D(1280, 720);

// for recovering relative cursor position
Vector2D m_vRelativeCursorCoordsOnLastWarp = Vector2D(-1, -1);

bool m_bFirstMap = false; // for layouts
bool m_bIsFloating = false;
Expand Down Expand Up @@ -446,6 +449,7 @@ class CWindow {
void onResourceChangeX11();
std::string fetchTitle();
std::string fetchClass();
void warpCursor();

// listeners
void onAck(uint32_t serial);
Expand Down
49 changes: 37 additions & 12 deletions src/managers/KeybindManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,16 @@ bool CKeybindManager::ensureMouseBindState() {
return false;
}

void updateRelativeCursorCoords() {
static auto PNOWARPS = CConfigValue<Hyprlang::INT>("cursor:no_warps");

if (*PNOWARPS)
return;

if (g_pCompositor->m_pLastWindow)
g_pCompositor->m_pLastWindow->m_vRelativeCursorCoordsOnLastWarp = g_pInputManager->getMouseCoordsInternal() - g_pCompositor->m_pLastWindow->m_vPosition;
}

bool CKeybindManager::tryMoveFocusToMonitor(CMonitor* monitor) {
if (!monitor)
return false;
Expand All @@ -277,8 +287,9 @@ bool CKeybindManager::tryMoveFocusToMonitor(CMonitor* monitor) {

const auto PNEWWINDOW = PNEWWORKSPACE->getLastFocusedWindow();
if (PNEWWINDOW) {
updateRelativeCursorCoords();
g_pCompositor->focusWindow(PNEWWINDOW);
g_pCompositor->warpCursorTo(PNEWWINDOW->middle());
PNEWWINDOW->warpCursor();

g_pInputManager->m_pForcedFocus = PNEWWINDOW;
g_pInputManager->simulateMouseMovement();
Expand Down Expand Up @@ -313,8 +324,9 @@ void CKeybindManager::switchToWindow(PHLWINDOW PWINDOWTOCHANGETO) {
if (!PWINDOWTOCHANGETO->m_bPinned)
g_pCompositor->setWindowFullscreen(PWINDOWTOCHANGETO, true, FSMODE);
} else {
updateRelativeCursorCoords();
g_pCompositor->focusWindow(PWINDOWTOCHANGETO);
g_pCompositor->warpCursorTo(PWINDOWTOCHANGETO->middle());
PWINDOWTOCHANGETO->warpCursor();

g_pInputManager->m_pForcedFocus = PWINDOWTOCHANGETO;
g_pInputManager->simulateMouseMovement();
Expand Down Expand Up @@ -1146,6 +1158,8 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) {
const auto POLDWS = PWINDOW->m_pWorkspace;
static auto PALLOWWORKSPACECYCLES = CConfigValue<Hyprlang::INT>("binds:allow_workspace_cycles");

updateRelativeCursorCoords();

g_pHyprRenderer->damageWindow(PWINDOW);

if (pWorkspace) {
Expand All @@ -1171,7 +1185,7 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) {
pMonitor->changeWorkspace(pWorkspace);

g_pCompositor->focusWindow(PWINDOW);
g_pCompositor->warpCursorTo(PWINDOW->middle());
PWINDOW->warpCursor();
}

void CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {
Expand Down Expand Up @@ -1303,8 +1317,9 @@ void CKeybindManager::swapActive(std::string args) {
if (!PWINDOWTOCHANGETO)
return;

updateRelativeCursorCoords();
g_pLayoutManager->getCurrentLayout()->switchWindows(PLASTWINDOW, PWINDOWTOCHANGETO);
g_pCompositor->warpCursorTo(PLASTWINDOW->middle());
PLASTWINDOW->warpCursor();
}

void CKeybindManager::moveActiveTo(std::string args) {
Expand Down Expand Up @@ -1357,9 +1372,11 @@ void CKeybindManager::moveActiveTo(std::string args) {
// If the window to change to is on the same workspace, switch them
const auto PWINDOWTOCHANGETO = g_pCompositor->getWindowInDirection(PLASTWINDOW, arg);
if (PWINDOWTOCHANGETO) {
updateRelativeCursorCoords();

g_pLayoutManager->getCurrentLayout()->moveWindowTo(PLASTWINDOW, args, silent);
if (!silent)
g_pCompositor->warpCursorTo(PLASTWINDOW->middle());
PLASTWINDOW->warpCursor();
return;
}

Expand Down Expand Up @@ -1896,6 +1913,8 @@ void CKeybindManager::focusWindow(std::string regexp) {
return;
}

updateRelativeCursorCoords();

if (g_pCompositor->m_pLastMonitor && g_pCompositor->m_pLastMonitor->activeWorkspace != PWINDOW->m_pWorkspace &&
g_pCompositor->m_pLastMonitor->activeSpecialWorkspace != PWINDOW->m_pWorkspace) {
Debug::log(LOG, "Fake executing workspace to move focus");
Expand Down Expand Up @@ -1926,7 +1945,7 @@ void CKeybindManager::focusWindow(std::string regexp) {
} else
g_pCompositor->focusWindow(PWINDOW);

g_pCompositor->warpCursorTo(PWINDOW->middle());
PWINDOW->warpCursor();
}

void CKeybindManager::tagWindow(std::string args) {
Expand Down Expand Up @@ -2445,6 +2464,8 @@ void CKeybindManager::moveWindowIntoGroup(PHLWINDOW pWindow, PHLWINDOW pWindowIn
if (pWindow->m_sGroupData.deny)
return;

updateRelativeCursorCoords();

g_pLayoutManager->getCurrentLayout()->onWindowRemoved(pWindow); // This removes groupped property!

static auto USECURRPOS = CConfigValue<Hyprlang::INT>("group:insert_after_current");
Expand All @@ -2455,7 +2476,7 @@ void CKeybindManager::moveWindowIntoGroup(PHLWINDOW pWindow, PHLWINDOW pWindowIn
pWindow->updateWindowDecos();
g_pLayoutManager->getCurrentLayout()->recalculateWindow(pWindow);
g_pCompositor->focusWindow(pWindow);
g_pCompositor->warpCursorTo(pWindow->middle());
pWindow->warpCursor();

if (!pWindow->getDecorationByType(DECORATION_GROUPBAR))
pWindow->addWindowDeco(std::make_unique<CHyprGroupBarDecoration>(pWindow));
Expand All @@ -2478,6 +2499,8 @@ void CKeybindManager::moveWindowOutOfGroup(PHLWINDOW pWindow, const std::string&
default: direction = DIRECTION_DEFAULT;
}

updateRelativeCursorCoords();

if (pWindow->m_sGroupData.pNextWindow.lock() == pWindow) {
pWindow->destroyGroup();
} else {
Expand All @@ -2493,10 +2516,10 @@ void CKeybindManager::moveWindowOutOfGroup(PHLWINDOW pWindow, const std::string&

if (*BFOCUSREMOVEDWINDOW) {
g_pCompositor->focusWindow(pWindow);
g_pCompositor->warpCursorTo(pWindow->middle());
pWindow->warpCursor();
} else {
g_pCompositor->focusWindow(PWINDOWPREV);
g_pCompositor->warpCursorTo(PWINDOWPREV->middle());
PWINDOWPREV->warpCursor();
}

g_pEventManager->postEvent(SHyprIPCEvent{"moveoutofgroup", std::format("{:x}", (uintptr_t)pWindow.get())});
Expand Down Expand Up @@ -2576,24 +2599,26 @@ void CKeybindManager::moveWindowOrGroup(std::string args) {
const bool ISWINDOWGROUPLOCKED = ISWINDOWGROUP && PWINDOW->getGroupHead()->m_sGroupData.locked;
const bool ISWINDOWGROUPSINGLE = ISWINDOWGROUP && PWINDOW->m_sGroupData.pNextWindow.lock() == PWINDOW;

updateRelativeCursorCoords();

// note: PWINDOWINDIR is not null implies !PWINDOW->m_bIsFloating
if (PWINDOWINDIR && PWINDOWINDIR->m_sGroupData.pNextWindow) { // target is group
if (!*PIGNOREGROUPLOCK && (PWINDOWINDIR->getGroupHead()->m_sGroupData.locked || ISWINDOWGROUPLOCKED || PWINDOW->m_sGroupData.deny)) {
g_pLayoutManager->getCurrentLayout()->moveWindowTo(PWINDOW, args);
g_pCompositor->warpCursorTo(PWINDOW->middle());
PWINDOW->warpCursor();
} else
moveWindowIntoGroup(PWINDOW, PWINDOWINDIR);
} else if (PWINDOWINDIR) { // target is regular window
if ((!*PIGNOREGROUPLOCK && ISWINDOWGROUPLOCKED) || !ISWINDOWGROUP || (ISWINDOWGROUPSINGLE && PWINDOW->m_eGroupRules & GROUP_SET_ALWAYS)) {
g_pLayoutManager->getCurrentLayout()->moveWindowTo(PWINDOW, args);
g_pCompositor->warpCursorTo(PWINDOW->middle());
PWINDOW->warpCursor();
} else
moveWindowOutOfGroup(PWINDOW, args);
} else if ((*PIGNOREGROUPLOCK || !ISWINDOWGROUPLOCKED) && ISWINDOWGROUP) { // no target window
moveWindowOutOfGroup(PWINDOW, args);
} else if (!PWINDOWINDIR && !ISWINDOWGROUP) { // no target in dir and not in group
g_pLayoutManager->getCurrentLayout()->moveWindowTo(PWINDOW, args);
g_pCompositor->warpCursorTo(PWINDOW->middle());
PWINDOW->warpCursor();
}

g_pCompositor->updateWindowAnimatedDecorationValues(PWINDOW);
Expand Down
Loading