From 5d20da1b3622864eeb06b726cfb27cc2e19c486d Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 14 Dec 2018 11:59:44 +0100 Subject: [PATCH 1/4] Viewport, DPI: Now using DpiScale from the ImGuiPlatformMonitor array instead of calling Platform_GetWindowDpiScale() before the platform window creation. Might even tentatively see if things work out without Platform_GetWindowDpiScale. (#1676) --- examples/imgui_impl_win32.cpp | 20 ++++---------------- examples/imgui_impl_win32.h | 7 +++---- imgui.cpp | 10 ++++++---- imgui.h | 8 ++++---- 4 files changed, 17 insertions(+), 28 deletions(-) diff --git a/examples/imgui_impl_win32.cpp b/examples/imgui_impl_win32.cpp index 63c270468..cf88c8232 100644 --- a/examples/imgui_impl_win32.cpp +++ b/examples/imgui_impl_win32.cpp @@ -366,7 +366,7 @@ void ImGui_ImplWin32_EnableDpiAwareness() float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor) { UINT xdpi = 96, ydpi = 96; - if (IsWindows8Point1OrGreater()) + if (::IsWindows8Point1OrGreater()) { static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process if (PFN_GetDpiForMonitor GetDpiForMonitorFn = (PFN_GetDpiForMonitor)::GetProcAddress(shcore_dll, "GetDpiForMonitor")) @@ -389,13 +389,6 @@ float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd) return ImGui_ImplWin32_GetDpiScaleForMonitor(monitor); } -float ImGui_ImplWin32_GetDpiScaleForRect(int x1, int y1, int x2, int y2) -{ - RECT viewport_rect = { (LONG)x1, (LONG)y1, (LONG)x2, (LONG)y2 }; - HMONITOR monitor = ::MonitorFromRect(&viewport_rect, MONITOR_DEFAULTTONEAREST); - return ImGui_ImplWin32_GetDpiScaleForMonitor(monitor); -} - //-------------------------------------------------------------------------------------------------------- // IME (Input Method Editor) basic support for e.g. Asian language users //-------------------------------------------------------------------------------------------------------- @@ -589,13 +582,8 @@ static void ImGui_ImplWin32_SetWindowAlpha(ImGuiViewport* viewport, float alpha) static float ImGui_ImplWin32_GetWindowDpiScale(ImGuiViewport* viewport) { ImGuiViewportDataWin32* data = (ImGuiViewportDataWin32*)viewport->PlatformUserData; - if (data && data->Hwnd) - return ImGui_ImplWin32_GetDpiScaleForHwnd(data->Hwnd); - - // The first frame a viewport is created we don't have a window yet - return ImGui_ImplWin32_GetDpiScaleForRect( - (int)(viewport->Pos.x), (int)(viewport->Pos.y), - (int)(viewport->Pos.x + viewport->Size.x), (int)(viewport->Pos.y + viewport->Size.y)); + IM_ASSERT(data->Hwnd != 0); + return ImGui_ImplWin32_GetDpiScaleForHwnd(data->Hwnd); } // FIXME-DPI: Testing DPI related ideas @@ -706,7 +694,7 @@ static void ImGui_ImplWin32_InitPlatformInterface() platform_io.Platform_GetWindowMinimized = ImGui_ImplWin32_GetWindowMinimized; platform_io.Platform_SetWindowTitle = ImGui_ImplWin32_SetWindowTitle; platform_io.Platform_SetWindowAlpha = ImGui_ImplWin32_SetWindowAlpha; - platform_io.Platform_GetWindowDpiScale = ImGui_ImplWin32_GetWindowDpiScale; + platform_io.Platform_GetWindowDpiScale = ImGui_ImplWin32_GetWindowDpiScale; // FIXME-DPI platform_io.Platform_OnChangedViewport = ImGui_ImplWin32_OnChangedViewport; // FIXME-DPI #if HAS_WIN32_IME platform_io.Platform_SetImeInputPos = ImGui_ImplWin32_SetImeInputPos; diff --git a/examples/imgui_impl_win32.h b/examples/imgui_impl_win32.h index 5f1631528..b7c9d8195 100644 --- a/examples/imgui_impl_win32.h +++ b/examples/imgui_impl_win32.h @@ -16,10 +16,9 @@ IMGUI_IMPL_API void ImGui_ImplWin32_Shutdown(); IMGUI_IMPL_API void ImGui_ImplWin32_NewFrame(); // DPI-related helpers (which run and compile without requiring 8.1 or 10, neither Windows version, neither associated SDK) -IMGUI_API void ImGui_ImplWin32_EnableDpiAwareness(); -IMGUI_API float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd); // HWND hwnd -IMGUI_API float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor); // HMONITOR monitor -IMGUI_API float ImGui_ImplWin32_GetDpiScaleForRect(int x1, int y1, int x2, int y2); +IMGUI_IMPL_API void ImGui_ImplWin32_EnableDpiAwareness(); +IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd); // HWND hwnd +IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor); // HMONITOR monitor // Handler for Win32 messages, update mouse/keyboard data. // You may or not need this for your implementation, but it can serve as reference for handling inputs. diff --git a/imgui.cpp b/imgui.cpp index a7db3b7d2..d499d1d81 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7376,8 +7376,10 @@ static void ImGui::UpdateViewports() // Update DPI scale float new_dpi_scale; - if (g.PlatformIO.Platform_GetWindowDpiScale) + if (g.PlatformIO.Platform_GetWindowDpiScale && platform_funcs_available) new_dpi_scale = g.PlatformIO.Platform_GetWindowDpiScale(viewport); + else if (viewport->PlatformMonitor != -1) + new_dpi_scale = g.PlatformIO.Monitors[viewport->PlatformMonitor].DpiScale; else new_dpi_scale = (viewport->DpiScale != 0.0f) ? viewport->DpiScale : 1.0f; if (viewport->DpiScale != 0.0f && new_dpi_scale != viewport->DpiScale) @@ -7490,10 +7492,10 @@ ImGuiViewportP* ImGui::AddUpdateViewport(ImGuiWindow* window, ImGuiID id, const g.DrawListSharedData.ClipRectFullscreen.z = ImMax(g.DrawListSharedData.ClipRectFullscreen.z, viewport->Pos.x + viewport->Size.x); g.DrawListSharedData.ClipRectFullscreen.w = ImMax(g.DrawListSharedData.ClipRectFullscreen.w, viewport->Pos.y + viewport->Size.y); - // Request an initial DpiScale before the OS platform window creation + // Store initial DpiScale before the OS platform window creation, based on expected monitor data. // This is so we can select an appropriate font size on the first frame of our window lifetime - if (g.PlatformIO.Platform_GetWindowDpiScale) - viewport->DpiScale = g.PlatformIO.Platform_GetWindowDpiScale(viewport); + if (viewport->PlatformMonitor != -1) + viewport->DpiScale = g.PlatformIO.Monitors[viewport->PlatformMonitor].DpiScale; } viewport->Window = window; diff --git a/imgui.h b/imgui.h index fc687fbc4..f70b465b2 100644 --- a/imgui.h +++ b/imgui.h @@ -2124,13 +2124,13 @@ struct ImFont // - if you are new to dear imgui and trying to integrate it into your engine, you should probably ignore this for now. //----------------------------------------------------------------------------- -// (Optional) Represent the bounds of each connected monitor/display -// Dear ImGui only uses this to clamp the position of popups and tooltips so they don't straddle multiple monitors. +// (Optional) Represent the bounds of each connected monitor/display and their DPI +// This is used for: multiple DPI support + clamping the position of popups and tooltips so they don't straddle multiple monitors. struct ImGuiPlatformMonitor { ImVec2 MainPos, MainSize; // Coordinates of the area displayed on this monitor (Min = upper left, Max = bottom right) ImVec2 WorkPos, WorkSize; // (Optional) Coordinates without task bars / side bars / menu bars. imgui uses this to avoid positioning popups/tooltips inside this region. - float DpiScale; + float DpiScale; // 1.0f = 96 DPI ImGuiPlatformMonitor() { MainPos = MainSize = WorkPos = WorkSize = ImVec2(0,0); DpiScale = 1.0f; } }; @@ -2165,7 +2165,7 @@ struct ImGuiPlatformIO void (*Platform_SetWindowAlpha)(ImGuiViewport* vp, float alpha); // (Optional) Setup window transparency void (*Platform_RenderWindow)(ImGuiViewport* vp, void* render_arg); // (Optional) Setup for render (platform side) void (*Platform_SwapBuffers)(ImGuiViewport* vp, void* render_arg); // (Optional) Call Present/SwapBuffers (platform side) - float (*Platform_GetWindowDpiScale)(ImGuiViewport* vp); // (Optional) [BETA] (FIXME-DPI) DPI handling: Return DPI scale for this viewport. 1.0f = 96 DPI. IMPORTANT: this will be called _before_ the window is created, in which case the implementation is expected to use the viewport->Pos/Size fields to estimate DPI value. + float (*Platform_GetWindowDpiScale)(ImGuiViewport* vp); // (Optional) [BETA] (FIXME-DPI) DPI handling: Return DPI scale for this viewport. 1.0f = 96 DPI. void (*Platform_OnChangedViewport)(ImGuiViewport* vp); // (Optional) [BETA] (FIXME-DPI) DPI handling: Called during Begin() every time the viewport we are outputting into changes, so back-end has a chance to swap fonts to adjust style. void (*Platform_SetImeInputPos)(ImGuiViewport* vp, ImVec2 pos); // (Optional) Set IME (Input Method Editor, e.g. for Asian languages) input position, so text preview appears over the imgui input box. int (*Platform_CreateVkSurface)(ImGuiViewport* vp, ImU64 vk_inst, const void* vk_allocators, ImU64* out_vk_surface); // (Optional) For Renderer to call into Platform code From 1a6ec208cc9e36127408a45b7954dc0cc74ec67b Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 18 Dec 2018 11:50:14 +0100 Subject: [PATCH 2/4] Docs: various updates, rewording, clarifying the purpose of a PR. --- .github/CONTRIBUTING.md | 1 + .github/pull_request_template.md | 1 + docs/README.md | 46 ++++++++++++++++++++------------ 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 4fe220b91..5bbd8e158 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -33,6 +33,7 @@ You may use the Issue Tracker to submit bug reports, feature requests or suggest If you have been using dear imgui for a while or have been using C/C++ for several years or have demonstrated good behavior here, it is ok to not fullfill every item to the letter. Those are guidelines and experienced users or members of the community will know which information are useful in a given context. ## How to create an Pull Request +- Please understand that by submitting a PR you are also submitting a request for the maintainer to review your code and then take over its maintenance forever. PR should be crafted both in the interest in the end-users and also to ease the maintainer into understanding and accepting it. - When adding a feature, please describe the usage context (how you intend to use it, why you need it, etc.). - When fixing a warning or compilation problem, please post the compiler log and specify the version and OS you are using. - Try to attach screenshots to clarify the context and demonstrate the feature at a glance. You can drag pictures/files here (prefer github attachments over 3rd party hosting). diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 05c68ea68..65ebcf24e 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,4 +1,5 @@ - Please read https://github.com/ocornut/imgui/blob/master/.github/CONTRIBUTING.md +- Please understand that by submitting a PR you are also submitting a request for the maintainer to review your code and then take over its maintenance forever. PR should be crafted both in the interest in the end-users and also to ease the maintainer into understanding and accepting it. - When adding a feature, please describe the usage context (how you intend to use it, why you need it, etc.). - When adding a feature, try to attach screenshots/gifs to clarify the context and demonstrate the feature at a glance. - When fixing a warning or compilation problem, post the compiler log and specify the version and OS you are using. diff --git a/docs/README.md b/docs/README.md index bd7117991..3507d1924 100644 --- a/docs/README.md +++ b/docs/README.md @@ -3,13 +3,16 @@ dear imgui, [![Build Status](https://travis-ci.org/ocornut/imgui.svg?branch=master)](https://travis-ci.org/ocornut/imgui) [![Coverity Status](https://scan.coverity.com/projects/4720/badge.svg)](https://scan.coverity.com/projects/4720) -_(This library is free but needs your support to sustain its development. There are many desirable features and maintenance ahead. If you are an individual using dear imgui, please consider donating via Patreon or PayPal. If your company is using dear imgui, please consider financial support (e.g. sponsoring a few weeks/months of development). I can invoice for technical support, custom development etc. Email: omarcornut at gmail)._ +_(This library is free as in freedom, but needs your support to sustain its development. In addition to maintenance and stability there are many desirable features yet to be added. If your company is using dear imgui, please consider reaching out for invoiced financial support. If you are an individual using dear imgui, please consider donating via Patreon or PayPal.)_ -Monthly donations via Patreon: -
[![Patreon](https://cloud.githubusercontent.com/assets/8225057/5990484/70413560-a9ab-11e4-8942-1a63607c0b00.png)](http://www.patreon.com/imgui) +Individuals/hobbyists: support continued maintenance and development via the monthly Patreon: +
 [![Patreon](https://cloud.githubusercontent.com/assets/8225057/5990484/70413560-a9ab-11e4-8942-1a63607c0b00.png)](http://www.patreon.com/imgui) -One-off donations via PayPal: -
[![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U) +Individuals/hobbyists: support continued maintenance and development via PayPal: +
  [![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U) + +Businesses: support continued maintenance and development via support contracts or sponsoring a few weeks/months of development: +
  _E-mail: omarcornut at gmail dot com_ Dear ImGui is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies). @@ -158,7 +161,7 @@ Some of the goals for 2019 are: - Finish work on docking, tabs. (see [#2109](https://github.com/ocornut/imgui/issues/2109), public branch looking for feedback) - Finish work on multiple viewports / multiple OS windows. (see [#1542](https://github.com/ocornut/imgui/issues/1542), public branch looking for feedback) - Finish work on gamepad/keyboard controls. (see [#787](https://github.com/ocornut/imgui/issues/787)) -- Add an automation and testing system, both to test the library and end-user apps. +- Add an automation and testing system, both to test the library and end-user apps. (see [#435](https://github.com/ocornut/imgui/issues/435)) - Make Columns better. (they are currently pretty terrible!) - Make the examples look better, improve styles, improve font support, make the examples hi-DPI aware. @@ -291,30 +294,39 @@ There is an auto-generated [c-api for Dear ImGui (cimgui)](https://github.com/ci Support dear imgui ------------------ +**How can I help?** + +- You may participate in the Discourse and GitHub [issues trackers](https://github.com/ocornut/imgui/issues). +- You may help with development and submit pull requests! Please understand that by submitting a PR you are also submitting a request for the maintainer to review your code and then take over its maintenance forever. PR should be crafted both in the interest in the end-users and also to ease the maintainer into understanding and accepting it. +- See [Help wanted](https://github.com/ocornut/imgui/wiki/Help-Wanted) on the Wiki for some more ideas. +- Convince your company to financially support this project. + **How can I help financing further development of Dear ImGui?** -Your contributions are keeping the library alive. If you are an individual using dear imgui, please consider donating to enable me to spend more time improving the library. +Your contributions are keeping this project alive. The library is free as in freedom, but continued maintenance and development are a full-time endeavor. In addition to maintenance and stability there are many desirable features yet to be added. If your company is using dear imgui, please consider reaching out for invoiced financial support. If you are an individual using dear imgui, please consider donating via Patreon or PayPal. Thank you! -Monthly donations via Patreon: -
[![Patreon](https://cloud.githubusercontent.com/assets/8225057/5990484/70413560-a9ab-11e4-8942-1a63607c0b00.png)](http://www.patreon.com/imgui) +Individuals/hobbyists: support continued maintenance and development via the monthly Patreon: +
 [![Patreon](https://cloud.githubusercontent.com/assets/8225057/5990484/70413560-a9ab-11e4-8942-1a63607c0b00.png)](http://www.patreon.com/imgui) -One-off donations via PayPal: -
[![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U) +Individuals/hobbyists: support continued maintenance and development via PayPal: +
  [![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U) -Ongoing dear imgui development is financially supported on [**Patreon**](http://www.patreon.com/imgui) and by private sponsors. -If your company uses dear imgui, please consider financial support (e.g. sponsoring a few weeks/months of development. I can also invoice for private support, custom development etc. contact me for details: omarcornut at gmail). Thanks! +Businesses: support continued maintenance and development via support contracts or sponsoring a few weeks/months of development: +
  _E-mail: omarcornut at gmail dot com_ + +Ongoing dear imgui development is financially supported by users and private sponsors (past and present): **Platinum-chocolate sponsors** -- Blizzard Entertainment. +- **Blizzard Entertainment**. **Double-chocolate sponsors** -- Media Molecule, Mobigame, Insomniac Games, Aras Pranckevičius, Lizardcube, Greggman, DotEmu, Nadeo, Supercell, Runner. +- Media Molecule, Mobigame, Insomniac Games, Aras Pranckevičius, Lizardcube, Greggman, DotEmu, Nadeo, Supercell, Runner, Aiden Koss. **Salty caramel supporters** -- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko, Mercury Labs, Singularity Demo Group, Mischa Alff, Sebastien Ronsse, Lionel Landwerlin, Nikolay Ivanov, Ron Gilbert, Brandon Townsend, Nikhil Deshpande, Cort Stratton, drudru, Harfang 3D, Jeff Roberts. +- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko, Mercury Labs, Singularity Demo Group, Mischa Alff, Sebastien Ronsse, Lionel Landwerlin, Nikolay Ivanov, Ron Gilbert, Brandon Townsend, Nikhil Deshpande, Cort Stratton, drudru, Harfang 3D, Jeff Roberts, Rainway inc. **Caramel supporters** -- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, Kit framework, Josh Faust, Martin Donlon, Quinton, Felix, Andrew Belt, Codecat, Cort Stratton, Claudio Canepa, Doug McNabb, Emmanuel Julien, Guillaume Chereau, Jeffrey Slutter, Jeremiah Deckard, r-lyeh, Roger Clark, Nekith, Joshua Fisher, Malte Hoffmann, Mustafa Karaalioglu, Merlyn Morgan-Graham, Per Vognsen, Fabian Giesen, Jan Staubach, Matt Hargett, John Shearer, Jesse Chounard, kingcoopa, Miloš Tošić, Jonas Bernemann, Johan Andersson, Nathan Hartman, Michael Labbe, Tomasz Golebiowski, Louis Schnellbach, Felipe Alfonso, Jimmy Andrews, Bojan Endrovski, Robin Berg Pettersen, Rachel Crawford, Edsel Malasig, Andrew Johnson, Sean Hunter, Jordan Mellow, Nefarius Software Solutions, Laura Wieme, Robert Nix, Mick Honey, Astrofra, Jonas Lehmann, Steven Kah Hien Wong, Bartosz Bielecki, Oscar Penas, A M, Liam Moynihan, Artometa. +- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, Kit framework, Josh Faust, Martin Donlon, Quinton, Felix, Andrew Belt, Codecat, Cort Stratton, Claudio Canepa, Doug McNabb, Emmanuel Julien, Guillaume Chereau, Jeffrey Slutter, Jeremiah Deckard, r-lyeh, Roger Clark, Nekith, Joshua Fisher, Malte Hoffmann, Mustafa Karaalioglu, Merlyn Morgan-Graham, Per Vognsen, Fabian Giesen, Jan Staubach, Matt Hargett, John Shearer, Jesse Chounard, kingcoopa, Miloš Tošić, Jonas Bernemann, Johan Andersson, Nathan Hartman, Michael Labbe, Tomasz Golebiowski, Louis Schnellbach, Felipe Alfonso, Jimmy Andrews, Bojan Endrovski, Robin Berg Pettersen, Rachel Crawford, Edsel Malasig, Andrew Johnson, Sean Hunter, Jordan Mellow, Nefarius Software Solutions, Laura Wieme, Robert Nix, Mick Honey, Astrofra, Jonas Lehmann, Steven Kah Hien Wong, Bartosz Bielecki, Oscar Penas, A M, Liam Moynihan, Artometa, Mark Lee, Dimitri Diakopoulos. And all other supporters; THANK YOU! (Please contact me if you would like to be added or removed from this list) From 510ca373a2286a498349d971318a6bbc98324864 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 18 Dec 2018 14:21:10 +0100 Subject: [PATCH 3/4] Moved setting up NavHideHighlightOneFrame from lower-level ClosePopupToLevel() to CloseCurrentPopup() with an explanation. (Followup on 68d3e139a74ed9d7cad4abb0f36466544ef24620) --- imgui.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 3d019dbc1..637bc5cd0 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6557,7 +6557,6 @@ void ImGui::ClosePopupToLevel(int remaining) if (g.NavLayer == 0) focus_window = NavRestoreLastChildNavWindow(focus_window); FocusWindow(focus_window); - focus_window->DC.NavHideHighlightOneFrame = true; g.OpenPopupStack.resize(remaining); } @@ -6571,6 +6570,12 @@ void ImGui::CloseCurrentPopup() while (popup_idx > 0 && g.OpenPopupStack[popup_idx].Window && (g.OpenPopupStack[popup_idx].Window->Flags & ImGuiWindowFlags_ChildMenu)) popup_idx--; ClosePopupToLevel(popup_idx); + + // A common pattern is to close a popup when selecting a menu item/selectable that will open another window. + // To improve this usage pattern, we avoid nav highlight for a single frame in the parent window. + // Similarly, we could avoid mouse hover highlight in this window but it is less visually problematic. + if (ImGuiWindow* window = g.NavWindow) + window->DC.NavHideHighlightOneFrame = true; } bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags) From ae76a1fda7e0caccad70b03933dcdf0199810d88 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 18 Dec 2018 14:58:35 +0100 Subject: [PATCH 4/4] Window, Focus, Popup: Fixed an issue where closing a popup by clicking another window with the _NoMove flag would refocus the parent window of the popup instead of the newly clicked window. --- docs/CHANGELOG.txt | 2 ++ imgui.cpp | 26 +++++++++++++++++++------- imgui_internal.h | 2 +- imgui_widgets.cpp | 4 ++-- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 9b3032332..b8419caa4 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -50,6 +50,8 @@ Other Changes: (It does not provide the docking/splitting/merging of windows available in the Docking branch) - Added ImGuiWindowFlags_UnsavedDocument window flag to append '*' to title without altering the ID, as a convenience to avoid using the ### operator. +- Window, Focus, Popup: Fixed an issue where closing a popup by clicking another window with the _NoMove flag would refocus + the parent window of the popup instead of the newly clicked window. - Window: Contents size is preserved while a window collapsed. Fix auto-resizing window losing their size for one frame when uncollapsed. - Window: Contents size is preserved while a window contents is hidden (unless it is hidden for resizing purpose). - Window: Resizing windows from edge is now enabled by default (io.ConfigWindowsResizeFromEdges=true). Note that diff --git a/imgui.cpp b/imgui.cpp index 637bc5cd0..caa852650 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6545,19 +6545,31 @@ void ImGui::ClosePopupsOverWindow(ImGuiWindow* ref_window) if (popup_count_to_keep < g.OpenPopupStack.Size) // This test is not required but it allows to set a convenient breakpoint on the statement below { //IMGUI_DEBUG_LOG("ClosePopupsOverWindow(%s) -> ClosePopupToLevel(%d)\n", ref_window->Name, popup_count_to_keep); - ClosePopupToLevel(popup_count_to_keep); + ClosePopupToLevel(popup_count_to_keep, false); } } -void ImGui::ClosePopupToLevel(int remaining) +void ImGui::ClosePopupToLevel(int remaining, bool apply_focus_to_window_under) { IM_ASSERT(remaining >= 0); ImGuiContext& g = *GImGui; ImGuiWindow* focus_window = (remaining > 0) ? g.OpenPopupStack[remaining-1].Window : g.OpenPopupStack[0].ParentWindow; - if (g.NavLayer == 0) - focus_window = NavRestoreLastChildNavWindow(focus_window); - FocusWindow(focus_window); g.OpenPopupStack.resize(remaining); + + // FIXME: This code is faulty and we may want to eventually to replace or remove the 'apply_focus_to_window_under=true' path completely. + // Instead of using g.OpenPopupStack[remaining-1].Window etc. we should find the highest root window that is behind the popups we are closing. + // The current code will set focus to the parent of the popup window which is incorrect. + // It rarely manifested until now because UpdateMouseMovingWindow() would call FocusWindow() again on the clicked window, + // leading to a chain of focusing A (clicked window) then B (parent window of the popup) then A again. + // However if the clicked window has the _NoMove flag set we would be left with B focused. + // For now, we have disabled this path when called from ClosePopupsOverWindow() because the users of ClosePopupsOverWindow() don't need to alter focus anyway, + // but we should inspect and fix this properly. + if (apply_focus_to_window_under) + { + if (g.NavLayer == 0) + focus_window = NavRestoreLastChildNavWindow(focus_window); + FocusWindow(focus_window); + } } // Close the popup we have begin-ed into. @@ -6569,7 +6581,7 @@ void ImGui::CloseCurrentPopup() return; while (popup_idx > 0 && g.OpenPopupStack[popup_idx].Window && (g.OpenPopupStack[popup_idx].Window->Flags & ImGuiWindowFlags_ChildMenu)) popup_idx--; - ClosePopupToLevel(popup_idx); + ClosePopupToLevel(popup_idx, true); // A common pattern is to close a popup when selecting a menu item/selectable that will open another window. // To improve this usage pattern, we avoid nav highlight for a single frame in the parent window. @@ -6636,7 +6648,7 @@ bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags fla { EndPopup(); if (is_open) - ClosePopupToLevel(g.BeginPopupStack.Size); + ClosePopupToLevel(g.BeginPopupStack.Size, true); return false; } return is_open; diff --git a/imgui_internal.h b/imgui_internal.h index 53408f12f..60704564f 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1297,7 +1297,7 @@ namespace ImGui // Popups, Modals, Tooltips IMGUI_API void OpenPopupEx(ImGuiID id); - IMGUI_API void ClosePopupToLevel(int remaining); + IMGUI_API void ClosePopupToLevel(int remaining, bool apply_focus_to_window_under); IMGUI_API void ClosePopupsOverWindow(ImGuiWindow* ref_window); IMGUI_API bool IsPopupOpen(ImGuiID id); // Test for id within current popup stack level (currently begin-ed into); this doesn't scan the whole popup stack! IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags); diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 367c4df9f..367b9bb61 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -5657,7 +5657,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) if (!enabled) // explicitly close if an open menu becomes disabled, facilitate users code a lot in pattern such as 'if (BeginMenu("options", has_object)) { ..use object.. }' want_close = true; if (want_close && IsPopupOpen(id)) - ClosePopupToLevel(g.BeginPopupStack.Size); + ClosePopupToLevel(g.BeginPopupStack.Size, true); IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.ItemFlags | ImGuiItemStatusFlags_Openable | (menu_is_open ? ImGuiItemStatusFlags_Opened : 0)); @@ -5694,7 +5694,7 @@ void ImGui::EndMenu() ImGuiWindow* window = g.CurrentWindow; if (g.NavWindow && g.NavWindow->ParentWindow == window && g.NavMoveDir == ImGuiDir_Left && NavMoveRequestButNoResultYet() && window->DC.LayoutType == ImGuiLayoutType_Vertical) { - ClosePopupToLevel(g.BeginPopupStack.Size); + ClosePopupToLevel(g.BeginPopupStack.Size, true); NavMoveRequestCancel(); }