mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-08-15 03:55:46 -07:00
dispatchers: add cyclenext hist option (#9055)
This commit is contained in:
@@ -1058,7 +1058,7 @@ PHLMONITOR CCompositor::getRealMonitorFromOutput(SP<Aquamarine::IOutput> out) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCompositor::focusWindow(PHLWINDOW pWindow, SP<CWLSurfaceResource> pSurface) {
|
void CCompositor::focusWindow(PHLWINDOW pWindow, SP<CWLSurfaceResource> pSurface, bool preserveFocusHistory) {
|
||||||
|
|
||||||
static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
|
static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
|
||||||
static auto PSPECIALFALLTHROUGH = CConfigValue<Hyprlang::INT>("input:special_fallthrough");
|
static auto PSPECIALFALLTHROUGH = CConfigValue<Hyprlang::INT>("input:special_fallthrough");
|
||||||
@@ -1178,11 +1178,12 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, SP<CWLSurfaceResource> pSurface
|
|||||||
|
|
||||||
g_pInputManager->recheckIdleInhibitorStatus();
|
g_pInputManager->recheckIdleInhibitorStatus();
|
||||||
|
|
||||||
|
if (!preserveFocusHistory) {
|
||||||
// move to front of the window history
|
// move to front of the window history
|
||||||
const auto HISTORYPIVOT = std::find_if(m_vWindowFocusHistory.begin(), m_vWindowFocusHistory.end(), [&](const auto& other) { return other.lock() == pWindow; });
|
const auto HISTORYPIVOT = std::ranges::find_if(m_vWindowFocusHistory, [&](const auto& other) { return other.lock() == pWindow; });
|
||||||
if (HISTORYPIVOT == m_vWindowFocusHistory.end()) {
|
if (HISTORYPIVOT == m_vWindowFocusHistory.end())
|
||||||
Debug::log(ERR, "BUG THIS: {} has no pivot in history", pWindow);
|
Debug::log(ERR, "BUG THIS: {} has no pivot in history", pWindow);
|
||||||
} else {
|
else
|
||||||
std::rotate(m_vWindowFocusHistory.begin(), HISTORYPIVOT, HISTORYPIVOT + 1);
|
std::rotate(m_vWindowFocusHistory.begin(), HISTORYPIVOT, HISTORYPIVOT + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1396,7 +1397,6 @@ void CCompositor::changeWindowZOrder(PHLWINDOW pWindow, bool top) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
x11Stack(pWindow, top, x11Stack);
|
x11Stack(pWindow, top, x11Stack);
|
||||||
|
|
||||||
for (const auto& it : toMove) {
|
for (const auto& it : toMove) {
|
||||||
moveToZ(it, top);
|
moveToZ(it, top);
|
||||||
}
|
}
|
||||||
@@ -1647,37 +1647,52 @@ PHLWINDOW CCompositor::getWindowInDirection(const CBox& box, PHLWORKSPACE pWorks
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
PHLWINDOW CCompositor::getNextWindowOnWorkspace(PHLWINDOW pWindow, bool focusableOnly, std::optional<bool> floating, bool visible) {
|
template <typename WINDOWPTR>
|
||||||
auto it = std::ranges::find(m_vWindows, pWindow);
|
static bool isWorkspaceMatches(WINDOWPTR pWindow, const WINDOWPTR w, bool anyWorkspace) {
|
||||||
const auto FINDER = [&](const PHLWINDOW& w) { return isWindowAvailableForCycle(pWindow, w, focusableOnly, floating, visible); };
|
|
||||||
const auto IN_RIGHT = std::find_if(it, m_vWindows.end(), FINDER);
|
|
||||||
if (IN_RIGHT != m_vWindows.end())
|
|
||||||
return *IN_RIGHT;
|
|
||||||
const auto IN_LEFT = std::find_if(m_vWindows.begin(), it, FINDER);
|
|
||||||
return *IN_LEFT;
|
|
||||||
}
|
|
||||||
|
|
||||||
PHLWINDOW CCompositor::getPrevWindowOnWorkspace(PHLWINDOW pWindow, bool focusableOnly, std::optional<bool> floating, bool visible) {
|
|
||||||
auto it = std::ranges::find(std::ranges::reverse_view(m_vWindows), pWindow);
|
|
||||||
const auto FINDER = [&](const PHLWINDOW& w) { return isWindowAvailableForCycle(pWindow, w, focusableOnly, floating, visible); };
|
|
||||||
const auto IN_LEFT = std::find_if(it, m_vWindows.rend(), FINDER);
|
|
||||||
if (IN_LEFT != m_vWindows.rend())
|
|
||||||
return *IN_LEFT;
|
|
||||||
const auto IN_RIGHT = std::find_if(m_vWindows.rbegin(), it, FINDER);
|
|
||||||
return *IN_RIGHT;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static bool isWorkspaceMatches(PHLWINDOW pWindow, const PHLWINDOW w, bool anyWorkspace) {
|
|
||||||
return anyWorkspace ? w->m_pWorkspace && w->m_pWorkspace->isVisible() : w->m_pWorkspace == pWindow->m_pWorkspace;
|
return anyWorkspace ? w->m_pWorkspace && w->m_pWorkspace->isVisible() : w->m_pWorkspace == pWindow->m_pWorkspace;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static bool isFloatingMatches(PHLWINDOW w, std::optional<bool> floating) {
|
template <typename WINDOWPTR>
|
||||||
|
static bool isFloatingMatches(WINDOWPTR w, std::optional<bool> floating) {
|
||||||
return !floating.has_value() || w->m_bIsFloating == floating.value();
|
return !floating.has_value() || w->m_bIsFloating == floating.value();
|
||||||
};
|
}
|
||||||
|
|
||||||
bool CCompositor::isWindowAvailableForCycle(PHLWINDOW pWindow, const PHLWINDOW w, bool focusableOnly, std::optional<bool> floating, bool anyWorkspace) {
|
template <typename WINDOWPTR>
|
||||||
return isFloatingMatches(w, floating) && w != pWindow && isWorkspaceMatches(pWindow, w, anyWorkspace) && w->m_bIsMapped && !w->isHidden() &&
|
static bool isWindowAvailableForCycle(WINDOWPTR pWindow, WINDOWPTR w, bool focusableOnly, std::optional<bool> floating, bool anyWorkspace = false) {
|
||||||
(!focusableOnly || !w->m_sWindowData.noFocus.valueOrDefault());
|
return isFloatingMatches(w, floating) &&
|
||||||
|
(w != pWindow && isWorkspaceMatches(pWindow, w, anyWorkspace) && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sWindowData.noFocus.valueOrDefault()));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Iterator>
|
||||||
|
static PHLWINDOW getWindowPred(Iterator cur, Iterator end, Iterator begin, const std::function<bool(const PHLWINDOW&)> PRED) {
|
||||||
|
const auto IN_ONE_SIDE = std::find_if(cur, end, PRED);
|
||||||
|
if (IN_ONE_SIDE != end)
|
||||||
|
return *IN_ONE_SIDE;
|
||||||
|
const auto IN_OTHER_SIDE = std::find_if(begin, cur, PRED);
|
||||||
|
return *IN_OTHER_SIDE;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Iterator>
|
||||||
|
static PHLWINDOW getWeakWindowPred(Iterator cur, Iterator end, Iterator begin, const std::function<bool(const PHLWINDOWREF&)> PRED) {
|
||||||
|
const auto IN_ONE_SIDE = std::find_if(cur, end, PRED);
|
||||||
|
if (IN_ONE_SIDE != end)
|
||||||
|
return IN_ONE_SIDE->lock();
|
||||||
|
const auto IN_OTHER_SIDE = std::find_if(begin, cur, PRED);
|
||||||
|
return IN_OTHER_SIDE->lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
PHLWINDOW CCompositor::getWindowCycleHist(PHLWINDOWREF cur, bool focusableOnly, std::optional<bool> floating, bool visible, bool next) {
|
||||||
|
const auto FINDER = [&](const PHLWINDOWREF& w) { return isWindowAvailableForCycle(cur, w, focusableOnly, floating, visible); };
|
||||||
|
// also m_vWindowFocusHistory has reverse order, so when it is next - we need to reverse again
|
||||||
|
return next ?
|
||||||
|
getWeakWindowPred(std::ranges::find(std::ranges::reverse_view(m_vWindowFocusHistory), cur), m_vWindowFocusHistory.rend(), m_vWindowFocusHistory.rbegin(), FINDER) :
|
||||||
|
getWeakWindowPred(std::ranges::find(m_vWindowFocusHistory, cur), m_vWindowFocusHistory.end(), m_vWindowFocusHistory.begin(), FINDER);
|
||||||
|
}
|
||||||
|
|
||||||
|
PHLWINDOW CCompositor::getWindowCycle(PHLWINDOW cur, bool focusableOnly, std::optional<bool> floating, bool visible, bool prev) {
|
||||||
|
const auto FINDER = [&](const PHLWINDOW& w) { return isWindowAvailableForCycle(cur, w, focusableOnly, floating, visible); };
|
||||||
|
return prev ? getWindowPred(std::ranges::find(std::ranges::reverse_view(m_vWindows), cur), m_vWindows.rend(), m_vWindows.rbegin(), FINDER) :
|
||||||
|
getWindowPred(std::ranges::find(m_vWindows, cur), m_vWindows.end(), m_vWindows.begin(), FINDER);
|
||||||
}
|
}
|
||||||
|
|
||||||
WORKSPACEID CCompositor::getNextAvailableNamedWorkspace() {
|
WORKSPACEID CCompositor::getNextAvailableNamedWorkspace() {
|
||||||
|
@@ -83,7 +83,7 @@ class CCompositor {
|
|||||||
PHLMONITOR getMonitorFromCursor();
|
PHLMONITOR getMonitorFromCursor();
|
||||||
PHLMONITOR getMonitorFromVector(const Vector2D&);
|
PHLMONITOR getMonitorFromVector(const Vector2D&);
|
||||||
void removeWindowFromVectorSafe(PHLWINDOW);
|
void removeWindowFromVectorSafe(PHLWINDOW);
|
||||||
void focusWindow(PHLWINDOW, SP<CWLSurfaceResource> pSurface = nullptr);
|
void focusWindow(PHLWINDOW, SP<CWLSurfaceResource> pSurface = nullptr, bool preserveFocusHistory = false);
|
||||||
void focusSurface(SP<CWLSurfaceResource>, PHLWINDOW pWindowOwner = nullptr);
|
void focusSurface(SP<CWLSurfaceResource>, PHLWINDOW pWindowOwner = nullptr);
|
||||||
bool monitorExists(PHLMONITOR);
|
bool monitorExists(PHLMONITOR);
|
||||||
PHLWINDOW vectorToWindowUnified(const Vector2D&, uint8_t properties, PHLWINDOW pIgnoreWindow = nullptr);
|
PHLWINDOW vectorToWindowUnified(const Vector2D&, uint8_t properties, PHLWINDOW pIgnoreWindow = nullptr);
|
||||||
@@ -105,8 +105,8 @@ class CCompositor {
|
|||||||
void cleanupFadingOut(const MONITORID& monid);
|
void cleanupFadingOut(const MONITORID& monid);
|
||||||
PHLWINDOW getWindowInDirection(PHLWINDOW, char);
|
PHLWINDOW getWindowInDirection(PHLWINDOW, char);
|
||||||
PHLWINDOW getWindowInDirection(const CBox& box, PHLWORKSPACE pWorkspace, char dir, PHLWINDOW ignoreWindow = nullptr, bool useVectorAngles = false);
|
PHLWINDOW getWindowInDirection(const CBox& box, PHLWORKSPACE pWorkspace, char dir, PHLWINDOW ignoreWindow = nullptr, bool useVectorAngles = false);
|
||||||
PHLWINDOW getNextWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional<bool> floating = {}, bool visible = false);
|
PHLWINDOW getWindowCycle(PHLWINDOW cur, bool focusableOnly = false, std::optional<bool> floating = std::nullopt, bool visible = false, bool prev = false);
|
||||||
PHLWINDOW getPrevWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional<bool> floating = {}, bool visible = false);
|
PHLWINDOW getWindowCycleHist(PHLWINDOWREF cur, bool focusableOnly = false, std::optional<bool> floating = std::nullopt, bool visible = false, bool next = false);
|
||||||
WORKSPACEID getNextAvailableNamedWorkspace();
|
WORKSPACEID getNextAvailableNamedWorkspace();
|
||||||
bool isPointOnAnyMonitor(const Vector2D&);
|
bool isPointOnAnyMonitor(const Vector2D&);
|
||||||
bool isPointOnReservedArea(const Vector2D& point, const PHLMONITOR monitor = nullptr);
|
bool isPointOnReservedArea(const Vector2D& point, const PHLMONITOR monitor = nullptr);
|
||||||
@@ -163,7 +163,6 @@ class CCompositor {
|
|||||||
void setRandomSplash();
|
void setRandomSplash();
|
||||||
void initManagers(eManagersInitStage stage);
|
void initManagers(eManagersInitStage stage);
|
||||||
void prepareFallbackOutput();
|
void prepareFallbackOutput();
|
||||||
bool isWindowAvailableForCycle(PHLWINDOW pWindow, PHLWINDOW w, bool focusableOnly, std::optional<bool> floating, bool anyWorkspace = false);
|
|
||||||
|
|
||||||
uint64_t m_iHyprlandPID = 0;
|
uint64_t m_iHyprlandPID = 0;
|
||||||
wl_event_source* m_critSigSource = nullptr;
|
wl_event_source* m_critSigSource = nullptr;
|
||||||
|
@@ -367,7 +367,7 @@ bool CKeybindManager::tryMoveFocusToMonitor(PHLMONITOR monitor) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CKeybindManager::switchToWindow(PHLWINDOW PWINDOWTOCHANGETO) {
|
void CKeybindManager::switchToWindow(PHLWINDOW PWINDOWTOCHANGETO, bool preserveFocusHistory) {
|
||||||
static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
|
static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
|
||||||
static auto PNOWARPS = CConfigValue<Hyprlang::INT>("cursor:no_warps");
|
static auto PNOWARPS = CConfigValue<Hyprlang::INT>("cursor:no_warps");
|
||||||
|
|
||||||
@@ -386,7 +386,7 @@ void CKeybindManager::switchToWindow(PHLWINDOW PWINDOWTOCHANGETO) {
|
|||||||
if (!PWINDOWTOCHANGETO->m_bPinned)
|
if (!PWINDOWTOCHANGETO->m_bPinned)
|
||||||
g_pCompositor->setWindowFullscreenInternal(PLASTWINDOW, FSMODE_NONE);
|
g_pCompositor->setWindowFullscreenInternal(PLASTWINDOW, FSMODE_NONE);
|
||||||
|
|
||||||
g_pCompositor->focusWindow(PWINDOWTOCHANGETO);
|
g_pCompositor->focusWindow(PWINDOWTOCHANGETO, nullptr, preserveFocusHistory);
|
||||||
|
|
||||||
if (!PWINDOWTOCHANGETO->m_bPinned)
|
if (!PWINDOWTOCHANGETO->m_bPinned)
|
||||||
g_pCompositor->setWindowFullscreenInternal(PWINDOWTOCHANGETO, MODE);
|
g_pCompositor->setWindowFullscreenInternal(PWINDOWTOCHANGETO, MODE);
|
||||||
@@ -396,7 +396,7 @@ void CKeybindManager::switchToWindow(PHLWINDOW PWINDOWTOCHANGETO) {
|
|||||||
PWINDOWTOCHANGETO->m_vRealSize->warp();
|
PWINDOWTOCHANGETO->m_vRealSize->warp();
|
||||||
} else {
|
} else {
|
||||||
updateRelativeCursorCoords();
|
updateRelativeCursorCoords();
|
||||||
g_pCompositor->focusWindow(PWINDOWTOCHANGETO);
|
g_pCompositor->focusWindow(PWINDOWTOCHANGETO, nullptr, preserveFocusHistory);
|
||||||
PWINDOWTOCHANGETO->warpCursor();
|
PWINDOWTOCHANGETO->warpCursor();
|
||||||
|
|
||||||
// Move mouse focus to the new window if required by current follow_mouse and warp modes
|
// Move mouse focus to the new window if required by current follow_mouse and warp modes
|
||||||
@@ -1473,7 +1473,7 @@ SDispatchResult CKeybindManager::moveFocusTo(std::string args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto PWINDOWTOCHANGETO = *PFULLCYCLE && PLASTWINDOW->isFullscreen() ?
|
const auto PWINDOWTOCHANGETO = *PFULLCYCLE && PLASTWINDOW->isFullscreen() ?
|
||||||
(arg == 'd' || arg == 'b' || arg == 'r' ? g_pCompositor->getNextWindowOnWorkspace(PLASTWINDOW, true) : g_pCompositor->getPrevWindowOnWorkspace(PLASTWINDOW, true)) :
|
g_pCompositor->getWindowCycle(PLASTWINDOW, true, {}, false, arg != 'd' && arg != 'b' && arg != 'r') :
|
||||||
g_pCompositor->getWindowInDirection(PLASTWINDOW, arg);
|
g_pCompositor->getWindowInDirection(PLASTWINDOW, arg);
|
||||||
|
|
||||||
// Prioritize focus change within groups if the window is a part of it.
|
// Prioritize focus change within groups if the window is a part of it.
|
||||||
@@ -2221,11 +2221,13 @@ SDispatchResult CKeybindManager::circleNext(std::string arg) {
|
|||||||
floatStatus = true;
|
floatStatus = true;
|
||||||
|
|
||||||
const auto VISIBLE = args.contains("visible") || args.contains("v");
|
const auto VISIBLE = args.contains("visible") || args.contains("v");
|
||||||
const auto& w = (args.contains("prev") || args.contains("p") || args.contains("last") || args.contains("l")) ?
|
const auto PREV = args.contains("prev") || args.contains("p") || args.contains("last") || args.contains("l");
|
||||||
g_pCompositor->getPrevWindowOnWorkspace(g_pCompositor->m_pLastWindow.lock(), true, floatStatus, VISIBLE) :
|
const auto NEXT = args.contains("next") || args.contains("n"); // prev is default in classic alt+tab
|
||||||
g_pCompositor->getNextWindowOnWorkspace(g_pCompositor->m_pLastWindow.lock(), true, floatStatus, VISIBLE);
|
const auto HIST = args.contains("hist") || args.contains("h");
|
||||||
|
const auto& w = HIST ? g_pCompositor->getWindowCycleHist(g_pCompositor->m_pLastWindow, true, floatStatus, VISIBLE, NEXT) :
|
||||||
|
g_pCompositor->getWindowCycle(g_pCompositor->m_pLastWindow.lock(), true, floatStatus, VISIBLE, PREV);
|
||||||
|
|
||||||
switchToWindow(w);
|
switchToWindow(w, HIST);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -2620,18 +2622,12 @@ SDispatchResult CKeybindManager::swapnext(std::string arg) {
|
|||||||
g_pCompositor->m_pLastWindow->m_pLastCycledWindow.lock() :
|
g_pCompositor->m_pLastWindow->m_pLastCycledWindow.lock() :
|
||||||
nullptr;
|
nullptr;
|
||||||
|
|
||||||
if (arg == "last" || arg == "l" || arg == "prev" || arg == "p")
|
const bool NEED_PREV = arg == "last" || arg == "l" || arg == "prev" || arg == "p";
|
||||||
toSwap = g_pCompositor->getPrevWindowOnWorkspace(PLASTCYCLED ? PLASTCYCLED : PLASTWINDOW, true);
|
toSwap = g_pCompositor->getWindowCycle(PLASTCYCLED ? PLASTCYCLED : PLASTWINDOW, true, std::nullopt, false, NEED_PREV);
|
||||||
else
|
|
||||||
toSwap = g_pCompositor->getNextWindowOnWorkspace(PLASTCYCLED ? PLASTCYCLED : PLASTWINDOW, true);
|
|
||||||
|
|
||||||
// sometimes we may come back to ourselves.
|
// sometimes we may come back to ourselves.
|
||||||
if (toSwap == PLASTWINDOW) {
|
if (toSwap == PLASTWINDOW)
|
||||||
if (arg == "last" || arg == "l" || arg == "prev" || arg == "p")
|
toSwap = g_pCompositor->getWindowCycle(PLASTWINDOW, true, std::nullopt, false, NEED_PREV);
|
||||||
toSwap = g_pCompositor->getPrevWindowOnWorkspace(PLASTWINDOW, true);
|
|
||||||
else
|
|
||||||
toSwap = g_pCompositor->getNextWindowOnWorkspace(PLASTWINDOW, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_pLayoutManager->getCurrentLayout()->switchWindows(PLASTWINDOW, toSwap);
|
g_pLayoutManager->getCurrentLayout()->switchWindows(PLASTWINDOW, toSwap);
|
||||||
|
|
||||||
|
@@ -148,7 +148,7 @@ class CKeybindManager {
|
|||||||
static bool tryMoveFocusToMonitor(PHLMONITOR monitor);
|
static bool tryMoveFocusToMonitor(PHLMONITOR monitor);
|
||||||
static void moveWindowOutOfGroup(PHLWINDOW pWindow, const std::string& dir = "");
|
static void moveWindowOutOfGroup(PHLWINDOW pWindow, const std::string& dir = "");
|
||||||
static void moveWindowIntoGroup(PHLWINDOW pWindow, PHLWINDOW pWindowInDirection);
|
static void moveWindowIntoGroup(PHLWINDOW pWindow, PHLWINDOW pWindowInDirection);
|
||||||
static void switchToWindow(PHLWINDOW PWINDOWTOCHANGETO);
|
static void switchToWindow(PHLWINDOW PWINDOWTOCHANGETO, bool preserveFocusHistory = false);
|
||||||
static uint64_t spawnRawProc(std::string, PHLWORKSPACE pInitialWorkspace);
|
static uint64_t spawnRawProc(std::string, PHLWORKSPACE pInitialWorkspace);
|
||||||
static uint64_t spawnWithRules(std::string, PHLWORKSPACE pInitialWorkspace);
|
static uint64_t spawnWithRules(std::string, PHLWORKSPACE pInitialWorkspace);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user