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 c) { +bool SScrollingData::visible(SP c, bool full) { static const auto PFSONONE = CConfigValue("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("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 target, bool hardInput) { +void CScrollingAlgorithm::focusOnInput(SP target, eInputMode input) { static const auto PFOLLOW_FOCUS_MIN_PERC = CConfigValue("scrolling:follow_min_visible"); if (!target || target->space() != m_parent->space()) @@ -540,7 +542,7 @@ void CScrollingAlgorithm::focusOnInput(SP 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 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("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 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 prev(SP c); SP atCenter(); - bool visible(SP c); + bool visible(SP c, bool full = false); void centerCol(SP c); void fitCol(SP c); void centerOrFitCol(SP 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 m_scrollingData; @@ -130,7 +136,7 @@ namespace Layout::Tiled { void focusTargetUpdate(SP target); void moveTargetTo(SP t, Math::eDirection dir, bool silent); - void focusOnInput(SP target, bool hardInput); + void focusOnInput(SP target, eInputMode input); friend struct SScrollingData; };