From 82f6283a8fdeb704fefc04319e4136c439e1d9d5 Mon Sep 17 00:00:00 2001 From: Pete Appleton Date: Mon, 19 Feb 2024 21:09:55 +0000 Subject: [PATCH] Refactor distance calculation --- src/Hy3Layout.cpp | 16 +++++++------- src/Hy3Node.cpp | 5 +++-- src/Hy3Node.hpp | 55 +++++++++++++++++++++++------------------------ 3 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp index 22382f7..3e9638a 100644 --- a/src/Hy3Layout.cpp +++ b/src/Hy3Layout.cpp @@ -1068,8 +1068,8 @@ CWindow* getWindowInDirection(CWindow* source, ShiftDirection direction, BitFlag if(layers_other_monitors == Layer::None && layers_same_monitor == Layer::None) return nullptr; CWindow *target_window = nullptr; - const auto current_surface_box = source->getWindowMainSurfaceBox(); - auto target_distance = Distance { direction }; + const auto source_middle = source->middle(); + std::optional target_distance; const auto static focus_policy = ConfigValue("plugin:hy3:focus_obscured_windows_policy"); bool permit_obscured_windows = *focus_policy == 0 || (*focus_policy == 2 && layers_same_monitor.HasNot(Layer::Floating | Layer::Tiled)); @@ -1097,8 +1097,8 @@ CWindow* getWindowInDirection(CWindow* source, ShiftDirection direction, BitFlag for(auto &pw: g_pCompositor->m_vWindows) { auto w = pw.get(); if(w != source && isCandidate(w)) { - auto dist = Distance { direction, current_surface_box, w->getWindowMainSurfaceBox() }; - if((dist < target_distance || (target_distance.isNotInitialised() && dist.isInDirection(direction))) && (permit_obscured_windows || isNotObscured(w)) ) { + auto dist = Distance { direction, source_middle, w->middle() }; + if((target_distance.has_value() ? dist < target_distance.value() : dist.isInDirection(direction)) && (permit_obscured_windows || isNotObscured(w)) ) { target_window = w; target_distance = dist; } @@ -1191,9 +1191,9 @@ void Hy3Layout::shiftFocus(int workspace, ShiftDirection direction, bool visible // If the closest window is tiled then focus the tiled node which was obtained from `shiftOrGetFocus`, // otherwise focus whichever is closer if(closest_window->m_bIsFloating) { - const auto source_box = source_window->getWindowMainSurfaceBox(); - Distance distanceToClosestWindow(direction, source_box, closest_window->getWindowMainSurfaceBox()); - Distance distanceToTiledNode(direction, source_box, candidate_node->getMainSurfaceBox()); + Distance distanceToClosestWindow(direction, source_window->middle(), closest_window->middle()); + Distance distanceToTiledNode(direction, source_window->middle(), candidate_node->middle()); + if(distanceToClosestWindow < distanceToTiledNode) { focus_closest_window = true; } @@ -1220,7 +1220,7 @@ void Hy3Layout::shiftFocus(int workspace, ShiftDirection direction, bool visible shiftFocusToMonitor(direction); } - if(new_monitor_id.has_value()) { + if(new_monitor_id && new_monitor_id.value() != source_window->m_iMonitorID) { if(auto *monitor = g_pCompositor->getMonitorFromID(new_monitor_id.value())) { g_pCompositor->setActiveMonitor(monitor); } diff --git a/src/Hy3Node.cpp b/src/Hy3Node.cpp index 6712919..f6c93cc 100644 --- a/src/Hy3Node.cpp +++ b/src/Hy3Node.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -861,8 +862,8 @@ int directionToIteratorIncrement(ShiftDirection direction) { } } -CBox Hy3Node::getMainSurfaceBox() { - return { this->position, this->size }; +Vector2D Hy3Node::middle() { + return this->position + this->size / 2.f; } void Hy3Node::resize(ShiftDirection direction, double delta, bool no_animation) { diff --git a/src/Hy3Node.hpp b/src/Hy3Node.hpp index 88f4d7c..42f3c9c 100644 --- a/src/Hy3Node.hpp +++ b/src/Hy3Node.hpp @@ -98,6 +98,7 @@ struct Hy3Node { CWindow* bringToTop(); void markFocused(); void raiseToTop(); + Vector2D middle(); Hy3Node* getFocusedNode(bool ignore_group_focus = false, bool stop_at_expanded = false); Hy3Node* findNeighbor(ShiftDirection); Hy3Node* getImmediateSibling(ShiftDirection); @@ -105,7 +106,6 @@ struct Hy3Node { void resize(ShiftDirection, double, bool no_animation = false); bool isIndirectlyFocused(); Hy3Node& getExpandActor(); - CBox getMainSurfaceBox(); void recalcSizePosRecursive(bool no_animation = false); void updateTabBar(bool no_animation = false); @@ -136,33 +136,32 @@ struct Hy3Node { }; struct Distance { - bool is_forward; - double primary_axis = -1; - double secondary_axis = -1; - bool operator< (Distance other) { - return isInitialised() - && other.isInitialised() - && is_forward == other.is_forward - && (primary_axis < other.primary_axis || (primary_axis == other.primary_axis && secondary_axis < other.secondary_axis)); - } - bool isInitialised() { return primary_axis != -1; } - bool isNotInitialised() { return primary_axis == -1; } - bool isSameDirection(Distance other) { - return other.primary_axis != 0 && other.is_forward == is_forward; - } - bool isInDirection(ShiftDirection direction) { - bool direction_is_forward = getSearchDirection(direction) == SearchDirection::Forwards; - return is_forward == direction_is_forward; - } - Distance(ShiftDirection direction) { - is_forward = getSearchDirection(direction) == SearchDirection::Forwards; - } - Distance(ShiftDirection direction, CBox from, CBox to) { - auto middle_from = from.middle(), middle_to = to.middle(); - auto primary_dist = getAxis(direction) == Axis::Horizontal ? middle_from.x - middle_to.x : middle_from.y - middle_to.y; + double primary_axis; + double secondary_axis; - is_forward = std::signbit(primary_dist); - primary_axis = abs(primary_dist); - secondary_axis = abs(getAxis(direction) == Axis::Horizontal ? middle_from.y - middle_to.y : middle_from.x - middle_to.x); + Distance() = default; + + Distance(ShiftDirection direction, Vector2D from, Vector2D to) { + auto dist = from - to; + primary_axis = getAxis(direction) == Axis::Horizontal ? dist.x : dist.y; + secondary_axis = getAxis(direction) == Axis::Horizontal ? dist.y : dist.x; + } + + bool operator< (Distance other) { + return signbit(primary_axis) == signbit(other.primary_axis) + && (abs(primary_axis) < abs(other.primary_axis) || (primary_axis == other.primary_axis && abs(secondary_axis) < abs(other.secondary_axis))); + } + + bool operator> (Distance other) { + return signbit(primary_axis) == signbit(other.primary_axis) + && (abs(primary_axis) > abs(other.primary_axis) || (primary_axis == other.primary_axis && abs(secondary_axis) > abs(other.secondary_axis))); + } + + bool isSameDirection(Distance other) { + return signbit(primary_axis) == signbit(other.primary_axis); + } + + bool isInDirection(ShiftDirection direction) { + return std::signbit(primary_axis) == (getSearchDirection(direction) == SearchDirection::Forwards); } }; \ No newline at end of file