c727ad11e3cef6fcf7a3f6864bc56c2a9cfd40fe

Author
outfoxxed <outfoxxed@outfoxxed.me>
Committer
outfoxxed <outfoxxed@outfoxxed.me>
Date

Message

Add floating window support to hy3:movefocus

Diff

 1diff --git a/src/Hy3Layout.cpp b/src/Hy3Layout.cpp
 2index 981a2f256d2f80a2f3b8eb0a82e0062a6f6a65f2..e26a05488103e8130c8da2a064bb393a35f5381e 100644
 3--- a/src/Hy3Layout.cpp
 4+++ b/src/Hy3Layout.cpp
 5@@ -698,7 +698,7 @@ CWindow* Hy3Layout::getNextWindowCandidate(CWindow* window) {
 6 
 7 	// return the first floating window on the same workspace that has not asked not to be focused
 8 	if (window->m_bIsFloating) {
 9-		for (std::unique_ptr<CWindow>& w: g_pCompositor->m_vWindows | std::views::reverse) {
10+		for (auto& w: g_pCompositor->m_vWindows | std::views::reverse) {
11 			if (w->m_bIsMapped && !w->isHidden() && w->m_bIsFloating && w->m_iX11Type != 2
12 			    && w->m_iWorkspaceID == window->m_iWorkspaceID && !w->m_bX11ShouldntFocus
13 			    && !w->m_bNoFocus && w.get() != window)
14@@ -937,10 +937,53 @@ void Hy3Layout::shiftWindow(int workspace, ShiftDirection direction, bool once,
15 }
16 
17 void Hy3Layout::shiftFocus(int workspace, ShiftDirection direction, bool visible) {
18+	auto* current_window = g_pCompositor->m_pLastWindow;
19+	auto* p_workspace = g_pCompositor->getWorkspaceByID(current_window->m_iWorkspaceID);
20+	if (p_workspace->m_bHasFullscreenWindow) return;
21+
22+	if (current_window != nullptr && current_window->m_bIsFloating) {
23+		CWindow* next_window = nullptr;
24+		double next_distance = -1;
25+
26+		for (auto& w: g_pCompositor->m_vWindows) {
27+			if (w->m_bIsMapped && !w->isHidden() && w->m_bIsFloating && w->m_iX11Type != 2
28+			    && w->m_iWorkspaceID == current_window->m_iWorkspaceID && !w->m_bX11ShouldntFocus
29+			    && !w->m_bNoFocus && w.get() != current_window)
30+			{
31+				double distance = 0;
32+
33+				auto cpos = current_window->m_vRealPosition.vec() + (current_window->m_vRealSize.vec() / 2);
34+				auto tpos = w->m_vRealPosition.vec() + (w->m_vRealSize.vec() / 2);
35+
36+				auto x_offset = tpos.x - cpos.x;
37+				auto y_offset = tpos.y - cpos.y;
38+
39+				if (abs(x_offset) > abs(y_offset)) {
40+					if (x_offset < 0 && direction == ShiftDirection::Left) distance = -x_offset;
41+					else if (x_offset > 0 && direction == ShiftDirection::Right) distance = x_offset;
42+				} else {
43+					if (y_offset < 0 && direction == ShiftDirection::Up) distance = -y_offset;
44+					else if (y_offset > 0 && direction == ShiftDirection::Down) distance = y_offset;
45+				}
46+
47+				if (distance <= 0) continue;
48+
49+				if (next_distance == -1 || distance < next_distance) {
50+					next_window = w.get();
51+					next_distance = distance;
52+				}
53+			}
54+		}
55+
56+		if (next_window != nullptr) g_pCompositor->focusWindow(next_window);
57+		return;
58+	}
59+
60 	auto* node = this->getWorkspaceFocusedNode(workspace);
61 	if (node == nullptr) return;
62 
63 	auto* target = this->shiftOrGetFocus(*node, direction, false, false, visible);
64+
65 	if (target != nullptr) {
66 		target->focus();
67 		while (target->parent != nullptr) target = target->parent;