imgui
imgui copied to clipboard
Checking if window has focus doesn't take into consideration other OS windows
ImGui::IsWindowFocused();
Returns if the window is the current ImGui window that has focus but doesn't take into consideration if it is focus in regard to other running apps. I don't have a problem with the way it is made but is there a way to check if that window is also the current focused os window?
Is there a way to do something like this?
ImGui::IsWindowFocused() && IsWindowFocused(GetCurrentOsWindowFromCurrentImguiWindow());
Correct, IsWindowFocused
is checking if a window is focused from the perspective of Dear ImGui. It doesn't take anything else into consideration.
Edit: See Omar's comment below.
~~Checking whether your app has focus is platform-specific and since you didn't fill out the issue template we can't know what platform you're on. (Either way it's outside the scope of what's relevant on this repo.)~~
~~That being said, if you're on Windows you can check if any of your app's windows have focus using GetActiveWindow() != NULL
on the UI thread.~~
As an undocumented thing, we maintain io.AppFocusLost on modern backends, we could probably rename it to io.AppHasFocus which is easier to digest and make it a documented ?
I stand corrected! Totally forgot backends handled focus events.
will appFocusLost be true for all unfoused windows? Changing it to io.AppHasFocus seems like a useful feature
Also is the io different for each window? Like if I use docking Imgui will it work for secondary windows? Or it just checks focus for the main window? I would want a way to check the focus for the current Imgui window regardless if it is docked in the main window or not.
This will be focus of the whole app aka the main window or any secondary dear imgui viewport.
To check OS focus for one specific viewport you may obtain the ImGuiViewport*
and call bool GetPlatformIO().Platform_GetWindowFocus(viewport);
Hm I don't know if I am doing anything wrong here but it seems to crash when moving the window outside the main window
ImGuiViewport *viewPort = ImGui::GetWindowViewport();
auto io = ImGui::GetIO();
windowInput.hasFocus = ImGui::GetPlatformIO().Platform_GetWindowFocus(viewPort) && !io.AppFocusLost;
platformUserData is null
but it seems to crash when moving the window outside the main window
Happens on the first frame of a new viewport, as Platform_CreateWindow()
hasn't been called yet. Internally we prefix our calls with this check:
if (viewport->PlatformWindowCreated)
if (g.PlatformIO.Platform_GetWindowFocus(viewport))
....
- I pushed d2f9c5d to move
PlatformWindowCreated
from privateImGuiViewportP
to publicImGuiViewport
- Or instead
if (viewport->PlatformUserData != NULL && g.PlatformIO.Platform_GetWindowFocus(viewport))
Right now it's not reasonable to move that responsibility from caller to backend because it would encourage "silently fail" behavior which I dislike.
I have now tried to add io.AppFocused
but:
-
io.AppFocusLost
is still needed as a trigger to allow app/engine to do custom clearing/cancelling operation. That's fine we can keep it! -
io.AddFocused
(== current state) cannot be reliably implemented as we don't have the INITIAL app state sent: neither Win32 nor SDL backends are generating an initialio.AddFocusEvent()
event on window creating. Defaulting totrue
would be technically incorrect. I'd prefer to not add it and instead let you do the polling for now.
Closing this for now as I believe calling Platform_GetWindowFocus()
answers the question.
I believe there are possibilities that:
- We add a bool Focused flag to
ImGuiViewport
eventually (even on master). Currently we can only get this reliably on docking branch. - We add an additional flag to
IsWindowFocused()
to check the platform/native state.
If this change we'll post here.
thank you, I'll look into it.
calling
Platform_GetWindowFocus()
answers the question.
Could you please provide an example. I am trying to run with no success:
platformIO.Platform_GetWindowFocus(viewport)
crashes 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));
@OneArb The platform IO functions are provided by the backend.
If ImGuiConfigFlags_ViewportsEnable
is not set during backend initialization those functions will not be provided.
@PathogenDavid Thanks.
That presumes I would be using a default backend from the examples/ folder:
I believe that is not the case as I am running the orx ImGui implementation.
When I set io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable
, I get core dumped.
I am running 1.89.3 docking build, GLFW 3.3.
I do not actually need to check OS focus within a specific viewport, but rather check if there is focus on the whole app level.
io.AppFocusLost
is probably what I want?
I am just trying to throttle down the framerate to lower consumption for gaming laptops when hovering away from ImGui or switching app.
io.AddFocusEvent(focus);
seems the way but I'd need an example on how to pull that event from the queue.
@OneArb Yeah, the backend must support viewports. (It's odd you got core dumped, but maybe your backend is barfing on something with viewports enabled.)
ImGuiIO::AppFocusLost
does sound like what you want, but keep in mind it requires support from the backend as well.
I'd need an example on how to pull that event from the queue.
Calling AddFocusEvent
is what drives the value of AppFocusLost
. Ut's meant to be called from the backend.
If you're using thegwydd/ImGuiOrx, it does not appear that it supports focus events. (Or the modern input queue at all -- it's quite dated.)
You might be better off approaching this from an Orx angle rather than a Dear ImGui one. Dear ImGui doesn't really know anything about operating system windows, apps, or app focus. Those responsibilities fall on the backend.
If you have access to the GLFWwindow*
used by your app, you should be able to install a focus callback with glfwSetWindowFocusCallback
.
You might need to chain-call the original callback if Orx installed one of its own. You can see examples of how to do this by searching for PrevUserCallbackWindowFocus
in imgui_impl_glfw.cpp
.