[ocornut/imgui]检查窗口是否具有焦点不考虑其他操作系统窗口

2024-05-09 162 views
9
ImGui::IsWindowFocused(); 

如果窗口是当前具有焦点的 ImGui 窗口,则返回,但不考虑它是否是其他正在运行的应用程序的焦点。我对它的制作方式没有问题,但是有没有办法检查该窗口是否也是当前聚焦的操作系统窗口?

有没有办法做这样的事情?

ImGui::IsWindowFocused() &&  IsWindowFocused(GetCurrentOsWindowFromCurrentImguiWindow());

回答

9

正确,IsWindowFocused是从 Dear ImGui 的角度检查窗口是否获得焦点。它不考虑其他任何事情。

编辑:请参阅下面奥马尔的评论。

检查您的应用程序是否具有焦点是特定于平台的,由于您没有填写问题模板,我们无法知道您所在的平台。 (无论哪种方式,它都超出了本存储库相关内容的范围。)

话虽这么说,如果您使用的是 Windows,您可以检查应用程序的任何窗口是否具有使用GetActiveWindow() != NULLUI 线程的焦点。

9

作为一个未记录的东西,我们在现代后端维护 io.AppFocusLost,我们可能可以将其重命名为 io.AppHasFocus,这样更容易消化并使其成为记录的?

9

我纠正了!完全忘记了后端处理焦点事件。

1

appFocusLost 对于所有未聚焦的窗口都是 true 吗?将其更改为 io.AppHasFocus 似乎是一个有用的功能

每个窗口的 io 也不同吗?就像如果我使用对接 Imgui 它可以用于辅助窗口吗?或者它只是检查主窗口的焦点?我想要一种方法来检查当前 Imgui 窗口的焦点,无论它是否停靠在主窗口中。

2

这将是整个应用程序的焦点,即主窗口或任何辅助的亲爱的 imgui 视口。

要检查某个特定视口的操作系统焦点,您可以获取ImGuiViewport*并调用bool GetPlatformIO().Platform_GetWindowFocus(viewport);

7

嗯,我不知道我在这里是否做错了什么,但将窗口移到主窗口之外时似乎会崩溃

ImGuiViewport *viewPort = ImGui::GetWindowViewport();
auto io = ImGui::GetIO();
windowInput.hasFocus = ImGui::GetPlatformIO().Platform_GetWindowFocus(viewPort) && !io.AppFocusLost;

图像

平台用户数据为空

7

但将窗口移到主窗口之外时似乎会崩溃

发生在新视口的第一帧上,因为Platform_CreateWindow()尚未被调用。在内部,我们使用此检查为调用添加前缀:

if (viewport->PlatformWindowCreated)
    if (g.PlatformIO.Platform_GetWindowFocus(viewport))
        ....
  • 我推动 d2f9c5dPlatformWindowCreated从私人转向ImGuiViewportP公共ImGuiViewport
  • 或者相反if (viewport->PlatformUserData != NULL && g.PlatformIO.Platform_GetWindowFocus(viewport))

目前,将责任从调用者转移到后端是不合理的,因为这会鼓励我不喜欢的“默默失败”行为。

8

我现在尝试添加io.AppFocused但是:

  • io.AppFocusLost仍然需要作为触发器来允许应用程序/引擎执行自定义清除/取消操作。没关系,我们可以保留它!
  • io.AddFocused(== 当前状态) 无法可靠地实现,因为我们没有发送 INITIAL 应用程序状态:Win32 和 SDL 后端都不会io.AddFocusEvent()在创建窗口时生成初始事件。默认为true在技术上是不正确的。我不想添加它,而是让您暂时进行投票。
4

现在就结束这个问题,因为我相信打电话Platform_GetWindowFocus()可以解决这个问题。

我相信存在以下可能性:

  • 我们最终添加了一个 bool Focused 标志ImGuiViewport(甚至在 master 上)。目前我们只能在对接分支上可靠地获得此信息。
  • 我们添加一个额外的标志来IsWindowFocused()检查平台/本机状态。

如果发生变化,我们将在此处发布。

7

谢谢你,我会调查一下。

3

打电话Platform_GetWindowFocus()回答了问题。

您能否举个例子。我试图运行但没有成功:

platformIO.Platform_GetWindowFocus(viewport)ImGui 崩溃。

    ImGuiPlatformIO& platformIO = ImGui::GetPlatformIO();
    ImGuiViewport* viewport = ImGui::GetMainViewport();

    if (viewport->PlatformWindowCreated)
        if (platformIO.Platform_GetWindowFocus(viewport))
            ImGui::Text("platformIO.Platform_GetWindowFocus(viewport) %d",
                         platformIO.Platform_GetWindowFocus(viewport));
4

@OneArb 平台IO功能由后端提供。

如果ImGuiConfigFlags_ViewportsEnable在后端初始化期间未设置,则不会提供这些功能。

5

@PathogenDavid 谢谢。

假设我会使用a default backend from the examples/ folder:

我相信情况并非如此,因为我正在运行 orx ImGui 实现。

当我设置时io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable,我会被核心转储。我正在运行 1.89.3 对接版本,GLFW 3.3。

我实际上不需要检查特定视口内的操作系统焦点,而是检查整个应用程序级别是否有焦点。

io.AppFocusLost可能是我想要的?

我只是想在远离 ImGui 或切换应用程序时降低帧速率以降低游戏笔记本电脑的消耗。

io.AddFocusEvent(focus);似乎是这样,但我需要一个关于如何从队列中提取该事件​​的示例。

8

@OneArb是的,后端必须支持视口。 (很奇怪你的核心被转储了,但也许你的后端在启用视口的东西上呕吐。)

ImGuiIO::AppFocusLost听起来确实像你想要的,但请记住它也需要后端的支持。

我需要一个有关如何从队列中提取该事件​​的示例。

调用AddFocusEvent是驱动 的价值的因素AppFocusLost。 Ut 应该从后端调用。

如果您使用的是gwydd/ImGuiOrx,它似乎不支持焦点事件。 (或者现代的输入队列——它已经相当过时了。)


从 Orx 角度而不是 Dear ImGui 角度来处理这个问题可能会更好。 Dear ImGui实际上对操作系统窗口、应用程序或应用程序焦点一无所知。这些责任落在后端。

如果您有权访问GLFWwindow*您的应用程序所使用的,您应该能够使用 来安装焦点回调glfwSetWindowFocusCallback

如果 Orx 安装了自己的回调之一,您可能需要链式调用原始回调。您可以通过搜索PrevUserCallbackWindowFocusin来查看如何执行此操作的示例imgui_impl_glfw.cpp