diff --git a/src/wl_init.c b/src/wl_init.c index ea621f9..8d674f4 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -497,7 +497,7 @@ static void registryHandleGlobal(void* data, if (strcmp(interface, "wl_compositor") == 0) { _glfw.wl.compositor = - wl_registry_bind(registry, name, &wl_compositor_interface, 1); + wl_registry_bind(registry, name, &wl_compositor_interface, 3); } else if (strcmp(interface, "wl_shm") == 0) { diff --git a/src/wl_monitor.c b/src/wl_monitor.c index fbcefd3..8817d7b 100644 --- a/src/wl_monitor.c +++ b/src/wl_monitor.c @@ -97,6 +97,9 @@ static void scale(void* data, struct wl_output* output, int32_t factor) { + struct _GLFWmonitor *monitor = data; + + monitor->wl.scale = factor; } static const struct wl_output_listener output_listener = { diff --git a/src/wl_platform.h b/src/wl_platform.h index dfc29c3..7f67ff2 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -65,8 +65,14 @@ typedef struct _GLFWwindowWayland struct wl_egl_window* native; struct wl_shell_surface* shell_surface; struct wl_callback* callback; + _GLFWcursor* currentCursor; double cursorPosX, cursorPosY; + + int scale; + _GLFWmonitor** monitors; + int monitorsCount; + int monitorsSize; } _GLFWwindowWayland; @@ -122,7 +128,7 @@ typedef struct _GLFWmonitorWayland int x; int y; - + int scale; } _GLFWmonitorWayland; diff --git a/src/wl_window.c b/src/wl_window.c index 4f7ffab..8fd2457 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -72,6 +72,80 @@ static const struct wl_shell_surface_listener shellSurfaceListener = { handlePopupDone }; +static void maybeChangeScale(_GLFWwindow* window) +{ + int scale = 0; + for (int i = 0; i < window->wl.monitorsCount; ++i) + { + int monitorScale = window->wl.monitors[i]->wl.scale; + if (scale < monitorScale) + { + scale = monitorScale; + } + } + if (scale != window->wl.scale) + { + int width = window->wl.width * scale; + int height = window->wl.height * scale; + printf("→ %d×%d (%d)\n", width, height, scale); + wl_egl_window_resize(window->wl.native, width, height, 0, 0); + wl_surface_set_buffer_scale(window->wl.surface, scale); + window->wl.scale = scale; + } +} + +static void handleEnter(void *data, + struct wl_surface *surface, + struct wl_output *output) +{ + _GLFWwindow* window = data; + _GLFWmonitor* monitor = wl_output_get_user_data(output); + + if (window->wl.monitorsCount + 1 > window->wl.monitorsSize) + { + _GLFWmonitor** monitors = window->wl.monitors; + int size = window->wl.monitorsSize + 1; + + monitors = realloc(monitors, size * sizeof(_GLFWmonitor*)); + + window->wl.monitors = monitors; + window->wl.monitorsSize = size; + } + + window->wl.monitors[window->wl.monitorsCount++] = monitor; + + maybeChangeScale(window); +} + +static void handleLeave(void *data, + struct wl_surface *surface, + struct wl_output *output) +{ + _GLFWwindow* window = data; + _GLFWmonitor* monitor = wl_output_get_user_data(output); + + GLboolean found = GL_FALSE; + for (int i = 0; i < window->wl.monitorsCount; ++i) + { + if (monitor == window->wl.monitors[i]) + { + found = GL_TRUE; + } + if (found) + { + window->wl.monitors[i] = window->wl.monitors[i + 1]; + } + } + --window->wl.monitorsCount; + + maybeChangeScale(window); +} + +static const struct wl_surface_listener surfaceListener = { + handleEnter, + handleLeave +}; + static GLboolean createSurface(_GLFWwindow* window, const _GLFWwndconfig* wndconfig) { @@ -79,6 +153,10 @@ static GLboolean createSurface(_GLFWwindow* window, if (!window->wl.surface) return GL_FALSE; + wl_surface_add_listener(window->wl.surface, + &surfaceListener, + window); + wl_surface_set_user_data(window->wl.surface, window); window->wl.native = wl_egl_window_create(window->wl.surface, @@ -98,6 +176,7 @@ static GLboolean createSurface(_GLFWwindow* window, window->wl.width = wndconfig->width; window->wl.height = wndconfig->height; + window->wl.scale = 1; return GL_TRUE; } @@ -237,6 +316,10 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, window->wl.currentCursor = NULL; + window->wl.monitors = calloc(1, sizeof(_GLFWmonitor*)); + window->wl.monitorsCount = 0; + window->wl.monitorsSize = 1; + return GL_TRUE; } @@ -305,6 +388,8 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height) { _glfwPlatformGetWindowSize(window, width, height); + *width *= window->wl.scale; + *height *= window->wl.scale; } void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,