소스 검색

Merge branch 'master' into docking

# Conflicts:
#	docs/CHANGELOG.txt
#	imgui.cpp
#	imgui.h
#	imgui_draw.cpp
ocornut 3 년 전
부모
커밋
9948535118

+ 14 - 14
.github/workflows/build.yml

@@ -246,7 +246,7 @@ jobs:
           #include "examples/example_null/main.cpp"
           #include "examples/example_null/main.cpp"
 
 
           EOF
           EOF
-          g++ -I. -Wall -Wformat -Wextra -Werror -Wno-zero-as-null-pointer-constant -Wno-double-promotion -Wno-variadic-macros -Wno-empty-body -o example_single_file example_single_file.cpp
+          g++ -I. -std=c++11 -Wall -Wformat -Wextra -Werror -Wno-zero-as-null-pointer-constant -Wno-double-promotion -Wno-variadic-macros -Wno-empty-body -o example_single_file example_single_file.cpp
 
 
     - name: Build example_null (freetype)
     - name: Build example_null (freetype)
       run: |
       run: |
@@ -262,7 +262,7 @@ jobs:
         #include "examples/example_null/main.cpp"
         #include "examples/example_null/main.cpp"
 
 
         EOF
         EOF
-        g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
+        g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
 
 
     - name: Build example_null (with ImWchar32)
     - name: Build example_null (with ImWchar32)
       run: |
       run: |
@@ -274,7 +274,7 @@ jobs:
         #include "examples/example_null/main.cpp"
         #include "examples/example_null/main.cpp"
 
 
         EOF
         EOF
-        g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
+        g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
 
 
     - name: Build example_null (with large ImDrawIdx + pointer ImTextureID)
     - name: Build example_null (with large ImDrawIdx + pointer ImTextureID)
       run: |
       run: |
@@ -287,7 +287,7 @@ jobs:
         #include "examples/example_null/main.cpp"
         #include "examples/example_null/main.cpp"
 
 
         EOF
         EOF
-        g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
+        g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
 
 
     - name: Build example_null (with IMGUI_DISABLE_OBSOLETE_FUNCTIONS)
     - name: Build example_null (with IMGUI_DISABLE_OBSOLETE_FUNCTIONS)
       run: |
       run: |
@@ -299,7 +299,7 @@ jobs:
         #include "examples/example_null/main.cpp"
         #include "examples/example_null/main.cpp"
 
 
         EOF
         EOF
-        g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
+        g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
 
 
     - name: Build example_null (with IMGUI_DISABLE_OBSOLETE_KEYIO)
     - name: Build example_null (with IMGUI_DISABLE_OBSOLETE_KEYIO)
       run: |
       run: |
@@ -311,7 +311,7 @@ jobs:
         #include "examples/example_null/main.cpp"
         #include "examples/example_null/main.cpp"
 
 
         EOF
         EOF
-        g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
+        g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
 
 
     - name: Build example_null (with IMGUI_DISABLE_DEMO_WINDOWS and IMGUI_DISABLE_METRICS_WINDOW)
     - name: Build example_null (with IMGUI_DISABLE_DEMO_WINDOWS and IMGUI_DISABLE_METRICS_WINDOW)
       run: |
       run: |
@@ -324,7 +324,7 @@ jobs:
         #include "examples/example_null/main.cpp"
         #include "examples/example_null/main.cpp"
 
 
         EOF
         EOF
-        g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
+        g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
 
 
     - name: Build example_null (with IMGUI_DISABLE_FILE_FUNCTIONS)
     - name: Build example_null (with IMGUI_DISABLE_FILE_FUNCTIONS)
       run: |
       run: |
@@ -336,7 +336,7 @@ jobs:
         #include "examples/example_null/main.cpp"
         #include "examples/example_null/main.cpp"
 
 
         EOF
         EOF
-        g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
+        g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
 
 
     - name: Build example_null (with IMGUI_USE_BGRA_PACKED_COLOR)
     - name: Build example_null (with IMGUI_USE_BGRA_PACKED_COLOR)
       run: |
       run: |
@@ -348,7 +348,7 @@ jobs:
         #include "examples/example_null/main.cpp"
         #include "examples/example_null/main.cpp"
 
 
         EOF
         EOF
-        g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
+        g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
 
 
     - name: Build example_null (with IM_VEC2_CLASS_EXTRA and IM_VEC4_CLASS_EXTRA)
     - name: Build example_null (with IM_VEC2_CLASS_EXTRA and IM_VEC4_CLASS_EXTRA)
       run: |
       run: |
@@ -368,7 +368,7 @@ jobs:
         #include "examples/example_null/main.cpp"
         #include "examples/example_null/main.cpp"
 
 
         EOF
         EOF
-        g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
+        g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
 
 
     - name: Build example_null (without c++ runtime, Clang)
     - name: Build example_null (without c++ runtime, Clang)
       run: |
       run: |
@@ -380,7 +380,7 @@ jobs:
         #include "examples/example_null/main.cpp"
         #include "examples/example_null/main.cpp"
 
 
         EOF
         EOF
-        clang++ -I. -Wall -Wformat -nodefaultlibs -fno-rtti -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp
+        clang++ -I. -std=c++11 -Wall -Wformat -nodefaultlibs -fno-rtti -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp
 
 
     - name: Build example_glfw_opengl2
     - name: Build example_glfw_opengl2
       run: make -C examples/example_glfw_opengl2
       run: make -C examples/example_glfw_opengl2
@@ -397,7 +397,7 @@ jobs:
       run: make -C examples/example_sdl_opengl3
       run: make -C examples/example_sdl_opengl3
 
 
     - name: Build with IMGUI_IMPL_VULKAN_NO_PROTOTYPES
     - name: Build with IMGUI_IMPL_VULKAN_NO_PROTOTYPES
-      run: g++ -c -I. -DIMGUI_IMPL_VULKAN_NO_PROTOTYPES=1 backends/imgui_impl_vulkan.cpp
+      run: g++ -c -I. -std=c++11 -DIMGUI_IMPL_VULKAN_NO_PROTOTYPES=1 backends/imgui_impl_vulkan.cpp
 
 
   MacOS:
   MacOS:
     runs-on: macos-latest
     runs-on: macos-latest
@@ -420,7 +420,7 @@ jobs:
         #include "examples/example_null/main.cpp"
         #include "examples/example_null/main.cpp"
 
 
         EOF
         EOF
-        clang++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
+        clang++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
 
 
     - name: Build example_null (without c++ runtime)
     - name: Build example_null (without c++ runtime)
       run: |
       run: |
@@ -431,7 +431,7 @@ jobs:
         #include "examples/example_null/main.cpp"
         #include "examples/example_null/main.cpp"
 
 
         EOF
         EOF
-        clang++ -I. -Wall -Wformat -nodefaultlibs -fno-rtti -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp
+        clang++ -I. -std=c++11 -Wall -Wformat -nodefaultlibs -fno-rtti -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp
 
 
     - name: Build example_glfw_opengl2
     - name: Build example_glfw_opengl2
       run: make -C examples/example_glfw_opengl2
       run: make -C examples/example_glfw_opengl2

+ 16 - 0
docs/CHANGELOG.txt

@@ -102,6 +102,22 @@ Other changes:
  VERSION 1.88 WIP (In Progress)
  VERSION 1.88 WIP (In Progress)
 -----------------------------------------------------------------------
 -----------------------------------------------------------------------
 
 
+Breaking changes:
+
+Other Changes:
+
+- Clipper: Fixed a regression in 1.86 when not calling clipper.End() and late destructing the
+  clipper instance. High-level languages (Lua,Rust etc.) would typically be affected. (#4822)
+- IsItemHovered(): added ImGuiHoveredFlags_NoNavOverride to disable the behavior where the
+  return value is overriden by focus when gamepad/keyboard navigation is active.
+- Inputs: Fixed IsMouseClicked() repeat mode rate being half of keyboard repeat rate.
+- Stack Tool: Added option to copy item path to clipboard. (#4631)
+- Misc: Fixed IsAnyItemHovered() returning false when using navigation.
+- Misc: Added constexpr to ImVec2/ImVec4 inline constructors. (#4995) [@Myriachan]
+- Misc: binary_to_compressed_c tool: Added -nostatic option. (#5021) [@podsvirov]
+- ImVector: Fixed erase() with empty range. (#5009) [@thedmd]
+- Drawlist: Fixed PathArcTo() emitting terminating vertices too close to arc vertices. (#4993) [@thedmd]
+
 Docking+Viewports Branch:
 Docking+Viewports Branch:
 
 
 - Viewports: Fixed main viewport size not matching ImDrawData::DisplaySize for one frame during resize
 - Viewports: Fixed main viewport size not matching ImDrawData::DisplaySize for one frame during resize

+ 1 - 1
examples/example_glfw_metal/Makefile

@@ -17,7 +17,7 @@ LIBS = -framework Metal -framework MetalKit -framework Cocoa -framework IOKit -f
 LIBS += -L/usr/local/lib -L/opt/homebrew/lib
 LIBS += -L/usr/local/lib -L/opt/homebrew/lib
 LIBS += -lglfw
 LIBS += -lglfw
 
 
-CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends -I/usr/local/include -I/opt/homebrew/include
+CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends -I/usr/local/include -I/opt/homebrew/include
 CXXFLAGS += -Wall -Wformat
 CXXFLAGS += -Wall -Wformat
 CFLAGS = $(CXXFLAGS)
 CFLAGS = $(CXXFLAGS)
 
 

+ 1 - 1
examples/example_glfw_opengl2/Makefile

@@ -22,7 +22,7 @@ SOURCES += $(IMGUI_DIR)/backends/imgui_impl_glfw.cpp $(IMGUI_DIR)/backends/imgui
 OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
 OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
 UNAME_S := $(shell uname -s)
 UNAME_S := $(shell uname -s)
 
 
-CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
+CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
 CXXFLAGS += -g -Wall -Wformat
 CXXFLAGS += -g -Wall -Wformat
 LIBS =
 LIBS =
 
 

+ 1 - 1
examples/example_glfw_opengl3/Makefile

@@ -23,7 +23,7 @@ OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
 UNAME_S := $(shell uname -s)
 UNAME_S := $(shell uname -s)
 LINUX_GL_LIBS = -lGL
 LINUX_GL_LIBS = -lGL
 
 
-CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
+CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
 CXXFLAGS += -g -Wall -Wformat
 CXXFLAGS += -g -Wall -Wformat
 LIBS =
 LIBS =
 
 

+ 1 - 1
examples/example_glut_opengl2/Makefile

@@ -17,7 +17,7 @@ SOURCES += $(IMGUI_DIR)/backends/imgui_impl_glut.cpp $(IMGUI_DIR)/backends/imgui
 OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
 OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
 UNAME_S := $(shell uname -s)
 UNAME_S := $(shell uname -s)
 
 
-CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
+CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
 CXXFLAGS += -g -Wall -Wformat
 CXXFLAGS += -g -Wall -Wformat
 LIBS =
 LIBS =
 
 

+ 2 - 2
examples/example_null/Makefile

@@ -17,7 +17,7 @@ SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui
 OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
 OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
 UNAME_S := $(shell uname -s)
 UNAME_S := $(shell uname -s)
 
 
-CXXFLAGS += -I$(IMGUI_DIR)
+CXXFLAGS += -std=c++11 -I$(IMGUI_DIR)
 CXXFLAGS += -g -Wall -Wformat
 CXXFLAGS += -g -Wall -Wformat
 LIBS =
 LIBS =
 
 
@@ -52,7 +52,7 @@ endif
 ifeq ($(UNAME_S), Darwin) #APPLE
 ifeq ($(UNAME_S), Darwin) #APPLE
 	ECHO_MESSAGE = "Mac OS X"
 	ECHO_MESSAGE = "Mac OS X"
 	ifeq ($(WITH_EXTRA_WARNINGS), 1)
 	ifeq ($(WITH_EXTRA_WARNINGS), 1)
-		CXXFLAGS += -Weverything -Wno-reserved-id-macro -Wno-c++98-compat-pedantic -Wno-padded -Wno-c++11-long-long -Wno-poison-system-directories
+		CXXFLAGS += -Weverything -Wno-reserved-id-macro -Wno-c++98-compat-pedantic -Wno-padded -Wno-poison-system-directories
 	endif
 	endif
 	CFLAGS = $(CXXFLAGS)
 	CFLAGS = $(CXXFLAGS)
 endif
 endif

+ 1 - 1
examples/example_sdl_metal/Makefile

@@ -17,7 +17,7 @@ LIBS = -framework Metal -framework MetalKit -framework Cocoa -framework IOKit -f
 LIBS += `sdl2-config --libs`
 LIBS += `sdl2-config --libs`
 LIBS += -L/usr/local/lib
 LIBS += -L/usr/local/lib
 
 
-CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends -I/usr/local/include
+CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends -I/usr/local/include
 CXXFLAGS += `sdl2-config --cflags`
 CXXFLAGS += `sdl2-config --cflags`
 CXXFLAGS += -Wall -Wformat
 CXXFLAGS += -Wall -Wformat
 CFLAGS = $(CXXFLAGS)
 CFLAGS = $(CXXFLAGS)

+ 1 - 1
examples/example_sdl_opengl2/Makefile

@@ -22,7 +22,7 @@ SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl.cpp $(IMGUI_DIR)/backends/imgui_
 OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
 OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
 UNAME_S := $(shell uname -s)
 UNAME_S := $(shell uname -s)
 
 
-CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
+CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
 CXXFLAGS += -g -Wall -Wformat
 CXXFLAGS += -g -Wall -Wformat
 LIBS =
 LIBS =
 
 

+ 1 - 1
examples/example_sdl_opengl3/Makefile

@@ -23,7 +23,7 @@ OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
 UNAME_S := $(shell uname -s)
 UNAME_S := $(shell uname -s)
 LINUX_GL_LIBS = -lGL
 LINUX_GL_LIBS = -lGL
 
 
-CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
+CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
 CXXFLAGS += -g -Wall -Wformat
 CXXFLAGS += -g -Wall -Wformat
 LIBS =
 LIBS =
 
 

+ 1 - 1
examples/example_sdl_sdlrenderer/Makefile

@@ -22,7 +22,7 @@ SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl.cpp $(IMGUI_DIR)/backends/imgui_
 OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
 OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
 UNAME_S := $(shell uname -s)
 UNAME_S := $(shell uname -s)
 
 
-CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
+CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
 CXXFLAGS += -g -Wall -Wformat
 CXXFLAGS += -g -Wall -Wformat
 LIBS =
 LIBS =
 
 

+ 4 - 4
imconfig.h

@@ -81,12 +81,12 @@
 //---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
 //---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
 // This will be inlined as part of ImVec2 and ImVec4 class declarations.
 // This will be inlined as part of ImVec2 and ImVec4 class declarations.
 /*
 /*
-#define IM_VEC2_CLASS_EXTRA                                                 \
-        ImVec2(const MyVec2& f) { x = f.x; y = f.y; }                       \
+#define IM_VEC2_CLASS_EXTRA                                                     \
+        constexpr ImVec2(const MyVec2& f) : x(f.x), y(f.y) {}                   \
         operator MyVec2() const { return MyVec2(x,y); }
         operator MyVec2() const { return MyVec2(x,y); }
 
 
-#define IM_VEC4_CLASS_EXTRA                                                 \
-        ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; }     \
+#define IM_VEC4_CLASS_EXTRA                                                     \
+        constexpr ImVec4(const MyVec4& f) : x(f.x), y(f.y), z(f.z), w(f.w) {}   \
         operator MyVec4() const { return MyVec4(x,y,z,w); }
         operator MyVec4() const { return MyVec4(x,y,z,w); }
 */
 */
 
 

+ 74 - 52
imgui.cpp

@@ -1,4 +1,4 @@
-// dear imgui, v1.87
+// dear imgui, 1.88 WIP
 // (main code and documentation)
 // (main code and documentation)
 
 
 // Help:
 // Help:
@@ -1216,7 +1216,7 @@ void ImGuiIO::AddInputCharacter(unsigned int c)
         return;
         return;
 
 
     ImGuiInputEvent e;
     ImGuiInputEvent e;
-    e.Type = ImGuiInputEventType_Char;
+    e.Type = ImGuiInputEventType_Text;
     e.Source = ImGuiInputSource_Keyboard;
     e.Source = ImGuiInputSource_Keyboard;
     e.Text.Char = c;
     e.Text.Char = c;
     g.InputEventsQueue.push_back(e);
     g.InputEventsQueue.push_back(e);
@@ -1286,7 +1286,7 @@ void ImGuiIO::ClearInputKeys()
         KeysData[n].DownDurationPrev = -1.0f;
         KeysData[n].DownDurationPrev = -1.0f;
     }
     }
     KeyCtrl = KeyShift = KeyAlt = KeySuper = false;
     KeyCtrl = KeyShift = KeyAlt = KeySuper = false;
-    KeyMods = KeyModsPrev = ImGuiKeyModFlags_None;
+    KeyMods = ImGuiKeyModFlags_None;
     for (int n = 0; n < IM_ARRAYSIZE(NavInputsDownDuration); n++)
     for (int n = 0; n < IM_ARRAYSIZE(NavInputsDownDuration); n++)
         NavInputsDownDuration[n] = NavInputsDownDurationPrev[n] = -1.0f;
         NavInputsDownDuration[n] = NavInputsDownDurationPrev[n] = -1.0f;
 }
 }
@@ -2614,15 +2614,14 @@ void ImGuiListClipper::Begin(int items_count, float items_height)
 
 
 void ImGuiListClipper::End()
 void ImGuiListClipper::End()
 {
 {
-    // In theory here we should assert that we are already at the right position, but it seems saner to just seek at the end and not assert/crash the user.
     ImGuiContext& g = *GImGui;
     ImGuiContext& g = *GImGui;
-    if (ItemsCount >= 0 && ItemsCount < INT_MAX && DisplayStart >= 0)
-        ImGuiListClipper_SeekCursorForItem(this, ItemsCount);
-    ItemsCount = -1;
-
-    // Restore temporary buffer and fix back pointers which may be invalidated when nesting
     if (ImGuiListClipperData* data = (ImGuiListClipperData*)TempData)
     if (ImGuiListClipperData* data = (ImGuiListClipperData*)TempData)
     {
     {
+        // In theory here we should assert that we are already at the right position, but it seems saner to just seek at the end and not assert/crash the user.
+        if (ItemsCount >= 0 && ItemsCount < INT_MAX && DisplayStart >= 0)
+            ImGuiListClipper_SeekCursorForItem(this, ItemsCount);
+
+        // Restore temporary buffer and fix back pointers which may be invalidated when nesting
         IM_ASSERT(data->ListClipper == this);
         IM_ASSERT(data->ListClipper == this);
         data->StepNo = data->Ranges.Size;
         data->StepNo = data->Ranges.Size;
         if (--g.ClipperTempDataStacked > 0)
         if (--g.ClipperTempDataStacked > 0)
@@ -2632,6 +2631,7 @@ void ImGuiListClipper::End()
         }
         }
         TempData = NULL;
         TempData = NULL;
     }
     }
+    ItemsCount = -1;
 }
 }
 
 
 void ImGuiListClipper::ForceDisplayRangeByIndices(int item_min, int item_max)
 void ImGuiListClipper::ForceDisplayRangeByIndices(int item_min, int item_max)
@@ -2764,8 +2764,8 @@ bool ImGuiListClipper::Step()
     // Advance the cursor to the end of the list and then returns 'false' to end the loop.
     // Advance the cursor to the end of the list and then returns 'false' to end the loop.
     if (ItemsCount < INT_MAX)
     if (ItemsCount < INT_MAX)
         ImGuiListClipper_SeekCursorForItem(this, ItemsCount);
         ImGuiListClipper_SeekCursorForItem(this, ItemsCount);
-    ItemsCount = -1;
 
 
+    End();
     return false;
     return false;
 }
 }
 
 
@@ -3544,7 +3544,7 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
 {
 {
     ImGuiContext& g = *GImGui;
     ImGuiContext& g = *GImGui;
     ImGuiWindow* window = g.CurrentWindow;
     ImGuiWindow* window = g.CurrentWindow;
-    if (g.NavDisableMouseHover && !g.NavDisableHighlight)
+    if (g.NavDisableMouseHover && !g.NavDisableHighlight && !(flags & ImGuiHoveredFlags_NoNavOverride))
     {
     {
         if ((g.LastItemData.InFlags & ImGuiItemFlags_Disabled) && !(flags & ImGuiHoveredFlags_AllowWhenDisabled))
         if ((g.LastItemData.InFlags & ImGuiItemFlags_Disabled) && !(flags & ImGuiHoveredFlags_AllowWhenDisabled))
             return false;
             return false;
@@ -3607,8 +3607,6 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id)
         return false;
         return false;
     if (!IsMouseHoveringRect(bb.Min, bb.Max))
     if (!IsMouseHoveringRect(bb.Min, bb.Max))
         return false;
         return false;
-    if (g.NavDisableMouseHover)
-        return false;
     if (!IsWindowContentHoverable(window, ImGuiHoveredFlags_None))
     if (!IsWindowContentHoverable(window, ImGuiHoveredFlags_None))
     {
     {
         g.HoveredIdDisabled = true;
         g.HoveredIdDisabled = true;
@@ -3644,6 +3642,9 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id)
             IM_DEBUG_BREAK();
             IM_DEBUG_BREAK();
     }
     }
 
 
+    if (g.NavDisableMouseHover)
+        return false;
+
     return true;
     return true;
 }
 }
 
 
@@ -4089,9 +4090,6 @@ static void ImGui::UpdateKeyboardInputs()
     ImGuiContext& g = *GImGui;
     ImGuiContext& g = *GImGui;
     ImGuiIO& io = g.IO;
     ImGuiIO& io = g.IO;
 
 
-    // Synchronize io.KeyMods with individual modifiers io.KeyXXX bools
-    io.KeyMods = GetMergedKeyModFlags();
-
     // Import legacy keys or verify they are not used
     // Import legacy keys or verify they are not used
 #ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
 #ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
     if (io.BackendUsingLegacyKeyArrays == 0)
     if (io.BackendUsingLegacyKeyArrays == 0)
@@ -4133,6 +4131,9 @@ static void ImGui::UpdateKeyboardInputs()
     }
     }
 #endif
 #endif
 
 
+    // Synchronize io.KeyMods with individual modifiers io.KeyXXX bools
+    io.KeyMods = GetMergedKeyModFlags();
+
     // Clear gamepad data if disabled
     // Clear gamepad data if disabled
     if ((io.BackendFlags & ImGuiBackendFlags_HasGamepad) == 0)
     if ((io.BackendFlags & ImGuiBackendFlags_HasGamepad) == 0)
         for (int i = ImGuiKey_Gamepad_BEGIN; i < ImGuiKey_Gamepad_END; i++)
         for (int i = ImGuiKey_Gamepad_BEGIN; i < ImGuiKey_Gamepad_END; i++)
@@ -5107,7 +5108,6 @@ void ImGui::EndFrame()
     // Clear Input data for next frame
     // Clear Input data for next frame
     g.IO.MouseWheel = g.IO.MouseWheelH = 0.0f;
     g.IO.MouseWheel = g.IO.MouseWheelH = 0.0f;
     g.IO.InputQueueCharacters.resize(0);
     g.IO.InputQueueCharacters.resize(0);
-    g.IO.KeyModsPrev = g.IO.KeyMods; // doing it here is better than in NewFrame() as we'll tolerate backend writing to KeyMods. If we want to firmly disallow it we should detect it.
     memset(g.IO.NavInputs, 0, sizeof(g.IO.NavInputs));
     memset(g.IO.NavInputs, 0, sizeof(g.IO.NavInputs));
 
 
     CallContextHooks(&g, ImGuiContextHookType_EndFramePost);
     CallContextHooks(&g, ImGuiContextHookType_EndFramePost);
@@ -8254,14 +8254,8 @@ bool ImGui::IsMouseClicked(ImGuiMouseButton button, bool repeat)
     const float t = g.IO.MouseDownDuration[button];
     const float t = g.IO.MouseDownDuration[button];
     if (t == 0.0f)
     if (t == 0.0f)
         return true;
         return true;
-
     if (repeat && t > g.IO.KeyRepeatDelay)
     if (repeat && t > g.IO.KeyRepeatDelay)
-    {
-        // FIXME: 2019/05/03: Our old repeat code was wrong here and led to doubling the repeat rate, which made it an ok rate for repeat on mouse hold.
-        int amount = CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, g.IO.KeyRepeatDelay, g.IO.KeyRepeatRate * 0.50f);
-        if (amount > 0)
-            return true;
-    }
+        return CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, g.IO.KeyRepeatDelay, g.IO.KeyRepeatRate) > 0;
     return false;
     return false;
 }
 }
 
 
@@ -8483,7 +8477,7 @@ void ImGui::UpdateInputEvents(bool trickle_fast_inputs)
                 }
                 }
             }
             }
         }
         }
-        else if (e->Type == ImGuiInputEventType_Char)
+        else if (e->Type == ImGuiInputEventType_Text)
         {
         {
             // Trickling Rule: Stop processing queued events if keys/mouse have been interacted with
             // Trickling Rule: Stop processing queued events if keys/mouse have been interacted with
             if (trickle_fast_inputs && (key_changed || mouse_button_changed != 0 || mouse_moved || mouse_wheeled))
             if (trickle_fast_inputs && (key_changed || mouse_button_changed != 0 || mouse_moved || mouse_wheeled))
@@ -11452,7 +11446,7 @@ static void ImGui::NavUpdateWindowing()
     // - Testing that only Alt is tested prevents Alt+Shift or AltGR from toggling menu layer.
     // - Testing that only Alt is tested prevents Alt+Shift or AltGR from toggling menu layer.
     // - AltGR is normally Alt+Ctrl but we can't reliably detect it (not all backends/systems/layout emit it as Alt+Ctrl). But even on keyboards without AltGR we don't want Alt+Ctrl to open menu anyway.
     // - AltGR is normally Alt+Ctrl but we can't reliably detect it (not all backends/systems/layout emit it as Alt+Ctrl). But even on keyboards without AltGR we don't want Alt+Ctrl to open menu anyway.
 	const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0;
 	const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0;
-    if (nav_keyboard_active && io.KeyMods == ImGuiKeyModFlags_Alt && (io.KeyModsPrev & ImGuiKeyModFlags_Alt) == 0)
+    if (nav_keyboard_active && IsKeyPressed(ImGuiKey_ModAlt))
     {
     {
         g.NavWindowingToggleLayer = true;
         g.NavWindowingToggleLayer = true;
         g.NavInputSource = ImGuiInputSource_Keyboard;
         g.NavInputSource = ImGuiInputSource_Keyboard;
@@ -11465,13 +11459,12 @@ static void ImGui::NavUpdateWindowing()
             g.NavWindowingToggleLayer = false;
             g.NavWindowingToggleLayer = false;
 
 
         // Apply layer toggle on release
         // Apply layer toggle on release
-        // Important: we don't assume that Alt was previously held in order to handle loss of focus when backend calls io.AddFocusEvent(false)
         // Important: as before version <18314 we lacked an explicit IO event for focus gain/loss, we also compare mouse validity to detect old backends clearing mouse pos on focus loss.
         // Important: as before version <18314 we lacked an explicit IO event for focus gain/loss, we also compare mouse validity to detect old backends clearing mouse pos on focus loss.
-        if (!(io.KeyMods & ImGuiKeyModFlags_Alt) && (io.KeyModsPrev & ImGuiKeyModFlags_Alt) && g.NavWindowingToggleLayer)
+        if (IsKeyReleased(ImGuiKey_ModAlt) && g.NavWindowingToggleLayer)
             if (g.ActiveId == 0 || g.ActiveIdAllowOverlap)
             if (g.ActiveId == 0 || g.ActiveIdAllowOverlap)
                 if (IsMousePosValid(&io.MousePos) == IsMousePosValid(&io.MousePosPrev))
                 if (IsMousePosValid(&io.MousePos) == IsMousePosValid(&io.MousePosPrev))
                     apply_toggle_layer = true;
                     apply_toggle_layer = true;
-        if (!io.KeyAlt)
+        if (!IsKeyDown(ImGuiKey_ModAlt))
             g.NavWindowingToggleLayer = false;
             g.NavWindowingToggleLayer = false;
     }
     }
 
 
@@ -17956,7 +17949,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
         Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL");
         Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL");
 
 
         int active_id_using_key_input_count = 0;
         int active_id_using_key_input_count = 0;
-        for (int n = 0; n < ImGuiKey_NamedKey_COUNT; n++)
+        for (int n = ImGuiKey_NamedKey_BEGIN; n < ImGuiKey_NamedKey_END; n++)
             active_id_using_key_input_count += g.ActiveIdUsingKeyInputMask[n] ? 1 : 0;
             active_id_using_key_input_count += g.ActiveIdUsingKeyInputMask[n] ? 1 : 0;
         Text("ActiveIdUsing: Wheel: %d, NavDirMask: %X, NavInputMask: %X, KeyInputMask: %d key(s)", g.ActiveIdUsingMouseWheel, g.ActiveIdUsingNavDirMask, g.ActiveIdUsingNavInputMask, active_id_using_key_input_count);
         Text("ActiveIdUsing: Wheel: %d, NavDirMask: %X, NavInputMask: %X, KeyInputMask: %d key(s)", g.ActiveIdUsingMouseWheel, g.ActiveIdUsingNavDirMask, g.ActiveIdUsingNavInputMask, active_id_using_key_input_count);
         Text("HoveredId: 0x%08X (%.2f sec), AllowOverlap: %d", g.HoveredIdPreviousFrame, g.HoveredIdTimer, g.HoveredIdAllowOverlap); // Not displaying g.HoveredId as it is update mid-frame
         Text("HoveredId: 0x%08X (%.2f sec), AllowOverlap: %d", g.HoveredIdPreviousFrame, g.HoveredIdTimer, g.HoveredIdAllowOverlap); // Not displaying g.HoveredId as it is update mid-frame
@@ -18674,27 +18667,44 @@ void ImGui::DebugHookIdInfo(ImGuiID id, ImGuiDataType data_type, const void* dat
     ImGuiStackLevelInfo* info = &tool->Results[tool->StackLevel];
     ImGuiStackLevelInfo* info = &tool->Results[tool->StackLevel];
     IM_ASSERT(info->ID == id && info->QueryFrameCount > 0);
     IM_ASSERT(info->ID == id && info->QueryFrameCount > 0);
 
 
-    int data_len;
     switch (data_type)
     switch (data_type)
     {
     {
     case ImGuiDataType_S32:
     case ImGuiDataType_S32:
         ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "%d", (int)(intptr_t)data_id);
         ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "%d", (int)(intptr_t)data_id);
         break;
         break;
     case ImGuiDataType_String:
     case ImGuiDataType_String:
-        data_len = data_id_end ? (int)((const char*)data_id_end - (const char*)data_id) : (int)strlen((const char*)data_id);
-        ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "\"%.*s\"", data_len, (const char*)data_id);
+        ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "%.*s", data_id_end ? (int)((const char*)data_id_end - (const char*)data_id) : (int)strlen((const char*)data_id), (const char*)data_id);
         break;
         break;
     case ImGuiDataType_Pointer:
     case ImGuiDataType_Pointer:
         ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "(void*)0x%p", data_id);
         ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "(void*)0x%p", data_id);
         break;
         break;
     case ImGuiDataType_ID:
     case ImGuiDataType_ID:
-        if (info->Desc[0] == 0) // PushOverrideID() is often used to avoid hashing twice, which would lead to 2 calls to DebugHookIdInfo(). We prioritize the first one.
-            ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "0x%08X [override]", id);
+        if (info->Desc[0] != 0) // PushOverrideID() is often used to avoid hashing twice, which would lead to 2 calls to DebugHookIdInfo(). We prioritize the first one.
+            return;
+        ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "0x%08X [override]", id);
         break;
         break;
     default:
     default:
         IM_ASSERT(0);
         IM_ASSERT(0);
     }
     }
     info->QuerySuccess = true;
     info->QuerySuccess = true;
+    info->DataType = data_type;
+}
+
+static int StackToolFormatLevelInfo(ImGuiStackTool* tool, int n, bool format_for_ui, char* buf, size_t buf_size)
+{
+    ImGuiStackLevelInfo* info = &tool->Results[n];
+    ImGuiWindow* window = (info->Desc[0] == 0 && n == 0) ? ImGui::FindWindowByID(info->ID) : NULL;
+    if (window)                                                                 // Source: window name (because the root ID don't call GetID() and so doesn't get hooked)
+        return ImFormatString(buf, buf_size, format_for_ui ? "\"%s\" [window]" : "%s", window->Name);
+    if (info->QuerySuccess)                                                     // Source: GetID() hooks (prioritize over ItemInfo() because we frequently use patterns like: PushID(str), Button("") where they both have same id)
+        return ImFormatString(buf, buf_size, (format_for_ui && info->DataType == ImGuiDataType_String) ? "\"%s\"" : "%s", info->Desc);
+    if (tool->StackLevel < tool->Results.Size)                                  // Only start using fallback below when all queries are done, so during queries we don't flickering ??? markers.
+        return (*buf = 0);
+#ifdef IMGUI_ENABLE_TEST_ENGINE
+    if (const char* label = ImGuiTestEngine_FindItemDebugLabel(GImGui, info->ID))   // Source: ImGuiTestEngine's ItemInfo()
+        return ImFormatString(buf, buf_size, format_for_ui ? "??? \"%s\"" : "%s", label);
+#endif
+    return ImFormatString(buf, buf_size, "???");
 }
 }
 
 
 // Stack Tool: Display UI
 // Stack Tool: Display UI
@@ -18710,6 +18720,7 @@ void ImGui::ShowStackToolWindow(bool* p_open)
     }
     }
 
 
     // Display hovered/active status
     // Display hovered/active status
+    ImGuiStackTool* tool = &g.DebugStackTool;
     const ImGuiID hovered_id = g.HoveredIdPreviousFrame;
     const ImGuiID hovered_id = g.HoveredIdPreviousFrame;
     const ImGuiID active_id = g.ActiveId;
     const ImGuiID active_id = g.ActiveId;
 #ifdef IMGUI_ENABLE_TEST_ENGINE
 #ifdef IMGUI_ENABLE_TEST_ENGINE
@@ -18720,8 +18731,33 @@ void ImGui::ShowStackToolWindow(bool* p_open)
     SameLine();
     SameLine();
     MetricsHelpMarker("Hover an item with the mouse to display elements of the ID Stack leading to the item's final ID.\nEach level of the stack correspond to a PushID() call.\nAll levels of the stack are hashed together to make the final ID of a widget (ID displayed at the bottom level of the stack).\nRead FAQ entry about the ID stack for details.");
     MetricsHelpMarker("Hover an item with the mouse to display elements of the ID Stack leading to the item's final ID.\nEach level of the stack correspond to a PushID() call.\nAll levels of the stack are hashed together to make the final ID of a widget (ID displayed at the bottom level of the stack).\nRead FAQ entry about the ID stack for details.");
 
 
+    // CTRL+C to copy path
+    const float time_since_copy = (float)g.Time - tool->CopyToClipboardLastTime;
+    Checkbox("Ctrl+C: copy path to clipboard", &tool->CopyToClipboardOnCtrlC);
+    SameLine();
+    TextColored((time_since_copy >= 0.0f && time_since_copy < 0.75f && ImFmod(time_since_copy, 0.25f) < 0.25f * 0.5f) ? ImVec4(1.f, 1.f, 0.3f, 1.f) : ImVec4(), "*COPIED*");
+    if (tool->CopyToClipboardOnCtrlC && IsKeyDown(ImGuiKey_ModCtrl) && IsKeyPressed(ImGuiKey_C))
+    {
+        tool->CopyToClipboardLastTime = (float)g.Time;
+        char* p = g.TempBuffer;
+        char* p_end = p + IM_ARRAYSIZE(g.TempBuffer);
+        for (int stack_n = 0; stack_n < tool->Results.Size && p + 3 < p_end; stack_n++)
+        {
+            *p++ = '/';
+            char level_desc[256];
+            StackToolFormatLevelInfo(tool, stack_n, false, level_desc, IM_ARRAYSIZE(level_desc));
+            for (int n = 0; level_desc[n] && p + 2 < p_end; n++)
+            {
+                if (level_desc[n] == '/')
+                    *p++ = '\\';
+                *p++ = level_desc[n];
+            }
+        }
+        *p = '\0';
+        SetClipboardText(g.TempBuffer);
+    }
+
     // Display decorated stack
     // Display decorated stack
-    ImGuiStackTool* tool = &g.DebugStackTool;
     tool->LastActiveFrame = g.FrameCount;
     tool->LastActiveFrame = g.FrameCount;
     if (tool->Results.Size > 0 && BeginTable("##table", 3, ImGuiTableFlags_Borders))
     if (tool->Results.Size > 0 && BeginTable("##table", 3, ImGuiTableFlags_Borders))
     {
     {
@@ -18735,23 +18771,9 @@ void ImGui::ShowStackToolWindow(bool* p_open)
             ImGuiStackLevelInfo* info = &tool->Results[n];
             ImGuiStackLevelInfo* info = &tool->Results[n];
             TableNextColumn();
             TableNextColumn();
             Text("0x%08X", (n > 0) ? tool->Results[n - 1].ID : 0);
             Text("0x%08X", (n > 0) ? tool->Results[n - 1].ID : 0);
-
             TableNextColumn();
             TableNextColumn();
-            ImGuiWindow* window = (info->Desc[0] == 0 && n == 0) ? FindWindowByID(info->ID) : NULL;
-            if (window)                                         // Source: window name (because the root ID don't call GetID() and so doesn't get hooked)
-                Text("\"%s\" [window]", window->Name);
-            else if (info->QuerySuccess)                        // Source: GetID() hooks (prioritize over ItemInfo() because we frequently use patterns like: PushID(str), Button("") where they both have same id)
-                TextUnformatted(info->Desc);
-            else if (tool->StackLevel >= tool->Results.Size)    // Only start using fallback below when all queries are done, so during queries we don't flickering ??? markers.
-            {
-#ifdef IMGUI_ENABLE_TEST_ENGINE
-                if (const char* label = ImGuiTestEngine_FindItemDebugLabel(&g, info->ID))    // Source: ImGuiTestEngine's ItemInfo()
-                    Text("??? \"%s\"", label);
-                else
-#endif
-                    TextUnformatted("???");
-            }
-
+            StackToolFormatLevelInfo(tool, n, true, g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer));
+            TextUnformatted(g.TempBuffer);
             TableNextColumn();
             TableNextColumn();
             Text("0x%08X", info->ID);
             Text("0x%08X", info->ID);
             if (n == tool->Results.Size - 1)
             if (n == tool->Results.Size - 1)

+ 10 - 10
imgui.h

@@ -1,4 +1,4 @@
-// dear imgui, v1.87
+// dear imgui, v1.88 WIP
 // (headers)
 // (headers)
 
 
 // Help:
 // Help:
@@ -64,8 +64,8 @@ Index of this file:
 
 
 // Version
 // Version
 // (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens)
 // (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens)
-#define IMGUI_VERSION               "1.87"
-#define IMGUI_VERSION_NUM           18701
+#define IMGUI_VERSION               "1.88 WIP"
+#define IMGUI_VERSION_NUM           18707
 #define IMGUI_CHECKVERSION()        ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
 #define IMGUI_CHECKVERSION()        ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
 #define IMGUI_HAS_TABLE
 #define IMGUI_HAS_TABLE
 #define IMGUI_HAS_VIEWPORT          // Viewport WIP branch
 #define IMGUI_HAS_VIEWPORT          // Viewport WIP branch
@@ -255,8 +255,8 @@ IM_MSVC_RUNTIME_CHECKS_OFF
 struct ImVec2
 struct ImVec2
 {
 {
     float                                   x, y;
     float                                   x, y;
-    ImVec2()                                { x = y = 0.0f; }
-    ImVec2(float _x, float _y)              { x = _x; y = _y; }
+    constexpr ImVec2()                      : x(0.0f), y(0.0f) { }
+    constexpr ImVec2(float _x, float _y)    : x(_x), y(_y) { }
     float  operator[] (size_t idx) const    { IM_ASSERT(idx <= 1); return (&x)[idx]; }    // We very rarely use this [] operator, the assert overhead is fine.
     float  operator[] (size_t idx) const    { IM_ASSERT(idx <= 1); return (&x)[idx]; }    // We very rarely use this [] operator, the assert overhead is fine.
     float& operator[] (size_t idx)          { IM_ASSERT(idx <= 1); return (&x)[idx]; }    // We very rarely use this [] operator, the assert overhead is fine.
     float& operator[] (size_t idx)          { IM_ASSERT(idx <= 1); return (&x)[idx]; }    // We very rarely use this [] operator, the assert overhead is fine.
 #ifdef IM_VEC2_CLASS_EXTRA
 #ifdef IM_VEC2_CLASS_EXTRA
@@ -267,9 +267,9 @@ struct ImVec2
 // ImVec4: 4D vector used to store clipping rectangles, colors etc. [Compile-time configurable type]
 // ImVec4: 4D vector used to store clipping rectangles, colors etc. [Compile-time configurable type]
 struct ImVec4
 struct ImVec4
 {
 {
-    float                                           x, y, z, w;
-    ImVec4()                                        { x = y = z = w = 0.0f; }
-    ImVec4(float _x, float _y, float _z, float _w)  { x = _x; y = _y; z = _z; w = _w; }
+    float                                                     x, y, z, w;
+    constexpr ImVec4()                                        : x(0.0f), y(0.0f), z(0.0f), w(0.0f) { }
+    constexpr ImVec4(float _x, float _y, float _z, float _w)  : x(_x), y(_y), z(_z), w(_w) { }
 #ifdef IM_VEC4_CLASS_EXTRA
 #ifdef IM_VEC4_CLASS_EXTRA
     IM_VEC4_CLASS_EXTRA     // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImVec4.
     IM_VEC4_CLASS_EXTRA     // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImVec4.
 #endif
 #endif
@@ -1327,6 +1327,7 @@ enum ImGuiHoveredFlags_
     ImGuiHoveredFlags_AllowWhenBlockedByActiveItem  = 1 << 7,   // Return true even if an active item is blocking access to this item/window. Useful for Drag and Drop patterns.
     ImGuiHoveredFlags_AllowWhenBlockedByActiveItem  = 1 << 7,   // Return true even if an active item is blocking access to this item/window. Useful for Drag and Drop patterns.
     ImGuiHoveredFlags_AllowWhenOverlapped           = 1 << 8,   // IsItemHovered() only: Return true even if the position is obstructed or overlapped by another window
     ImGuiHoveredFlags_AllowWhenOverlapped           = 1 << 8,   // IsItemHovered() only: Return true even if the position is obstructed or overlapped by another window
     ImGuiHoveredFlags_AllowWhenDisabled             = 1 << 9,   // IsItemHovered() only: Return true even if the item is disabled
     ImGuiHoveredFlags_AllowWhenDisabled             = 1 << 9,   // IsItemHovered() only: Return true even if the item is disabled
+    ImGuiHoveredFlags_NoNavOverride                 = 1 << 10,  // Disable using gamepad/keyboard navigation state when active, always query mouse.
     ImGuiHoveredFlags_RectOnly                      = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped,
     ImGuiHoveredFlags_RectOnly                      = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped,
     ImGuiHoveredFlags_RootAndChildWindows           = ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows
     ImGuiHoveredFlags_RootAndChildWindows           = ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows
 };
 };
@@ -1893,7 +1894,7 @@ struct ImVector
     inline void         pop_back()                          { IM_ASSERT(Size > 0); Size--; }
     inline void         pop_back()                          { IM_ASSERT(Size > 0); Size--; }
     inline void         push_front(const T& v)              { if (Size == 0) push_back(v); else insert(Data, v); }
     inline void         push_front(const T& v)              { if (Size == 0) push_back(v); else insert(Data, v); }
     inline T*           erase(const T* it)                  { IM_ASSERT(it >= Data && it < Data + Size); const ptrdiff_t off = it - Data; memmove(Data + off, Data + off + 1, ((size_t)Size - (size_t)off - 1) * sizeof(T)); Size--; return Data + off; }
     inline T*           erase(const T* it)                  { IM_ASSERT(it >= Data && it < Data + Size); const ptrdiff_t off = it - Data; memmove(Data + off, Data + off + 1, ((size_t)Size - (size_t)off - 1) * sizeof(T)); Size--; return Data + off; }
-    inline T*           erase(const T* it, const T* it_last){ IM_ASSERT(it >= Data && it < Data + Size && it_last > it && it_last <= Data + Size); const ptrdiff_t count = it_last - it; const ptrdiff_t off = it - Data; memmove(Data + off, Data + off + count, ((size_t)Size - (size_t)off - (size_t)count) * sizeof(T)); Size -= (int)count; return Data + off; }
+    inline T*           erase(const T* it, const T* it_last){ IM_ASSERT(it >= Data && it < Data + Size && it_last >= it && it_last <= Data + Size); const ptrdiff_t count = it_last - it; const ptrdiff_t off = it - Data; memmove(Data + off, Data + off + count, ((size_t)Size - (size_t)off - (size_t)count) * sizeof(T)); Size -= (int)count; return Data + off; }
     inline T*           erase_unsorted(const T* it)         { IM_ASSERT(it >= Data && it < Data + Size);  const ptrdiff_t off = it - Data; if (it < Data + Size - 1) memcpy(Data + off, Data + Size - 1, sizeof(T)); Size--; return Data + off; }
     inline T*           erase_unsorted(const T* it)         { IM_ASSERT(it >= Data && it < Data + Size);  const ptrdiff_t off = it - Data; if (it < Data + Size - 1) memcpy(Data + off, Data + Size - 1, sizeof(T)); Size--; return Data + off; }
     inline T*           insert(const T* it, const T& v)     { IM_ASSERT(it >= Data && it <= Data + Size); const ptrdiff_t off = it - Data; if (Size == Capacity) reserve(_grow_capacity(Size + 1)); if (off < (int)Size) memmove(Data + off + 1, Data + off, ((size_t)Size - (size_t)off) * sizeof(T)); memcpy(&Data[off], &v, sizeof(v)); Size++; return Data + off; }
     inline T*           insert(const T* it, const T& v)     { IM_ASSERT(it >= Data && it <= Data + Size); const ptrdiff_t off = it - Data; if (Size == Capacity) reserve(_grow_capacity(Size + 1)); if (off < (int)Size) memmove(Data + off + 1, Data + off, ((size_t)Size - (size_t)off) * sizeof(T)); memcpy(&Data[off], &v, sizeof(v)); Size++; return Data + off; }
     inline bool         contains(const T& v) const          { const T* data = Data;  const T* data_end = Data + Size; while (data < data_end) if (*data++ == v) return true; return false; }
     inline bool         contains(const T& v) const          { const T* data = Data;  const T* data_end = Data + Size; while (data < data_end) if (*data++ == v) return true; return false; }
@@ -2121,7 +2122,6 @@ struct ImGuiIO
 
 
     // Other state maintained from data above + IO function calls
     // Other state maintained from data above + IO function calls
     ImGuiKeyModFlags KeyMods;                       // Key mods flags (same as io.KeyCtrl/KeyShift/KeyAlt/KeySuper but merged into flags), updated by NewFrame()
     ImGuiKeyModFlags KeyMods;                       // Key mods flags (same as io.KeyCtrl/KeyShift/KeyAlt/KeySuper but merged into flags), updated by NewFrame()
-    ImGuiKeyModFlags KeyModsPrev;                   // Key mods flags (from previous frame)
     ImGuiKeyData KeysData[ImGuiKey_KeysData_SIZE];  // Key state for all known keys. Use IsKeyXXX() functions to access this.
     ImGuiKeyData KeysData[ImGuiKey_KeysData_SIZE];  // Key state for all known keys. Use IsKeyXXX() functions to access this.
     bool        WantCaptureMouseUnlessPopupClose;   // Alternative to WantCaptureMouse: (WantCaptureMouse == true && WantCaptureMouseUnlessPopupClose == false) when a click over void is expected to close a popup.
     bool        WantCaptureMouseUnlessPopupClose;   // Alternative to WantCaptureMouse: (WantCaptureMouse == true && WantCaptureMouseUnlessPopupClose == false) when a click over void is expected to close a popup.
     ImVec2      MousePosPrev;                       // Previous mouse position (note that MouseDelta is not necessary == MousePos-MousePosPrev, in case either position is invalid)
     ImVec2      MousePosPrev;                       // Previous mouse position (note that MouseDelta is not necessary == MousePos-MousePosPrev, in case either position is invalid)

+ 1 - 1
imgui_demo.cpp

@@ -1,4 +1,4 @@
-// dear imgui, v1.87
+// dear imgui, v1.88 WIP
 // (demo code)
 // (demo code)
 
 
 // Help:
 // Help:

+ 3 - 3
imgui_draw.cpp

@@ -1,4 +1,4 @@
-// dear imgui, v1.87
+// dear imgui, v1.88 WIP
 // (drawing and font code)
 // (drawing and font code)
 
 
 /*
 /*
@@ -1214,8 +1214,8 @@ void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, floa
 
 
         const float a_min_segment_angle = a_min_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
         const float a_min_segment_angle = a_min_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
         const float a_max_segment_angle = a_max_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
         const float a_max_segment_angle = a_max_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
-        const bool a_emit_start = (a_min_segment_angle - a_min) != 0.0f;
-        const bool a_emit_end = (a_max - a_max_segment_angle) != 0.0f;
+        const bool a_emit_start = ImAbs(a_min_segment_angle - a_min) >= 1e-5f;
+        const bool a_emit_end = ImAbs(a_max - a_max_segment_angle) >= 1e-5f;
 
 
         _Path.reserve(_Path.Size + (a_mid_samples + 1 + (a_emit_start ? 1 : 0) + (a_emit_end ? 1 : 0)));
         _Path.reserve(_Path.Size + (a_mid_samples + 1 + (a_emit_start ? 1 : 0) + (a_emit_end ? 1 : 0)));
         if (a_emit_start)
         if (a_emit_start)

+ 21 - 18
imgui_internal.h

@@ -1,4 +1,4 @@
-// dear imgui, v1.87
+// dear imgui, v1.88 WIP
 // (internal structures/api)
 // (internal structures/api)
 
 
 // You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility!
 // You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility!
@@ -481,17 +481,17 @@ IM_MSVC_RUNTIME_CHECKS_OFF
 struct ImVec1
 struct ImVec1
 {
 {
     float   x;
     float   x;
-    ImVec1()         { x = 0.0f; }
-    ImVec1(float _x) { x = _x; }
+    constexpr ImVec1()         : x(0.0f) { }
+    constexpr ImVec1(float _x) : x(_x) { }
 };
 };
 
 
 // Helper: ImVec2ih (2D vector, half-size integer, for long-term packed storage)
 // Helper: ImVec2ih (2D vector, half-size integer, for long-term packed storage)
 struct ImVec2ih
 struct ImVec2ih
 {
 {
     short   x, y;
     short   x, y;
-    ImVec2ih()                           { x = y = 0; }
-    ImVec2ih(short _x, short _y)         { x = _x; y = _y; }
-    explicit ImVec2ih(const ImVec2& rhs) { x = (short)rhs.x; y = (short)rhs.y; }
+    constexpr ImVec2ih()                           : x(0), y(0) {}
+    constexpr ImVec2ih(short _x, short _y)         : x(_x), y(_y) {}
+    constexpr explicit ImVec2ih(const ImVec2& rhs) : x((short)rhs.x), y((short)rhs.y) {}
 };
 };
 
 
 // Helper: ImRect (2D axis aligned bounding-box)
 // Helper: ImRect (2D axis aligned bounding-box)
@@ -501,10 +501,10 @@ struct IMGUI_API ImRect
     ImVec2      Min;    // Upper-left
     ImVec2      Min;    // Upper-left
     ImVec2      Max;    // Lower-right
     ImVec2      Max;    // Lower-right
 
 
-    ImRect()                                        : Min(0.0f, 0.0f), Max(0.0f, 0.0f)  {}
-    ImRect(const ImVec2& min, const ImVec2& max)    : Min(min), Max(max)                {}
-    ImRect(const ImVec4& v)                         : Min(v.x, v.y), Max(v.z, v.w)      {}
-    ImRect(float x1, float y1, float x2, float y2)  : Min(x1, y1), Max(x2, y2)          {}
+    constexpr ImRect()                                        : Min(0.0f, 0.0f), Max(0.0f, 0.0f)  {}
+    constexpr ImRect(const ImVec2& min, const ImVec2& max)    : Min(min), Max(max)                {}
+    constexpr ImRect(const ImVec4& v)                         : Min(v.x, v.y), Max(v.z, v.w)      {}
+    constexpr ImRect(float x1, float y1, float x2, float y2)  : Min(x1, y1), Max(x2, y2)          {}
 
 
     ImVec2      GetCenter() const                   { return ImVec2((Min.x + Max.x) * 0.5f, (Min.y + Max.y) * 0.5f); }
     ImVec2      GetCenter() const                   { return ImVec2((Min.x + Max.x) * 0.5f, (Min.y + Max.y) * 0.5f); }
     ImVec2      GetSize() const                     { return ImVec2(Max.x - Min.x, Max.y - Min.y); }
     ImVec2      GetSize() const                     { return ImVec2(Max.x - Min.x, Max.y - Min.y); }
@@ -559,11 +559,11 @@ struct ImBitArray
     ImBitArray()                                { ClearAllBits(); }
     ImBitArray()                                { ClearAllBits(); }
     void            ClearAllBits()              { memset(Storage, 0, sizeof(Storage)); }
     void            ClearAllBits()              { memset(Storage, 0, sizeof(Storage)); }
     void            SetAllBits()                { memset(Storage, 255, sizeof(Storage)); }
     void            SetAllBits()                { memset(Storage, 255, sizeof(Storage)); }
-    bool            TestBit(int n) const        { IM_ASSERT(n + OFFSET < BITCOUNT); return ImBitArrayTestBit(Storage, n + OFFSET); }
-    void            SetBit(int n)               { IM_ASSERT(n + OFFSET < BITCOUNT); ImBitArraySetBit(Storage, n + OFFSET); }
-    void            ClearBit(int n)             { IM_ASSERT(n + OFFSET < BITCOUNT); ImBitArrayClearBit(Storage, n + OFFSET); }
-    void            SetBitRange(int n, int n2)  { ImBitArraySetBitRange(Storage, n + OFFSET, n2 + OFFSET); } // Works on range [n..n2)
-    bool            operator[](int n) const     { IM_ASSERT(n + OFFSET < BITCOUNT); return ImBitArrayTestBit(Storage, n + OFFSET); }
+    bool            TestBit(int n) const        { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); return ImBitArrayTestBit(Storage, n); }
+    void            SetBit(int n)               { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); ImBitArraySetBit(Storage, n); }
+    void            ClearBit(int n)             { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); ImBitArrayClearBit(Storage, n); }
+    void            SetBitRange(int n, int n2)  { n += OFFSET; n2 += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT && n2 > n && n2 <= BITCOUNT); ImBitArraySetBitRange(Storage, n, n2); } // Works on range [n..n2)
+    bool            operator[](int n) const     { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); return ImBitArrayTestBit(Storage, n); }
 };
 };
 
 
 // Helper: ImBitVector
 // Helper: ImBitVector
@@ -1192,7 +1192,7 @@ enum ImGuiInputEventType
     ImGuiInputEventType_MouseButton,
     ImGuiInputEventType_MouseButton,
     ImGuiInputEventType_MouseViewport,
     ImGuiInputEventType_MouseViewport,
     ImGuiInputEventType_Key,
     ImGuiInputEventType_Key,
-    ImGuiInputEventType_Char,
+    ImGuiInputEventType_Text,
     ImGuiInputEventType_Focus,
     ImGuiInputEventType_Focus,
     ImGuiInputEventType_COUNT
     ImGuiInputEventType_COUNT
 };
 };
@@ -1686,7 +1686,8 @@ struct ImGuiStackLevelInfo
     ImGuiID                 ID;
     ImGuiID                 ID;
     ImS8                    QueryFrameCount;            // >= 1: Query in progress
     ImS8                    QueryFrameCount;            // >= 1: Query in progress
     bool                    QuerySuccess;               // Obtained result from DebugHookIdInfo()
     bool                    QuerySuccess;               // Obtained result from DebugHookIdInfo()
-    char                    Desc[58];                   // Arbitrarily sized buffer to hold a result (FIXME: could replace Results[] with a chunk stream?)
+    ImGuiDataType           DataType : 8;
+    char                    Desc[57];                   // Arbitrarily sized buffer to hold a result (FIXME: could replace Results[] with a chunk stream?) FIXME: Now that we added CTRL+C this should be fixed.
 
 
     ImGuiStackLevelInfo()   { memset(this, 0, sizeof(*this)); }
     ImGuiStackLevelInfo()   { memset(this, 0, sizeof(*this)); }
 };
 };
@@ -1698,8 +1699,10 @@ struct ImGuiStackTool
     int                     StackLevel;                 // -1: query stack and resize Results, >= 0: individual stack level
     int                     StackLevel;                 // -1: query stack and resize Results, >= 0: individual stack level
     ImGuiID                 QueryId;                    // ID to query details for
     ImGuiID                 QueryId;                    // ID to query details for
     ImVector<ImGuiStackLevelInfo> Results;
     ImVector<ImGuiStackLevelInfo> Results;
+    bool                    CopyToClipboardOnCtrlC;
+    float                   CopyToClipboardLastTime;
 
 
-    ImGuiStackTool()        { memset(this, 0, sizeof(*this)); }
+    ImGuiStackTool()        { memset(this, 0, sizeof(*this)); CopyToClipboardLastTime = -FLT_MAX; }
 };
 };
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------

+ 1 - 1
imgui_tables.cpp

@@ -1,4 +1,4 @@
-// dear imgui, v1.87
+// dear imgui, v1.88 WIP
 // (tables and columns code)
 // (tables and columns code)
 
 
 /*
 /*

+ 3 - 2
imgui_widgets.cpp

@@ -1,4 +1,4 @@
-// dear imgui, v1.87
+// dear imgui, v1.88 WIP
 // (widgets code)
 // (widgets code)
 
 
 /*
 /*
@@ -82,6 +82,7 @@ Index of this file:
 #pragma GCC diagnostic ignored "-Wpragmas"                          // warning: unknown option after '#pragma GCC diagnostic' kind
 #pragma GCC diagnostic ignored "-Wpragmas"                          // warning: unknown option after '#pragma GCC diagnostic' kind
 #pragma GCC diagnostic ignored "-Wformat-nonliteral"                // warning: format not a string literal, format string not checked
 #pragma GCC diagnostic ignored "-Wformat-nonliteral"                // warning: format not a string literal, format string not checked
 #pragma GCC diagnostic ignored "-Wclass-memaccess"                  // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
 #pragma GCC diagnostic ignored "-Wclass-memaccess"                  // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
+#pragma GCC diagnostic ignored "-Wdeprecated-enum-enum-conversion"  // warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated
 #endif
 #endif
 
 
 //-------------------------------------------------------------------------
 //-------------------------------------------------------------------------
@@ -6937,7 +6938,7 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
     if (!enabled)
     if (!enabled)
         EndDisabled();
         EndDisabled();
 
 
-    const bool hovered = (g.HoveredId == id) && enabled;
+    const bool hovered = (g.HoveredId == id) && enabled && !g.NavDisableMouseHover;
     if (menuset_is_open)
     if (menuset_is_open)
         g.NavWindow = backed_nav_window;
         g.NavWindow = backed_nav_window;
 
 

+ 12 - 9
misc/fonts/binary_to_compressed_c.cpp

@@ -15,7 +15,7 @@
 // You can also find a precompiled Windows binary in the binary/demo package available from https://github.com/ocornut/imgui
 // You can also find a precompiled Windows binary in the binary/demo package available from https://github.com/ocornut/imgui
 
 
 // Usage:
 // Usage:
-//   binary_to_compressed_c.exe [-base85] [-nocompress] <inputfile> <symbolname>
+//   binary_to_compressed_c.exe [-base85] [-nocompress] [-nostatic] <inputfile> <symbolname>
 // Usage example:
 // Usage example:
 //   # binary_to_compressed_c.exe myfont.ttf MyFont > myfont.cpp
 //   # binary_to_compressed_c.exe myfont.ttf MyFont > myfont.cpp
 //   # binary_to_compressed_c.exe -base85 myfont.ttf MyFont > myfont.cpp
 //   # binary_to_compressed_c.exe -base85 myfont.ttf MyFont > myfont.cpp
@@ -31,23 +31,25 @@ typedef unsigned int stb_uint;
 typedef unsigned char stb_uchar;
 typedef unsigned char stb_uchar;
 stb_uint stb_compress(stb_uchar* out, stb_uchar* in, stb_uint len);
 stb_uint stb_compress(stb_uchar* out, stb_uchar* in, stb_uint len);
 
 
-static bool binary_to_compressed_c(const char* filename, const char* symbol, bool use_base85_encoding, bool use_compression);
+static bool binary_to_compressed_c(const char* filename, const char* symbol, bool use_base85_encoding, bool use_compression, bool use_static);
 
 
 int main(int argc, char** argv)
 int main(int argc, char** argv)
 {
 {
     if (argc < 3)
     if (argc < 3)
     {
     {
-        printf("Syntax: %s [-base85] [-nocompress] <inputfile> <symbolname>\n", argv[0]);
+        printf("Syntax: %s [-base85] [-nocompress] [-nostatic] <inputfile> <symbolname>\n", argv[0]);
         return 0;
         return 0;
     }
     }
 
 
     int argn = 1;
     int argn = 1;
     bool use_base85_encoding = false;
     bool use_base85_encoding = false;
     bool use_compression = true;
     bool use_compression = true;
-    if (argv[argn][0] == '-')
+    bool use_static = true;
+    while (argn < (argc - 2) && argv[argn][0] == '-')
     {
     {
         if (strcmp(argv[argn], "-base85") == 0) { use_base85_encoding = true; argn++; }
         if (strcmp(argv[argn], "-base85") == 0) { use_base85_encoding = true; argn++; }
         else if (strcmp(argv[argn], "-nocompress") == 0) { use_compression = false; argn++; }
         else if (strcmp(argv[argn], "-nocompress") == 0) { use_compression = false; argn++; }
+        else if (strcmp(argv[argn], "-nostatic") == 0) { use_static = false; argn++; }
         else
         else
         {
         {
             fprintf(stderr, "Unknown argument: '%s'\n", argv[argn]);
             fprintf(stderr, "Unknown argument: '%s'\n", argv[argn]);
@@ -55,7 +57,7 @@ int main(int argc, char** argv)
         }
         }
     }
     }
 
 
-    bool ret = binary_to_compressed_c(argv[argn], argv[argn + 1], use_base85_encoding, use_compression);
+    bool ret = binary_to_compressed_c(argv[argn], argv[argn + 1], use_base85_encoding, use_compression, use_static);
     if (!ret)
     if (!ret)
         fprintf(stderr, "Error opening or reading file: '%s'\n", argv[argn]);
         fprintf(stderr, "Error opening or reading file: '%s'\n", argv[argn]);
     return ret ? 0 : 1;
     return ret ? 0 : 1;
@@ -67,7 +69,7 @@ char Encode85Byte(unsigned int x)
     return (x >= '\\') ? x + 1 : x;
     return (x >= '\\') ? x + 1 : x;
 }
 }
 
 
-bool binary_to_compressed_c(const char* filename, const char* symbol, bool use_base85_encoding, bool use_compression)
+bool binary_to_compressed_c(const char* filename, const char* symbol, bool use_base85_encoding, bool use_compression, bool use_static)
 {
 {
     // Read file
     // Read file
     FILE* f = fopen(filename, "rb");
     FILE* f = fopen(filename, "rb");
@@ -90,10 +92,11 @@ bool binary_to_compressed_c(const char* filename, const char* symbol, bool use_b
     FILE* out = stdout;
     FILE* out = stdout;
     fprintf(out, "// File: '%s' (%d bytes)\n", filename, (int)data_sz);
     fprintf(out, "// File: '%s' (%d bytes)\n", filename, (int)data_sz);
     fprintf(out, "// Exported using binary_to_compressed_c.cpp\n");
     fprintf(out, "// Exported using binary_to_compressed_c.cpp\n");
+    const char* static_str = use_static ? "static " : "";
     const char* compressed_str = use_compression ? "compressed_" : "";
     const char* compressed_str = use_compression ? "compressed_" : "";
     if (use_base85_encoding)
     if (use_base85_encoding)
     {
     {
-        fprintf(out, "static const char %s_%sdata_base85[%d+1] =\n    \"", symbol, compressed_str, (int)((compressed_sz + 3) / 4)*5);
+        fprintf(out, "%sconst char %s_%sdata_base85[%d+1] =\n    \"", static_str, symbol, compressed_str, (int)((compressed_sz + 3) / 4)*5);
         char prev_c = 0;
         char prev_c = 0;
         for (int src_i = 0; src_i < compressed_sz; src_i += 4)
         for (int src_i = 0; src_i < compressed_sz; src_i += 4)
         {
         {
@@ -112,8 +115,8 @@ bool binary_to_compressed_c(const char* filename, const char* symbol, bool use_b
     }
     }
     else
     else
     {
     {
-        fprintf(out, "static const unsigned int %s_%ssize = %d;\n", symbol, compressed_str, (int)compressed_sz);
-        fprintf(out, "static const unsigned int %s_%sdata[%d/4] =\n{", symbol, compressed_str, (int)((compressed_sz + 3) / 4)*4);
+        fprintf(out, "%sconst unsigned int %s_%ssize = %d;\n", static_str, symbol, compressed_str, (int)compressed_sz);
+        fprintf(out, "%sconst unsigned int %s_%sdata[%d/4] =\n{", static_str, symbol, compressed_str, (int)((compressed_sz + 3) / 4)*4);
         int column = 0;
         int column = 0;
         for (int i = 0; i < compressed_sz; i += 4)
         for (int i = 0; i < compressed_sz; i += 4)
         {
         {