Skip to content

Commit e6a4ac4

Browse files
committed
Multi monitor Wrapping looks good in initial testing
1 parent d78fe63 commit e6a4ac4

1 file changed

Lines changed: 22 additions & 136 deletions

File tree

v4.0/src/mouse_wrap.c

Lines changed: 22 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -253,11 +253,10 @@ void WrapMouseWhileDragging()
253253
me_Edge hit_edge = contour_to_use->edges[i];
254254
BOOL on_edge_vicinity = IsPointNearEdge(current_pos, hit_edge, PIXEL_TOLERANCE);
255255

256+
char dbg_buf[512]; // Declare dbg_buf here
256257
POINT new_pos = current_pos;
257-
BOOL wrap_logic_applied = FALSE;
258258

259259
if (on_edge_vicinity) {
260-
char dbg_buf[512];
261260
sprintf_s(dbg_buf, sizeof(dbg_buf), "Wrap: Hit edge %zu: (%ld,%ld)-(%ld,%ld). Cursor: (%ld,%ld). Contour: %s\n",
262261
i, hit_edge.x1, hit_edge.y1, hit_edge.x2, hit_edge.y2,
263262
current_pos.x, current_pos.y, contour_type_str);
@@ -268,142 +267,29 @@ void WrapMouseWhileDragging()
268267
contour_center_x, contour_center_y);
269268
OutputDebugStringA(dbg_buf);
270269

271-
// Specific 2-monitor vertical wrapping logic
272-
if (hit_edge.x1 == hit_edge.x2 && monitor_count == 2) {
273-
me_Rect m_left_rect, m_right_rect;
274-
// Determine which monitor is physically to the left and which is to the right
275-
if (monitor_rects_array[0].xMin < monitor_rects_array[1].xMin) {
276-
m_left_rect = monitor_rects_array[0];
277-
m_right_rect = monitor_rects_array[1];
278-
} else {
279-
m_left_rect = monitor_rects_array[1];
280-
m_right_rect = monitor_rects_array[0];
281-
}
282-
sprintf_s(dbg_buf, sizeof(dbg_buf), "Wrap: 2Mon V. M_Left:(%ld,%ld R:%ld B:%ld), M_Right:(%ld,%ld R:%ld B:%ld)\n",
283-
m_left_rect.xMin, m_left_rect.yMin, m_left_rect.xMax, m_left_rect.yMax,
284-
m_right_rect.xMin, m_right_rect.yMin, m_right_rect.xMax, m_right_rect.yMax);
270+
// General heuristic for vertical edges
271+
if (hit_edge.x1 == hit_edge.x2) {
272+
BOOL is_left_edge = (abs(hit_edge.x1 - contour_min_x) <= PIXEL_TOLERANCE);
273+
BOOL is_right_edge = (abs(hit_edge.x1 - contour_max_x) <= PIXEL_TOLERANCE);
274+
sprintf_s(dbg_buf, sizeof(dbg_buf), "Wrap: V Hit Details. Edge:(%ld,%ld)-(%ld,%ld). Cursor:(%ld,%ld). IsLeftEdge: %s. IsRightEdge: %s\n",
275+
hit_edge.x1, hit_edge.y1, hit_edge.x2, hit_edge.y2, current_pos.x, current_pos.y, is_left_edge ? "TRUE" : "FALSE", is_right_edge ? "TRUE" : "FALSE");
285276
OutputDebugStringA(dbg_buf);
286277

287-
// Define conceptual edges of the individual monitors
288-
me_Edge m_left_rect_L_edge = me_create_edge(m_left_rect.xMin, m_left_rect.xMin, m_left_rect.yMin, m_left_rect.yMax);
289-
me_Edge m_left_rect_R_edge = me_create_edge(m_left_rect.xMax, m_left_rect.xMax, m_left_rect.yMin, m_left_rect.yMax);
290-
me_Edge m_right_rect_L_edge = me_create_edge(m_right_rect.xMin, m_right_rect.xMin, m_right_rect.yMin, m_right_rect.yMax);
291-
me_Edge m_right_rect_R_edge = me_create_edge(m_right_rect.xMax, m_right_rect.xMax, m_right_rect.yMin, m_right_rect.yMax);
292-
293-
// Check for internal pass-through condition
294-
if (m_left_rect.xMax == m_right_rect.xMin) { // Monitors are perfectly adjacent
295-
BOOL is_pass_through = FALSE;
296-
// Case 1: Cursor hits right edge of left monitor, check if it can pass into right monitor
297-
if (me_edge_equals(&hit_edge, &m_left_rect_R_edge) &&
298-
(current_pos.y >= m_right_rect.yMin && current_pos.y <= m_right_rect.yMax)) {
299-
is_pass_through = TRUE;
300-
}
301-
// Case 2: Cursor hits left edge of right monitor, check if it can pass into left monitor
302-
else if (me_edge_equals(&hit_edge, &m_right_rect_L_edge) &&
303-
(current_pos.y >= m_left_rect.yMin && current_pos.y <= m_left_rect.yMax)) {
304-
is_pass_through = TRUE;
305-
}
306-
307-
if (is_pass_through) {
308-
sprintf_s(dbg_buf, sizeof(dbg_buf), "Wrap: 2Mon Internal Pass-through at X=%ld. No teleport.\n", m_left_rect.xMax);
309-
OutputDebugStringA(dbg_buf);
310-
return; // Exit: cursor passes naturally, no SetCursorPos needed for this event
311-
}
312-
}
313-
314-
// If not a pass-through, apply standard 2-monitor exterior wrapping logic
315-
if (me_edge_equals(&hit_edge, &m_left_rect_L_edge)) { // Hit M_Left's Left edge
316-
new_pos.x = m_right_rect.xMax - WRAP_OFFSET;
317-
new_pos.y = max(m_right_rect.yMin, min(current_pos.y, m_right_rect.yMax));
318-
sprintf_s(dbg_buf, sizeof(dbg_buf), "Wrap: 2Mon Case: M_Left_L to M_Right_R. NewPos:(%ld,%ld)\n", new_pos.x, new_pos.y); OutputDebugStringA(dbg_buf);
319-
wrap_logic_applied = TRUE;
320-
} else if (me_edge_equals(&hit_edge, &m_left_rect_R_edge)) { // Hit M_Left's Right edge (and not pass-through)
321-
new_pos.x = m_right_rect.xMin + WRAP_OFFSET;
322-
new_pos.y = max(m_right_rect.yMin, min(current_pos.y, m_right_rect.yMax));
323-
sprintf_s(dbg_buf, sizeof(dbg_buf), "Wrap: 2Mon Case: M_Left_R to M_Right_L. NewPos:(%ld,%ld)\n", new_pos.x, new_pos.y); OutputDebugStringA(dbg_buf);
324-
wrap_logic_applied = TRUE;
325-
} else if (me_edge_equals(&hit_edge, &m_right_rect_L_edge)) { // Hit M_Right's Left edge (and not pass-through)
326-
new_pos.x = m_left_rect.xMax - WRAP_OFFSET;
327-
new_pos.y = max(m_left_rect.yMin, min(current_pos.y, m_left_rect.yMax));
328-
sprintf_s(dbg_buf, sizeof(dbg_buf), "Wrap: 2Mon Case: M_Right_L to M_Left_R. NewPos:(%ld,%ld)\n", new_pos.x, new_pos.y); OutputDebugStringA(dbg_buf);
329-
wrap_logic_applied = TRUE;
330-
} else if (me_edge_equals(&hit_edge, &m_right_rect_R_edge)) { // Hit M_Right's Right edge
331-
new_pos.x = m_left_rect.xMin + WRAP_OFFSET;
332-
new_pos.y = max(m_left_rect.yMin, min(current_pos.y, m_left_rect.yMax));
333-
sprintf_s(dbg_buf, sizeof(dbg_buf), "Wrap: 2Mon Case: M_Right_R to M_Left_L. NewPos:(%ld,%ld)\n", new_pos.x, new_pos.y); OutputDebugStringA(dbg_buf);
334-
wrap_logic_applied = TRUE;
335-
}
336-
}
337-
338-
if (!wrap_logic_applied) { // General heuristic or horizontal edge or not 2 monitors for V-edge, or 2-mon logic decided not to apply (e.g. edge didn't match)
339-
if (hit_edge.x1 == hit_edge.x2) { // Hit a vertical edge (general heuristic)
340-
BOOL is_left_ish_hit = (hit_edge.x1 < contour_center_x);
341-
sprintf_s(dbg_buf, sizeof(dbg_buf), "Wrap: Vertical hit (gen heuristic). IsLeft-ish: %s.\n", is_left_ish_hit ? "TRUE" : "FALSE"); OutputDebugStringA(dbg_buf);
342-
for (SIZE_T j = 0; j < contour_to_use->size; j++) {
343-
if (i == j) continue;
344-
me_Edge candidate_edge = contour_to_use->edges[j];
345-
if (candidate_edge.x1 == candidate_edge.x2) {
346-
BOOL is_candidate_opposite_side = (is_left_ish_hit && candidate_edge.x1 > contour_center_x) ||
347-
(!is_left_ish_hit && candidate_edge.x1 < contour_center_x);
348-
if (is_candidate_opposite_side) {
349-
if (current_pos.y >= candidate_edge.y1 && current_pos.y <= candidate_edge.y2) {
350-
new_pos.x = candidate_edge.x1 + (is_left_ish_hit ? -WRAP_OFFSET : WRAP_OFFSET);
351-
wrap_logic_applied = TRUE;
352-
sprintf_s(dbg_buf, sizeof(dbg_buf), "Wrap: Found V candidate (gen) %zu. NewX: %ld\n", j, new_pos.x); OutputDebugStringA(dbg_buf);
353-
break;
354-
}
355-
}
356-
}
357-
}
358-
if (!wrap_logic_applied) {
359-
new_pos.x = is_left_ish_hit ? (contour_max_x - WRAP_OFFSET) : (contour_min_x + WRAP_OFFSET);
360-
new_pos.y = max(contour_min_y, min(current_pos.y, contour_max_y));
361-
sprintf_s(dbg_buf, sizeof(dbg_buf), "Wrap: V Fallback (gen). NewX: %ld, NewY: %ld\n", new_pos.x, new_pos.y);
362-
OutputDebugStringA(dbg_buf);
363-
wrap_logic_applied = TRUE; // Fallback is also an applied logic
364-
}
365-
} else { // Hit a horizontal edge (hit_edge.y1 == hit_edge.y2)
366-
BOOL is_top_edge = (abs(hit_edge.y1 - contour_min_y) <= PIXEL_TOLERANCE);
367-
BOOL is_bottom_edge = (abs(hit_edge.y1 - contour_max_y) <= PIXEL_TOLERANCE);
368-
sprintf_s(dbg_buf, sizeof(dbg_buf), "Wrap: H Hit Details. Edge:(%ld,%ld)-(%ld,%ld). Cursor:(%ld,%ld). IsTopEdge: %s. IsBottomEdge: %s\n",
369-
hit_edge.x1, hit_edge.y1, hit_edge.x2, hit_edge.y2, current_pos.x, current_pos.y, is_top_edge ? "TRUE" : "FALSE", is_bottom_edge ? "TRUE" : "FALSE");
370-
OutputDebugStringA(dbg_buf);
371-
372-
for (SIZE_T j = 0; j < contour_to_use->size; j++) {
373-
if (i == j) continue;
374-
me_Edge candidate_edge = contour_to_use->edges[j];
375-
if (candidate_edge.y1 == candidate_edge.y2) { // Is candidate horizontal?
376-
BOOL is_candidate_top_edge = (abs(candidate_edge.y1 - contour_min_y) <= PIXEL_TOLERANCE);
377-
BOOL is_candidate_bottom_edge = (abs(candidate_edge.y1 - contour_max_y) <= PIXEL_TOLERANCE);
378-
379-
if ((is_top_edge && is_candidate_bottom_edge) || (is_bottom_edge && is_candidate_top_edge)) {
380-
sprintf_s(dbg_buf, sizeof(dbg_buf), "Wrap: H Candidate %zu:(%ld,%ld)-(%ld,%ld) considered. CursorX:%ld in [%ld,%ld]?\n",
381-
j, candidate_edge.x1, candidate_edge.y1, candidate_edge.x2, candidate_edge.y2,
382-
current_pos.x, candidate_edge.x1, candidate_edge.x2);
383-
OutputDebugStringA(dbg_buf);
384-
if (current_pos.x >= candidate_edge.x1 && current_pos.x <= candidate_edge.x2) {
385-
new_pos.y = candidate_edge.y1 + (is_top_edge ? -WRAP_OFFSET : WRAP_OFFSET);
386-
// new_pos.x remains current_pos.x
387-
wrap_logic_applied = TRUE;
388-
sprintf_s(dbg_buf, sizeof(dbg_buf), "Wrap: Found H candidate (gen) %zu. Edge:(%ld,%ld)-(%ld,%ld). NewY: %ld. CursorX kept: %ld\n",
389-
j, candidate_edge.x1, candidate_edge.y1, candidate_edge.x2, candidate_edge.y2, new_pos.y, current_pos.x);
390-
OutputDebugStringA(dbg_buf);
391-
break;
392-
}
393-
}
394-
}
395-
}
396-
if (!wrap_logic_applied) {
397-
sprintf_s(dbg_buf, sizeof(dbg_buf), "Wrap: H No candidate found. Applying Fallback. IsTopEdge:%s. IsBottomEdge:%s. ContourMin/Max Y:(%ld,%ld). CursorX:%ld. ContourMin/Max X:(%ld,%ld)\n",
398-
is_top_edge ? "TRUE" : "FALSE", is_bottom_edge ? "TRUE" : "FALSE", contour_min_y, contour_max_y, current_pos.x, contour_min_x, contour_max_x);
399-
OutputDebugStringA(dbg_buf);
400-
new_pos.y = is_top_edge ? (contour_max_y - WRAP_OFFSET) : (contour_min_y + WRAP_OFFSET);
401-
new_pos.x = max(contour_min_x, min(current_pos.x, contour_max_x));
402-
sprintf_s(dbg_buf, sizeof(dbg_buf), "Wrap: H Fallback Result. NewPos:(%ld,%ld)\n", new_pos.x, new_pos.y);
403-
OutputDebugStringA(dbg_buf);
404-
wrap_logic_applied = TRUE; // Fallback is also an applied logic
405-
}
406-
}
278+
new_pos.x = is_left_edge ? (contour_max_x - WRAP_OFFSET) : (contour_min_x + WRAP_OFFSET);
279+
new_pos.y = max(contour_min_y, min(current_pos.y, contour_max_y));
280+
sprintf_s(dbg_buf, sizeof(dbg_buf), "Wrap: V Fallback Result. NewPos:(%ld,%ld)\n", new_pos.x, new_pos.y);
281+
OutputDebugStringA(dbg_buf);
282+
} else { // Hit a horizontal edge (hit_edge.y1 == hit_edge.y2)
283+
BOOL is_top_edge = (abs(hit_edge.y1 - contour_min_y) <= PIXEL_TOLERANCE);
284+
BOOL is_bottom_edge = (abs(hit_edge.y1 - contour_max_y) <= PIXEL_TOLERANCE);
285+
sprintf_s(dbg_buf, sizeof(dbg_buf), "Wrap: H Hit Details. Edge:(%ld,%ld)-(%ld,%ld). Cursor:(%ld,%ld). IsTopEdge: %s. IsBottomEdge: %s\n",
286+
hit_edge.x1, hit_edge.y1, hit_edge.x2, hit_edge.y2, current_pos.x, current_pos.y, is_top_edge ? "TRUE" : "FALSE", is_bottom_edge ? "TRUE" : "FALSE");
287+
OutputDebugStringA(dbg_buf);
288+
289+
new_pos.y = is_top_edge ? (contour_max_y - WRAP_OFFSET) : (contour_min_y + WRAP_OFFSET);
290+
new_pos.x = max(contour_min_x, min(current_pos.x, contour_max_x));
291+
sprintf_s(dbg_buf, sizeof(dbg_buf), "Wrap: H Fallback Result. NewPos:(%ld,%ld)\n", new_pos.x, new_pos.y);
292+
OutputDebugStringA(dbg_buf);
407293
}
408294

409295
sprintf_s(dbg_buf, sizeof(dbg_buf), "Wrap: Final NewPos after H/V logic: (%ld,%ld)\n", new_pos.x, new_pos.y);

0 commit comments

Comments
 (0)