ScenicFramework / scenic

Core Scenic library
Apache License 2.0
1.97k stars 137 forks source link

Mouse cursor hides behind window #324

Closed mneumann closed 9 months ago

mneumann commented 1 year ago

Checklist

Versions and Environment

Elixir:

# elixir -v
Erlang/OTP 25 [erts-13.2.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit:ns] [dtrace]

Elixir 1.15.0 (compiled with Erlang/OTP 25)

Erlang:

# erl -v
Erlang/OTP 25 [erts-13.2.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit:ns] [dtrace]

Eshell V13.2.2.2  (abort with ^G)

Scenic:

# mix deps | grep scenic
* scenic 0.11.1 (Hex package) (mix)
  locked at 0.11.1 (scenic) 86845290
* scenic_driver_local 0.11.0 (Hex package) (mix)
  locked at 0.11.0 (scenic_driver_local) 77b27b82

OS:

# uname -a
FreeBSD tuxe 13.2-RELEASE-p1 FreeBSD 13.2-RELEASE-p1 GENERIC amd64

Steps to reproduce

I am creating a mix scenic.new foobar app. Then mix run.scenic. The GLFW window appears. The window is 800x600. Initially, the mouse cursor appears over the window. If I move the window out of the window and back into the window, the mouse cursor is no longer visible. If I now move the window, the mouse cursor appears again.

I am using Wayland and hikari composer.

Expected Behavior

As with any other application, if I move the mouse into the window again, the mouse cursor is visible.

Actual Behavior

The mouse cursor is invisible unless I move the window again.

Additional Comments

I will try X11 and another Wayland composer just to be sure this is not an issue with Scenic itself.

crertel commented 1 year ago

Can you link to a repo that can repro this issue by any chance?

mneumann commented 1 year ago

@crertel it really is just the basic app created by mix scenic.new. I figured out a solution, which I will post as PR to scenic_driver_local in a few minutes.

What fixed the problem is the following (in c_src/device/glfw.c):

void refresh_window(GLFWwindow* window)
{
  int window_width, window_height;
  glfwGetWindowSize(window, &window_width, &window_height);

    reshape_window(window, window_width, window_height);
}

void focus_window(GLFWwindow* window, int focused)
{
  if (focused == GLFW_TRUE) {
    glfwSetCursor(window, g_glfw_data.p_cursor);
    glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
  }
}

// in device_init
// If I don't explicitly set a standard cursor, the `glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);` call will change the cursor to an "x".
g_glfw_data.p_cursor = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);

// in setup_window
glfwSetWindowRefreshCallback(window, refresh_window);
glfwSetWindowFocusCallback(window, focus_window);