From 6a734e444d95614c66ade3a29bdd64fb7429dc16 Mon Sep 17 00:00:00 2001 From: Michael Neumann Date: Sun, 16 Jul 2023 21:34:50 +0200 Subject: [PATCH] glfw - Fix hidden cursor on re-focus and window repaint * Related bug report: https://github.com/ScenicFramework/scenic/issues/324 * On some Window managers (e.g. CTWM) the window is not repainted when another window is moved over it. Add `refresh_window_callback` and "redraw" (reuse `reshape_window` for now...). * At least on Hikari (Wayland), when the cursor leaves the window and re-enters the window, the cusor was no longer visible. This commit fixes this issue by adding a `focus_window_callback` and explicitly setting the cursor when focus is regained. * NOTE: This might (or might not) show a cursor where no cursor is wanted (touch-screen devices?). To fix this, the `glfwSetCusor` and `glfwSetInputMode` calls in `focus_window_callback` should be conditionalized by a global per-device setting, whether a cursor is desired or not. --- c_src/device/glfw.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/c_src/device/glfw.c b/c_src/device/glfw.c index 67d2c1c..656b0e9 100644 --- a/c_src/device/glfw.c +++ b/c_src/device/glfw.c @@ -41,6 +41,7 @@ typedef struct { bool glew_ok; GLFWwindow* p_window; + GLFWcursor *p_cursor; device_info_t* p_info; } glfw_data_t; @@ -153,6 +154,26 @@ void window_close_callback(GLFWwindow* window) glfwSetWindowShouldClose(window, false); } +//--------------------------------------------------------- +void refresh_window_callback(GLFWwindow* window) +{ + // XXX: This is a hack. I just want to redraw the window here w/o reshaping the window. + int window_width, window_height; + glfwGetWindowSize(window, &window_width, &window_height); + reshape_window(window, window_width, window_height); +} + +//--------------------------------------------------------- +void focus_window_callback(GLFWwindow* window, int focused) +{ + if (focused == GLFW_TRUE) { + // If we enter focus again, set the cursor. If we don't do this, + // the cursor is missing for some WM / composers. + glfwSetCursor(window, g_glfw_data.p_cursor); + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + } +} + // //============================================================================= // // main setup @@ -213,6 +234,8 @@ NVGcontext* setup_window(GLFWwindow* window, const device_opts_t* p_opts) glfwSetMouseButtonCallback(window, mouse_button_callback); glfwSetScrollCallback(window, scroll_callback); glfwSetWindowCloseCallback(window, window_close_callback); + glfwSetWindowRefreshCallback(window, refresh_window_callback); + glfwSetWindowFocusCallback(window, focus_window_callback); // set the initial clear color glClearColor(0.0, 0.0, 0.0, 1.0); @@ -255,6 +278,9 @@ int device_init(const device_opts_t* p_opts, return -1; } + // Setup a standard cursor. XXX: We might not want to show a cursor + g_glfw_data.p_cursor = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); + // set up one-time features of the window g_glfw_data.p_info = p_info; p_info->v_ctx = setup_window(g_glfw_data.p_window, p_opts);