electron [Bug]: 无法在Windows上通过编程方式将原生窗口设置为焦点

l5tcr1uw  于 5个月前  发布在  Electron
关注(0)|答案(6)|浏览(74)

预检清单

Electron 版本

17.0.0

您正在使用的操作系统是什么?

Windows

您正在使用的操作系统版本是什么?

Windows 10 21H1

您正在使用的架构是什么?

x64

最后已知的工作 Electron 版本是什么?

预期行为

在 BrowserWindow 上调用 focus() 应该会使原生窗口获得焦点。

实际行为

调用 focus() 似乎会将焦点给予 BrowserWindow,而 DOM 认为它已经获得了焦点。然而,原生窗口尚未获得焦点,输入仍然会发送到之前获得焦点的窗口。

测试用例 Gist URL

https://gist.github.com/cf4d9a1f3705d59756489ef8cccf048e

其他信息

我最初调查了一个使用协议激活时不聚焦 APP 的 Action Center 通知的 bug。可以在此处找到重现问题。https://github.com/bitdisaster/electron-focus-issue 当时我认为 AC 和切换焦点之间存在特殊情况。然而,上面提供的gist显示了一个更简单的重现问题。我只是提供了通知重现以防两种不同的根本原因导致相同的症状。

pes8fvy9

pes8fvy91#

看起来像是 #29082 的重复,而 #29082 可能又是 #25578 的重复。

agxfikkp

agxfikkp2#

我进行了更多的调查,这在一定程度上是“按预期工作”。然而,仍然有一个场景被认为是一个bug。

场景1:
我们试图以某种原因在进程的生命周期内通过编程方式抢占焦点。(参见我的gist)相反,我们只是在任务栏上 Flink 以吸引用户的注意力。这是有意为之的。Windows有一个防止焦点窃取的功能。

场景2:
我们本应被操作系统正确激活并拥有焦点,但我们运行在单示例模式下。当我们运行在单示例模式时,新启动的进程应该有权将UI元素向前推进并获得焦点。然而,我们只是将参数转发给我们应用程序的第一个示例并退出。当正在运行的示例对激活做出React并尝试窃取焦点时,它没有这个权利。解决这个问题的方法是在退出之前使用Windows API调用第二个示例。这应该给第一个示例窃取焦点的机会https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-allowsetforegroundwindow
此场景的repo: https://github.com/bitdisaster/electron-focus-issue

rfbsl7qr

rfbsl7qr3#

这个问题已经被自动标记为过时。如果这个问题仍然影响到你,请留下任何评论(例如“提升”),我们会保持开放。如果你有任何新的附加信息——特别是,如果这个问题在 latest version of Electronbeta 中仍然可复现——请在你的评论中包含它!

yv5phkfx

yv5phkfx4#

这仍然是一个问题。

h79rfbju

h79rfbju5#

我遇到了同样的问题,从Windows toast通知中激活协议没有使我的主窗口成为前台窗口。协议激活启动一个新的Electron进程,该进程将向打开的进程发送消息,导致它尝试将自己聚焦为前台窗口。从鼠标点击到运行的Electron示例的进程链无法正确设置前台窗口。我发现第二个Electron进程在调用AllowSetForegroundWindow时失败,并出现ERROR_ACCESS_DENIED错误。

我通过将chrome/browser/win/chrome_process_finder.cc中的AttemptToNotifyRunningChrome更改为在调用AllowSetForegroundWindow之前发送键盘输入来解决这个问题,这是一种Chrome在其自己的通知助手chrome/notification_helper/notification_activator.cc(参见https://chromium.googlesource.com/chromium/src.git/+/a3c45c46562ec1d99737516cc83aa7c7b916851f%5E%21)中已经使用的技术。

fbcarpbf

fbcarpbf6#

在这里也存在同样的问题。

相关问题