Refactor distance calculation

This commit is contained in:
Pete Appleton 2024-02-19 21:09:55 +00:00
parent 946076d380
commit 82f6283a8f
3 changed files with 38 additions and 38 deletions

View file

@ -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<Distance> target_distance;
const auto static focus_policy = ConfigValue<Hyprlang::INT>("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);
}

View file

@ -1,3 +1,4 @@
#include <assert.h>
#include <sstream>
#include <hyprland/src/Compositor.hpp>
@ -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) {

View file

@ -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);
}
};