Skip to content

Commit

Permalink
fix: main window follow mouse problem #32
Browse files Browse the repository at this point in the history
  • Loading branch information
ZGGSONG committed Mar 12, 2024
1 parent 37ab542 commit 4c65808
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 45 deletions.
14 changes: 10 additions & 4 deletions src/STranslate.Util/CommonUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -389,18 +389,24 @@ public static Dictionary<string, T> GetEnumList<T>()
/// 获取鼠标位置
/// </summary>
/// <returns></returns>
public static Point GetMousePositionWindowsForms()
public static Tuple<Point, Rect> GetPositionInfos()
{
//获取未进行缩放的position信息
var ms = System.Windows.Forms.Control.MousePosition;
var screen = WpfScreenHelper.Screen.AllScreens.FirstOrDefault(s => s.WpfBounds.Contains(new Point(ms.X, ms.Y)));
//原始数据是否在原始分辨率的屏幕内
var screen = WpfScreenHelper.Screen.AllScreens.FirstOrDefault(s => s.Bounds.Contains(new Point(ms.X, ms.Y)));

if (screen != null)
{
//获取缩放比例
double dpiScale = screen.ScaleFactor;
return new Point(ms.X / dpiScale, ms.Y / dpiScale);
//获取处理后的屏幕数据
var bounds = screen.WpfBounds;
//返回处理后的数据
return new(new Point(ms.X / dpiScale, ms.Y / dpiScale), bounds);
}

return new Point(ms.X, ms.Y);
throw new ArgumentNullException();
}

/// <summary>
Expand Down
113 changes: 80 additions & 33 deletions src/STranslate/ViewModels/NotifyIconViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ private void InputTranslate(Window view)
Singleton<OutputViewModel>.Instance.SingleTranslateCancelCommand.Execute(null);
Singleton<InputViewModel>.Instance.TranslateCancelCommand.Execute(null);
Clear();
ShowAndActive(view);
ShowAndActive(view, Singleton<ConfigHelper>.Instance.CurrentConfig?.IsFollowMouse ?? false);
}

[RelayCommand]
Expand All @@ -139,7 +139,7 @@ private void CrossWordTranslate(Window view)
Clear();

Singleton<InputViewModel>.Instance.InputContent = content;
ShowAndActive(view);
ShowAndActive(view, Singleton<ConfigHelper>.Instance.CurrentConfig?.IsFollowMouse ?? false);

Singleton<InputViewModel>.Instance.TranslateCommand.Execute(null);
}
Expand Down Expand Up @@ -177,15 +177,15 @@ private void QRCode(object obj)
internal void QRCodeHandler()
{
ScreenshotView view = new();
ShowAndActive(view, false);
ShowAndActive(view);

view.BitmapCallback += (
bitmap =>
{
//显示OCR窗口
OCRView? view = Application.Current.Windows.OfType<OCRView>().FirstOrDefault();
view ??= new OCRView();
ShowAndActive(view, false);
ShowAndActive(view);

//显示截图
var bs = BitmapUtil.ConvertBitmap2BitmapSource(bitmap);
Expand Down Expand Up @@ -223,15 +223,15 @@ private void OCR(object obj)
internal void OCRHandler()
{
ScreenshotView view = new();
ShowAndActive(view, false);
ShowAndActive(view);

view.BitmapCallback += (
bitmap =>
{
//显示OCR窗口
OCRView? view = Application.Current.Windows.OfType<OCRView>().FirstOrDefault();
view ??= new OCRView();
ShowAndActive(view, false);
ShowAndActive(view);

//显示截图
var bs = BitmapUtil.ConvertBitmap2BitmapSource(bitmap);
Expand Down Expand Up @@ -269,7 +269,7 @@ private void SilentOCR(object? obj)
internal void SilentOCRHandler()
{
ScreenshotView view = new();
ShowAndActive(view, false);
ShowAndActive(view);

view.BitmapCallback += (
bitmap =>
Expand Down Expand Up @@ -323,7 +323,7 @@ private void ScreenShotTranslate(object obj)
internal void ScreenShotHandler()
{
ScreenshotView view = new();
ShowAndActive(view, false);
ShowAndActive(view);

view.BitmapCallback += (
bitmap =>
Expand All @@ -337,7 +337,7 @@ internal void ScreenShotHandler()
Clear();

MainView view = Application.Current.Windows.OfType<MainView>().FirstOrDefault()!;
ShowAndActive(view);
ShowAndActive(view, Singleton<ConfigHelper>.Instance.CurrentConfig?.IsFollowMouse ?? false);

var bytes = BitmapUtil.ConvertBitmap2Bytes(bitmap);

Expand Down Expand Up @@ -401,23 +401,18 @@ internal void Clear()
Singleton<OutputViewModel>.Instance.Clear();
}

private void ShowAndActive(Window view, bool canFollowMouse = true)
private void ShowAndActive(Window view, bool canFollowMouse = false)
{
if ((Singleton<ConfigHelper>.Instance.CurrentConfig?.IsFollowMouse ?? false) && canFollowMouse)
{
Point mouseLocation = CommonUtil.GetMousePositionWindowsForms();
view.Left = mouseLocation.X;
view.Top = mouseLocation.Y;
}
if (view.WindowState == WindowState.Minimized)
{
view.WindowState = WindowState.Normal; // Restore the window if it was minimized.
}
if (!view.Topmost) // Ensure the window is topmost if it's not already.
if (canFollowMouse)
{
view.Topmost = true; // Temporarily make the window topmost.
view.Topmost = false; // Then set it back to normal state, this is a trick to bring it to the front.
var position = FollowMouseHandler(view);

view.Left = position.Item1;
view.Top = position.Item2;
}

SpecialWindowActiveHandler(view);

if (view is MainView mview)
{
mview.ViewAnimation();
Expand All @@ -443,21 +438,21 @@ private void ShowAndActive(Window view, bool canFollowMouse = true)
[RelayCommand]
private void OpenPreference()
{
PreferenceView? window = Application.Current.Windows.OfType<PreferenceView>().FirstOrDefault();
window ??= new PreferenceView();
window.UpdateNavigation();
PreferenceView? view = Application.Current.Windows.OfType<PreferenceView>().FirstOrDefault();
view ??= new PreferenceView();
view.UpdateNavigation();

ShowAndActive(window, false);
ShowAndActive(view);
}

[RelayCommand]
private void OpenHistory()
{
PreferenceView? window = Application.Current.Windows.OfType<PreferenceView>().FirstOrDefault();
window ??= new PreferenceView();
window.UpdateNavigation(PerferenceType.History);
PreferenceView? view = Application.Current.Windows.OfType<PreferenceView>().FirstOrDefault();
view ??= new PreferenceView();
view.UpdateNavigation(PerferenceType.History);

ShowAndActive(window, false);
ShowAndActive(view);
}

[RelayCommand]
Expand All @@ -477,7 +472,7 @@ private void ClipboardMonitor(Window view)
{
IsClipboardMonitor = !IsClipboardMonitor;
IsEnabledClipboardMonitor = IsClipboardMonitor ? ConstStr.TAGTRUE : ConstStr.TAGFALSE;

if (IsClipboardMonitor)
{
// 开始监听剪贴板变化
Expand Down Expand Up @@ -519,7 +514,7 @@ private void ClipboardChanged(string content, Window view)
Clear();

Singleton<InputViewModel>.Instance.InputContent = content;
ShowAndActive(view);
ShowAndActive(view, Singleton<ConfigHelper>.Instance.CurrentConfig?.IsFollowMouse ?? false);

Singleton<InputViewModel>.Instance.TranslateCommand.Execute(null);
}
Expand Down Expand Up @@ -563,5 +558,57 @@ private void Exit()

Application.Current.Shutdown();
}

/// <summary>
/// 跟随鼠标处理
/// </summary>
/// <param name="view"></param>
/// <returns></returns>
private Tuple<double, double> FollowMouseHandler(Window view)
{
var infos = CommonUtil.GetPositionInfos();
var position = infos.Item1;
var bounds = infos.Item2;
var left = position.X;
var top = position.Y;

//保持页面在屏幕上方三分之一处
if ((top - bounds.Top) * 3 > bounds.Height)
{
top = bounds.Height / 3 + bounds.Top;
}

//如果当前高度不足以容纳最大高度的内容,则使用最大高度为窗口Top值
if (bounds.Height - top + bounds.Top < view.MaxHeight)
{
top = bounds.Height - view.MaxHeight + bounds.Top - 48;
}

//右侧不超出当前屏幕区域
if (left + view.Width > (bounds.Left + bounds.Width))
{
left = bounds.Left + bounds.Width - view.Width;
}
return new Tuple<double, double>(left, top);
}

/// <summary>
/// 特定情况下窗口无法激活的问题
/// 1. 主窗口非置顶并且设置页面已经存在时激活设置页面
/// 2. 设置页面最小化再激活
/// </summary>
/// <param name="view"></param>
private void SpecialWindowActiveHandler(Window view)
{
if (view.WindowState == WindowState.Minimized)
{
view.WindowState = WindowState.Normal; // Restore the window if it was minimized.
}
if (!view.Topmost) // Ensure the window is topmost if it's not already.
{
view.Topmost = true; // Temporarily make the window topmost.
view.Topmost = false; // Then set it back to normal state, this is a trick to bring it to the front.
}
}
}
}
8 changes: 2 additions & 6 deletions src/STranslate/Views/Preference/CommonPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@
HorizontalAlignment="Right"
ItemsSource="{Binding ProxyMethodList}"
SelectedValue="{Binding ProxyMethod, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

</DockPanel>

<!-- // 代理配置 // -->
Expand All @@ -117,7 +116,6 @@
HorizontalAlignment="Right"
Placeholder="请输入IP地址"
Text="{Binding ProxyIp, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />

</DockPanel>
<DockPanel Margin="20,10" Visibility="{Binding ProxyMethod, Converter={StaticResource ProxyMethodToVisibilityConverter}}">
<TextBlock Text="端口" />
Expand All @@ -127,7 +125,6 @@
Placeholder="请输入端口号"
PreviewKeyDown="AcceptOnlyNumber"
Text="{Binding ProxyPort, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />

</DockPanel>

<DockPanel Margin="20,10" Visibility="{Binding ProxyMethod, Converter={StaticResource ProxyMethodToVisibilityConverter}}">
Expand All @@ -150,7 +147,6 @@
<Binding Path="IsProxyAuthentication" />
</MultiBinding>
</DockPanel.Visibility>

</DockPanel>

<DockPanel Margin="20,10">
Expand Down Expand Up @@ -227,8 +223,8 @@
</DockPanel>

<DockPanel Margin="20,10">
<TextBlock Text="窗口跟随鼠标" />
<TextBlock Style="{DynamicResource InfoTextBlock}" ToolTip="主窗口弹出位置跟随鼠标位置" />
<TextBlock Text="窗口跟随鼠标(输入、截图、划词和监听剪贴板)" />
<TextBlock Style="{DynamicResource InfoTextBlock}" ToolTip="输入、截图、划词和监听剪贴板进行翻译时&#13;主窗口弹出位置跟随鼠标位置" />
<ToggleButton Height="26" HorizontalAlignment="Right" IsChecked="{Binding IsFollowMouse}" />
</DockPanel>

Expand Down
4 changes: 2 additions & 2 deletions src/STranslate/Views/ScreenshotView.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ public ScreenshotView()

_rectangle = new();
var ms = System.Windows.Forms.Control.MousePosition;
var screen = WpfScreenHelper.Screen.AllScreens.FirstOrDefault(screen => screen.WpfBounds.Contains(new Point(ms.X, ms.Y)));
var screen = WpfScreenHelper.Screen.AllScreens.FirstOrDefault(screen => screen.Bounds.Contains(new Point(ms.X, ms.Y)));
if (screen == null)
{
Log.LogService.Logger.Error("恶性BUG,未获取到屏幕数据");
Log.LogService.Logger.Error("未获取到屏幕数据");
return;
}

Expand Down

0 comments on commit 4c65808

Please sign in to comment.