Skip to content

Commit e8678ef

Browse files
committed
[API] Make GLFW to check availability of features
1 parent d1e264a commit e8678ef

File tree

2 files changed

+70
-15
lines changed

2 files changed

+70
-15
lines changed

imgui-lwjgl3/src/main/java/imgui/gl3/ImGuiImplGl3.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
/**
2323
* This class is a straightforward port of the
24-
* <a href="https://raw.githubusercontent.com/ocornut/imgui/05bc204dbd80dfebb3dab1511caf1cb980620c76/examples/imgui_impl_opengl3.cpp">imgui_impl_opengl3.cpp</a>.
24+
* <a href="https://raw.githubusercontent.com/ocornut/imgui/256594575d95d56dda616c544c509740e74906b4/backends/imgui_impl_opengl3.cpp">imgui_impl_opengl3.cpp</a>.
2525
* <p>
2626
* It do support a backup and restoring of the GL state in the same way the original Dear ImGui code does.
2727
* Some of the very specific OpenGL variables may be ignored here,

imgui-lwjgl3/src/main/java/imgui/glfw/ImGuiImplGlfw.java

Lines changed: 69 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,28 @@
3838

3939
/**
4040
* This class is a straightforward port of the
41-
* <a href="https://raw.githubusercontent.com/ocornut/imgui/05bc204dbd80dfebb3dab1511caf1cb980620c76/examples/imgui_impl_glfw.cpp">imgui_impl_glfw.cpp</a>.
41+
* <a href="https://raw.githubusercontent.com/ocornut/imgui/256594575d95d56dda616c544c509740e74906b4/backends/imgui_impl_glfw.cpp">imgui_impl_glfw.cpp</a>.
4242
* <p>
4343
* It supports clipboard, gamepad, mouse and keyboard in the same way the original Dear ImGui code does. You can copy-paste this class in your codebase and
4444
* modify the rendering routine in the way you'd like.
4545
*/
4646
public class ImGuiImplGlfw {
47-
protected static final boolean IS_WINDOWS = System.getProperty("os.name", "generic").toLowerCase().contains("win");
47+
private static final String OS = System.getProperty("os.name", "generic").toLowerCase();
48+
protected static final boolean IS_WINDOWS = OS.contains("win");
49+
protected static final boolean IS_APPLE = OS.contains("mac") || OS.contains("darwin");
4850

4951
// Pointer of the current GLFW window
5052
private long windowPtr;
5153

54+
// Some features may be available only from a specific version
55+
private boolean glfwHawWindowTopmost;
56+
private boolean glfwHasWindowAlpha;
57+
private boolean glfwHasPerMonitorDpi;
58+
private boolean glfwHasFocusWindow;
59+
private boolean glfwHasFocusOnShow;
60+
private boolean glfwHasMonitorWorkArea;
61+
private boolean glfwHasOsxWindowPosFix;
62+
5263
// For application window properties
5364
private final int[] winWidth = new int[1];
5465
private final int[] winHeight = new int[1];
@@ -167,6 +178,8 @@ public void monitorCallback(final long windowId, final int event) {
167178
public boolean init(final long windowId, final boolean installCallbacks) {
168179
this.windowPtr = windowId;
169180

181+
detectGlfwVersionAndEnabledFeatures();
182+
170183
final ImGuiIO io = ImGui.getIO();
171184

172185
io.addBackendFlags(ImGuiBackendFlags.HasMouseCursors | ImGuiBackendFlags.HasSetMousePos | ImGuiBackendFlags.PlatformHasViewports);
@@ -307,6 +320,22 @@ public void dispose() {
307320
}
308321
}
309322

323+
private void detectGlfwVersionAndEnabledFeatures() {
324+
final int[] major = new int[1];
325+
final int[] minor = new int[1];
326+
final int[] rev = new int[1];
327+
glfwGetVersion(major, minor, rev);
328+
329+
final int version = major[0] * 1000 + minor[0] * 100 + rev[0] * 10;
330+
331+
glfwHawWindowTopmost = version >= 3200;
332+
glfwHasWindowAlpha = version >= 3300;
333+
glfwHasPerMonitorDpi = version >= 3300;
334+
glfwHasFocusWindow = version >= 3200;
335+
glfwHasFocusOnShow = version >= 3300;
336+
glfwHasMonitorWorkArea = version >= 3300;
337+
}
338+
310339
private void updateMousePosAndButtons() {
311340
final ImGuiIO io = ImGui.getIO();
312341

@@ -459,15 +488,17 @@ private void updateMonitors() {
459488
final float mainSizeX = vidMode.width();
460489
final float mainSizeY = vidMode.height();
461490

462-
glfwGetMonitorWorkarea(monitor, monitorWorkAreaX, monitorWorkAreaY, monitorWorkAreaWidth, monitorWorkAreaHeight);
491+
if (glfwHasMonitorWorkArea) {
492+
glfwGetMonitorWorkarea(monitor, monitorWorkAreaX, monitorWorkAreaY, monitorWorkAreaWidth, monitorWorkAreaHeight);
493+
}
463494

464495
float workPosX = 0;
465496
float workPosY = 0;
466497
float workSizeX = 0;
467498
float workSizeY = 0;
468499

469500
// Workaround a small GLFW issue reporting zero on monitor changes: https://github.com/glfw/glfw/pull/1761
470-
if (monitorWorkAreaWidth[0] > 0 && monitorWorkAreaHeight[0] > 0) {
501+
if (glfwHasMonitorWorkArea && monitorWorkAreaWidth[0] > 0 && monitorWorkAreaHeight[0] > 0) {
471502
workPosX = monitorWorkAreaX[0];
472503
workPosY = monitorWorkAreaY[0];
473504
workSizeX = monitorWorkAreaWidth[0];
@@ -476,7 +507,9 @@ private void updateMonitors() {
476507

477508
// Warning: the validity of monitor DPI information on Windows depends on the application DPI awareness settings,
478509
// which generally needs to be set in the manifest or at runtime.
479-
glfwGetMonitorContentScale(monitor, monitorContentScaleX, monitorContentScaleY);
510+
if (glfwHasPerMonitorDpi) {
511+
glfwGetMonitorContentScale(monitor, monitorContentScaleX, monitorContentScaleY);
512+
}
480513
final float dpiScale = monitorContentScaleX[0];
481514

482515
platformIO.pushMonitors(mainPosX, mainPosY, mainSizeX, mainSizeY, workPosX, workPosY, workSizeX, workSizeY, dpiScale);
@@ -537,9 +570,13 @@ public void accept(final ImGuiViewport vp) {
537570
// With GLFW 3.3, the hint GLFW_FOCUS_ON_SHOW fixes this problem
538571
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
539572
glfwWindowHint(GLFW_FOCUSED, GLFW_FALSE);
540-
glfwWindowHint(GLFW_FOCUS_ON_SHOW, GLFW_FALSE);
573+
if (glfwHasFocusOnShow) {
574+
glfwWindowHint(GLFW_FOCUS_ON_SHOW, GLFW_FALSE);
575+
}
541576
glfwWindowHint(GLFW_DECORATED, vp.hasFlags(ImGuiViewportFlags.NoDecoration) ? GLFW_FALSE : GLFW_TRUE);
542-
glfwWindowHint(GLFW_FLOATING, vp.hasFlags(ImGuiViewportFlags.TopMost) ? GLFW_TRUE : GLFW_FALSE);
577+
if (glfwHawWindowTopmost) {
578+
glfwWindowHint(GLFW_FLOATING, vp.hasFlags(ImGuiViewportFlags.TopMost) ? GLFW_TRUE : GLFW_FALSE);
579+
}
543580

544581
data.window = glfwCreateWindow((int) vp.getSizeX(), (int) vp.getSizeY(), "No Title Yet", NULL, windowPtr);
545582
data.windowOwned = true;
@@ -628,10 +665,24 @@ public void get(final ImGuiViewport vp, final ImVec2 dstImVec2) {
628665
}
629666
}
630667

631-
private static final class SetWindowSizeFunction extends ImPlatformFuncViewportImVec2 {
668+
private final class SetWindowSizeFunction extends ImPlatformFuncViewportImVec2 {
669+
private final int[] x = new int[1];
670+
private final int[] y = new int[1];
671+
private final int[] width = new int[1];
672+
private final int[] height = new int[1];
673+
632674
@Override
633675
public void accept(final ImGuiViewport vp, final ImVec2 imVec2) {
634676
final ImGuiViewportDataGlfw data = (ImGuiViewportDataGlfw) vp.getPlatformUserData();
677+
// Native OS windows are positioned from the bottom-left corner on macOS, whereas on other platforms they are
678+
// positioned from the upper-left corner. GLFW makes an effort to convert macOS style coordinates, however it
679+
// doesn't handle it when changing size. We are manually moving the window in order for changes of size to be based
680+
// on the upper-left corner.
681+
if (IS_APPLE && !glfwHasOsxWindowPosFix) {
682+
glfwGetWindowPos(data.window, x, y);
683+
glfwGetWindowSize(data.window, width, height);
684+
glfwSetWindowPos(data.window, x[0], y[0] - height[0] + (int) imVec2.y);
685+
}
635686
data.ignoreWindowSizeEventFrame = ImGui.getFrameCount();
636687
glfwSetWindowSize(data.window, (int) imVec2.x, (int) imVec2.y);
637688
}
@@ -645,11 +696,13 @@ public void accept(final ImGuiViewport vp, final String str) {
645696
}
646697
}
647698

648-
private static final class SetWindowFocusFunction extends ImPlatformFuncViewport {
699+
private final class SetWindowFocusFunction extends ImPlatformFuncViewport {
649700
@Override
650701
public void accept(final ImGuiViewport vp) {
651-
final ImGuiViewportDataGlfw data = (ImGuiViewportDataGlfw) vp.getPlatformUserData();
652-
glfwFocusWindow(data.window);
702+
if (glfwHasFocusWindow) {
703+
final ImGuiViewportDataGlfw data = (ImGuiViewportDataGlfw) vp.getPlatformUserData();
704+
glfwFocusWindow(data.window);
705+
}
653706
}
654707
}
655708

@@ -669,11 +722,13 @@ public boolean get(final ImGuiViewport vp) {
669722
}
670723
}
671724

672-
private static final class SetWindowAlphaFunction extends ImPlatformFuncViewportFloat {
725+
private final class SetWindowAlphaFunction extends ImPlatformFuncViewportFloat {
673726
@Override
674727
public void accept(final ImGuiViewport vp, final float f) {
675-
final ImGuiViewportDataGlfw data = (ImGuiViewportDataGlfw) vp.getPlatformUserData();
676-
glfwSetWindowOpacity(data.window, f);
728+
if (glfwHasWindowAlpha) {
729+
final ImGuiViewportDataGlfw data = (ImGuiViewportDataGlfw) vp.getPlatformUserData();
730+
glfwSetWindowOpacity(data.window, f);
731+
}
677732
}
678733
}
679734

0 commit comments

Comments
 (0)