mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-10-31 05:01:05 +01:00 
			
		
		
		
	Viewport, Platform: Refresh monitor list (win32, glfw) + avoid calling GetWindowFocus before platform window creation to not require of backend to null-check things inconsistently. (#1542)
This commit is contained in:
		
							
								
								
									
										3
									
								
								TODO.txt
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								TODO.txt
									
									
									
									
									
								
							| @@ -262,6 +262,9 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i | ||||
|  - viewport: store per-viewport/monitor DPI in .ini file so an application reload or main window changing DPI on reload can be properly patched for. | ||||
|  - viewport: vulkan renderer implementation.  | ||||
|  - viewport: need to clarify how to use GetMousePos() from a user point of view. | ||||
|  - platform: glfw: no support for ImGuiBackendFlags_HasMouseHoveredViewport.  | ||||
|  - platform: sdl: no support for ImGuiBackendFlags_HasMouseHoveredViewport. maybe we could use SDL_GetMouseFocus() / SDL_WINDOW_MOUSE_FOCUS if imgui could fallback on its heuristic when NoInputs is set | ||||
|  - platform: sdl: no refresh of monitor/display (SDL doesn't seem to have an event for it). | ||||
|  | ||||
|  - inputs: we need an explicit flag about whether the imgui window is focused, to be able to distinguish focused key releases vs alt-tabbing all release behaviors. | ||||
|  - inputs: rework IO system to be able to pass actual ordered/timestamped events. use an event queue? (~#335, #71) | ||||
|   | ||||
| @@ -53,10 +53,12 @@ static GlfwClientApi    g_ClientApi = GlfwClientApi_Unknown; | ||||
| static double           g_Time = 0.0f; | ||||
| static bool             g_MouseJustPressed[5] = { false, false, false, false, false }; | ||||
| static GLFWcursor*      g_MouseCursors[ImGuiMouseCursor_Count_] = { 0 }; | ||||
| static bool             g_WantUpdateMonitors = true; | ||||
|  | ||||
| // Forward Declarations | ||||
| static void ImGui_ImplGlfw_InitPlatformInterface(); | ||||
| static void ImGui_ImplGlfw_ShutdownPlatformInterface(); | ||||
| static void ImGui_ImplGlfw_UpdateMonitors(); | ||||
|  | ||||
| static const char* ImGui_ImplGlfw_GetClipboardText(void* user_data) | ||||
| { | ||||
| @@ -271,6 +273,8 @@ void ImGui_ImplGlfw_NewFrame() | ||||
|     glfwGetFramebufferSize(g_Window, &display_w, &display_h); | ||||
|     io.DisplaySize = ImVec2((float)w, (float)h); | ||||
|     io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); | ||||
|     if (g_WantUpdateMonitors) | ||||
|         ImGui_ImplGlfw_UpdateMonitors(); | ||||
|  | ||||
|     // Setup time step | ||||
|     double current_time = glfwGetTime(); | ||||
| @@ -562,7 +566,6 @@ static int ImGui_ImplGlfw_CreateVkSurface(ImGuiViewport* viewport, ImU64 vk_inst | ||||
| } | ||||
| #endif // GLFW_HAS_VULKAN | ||||
|  | ||||
| // FIXME-PLATFORM: Update monitor list when changed (using glfwSetMonitorCallback?) | ||||
| // FIXME-PLATFORM: GLFW doesn't export monitor work area (see https://github.com/glfw/glfw/pull/989) | ||||
| static void ImGui_ImplGlfw_UpdateMonitors() | ||||
| { | ||||
| @@ -586,6 +589,12 @@ static void ImGui_ImplGlfw_UpdateMonitors() | ||||
| #endif | ||||
|         platform_io.Monitors.push_back(monitor); | ||||
|     } | ||||
|     g_WantUpdateMonitors = false; | ||||
| } | ||||
|  | ||||
| static void ImGui_ImplGlfw_MonitorCallback(GLFWmonitor*, int) | ||||
| { | ||||
|     g_WantUpdateMonitors = true; | ||||
| } | ||||
|  | ||||
| static void ImGui_ImplGlfw_InitPlatformInterface() | ||||
| @@ -614,7 +623,9 @@ static void ImGui_ImplGlfw_InitPlatformInterface() | ||||
|     platform_io.Platform_SetImeInputPos = ImGui_ImplWin32_SetImeInputPos; | ||||
| #endif | ||||
|  | ||||
|     // Note: monitor callback are broken GLFW 3.2 and earlier (see github.com/glfw/glfw/issues/784) | ||||
|     ImGui_ImplGlfw_UpdateMonitors(); | ||||
|     glfwSetMonitorCallback(ImGui_ImplGlfw_MonitorCallback); | ||||
|  | ||||
|     // Register main window handle (which is owned by the main application, not by us) | ||||
|     ImGuiViewport* main_viewport = ImGui::GetMainViewport(); | ||||
|   | ||||
| @@ -418,8 +418,7 @@ static void ImGui_ImplSDL2_SetWindowFocus(ImGuiViewport* viewport) | ||||
| static bool ImGui_ImplSDL2_GetWindowFocus(ImGuiViewport* viewport) | ||||
| { | ||||
|     ImGuiViewportDataSDL2* data = (ImGuiViewportDataSDL2*)viewport->PlatformUserData; | ||||
|     bool focus = (SDL_GetWindowFlags(data->Window) & SDL_WINDOW_INPUT_FOCUS) != 0; | ||||
|     return focus; | ||||
|     return (SDL_GetWindowFlags(data->Window) & SDL_WINDOW_INPUT_FOCUS) != 0; | ||||
| } | ||||
|  | ||||
| static void ImGui_ImplSDL2_RenderWindow(ImGuiViewport* viewport, void*) | ||||
| @@ -452,7 +451,7 @@ static int ImGui_ImplSDL2_CreateVkSurface(ImGuiViewport* viewport, ImU64 vk_inst | ||||
| } | ||||
| #endif // SDL_HAS_VULKAN | ||||
|  | ||||
| // FIXME-PLATFORM: Update monitor list when changed? | ||||
| // FIXME-PLATFORM: SDL doesn't have an event to notify the application of display/monitor changes | ||||
| static void ImGui_ImplSDL2_UpdateMonitors() | ||||
| { | ||||
|     ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); | ||||
|   | ||||
| @@ -8,6 +8,7 @@ | ||||
| #include <tchar.h> | ||||
|  | ||||
| // CHANGELOG | ||||
| // (minor and older changes stripped away, please see git history for details) | ||||
| //  2018-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. | ||||
| //  2018-03-20: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors and ImGuiBackendFlags_HasSetMousePos flags + honor ImGuiConfigFlags_NoMouseCursorChange flag. | ||||
| //  2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling). | ||||
| @@ -26,10 +27,12 @@ static HWND                 g_hWnd = 0; | ||||
| static INT64                g_Time = 0; | ||||
| static INT64                g_TicksPerSecond = 0; | ||||
| static ImGuiMouseCursor     g_LastMouseCursor = ImGuiMouseCursor_Count_; | ||||
| static bool                 g_WantUpdateMonitors = true; | ||||
|  | ||||
| // Forward Declarations | ||||
| static void ImGui_ImplWin32_InitPlatformInterface(); | ||||
| static void ImGui_ImplWin32_ShutdownPlatformInterface(); | ||||
| static void ImGui_ImplWin32_UpdateMonitors(); | ||||
|  | ||||
| // Functions | ||||
| bool    ImGui_ImplWin32_Init(void* hwnd) | ||||
| @@ -159,6 +162,8 @@ void    ImGui_ImplWin32_NewFrame() | ||||
|     RECT rect; | ||||
|     ::GetClientRect(g_hWnd, &rect); | ||||
|     io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top)); | ||||
|     if (g_WantUpdateMonitors) | ||||
|         ImGui_ImplWin32_UpdateMonitors(); | ||||
|  | ||||
|     // Setup time step | ||||
|     INT64 current_time; | ||||
| @@ -251,7 +256,7 @@ IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wPa | ||||
|         io.MouseWheelH += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; | ||||
|         return 0; | ||||
|     case WM_MOUSEMOVE: | ||||
|         io.MousePos.x = (signed short)(lParam); | ||||
|         io.MousePos.x = (signed short)(lParam);                 // Note: this is used for single-viewport support, but in reality the code in ImGui_ImplWin32_UpdateMousePos() overwrite this. | ||||
|         io.MousePos.y = (signed short)(lParam >> 16); | ||||
|         return 0; | ||||
|     case WM_KEYDOWN: | ||||
| @@ -273,6 +278,9 @@ IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wPa | ||||
|         if (LOWORD(lParam) == HTCLIENT && ImGui_ImplWin32_UpdateMouseCursor()) | ||||
|             return 1; | ||||
|         return 0; | ||||
|     case WM_DISPLAYCHANGE: | ||||
|         g_WantUpdateMonitors = true; | ||||
|         return 0; | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
| @@ -623,11 +631,11 @@ static BOOL CALLBACK ImGui_ImplWin32_UpdateMonitors_EnumFunc(HMONITOR monitor, H | ||||
|     return TRUE; | ||||
| } | ||||
|  | ||||
| // FIXME-PLATFORM: Update monitor list when changed (WM_DISPLAYCHANGE?) | ||||
| static void ImGui_ImplWin32_UpdateMonitors() | ||||
| { | ||||
|     ImGui::GetPlatformIO().Monitors.resize(0); | ||||
|     ::EnumDisplayMonitors(NULL, NULL, ImGui_ImplWin32_UpdateMonitors_EnumFunc, NULL); | ||||
|     g_WantUpdateMonitors = false; | ||||
| } | ||||
|  | ||||
| static void ImGui_ImplWin32_InitPlatformInterface() | ||||
|   | ||||
							
								
								
									
										42
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								imgui.cpp
									
									
									
									
									
								
							| @@ -3580,21 +3580,6 @@ void ImGui::UpdatePlatformWindows() | ||||
|     if (!(g.IO.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)) | ||||
|         return; | ||||
|  | ||||
|     // Update our implicit z-order knowledge of platform windows, which is used when the back-end cannot provide io.MouseHoveredViewport. | ||||
|     if (g.PlatformIO.Platform_GetWindowFocus) | ||||
|     { | ||||
|         ImGuiViewportP* focused_viewport = NULL; | ||||
|         for (int i = 0; i < g.Viewports.Size && focused_viewport == NULL; i++) | ||||
|             if (g.PlatformIO.Platform_GetWindowFocus(g.Viewports[i])) | ||||
|                 focused_viewport = g.Viewports[i]; | ||||
|         if (focused_viewport && g.PlatformLastFocusedViewport != focused_viewport->ID) | ||||
|         { | ||||
|             if (focused_viewport->LastFrontMostStampCount != g.WindowsFrontMostStampCount) | ||||
|                 focused_viewport->LastFrontMostStampCount = ++g.WindowsFrontMostStampCount; | ||||
|             g.PlatformLastFocusedViewport = focused_viewport->ID; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Create/resize/destroy platform windows to match each active viewport. | ||||
|     // Skip the main viewport (index 0), which is always fully handled by the application! | ||||
|     for (int i = 1; i < g.Viewports.Size; i++) | ||||
| @@ -3631,13 +3616,14 @@ void ImGui::UpdatePlatformWindows() | ||||
|         } | ||||
|  | ||||
|         // Create window | ||||
|         bool is_new_window = (viewport->PlatformHandle == NULL && viewport->PlatformUserData == NULL && viewport->RendererUserData == NULL); | ||||
|         if (is_new_window && viewport->PlatformHandle == NULL && viewport->PlatformUserData == NULL) | ||||
|             g.PlatformIO.Platform_CreateWindow(viewport); | ||||
|         if (is_new_window && viewport->RendererUserData == NULL && g.PlatformIO.Renderer_CreateWindow != NULL) | ||||
|         bool is_new_window = (viewport->CreatedPlatformWindow == false); | ||||
|         if (is_new_window) | ||||
|         { | ||||
|             g.PlatformIO.Renderer_CreateWindow(viewport); | ||||
|             g.PlatformIO.Platform_CreateWindow(viewport); | ||||
|             if (g.PlatformIO.Renderer_CreateWindow != NULL) | ||||
|                 g.PlatformIO.Renderer_CreateWindow(viewport); | ||||
|             viewport->RendererLastSize = viewport->Size; | ||||
|             viewport->CreatedPlatformWindow = true; | ||||
|         } | ||||
|  | ||||
|         // Apply Position and Size (from ImGui to Platform/Renderer back-ends) | ||||
| @@ -3682,6 +3668,22 @@ void ImGui::UpdatePlatformWindows() | ||||
|         // Clear request flags | ||||
|         viewport->PlatformRequestClose = viewport->PlatformRequestMove = viewport->PlatformRequestResize = false; | ||||
|     } | ||||
|  | ||||
|     // Update our implicit z-order knowledge of platform windows, which is used when the back-end cannot provide io.MouseHoveredViewport. | ||||
|     if (g.PlatformIO.Platform_GetWindowFocus != NULL) | ||||
|     { | ||||
|         ImGuiViewportP* focused_viewport = NULL; | ||||
|         for (int i = 0; i < g.Viewports.Size && focused_viewport == NULL; i++) | ||||
|             if (g.Viewports[i]->PlatformUserData != NULL || g.Viewports[i]->PlatformHandle != NULL || g.Viewports[i]->CreatedPlatformWindow) | ||||
|                 if (g.PlatformIO.Platform_GetWindowFocus(g.Viewports[i])) | ||||
|                     focused_viewport = g.Viewports[i]; | ||||
|         if (focused_viewport && g.PlatformLastFocusedViewport != focused_viewport->ID) | ||||
|         { | ||||
|             if (focused_viewport->LastFrontMostStampCount != g.WindowsFrontMostStampCount) | ||||
|                 focused_viewport->LastFrontMostStampCount = ++g.WindowsFrontMostStampCount; | ||||
|             g.PlatformLastFocusedViewport = focused_viewport->ID; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| // This is a default/basic function for performing the rendering/swap of multiple platform windows. | ||||
|   | ||||
| @@ -515,6 +515,7 @@ struct ImGuiViewportP : public ImGuiViewport | ||||
|     int                 LastFrontMostStampCount;  // Last stamp number from when a window hosted by this viewport was made front-most (by comparing this value between two viewport we have an implicit viewport z-order | ||||
|     ImGuiID             LastNameHash; | ||||
|     ImVec2              LastPos; | ||||
|     bool                CreatedPlatformWindow; | ||||
|     float               Alpha;                    // Window opacity (when dragging dockable windows/viewports we make them transparent) | ||||
|     float               LastAlpha; | ||||
|     int                 PlatformMonitor; | ||||
| @@ -524,7 +525,7 @@ struct ImGuiViewportP : public ImGuiViewport | ||||
|     ImDrawDataBuilder   DrawDataBuilder; | ||||
|     ImVec2              RendererLastSize; | ||||
|  | ||||
|     ImGuiViewportP()         { Idx = 1; LastFrameActive = LastFrameOverlayDrawList = LastFrontMostStampCount = -1; LastNameHash = 0; Alpha = LastAlpha = 1.0f; PlatformMonitor = INT_MIN; Window = NULL; OverlayDrawList = NULL; RendererLastSize = ImVec2(-1.0f,-1.0f); } | ||||
|     ImGuiViewportP()         { Idx = 1; LastFrameActive = LastFrameOverlayDrawList = LastFrontMostStampCount = -1; LastNameHash = 0; CreatedPlatformWindow = false; Alpha = LastAlpha = 1.0f; PlatformMonitor = INT_MIN; Window = NULL; OverlayDrawList = NULL; RendererLastSize = ImVec2(-1.0f,-1.0f); } | ||||
|     ~ImGuiViewportP()        { if (OverlayDrawList) IM_DELETE(OverlayDrawList); } | ||||
|     ImRect  GetRect() const  { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); } | ||||
|     ImVec2  GetCenter() const{ return ImVec2(Pos.x + Size.x * 0.5f, Pos.y + Size.y * 0.5f); } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user