From aba6c18a2515411d081d5b8e229aa51e490304e6 Mon Sep 17 00:00:00 2001
From: CJKmkp <2564608840@qq.com>
Date: Sat, 23 Aug 2025 18:24:24 +0800
Subject: [PATCH] fix:issue #133
---
Ink Canvas/MainWindow_cs/MW_TouchEvents.cs | 186 +++++++++++++++++++--
1 file changed, 172 insertions(+), 14 deletions(-)
diff --git a/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs b/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs
index 49b8aeb8..44a9671d 100644
--- a/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs
+++ b/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs
@@ -1,6 +1,7 @@
using Ink_Canvas.Helpers;
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
@@ -343,6 +344,10 @@ namespace Ink_Canvas
private InkCanvasEditingMode palmEraserLastEditingMode = InkCanvasEditingMode.Ink;
private bool palmEraserLastIsHighlighter;
private bool palmEraserWasEnabledBeforeMultiTouch;
+ private bool palmEraserTouchDownHandled = false; // 新增:标记手掌擦触摸按下是否已处理
+ private DateTime palmEraserActivationTime; // 新增:记录手掌擦激活时间
+ private const int PALM_ERASER_TIMEOUT_MS = 5000; // 新增:手掌擦超时时间(5秒)
+ private System.Windows.Threading.DispatcherTimer palmEraserRecoveryTimer; // 新增:手掌擦恢复定时器
private void inkCanvas_PreviewTouchDown(object sender, TouchEventArgs e)
{
@@ -395,8 +400,8 @@ namespace Ink_Canvas
BlackboardUIGridForInkReplay.IsHitTestVisible = false;
dec.Add(e.TouchDevice.Id);
- // Palm Eraser 逻辑
- if (Settings.Canvas.EnablePalmEraser && dec.Count >= 2 && !isPalmEraserActive)
+ // Palm Eraser 逻辑 - 修复:只在触摸按下时处理一次,避免重复触发
+ if (Settings.Canvas.EnablePalmEraser && dec.Count >= 2 && !isPalmEraserActive && !palmEraserTouchDownHandled)
{
var bounds = e.GetTouchPoint(inkCanvas).Bounds;
double palmThreshold = 40; // 触摸面积阈值,可根据实际调整
@@ -408,6 +413,11 @@ namespace Ink_Canvas
// 切换为橡皮擦
EraserIcon_Click(null, null);
isPalmEraserActive = true;
+ palmEraserActivationTime = DateTime.Now; // 记录激活时间
+ palmEraserTouchDownHandled = true; // 标记已处理
+
+ // 启动恢复定时器,防止卡死
+ StartPalmEraserRecoveryTimer();
}
}
@@ -474,23 +484,86 @@ namespace Ink_Canvas
{
// 恢复高光状态
drawingAttributes.IsHighlighter = palmEraserLastIsHighlighter;
- // 恢复编辑模式
- if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint)
+ // 恢复编辑模式 - 修复:确保正确恢复状态
+ try
{
- if (palmEraserLastEditingMode == InkCanvasEditingMode.Ink)
+ if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint)
{
- PenIcon_Click(null, null);
- }
- else if (palmEraserLastEditingMode == InkCanvasEditingMode.Select)
- {
- SymbolIconSelect_MouseUp(null, null);
- }
- else
- {
- inkCanvas.EditingMode = palmEraserLastEditingMode;
+ if (palmEraserLastEditingMode == InkCanvasEditingMode.Ink)
+ {
+ PenIcon_Click(null, null);
+ }
+ else if (palmEraserLastEditingMode == InkCanvasEditingMode.Select)
+ {
+ SymbolIconSelect_MouseUp(null, null);
+ }
+ else
+ {
+ inkCanvas.EditingMode = palmEraserLastEditingMode;
+ }
}
}
+ catch (Exception ex)
+ {
+ // 如果恢复失败,强制切换到批注模式
+ Trace.WriteLine($"Palm eraser recovery failed: {ex.Message}, forcing to Ink mode");
+ inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
+ }
+
+ // 重置手掌擦状态
isPalmEraserActive = false;
+ palmEraserTouchDownHandled = false;
+
+ // 停止恢复定时器
+ StopPalmEraserRecoveryTimer();
+
+ // 确保触摸事件能正常响应
+ inkCanvas.IsHitTestVisible = true;
+ inkCanvas.IsManipulationEnabled = true;
+ }
+
+ // 新增:超时检测 - 如果手掌擦激活时间过长,强制重置状态
+ if (isPalmEraserActive && dec.Count == 0)
+ {
+ var timeSinceActivation = DateTime.Now - palmEraserActivationTime;
+ if (timeSinceActivation.TotalMilliseconds > PALM_ERASER_TIMEOUT_MS)
+ {
+ Trace.WriteLine($"Palm eraser timeout detected ({timeSinceActivation.TotalMilliseconds}ms), forcing recovery");
+
+ // 强制恢复状态
+ try
+ {
+ if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint)
+ {
+ if (palmEraserLastEditingMode == InkCanvasEditingMode.Ink)
+ {
+ PenIcon_Click(null, null);
+ }
+ else if (palmEraserLastEditingMode == InkCanvasEditingMode.Select)
+ {
+ SymbolIconSelect_MouseUp(null, null);
+ }
+ else
+ {
+ inkCanvas.EditingMode = palmEraserLastEditingMode;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Trace.WriteLine($"Palm eraser timeout recovery failed: {ex.Message}, forcing to Ink mode");
+ inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
+ }
+
+ // 重置所有手掌擦状态
+ isPalmEraserActive = false;
+ palmEraserTouchDownHandled = false;
+ inkCanvas.IsHitTestVisible = true;
+ inkCanvas.IsManipulationEnabled = true;
+
+ // 停止恢复定时器
+ StopPalmEraserRecoveryTimer();
+ }
}
// 修复:几何绘制模式下,触摸抬手时应该正确处理,而不是简单模拟鼠标事件
if (drawingShapeMode != 0)
@@ -551,6 +624,16 @@ namespace Ink_Canvas
{
inkCanvas.EditingMode = lastInkCanvasEditingMode;
}
+
+ // 修复:确保手掌擦除后触摸事件能正常响应
+ if (isPalmEraserActive)
+ {
+ // 如果手掌擦还在激活状态但触摸点已清空,强制重置状态
+ isPalmEraserActive = false;
+ palmEraserTouchDownHandled = false;
+ inkCanvas.IsHitTestVisible = true;
+ inkCanvas.IsManipulationEnabled = true;
+ }
}
}
inkCanvas.Opacity = 1;
@@ -753,5 +836,80 @@ namespace Ink_Canvas
ToggleSwitchEnablePalmEraser.IsOn = false;
}
}
+
+ ///
+ /// 启动手掌擦恢复定时器,防止卡死状态
+ ///
+ private void StartPalmEraserRecoveryTimer()
+ {
+ if (palmEraserRecoveryTimer == null)
+ {
+ palmEraserRecoveryTimer = new System.Windows.Threading.DispatcherTimer();
+ palmEraserRecoveryTimer.Interval = TimeSpan.FromMilliseconds(1000); // 每秒检查一次
+ palmEraserRecoveryTimer.Tick += PalmEraserRecoveryTimer_Tick;
+ }
+
+ palmEraserRecoveryTimer.Start();
+ }
+
+ ///
+ /// 停止手掌擦恢复定时器
+ ///
+ private void StopPalmEraserRecoveryTimer()
+ {
+ if (palmEraserRecoveryTimer != null)
+ {
+ palmEraserRecoveryTimer.Stop();
+ }
+ }
+
+ ///
+ /// 手掌擦恢复定时器事件处理
+ ///
+ private void PalmEraserRecoveryTimer_Tick(object sender, EventArgs e)
+ {
+ if (!isPalmEraserActive) return;
+
+ // 检查是否超时
+ var timeSinceActivation = DateTime.Now - palmEraserActivationTime;
+ if (timeSinceActivation.TotalMilliseconds > PALM_ERASER_TIMEOUT_MS)
+ {
+ Trace.WriteLine($"Palm eraser recovery timer triggered, forcing recovery after {timeSinceActivation.TotalMilliseconds}ms");
+
+ // 强制恢复状态
+ try
+ {
+ if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint)
+ {
+ if (palmEraserLastEditingMode == InkCanvasEditingMode.Ink)
+ {
+ PenIcon_Click(null, null);
+ }
+ else if (palmEraserLastEditingMode == InkCanvasEditingMode.Select)
+ {
+ SymbolIconSelect_MouseUp(null, null);
+ }
+ else
+ {
+ inkCanvas.EditingMode = palmEraserLastEditingMode;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Trace.WriteLine($"Palm eraser recovery timer failed: {ex.Message}, forcing to Ink mode");
+ inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
+ }
+
+ // 重置所有手掌擦状态
+ isPalmEraserActive = false;
+ palmEraserTouchDownHandled = false;
+ inkCanvas.IsHitTestVisible = true;
+ inkCanvas.IsManipulationEnabled = true;
+
+ // 停止定时器
+ StopPalmEraserRecoveryTimer();
+ }
+ }
}
}