summaryrefslogtreecommitdiff
path: root/src/layout/algorithm/tiled/scrolling
diff options
context:
space:
mode:
authorVaxry <vaxry@vaxry.net>2026-02-24 12:27:00 +0000
committerVaxry <vaxry@vaxry.net>2026-02-24 12:27:00 +0000
commitfbf67ef050c8a82ffe6156b255cc89d6020c1084 (patch)
tree921362eaddd964015fabe55dced231e3f8c15c9a /src/layout/algorithm/tiled/scrolling
parentbe893a81b4533d1dc22e91f7d603dbb536ed79f8 (diff)
algo/scrolling: adjust focus callbacks to be more intuitive
Diffstat (limited to 'src/layout/algorithm/tiled/scrolling')
-rw-r--r--src/layout/algorithm/tiled/scrolling/ScrollTapeController.cpp7
-rw-r--r--src/layout/algorithm/tiled/scrolling/ScrollTapeController.hpp2
-rw-r--r--src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.cpp32
-rw-r--r--src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.hpp10
4 files changed, 36 insertions, 15 deletions
diff --git a/src/layout/algorithm/tiled/scrolling/ScrollTapeController.cpp b/src/layout/algorithm/tiled/scrolling/ScrollTapeController.cpp
index 63b98717..c6cda4b5 100644
--- a/src/layout/algorithm/tiled/scrolling/ScrollTapeController.cpp
+++ b/src/layout/algorithm/tiled/scrolling/ScrollTapeController.cpp
@@ -241,7 +241,7 @@ void CScrollTapeController::fitStrip(size_t stripIndex, const CBox& usableArea,
m_offset = std::clamp(m_offset, stripStart - usablePrimary + stripSize, stripStart);
}
-bool CScrollTapeController::isStripVisible(size_t stripIndex, const CBox& usableArea, bool fullscreenOnOne) const {
+bool CScrollTapeController::isStripVisible(size_t stripIndex, const CBox& usableArea, bool fullscreenOnOne, bool full) const {
if (stripIndex >= m_strips.size())
return false;
@@ -250,7 +250,10 @@ bool CScrollTapeController::isStripVisible(size_t stripIndex, const CBox& usable
const double viewStart = m_offset;
const double viewEnd = m_offset + getPrimary(usableArea.size());
- return stripStart < viewEnd && viewStart < stripEnd;
+ if (!full)
+ return stripStart < viewEnd && viewStart < stripEnd;
+ else
+ return stripStart >= viewStart && stripEnd <= viewEnd;
}
size_t CScrollTapeController::getStripAtCenter(const CBox& usableArea, bool fullscreenOnOne) const {
diff --git a/src/layout/algorithm/tiled/scrolling/ScrollTapeController.hpp b/src/layout/algorithm/tiled/scrolling/ScrollTapeController.hpp
index d03a9b94..4e0fef7f 100644
--- a/src/layout/algorithm/tiled/scrolling/ScrollTapeController.hpp
+++ b/src/layout/algorithm/tiled/scrolling/ScrollTapeController.hpp
@@ -63,7 +63,7 @@ namespace Layout::Tiled {
void centerStrip(size_t stripIndex, const CBox& usableArea, bool fullscreenOnOne = false);
void fitStrip(size_t stripIndex, const CBox& usableArea, bool fullscreenOnOne = false);
- bool isStripVisible(size_t stripIndex, const CBox& usableArea, bool fullscreenOnOne = false) const;
+ bool isStripVisible(size_t stripIndex, const CBox& usableArea, bool fullscreenOnOne = false, bool full = false) const;
size_t getStripAtCenter(const CBox& usableArea, bool fullscreenOnOne = false) const;
diff --git a/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.cpp b/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.cpp
index 247795ed..8206a796 100644
--- a/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.cpp
+++ b/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.cpp
@@ -448,13 +448,13 @@ double SScrollingData::maxWidth() {
return controller->calculateMaxExtent(USABLE, *PFSONONE);
}
-bool SScrollingData::visible(SP<SColumnData> c) {
+bool SScrollingData::visible(SP<SColumnData> c, bool full) {
static const auto PFSONONE = CConfigValue<Hyprlang::INT>("scrolling:fullscreen_on_one_column");
const auto USABLE = algorithm->usableArea();
int64_t colIdx = idx(c);
if (colIdx >= 0)
- return controller->isStripVisible(colIdx, USABLE, *PFSONONE);
+ return controller->isStripVisible(colIdx, USABLE, *PFSONONE, full);
return false;
}
@@ -497,8 +497,10 @@ CScrollingAlgorithm::CScrollingAlgorithm() {
});
m_mouseButtonCallback = Event::bus()->m_events.input.mouse.button.listen([this](IPointer::SButtonEvent e, Event::SCallbackInfo&) {
- if (e.state == WL_POINTER_BUTTON_STATE_RELEASED && Desktop::focusState()->window())
- focusOnInput(Desktop::focusState()->window()->layoutTarget(), true);
+ static const auto PFOLLOW_FOCUS = CConfigValue<Hyprlang::INT>("scrolling:follow_focus");
+
+ if (*PFOLLOW_FOCUS && e.state == WL_POINTER_BUTTON_STATE_RELEASED && Desktop::focusState()->window())
+ focusOnInput(Desktop::focusState()->window()->layoutTarget(), INPUT_MODE_CLICK);
});
m_focusCallback = Event::bus()->m_events.window.active.listen([this](PHLWINDOW pWindow, Desktop::eFocusReason reason) {
@@ -517,7 +519,7 @@ CScrollingAlgorithm::CScrollingAlgorithm() {
if (!TARGET || TARGET->floating())
return;
- focusOnInput(TARGET, Desktop::isHardInputFocusReason(reason));
+ focusOnInput(TARGET, reason == Desktop::FOCUS_REASON_CLICK ? INPUT_MODE_CLICK : (Desktop::isHardInputFocusReason(reason) ? INPUT_MODE_KB : INPUT_MODE_SOFT));
});
// Initialize default widths and direction
@@ -530,7 +532,7 @@ CScrollingAlgorithm::~CScrollingAlgorithm() {
m_focusCallback.reset();
}
-void CScrollingAlgorithm::focusOnInput(SP<ITarget> target, bool hardInput) {
+void CScrollingAlgorithm::focusOnInput(SP<ITarget> target, eInputMode input) {
static const auto PFOLLOW_FOCUS_MIN_PERC = CConfigValue<Hyprlang::FLOAT>("scrolling:follow_min_visible");
if (!target || target->space() != m_parent->space())
@@ -540,7 +542,7 @@ void CScrollingAlgorithm::focusOnInput(SP<ITarget> target, bool hardInput) {
if (!TARGETDATA)
return;
- if (*PFOLLOW_FOCUS_MIN_PERC > 0.F && !hardInput) {
+ if (*PFOLLOW_FOCUS_MIN_PERC > 0.F && input == INPUT_MODE_SOFT) {
// check how much of the window is visible, unless hard input focus
const auto IS_HORIZ = m_scrollingData->controller->isPrimaryHorizontal();
@@ -557,8 +559,12 @@ void CScrollingAlgorithm::focusOnInput(SP<ITarget> target, bool hardInput) {
return;
}
+ // if we moved via non-kb, and it's fully visible, ignore
+ if (m_scrollingData->visible(TARGETDATA->column.lock(), true) && input != INPUT_MODE_KB)
+ return;
+
static const auto PFITMETHOD = CConfigValue<Hyprlang::INT>("scrolling:focus_fit_method");
- if (*PFITMETHOD == 1)
+ if (*PFITMETHOD == 1 || input == INPUT_MODE_CLICK)
m_scrollingData->fitCol(TARGETDATA->column.lock());
else
m_scrollingData->centerCol(TARGETDATA->column.lock());
@@ -770,8 +776,14 @@ void CScrollingAlgorithm::resizeTarget(const Vector2D& delta, SP<ITarget> target
}
void CScrollingAlgorithm::recalculate() {
- if (Desktop::focusState()->window())
- focusOnInput(Desktop::focusState()->window()->layoutTarget(), true);
+ if (Desktop::focusState()->window()) {
+ const auto TARGET = Desktop::focusState()->window()->layoutTarget();
+
+ const auto TARGETDATA = dataFor(TARGET);
+
+ if (TARGETDATA && !m_scrollingData->visible(TARGETDATA->column.lock(), true))
+ focusOnInput(Desktop::focusState()->window()->layoutTarget(), INPUT_MODE_KB);
+ }
m_scrollingData->recalculate();
}
diff --git a/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.hpp b/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.hpp
index 109aa99e..20db6efe 100644
--- a/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.hpp
+++ b/src/layout/algorithm/tiled/scrolling/ScrollingAlgorithm.hpp
@@ -77,7 +77,7 @@ namespace Layout::Tiled {
SP<SColumnData> prev(SP<SColumnData> c);
SP<SColumnData> atCenter();
- bool visible(SP<SColumnData> c);
+ bool visible(SP<SColumnData> c, bool full = false);
void centerCol(SP<SColumnData> c);
void fitCol(SP<SColumnData> c);
void centerOrFitCol(SP<SColumnData> c);
@@ -111,6 +111,12 @@ namespace Layout::Tiled {
CBox usableArea();
+ enum eInputMode : uint8_t {
+ INPUT_MODE_SOFT = 0,
+ INPUT_MODE_CLICK,
+ INPUT_MODE_KB
+ };
+
private:
SP<SScrollingData> m_scrollingData;
@@ -130,7 +136,7 @@ namespace Layout::Tiled {
void focusTargetUpdate(SP<ITarget> target);
void moveTargetTo(SP<ITarget> t, Math::eDirection dir, bool silent);
- void focusOnInput(SP<ITarget> target, bool hardInput);
+ void focusOnInput(SP<ITarget> target, eInputMode input);
friend struct SScrollingData;
};