hcfyapp / crx-selection-translate

一站式划词 / 截图 / 网页全文 / 音视频 AI 翻译扩展。
https://hcfy.ai
4.08k stars 540 forks source link

在浏览器外使用独立窗口,打开“持续监听剪贴板”后,复制新内容,窗口疑似因系统原因无法正常弹出 #2043

Open shelfofclub opened 4 months ago

shelfofclub commented 4 months ago

基本信息

划词翻译版本:v10.10.0 浏览器版本:Edge 126.0.2592.81 操作系统:Win 11 23H2

重现问题的步骤

  1. 打开第三方PDF软件
  2. 打开独立窗口,并打开持续监听剪贴板
  3. 复制一段内容

预期行为

自动弹出窗口

实际行为

程序应该是尝试弹出窗口,但系统没让它弹出,任务栏中划词翻译的图标状态是红色闪烁的。 如果是当浏览器在前台获得焦点的时候,复制内容后可以弹出窗口。

补充信息

猜测是系统或者浏览器阻止了弹出,请问在哪里设置可以让它们放行?

lmk123 commented 4 months ago

看描述,我感觉是因为你在划词翻译设置 - 独立翻译窗口 开启了【不要获取焦点】,这个选项开启之后,独立翻译窗口不会自动出现在屏幕最前面。

你可以确认一下是不是因为这个,如果不是的话,我确实也没啥思路了 :joy:

shelfofclub commented 4 months ago

看描述,我感觉是因为你在划词翻译设置 - 独立翻译窗口 开启了【不要获取焦点】,这个选项开启之后,独立翻译窗口不会自动出现在屏幕最前面。

你可以确认一下是不是因为这个,如果不是的话,我确实也没啥思路了 😂

没有开启这个功能,另外也观察到收到刚才回复的邮件,点击通知后,thunderbird也不能弹出窗口。大概率应该是win的一些策略问题了,不知道有没有相关的设置可以更改?

lmk123 commented 4 months ago

操作系统方面的问题我不太清楚,且目前你是第一个反馈这个问题的,也没有经验可以参考 :joy:

DrPeaboss commented 4 months ago

可以复现,估计原因是调用了SetForegroundWindow来弹出窗口的,参考微软的文档 https://learn.microsoft.com/zh-cn/windows/win32/api/winuser/nf-winuser-setforegroundwindow?redirectedfrom=MSDN 可知存在限制。

网上找到的解决方法是先调用AttachThreadInput然后调用SetForegroundWindow

HWND hForeWnd = GetForegroundWindow();
DWORD dwForeID = GetWindowThreadProcessId(hForeWnd, NULL);
DWORD dwCurID = GetCurrentThreadId();
AttachThreadInput(dwCurID, dwForeID, TRUE);
SetForegroundWindow(hWnd);
AttachThreadInput(dwCurID, dwForeID, FALSE);

我在win32程序测试可以。

shelfofclub commented 4 months ago

thunderbird也不能弹出窗口

我的thunderbird是从商店装的。跟平常用安装包安装的应该是不一样,不知道是不是win32的,这年头恐怕没多少搞纯uwp的吧,微软自己都砍了uwp,也许是win32转的某种?不是很了解现在的商店,只知道原来的商店里面要么是纯uwp,要么像老的QQ桌面版,用win32转的。

DrPeaboss commented 4 months ago

ThunderBird应该是win32的,因为几年前微软放开了商店的限制。

目前在win11可以发现不论是什么程序都存在在后台的情况下调用SetForegroundWindow不能弹出只会任务栏闪烁。也就是说必须要在前台程序的消息队列调用SetForegroundWindow才能显示其他进程的窗口。

shelfofclub commented 4 months ago

在win10 22H2有同样问题,独立翻译窗口只在任务栏红色闪烁,并不能弹出。

有点神奇,本以为是win11的问题,现在看win10 11都有,这应该覆盖不少人群,之前竟然没反馈过类似问题。

lmk123 commented 4 months ago

你确实是第一个反馈这个问题的人 :joy:

划词翻译打开独立翻译窗口用的是 Chrome 提供的 chrome.windows.create() 方法,前面提到的 Windows 的那些方法其实是 Chrome 浏览器在使用,换句话说,这个问题没法从划词翻译这边解决 :joy:

shelfofclub commented 4 months ago

明白,我现在用powertoys的置顶来应对这个问题。

DrPeaboss commented 4 months ago

我测试了一下,用detours去hook了浏览器进程的SetForegroundWindow,果然如此。

typedef BOOL(WINAPI* REAL_SFW_PROC) (HWND h);
REAL_SFW_PROC real_sfw;

static BOOL fk_sfw(HWND h)
{
    HWND hForeWnd = GetForegroundWindow();
    DWORD dwForeID = GetWindowThreadProcessId(hForeWnd, NULL);
    DWORD dwCurID = GetCurrentThreadId();
    AttachThreadInput(dwCurID, dwForeID, TRUE);
    BOOL result = real_sfw(h);
    AttachThreadInput(dwCurID, dwForeID, FALSE);
    return result;
}

不过浏览器端确实无法解决,所以PowerToys的置顶确实是一个workaround。

如果要实现完整的功能,除非把独立窗口模块单独打包成exe分发。