Wayland pointer lock fixes
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good

This commit is contained in:
IoIxD 2026-03-27 17:15:59 -07:00
commit 252490e2cf
5 changed files with 284 additions and 223 deletions

View file

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.25)
project(
milsko
milsko
)
include(CheckIncludeFiles)
@ -20,123 +20,123 @@ option(MW_BUILD_STATIC "Build a static library" OFF)
option(MW_INSTALL_HEADERS "Install headers" ON)
if(${CMAKE_SYSTEM_NAME} STREQUAL Darwin)
option(MW_USE_FREETYPE2 "Use FreeType 2" OFF)
option(MW_USE_FREETYPE2 "Use FreeType 2" OFF)
else()
option(MW_USE_FREETYPE2 "Use FreeType 2" ON)
option(MW_USE_FREETYPE2 "Use FreeType 2" ON)
endif()
if(${CMAKE_SYSTEM_NAME} STREQUAL Linux)
option(MW_USE_WAYLAND "Enable Wayland backend" ON)
option(MW_USE_WAYLAND "Enable Wayland backend" ON)
endif()
file(
GLOB
SOURCES
src/*.c src/cursor/*.c src/icon/*.c src/widget/*.c src/text/*.c src/text/font/*.c src/dialog/*.c src/abstract/*.c external/*.c
GLOB
SOURCES
src/*.c src/cursor/*.c src/icon/*.c src/widget/*.c src/text/*.c src/text/font/*.c src/dialog/*.c src/abstract/*.c external/*.c
)
list(REMOVE_ITEM SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/widget/opengl.c")
list(REMOVE_ITEM SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/widget/vulkan.c")
if(NOT MW_USE_STB_IMAGE)
list(REMOVE_ITEM SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/external/stb_image.c")
list(REMOVE_ITEM SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/external/stb_image.c")
endif()
if(NOT MW_USE_STB_TRUETYPE)
list(REMOVE_ITEM SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/external/stb_truetype.c")
list(REMOVE_ITEM SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/external/stb_truetype.c")
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "NetBSD")
list(APPEND CMAKE_REQUIRED_INCLUDES "/usr/X11R7/include")
list(APPEND CMAKE_REQUIRED_INCLUDES "/usr/pkg/include")
list(APPEND CMAKE_REQUIRED_INCLUDES "/usr/X11R7/include")
list(APPEND CMAKE_REQUIRED_INCLUDES "/usr/pkg/include")
endif()
if(MW_TRY_OPENGL)
find_package(OpenGL)
if(OpenGL_FOUND)
set(MW_BUILD_OPENGL ON)
set(MW_BUILD_OPENGL ON)
list(APPEND SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/widget/opengl.c")
if(APPLE)
list(APPEND SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/widget/opengl_cocoa.m")
endif()
message(STATUS "OpenGL widget has been enabled")
else()
message(WARNING "OpenGL widget has been disabled")
endif()
message(STATUS "OpenGL widget has been enabled")
else()
message(WARNING "OpenGL widget has been disabled")
endif()
endif()
if(MW_TRY_VULKAN)
check_include_files(vulkan/vulkan.h HAVE_VULKAN_VULKAN_H)
if(HAVE_VULKAN_VULKAN_H)
set(MW_BUILD_VULKAN ON)
list(APPEND SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/widget/vulkan.c")
message(STATUS "Vulkan widget has been enabled")
else()
message(WARNING "Vulkan widget has been disabled")
endif()
check_include_files(vulkan/vulkan.h HAVE_VULKAN_VULKAN_H)
if(HAVE_VULKAN_VULKAN_H)
set(MW_BUILD_VULKAN ON)
list(APPEND SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/widget/vulkan.c")
message(STATUS "Vulkan widget has been enabled")
else()
message(WARNING "Vulkan widget has been disabled")
endif()
endif()
if(MW_BUILD_STATIC)
message(STATUS "Building Milsko as a static library")
add_library(
Mw
${SOURCES}
message(STATUS "Building Milsko as a static library")
add_library(
Mw
${SOURCES}
)
elseif(MW_BUILD_SHARED)
message(STATUS "Building Milsko as a shared library")
add_library(
Mw
SHARED
${SOURCES}
message(STATUS "Building Milsko as a shared library")
add_library(
Mw
SHARED
${SOURCES}
)
else()
message(ERROR "Must either build a shared library or a static library")
message(ERROR "Must either build a shared library or a static library")
endif()
if(MW_USE_STB_IMAGE)
target_compile_definitions(
Mw
PRIVATE
USE_STB_IMAGE
)
target_compile_definitions(
Mw
PRIVATE
USE_STB_IMAGE
)
else()
file(
GLOB
IMAGE_SOURCES
external/libz/src/*.c external/libjpeg/src/*.c external/libpng/src/*.c
)
target_sources(
Mw
PRIVATE
${MW_IMAGE_SOURCES}
)
target_include_directories(
Mw
PRIVATE
external/libz/include external/libjpeg/include external/libpng/include
)
file(
GLOB
IMAGE_SOURCES
external/libz/src/*.c external/libjpeg/src/*.c external/libpng/src/*.c
)
target_sources(
Mw
PRIVATE
${MW_IMAGE_SOURCES}
)
target_include_directories(
Mw
PRIVATE
external/libz/include external/libjpeg/include external/libpng/include
)
endif()
if(MW_USE_STB_TRUETYPE)
target_compile_definitions(
Mw
PRIVATE
USE_STB_TRUETYPE
)
target_compile_definitions(
Mw
PRIVATE
USE_STB_TRUETYPE
)
endif()
if(MW_USE_FREETYPE2)
target_compile_definitions(
Mw
PRIVATE
USE_FREETYPE2
)
target_compile_definitions(
Mw
PRIVATE
USE_FREETYPE2
)
find_package(PkgConfig)
pkg_check_modules(FT2 REQUIRED freetype2)
list(APPEND INCLUDE_DIRS ${FT2_INCLUDE_DIRS})
list(APPEND LIBRARY_DIRS ${FT2_LIBRARY_DIRS})
list(APPEND LIBRARIES ${FT2_LIBRARIES})
find_package(PkgConfig)
pkg_check_modules(FT2 REQUIRED freetype2)
list(APPEND INCLUDE_DIRS ${FT2_INCLUDE_DIRS})
list(APPEND LIBRARY_DIRS ${FT2_LIBRARY_DIRS})
list(APPEND LIBRARIES ${FT2_LIBRARIES})
endif()
if(MW_USE_WAYLAND)
@ -150,10 +150,10 @@ if(MW_USE_WAYLAND)
COMMAND_ECHO STDOUT
)
target_sources(
Mw
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src/backend/wayland-core-protocol.c
)
Mw
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src/backend/wayland-core-protocol.c
)
execute_process(
COMMAND wayland-scanner client-header /usr/share/wayland/wayland.xml ${CMAKE_CURRENT_SOURCE_DIR}/include/Mw/LowLevel/Wayland/wayland-core-protocol.h
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
@ -177,10 +177,10 @@ if(MW_USE_WAYLAND)
COMMAND_ECHO STDOUT
)
target_sources(
Mw
PRIVATE
Mw
PRIVATE
${proto_c}
)
)
execute_process(
COMMAND wayland-scanner client-header /usr/share/wayland-protocols/${tier}/${proto}/${proto}${ver}.xml ${CMAKE_CURRENT_SOURCE_DIR}/include/Mw/LowLevel/Wayland/${proto}-client-protocol.h
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
@ -193,11 +193,11 @@ if(MW_USE_WAYLAND)
endfunction()
check_include_files(wayland-client.h HAVE_WL_H)
check_include_files(xkbcommon/xkbcommon.h HAVE_XKBCOMMON_H)
check_include_files(xkbcommon/xkbcommon.h HAVE_XKBCOMMON_H)
check_include_files(cairo/cairo.h HAVE_CAIRO_H)
if(HAVE_WL_H)
if(HAVE_XKBCOMMON_H)
if(HAVE_CAIRO_H)
if(HAVE_WL_H)
if(HAVE_XKBCOMMON_H)
if(HAVE_CAIRO_H)
scan_wayland_protocol_core()
scan_wayland_protocol("stable" "xdg-shell" "")
scan_wayland_protocol("stable" "viewporter" "")
@ -207,156 +207,157 @@ if(MW_USE_WAYLAND)
scan_wayland_protocol("unstable" "xdg-decoration" "-unstable-v1")
scan_wayland_protocol("unstable" "primary-selection" "-unstable-v1")
scan_wayland_protocol("unstable" "pointer-constraints" "-unstable-v1")
scan_wayland_protocol("unstable" "relative-pointer" "-unstable-v1")
target_sources(
Mw
PRIVATE
src/backend/wayland.c
)
Mw
PRIVATE
src/backend/wayland.c
)
target_compile_definitions(
Mw
PRIVATE
USE_WAYLAND
)
message(STATUS "Wayland backend has been enabled")
else()
message(WARNING "Wayland backend has been disabled")
endif()
else()
message(WARNING "Wayland backend has been disabled")
endif()
else()
message(WARNING "Wayland backend has been disabled")
endif()
message(STATUS "Wayland backend has been enabled")
else()
message(WARNING "Wayland backend has been disabled")
endif()
else()
message(WARNING "Wayland backend has been disabled")
endif()
else()
message(WARNING "Wayland backend has been disabled")
endif()
endif()
if(APPLE AND MW_BUILD_OPENGL)
target_compile_definitions(
Mw
PRIVATE
GL_SILENCE_DEPRECATION
)
Mw
PRIVATE
GL_SILENCE_DEPRECATION
)
endif()
target_include_directories(
Mw
PUBLIC
include
Mw
PUBLIC
include
)
if(MW_CLASSIC_THEME)
target_compile_definitions(
Mw
PRIVATE
USE_CLASSIC_THEME
)
target_compile_definitions(
Mw
PRIVATE
USE_CLASSIC_THEME
)
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
target_sources(
Mw
PRIVATE
src/backend/gdi.c
)
target_compile_definitions(
Mw
PRIVATE
USE_GDI
)
list(APPEND LIBRARIES gdi32)
target_link_options(
Mw
PRIVATE
-static-libgcc
)
target_sources(
Mw
PRIVATE
src/backend/gdi.c
)
target_compile_definitions(
Mw
PRIVATE
USE_GDI
)
list(APPEND LIBRARIES gdi32)
target_link_options(
Mw
PRIVATE
-static-libgcc
)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
target_sources(
Mw
PRIVATE
src/backend/cocoa.m
)
target_compile_definitions(
Mw
PRIVATE
USE_COCOA
)
list(APPEND LIBRARIES objc)
target_link_options(
Mw
PRIVATE
-framework Cocoa
)
target_sources(
Mw
PRIVATE
src/backend/cocoa.m
)
target_compile_definitions(
Mw
PRIVATE
USE_COCOA
)
list(APPEND LIBRARIES objc)
target_link_options(
Mw
PRIVATE
-framework Cocoa
)
else()
find_package(PkgConfig)
pkg_check_modules(X11 REQUIRED x11)
pkg_check_modules(XRENDER REQUIRED xrender)
find_package(PkgConfig)
pkg_check_modules(X11 REQUIRED x11)
pkg_check_modules(XRENDER REQUIRED xrender)
target_sources(
Mw
PRIVATE
src/backend/x11.c
)
target_compile_definitions(
Mw
PRIVATE
USE_X11
)
list(APPEND INCLUDE_DIRS ${X11_INCLUDE_DIRS} ${XRENDER_INCLUDE_DIRS})
list(APPEND LIBRARY_DIRS ${X11_LIBRARY_DIRS} ${XRENDER_LIBRARY_DIRS})
list(APPEND LIBRARIES ${X11_LIBRARIES} ${XRENDER_LIBRARIES} m)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
list(APPEND LIBRARIES dl)
endif()
target_sources(
Mw
PRIVATE
src/backend/x11.c
)
target_compile_definitions(
Mw
PRIVATE
USE_X11
)
list(APPEND INCLUDE_DIRS ${X11_INCLUDE_DIRS} ${XRENDER_INCLUDE_DIRS})
list(APPEND LIBRARY_DIRS ${X11_LIBRARY_DIRS} ${XRENDER_LIBRARY_DIRS})
list(APPEND LIBRARIES ${X11_LIBRARIES} ${XRENDER_LIBRARIES} m)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
list(APPEND LIBRARIES dl)
endif()
endif()
target_include_directories(
Mw
PRIVATE
${INCLUDE_DIRS}
Mw
PRIVATE
${INCLUDE_DIRS}
)
target_link_directories(
Mw
PRIVATE
${LIBRARY_DIRS}
Mw
PRIVATE
${LIBRARY_DIRS}
)
target_link_libraries(
Mw
PRIVATE
${LIBRARIES}
Mw
PRIVATE
${LIBRARIES}
)
if(MW_BUILD_VULKAN)
check_include_files(vulkan/vk_enum_string_helper.h HAS_VK_ENUM_STRING_HELPER)
if(HAS_VK_ENUM_STRING_HELPER)
target_compile_definitions(
Mw
PRIVATE
HAS_VK_ENUM_STRING_HELPER
)
endif()
check_include_files(vulkan/vk_enum_string_helper.h HAS_VK_ENUM_STRING_HELPER)
if(HAS_VK_ENUM_STRING_HELPER)
target_compile_definitions(
Mw
PRIVATE
HAS_VK_ENUM_STRING_HELPER
)
endif()
endif()
target_compile_definitions(
Mw
PRIVATE
_MILSKO
Mw
PRIVATE
_MILSKO
)
install(
TARGETS Mw
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
TARGETS Mw
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
if(MW_INSTALL_HEADERS)
install(
DIRECTORY include/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILES_MATCHING PATTERN "*.h"
)
install(
DIRECTORY include/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILES_MATCHING PATTERN "*.h"
)
endif()
if(MW_BUILD_EXAMPLES)
add_subdirectory(examples)
add_subdirectory(examples)
endif()

View file

@ -289,6 +289,7 @@ MwInline int wayland_load_funcs() {
#include "Wayland/cursor-shape-client-protocol.h"
#include "Wayland/primary-selection-client-protocol.h"
#include "Wayland/pointer-constraints-client-protocol.h"
#include "Wayland/relative-pointer-client-protocol.h"
#include "Wayland/xdg-toplevel-icon-client-protocol.h"
#endif
@ -426,10 +427,12 @@ struct _MwLLWayland {
struct wp_viewport* vp;
MwBool do_lock_pointer;
struct zwp_pointer_constraints_v1* pointer_constraints;
struct zwp_locked_pointer_v1* locked_pointer;
MwBool pointer_constrained;
MwBool do_lock_pointer;
struct zwp_pointer_constraints_v1* pointer_constraints;
struct zwp_relative_pointer_manager_v1* relative_pointer_manager;
struct zwp_relative_pointer_v1* relative_pointer;
struct zwp_locked_pointer_v1* locked_pointer;
MwBool pointer_constrained;
/* clipboard related stuff.
* Note that unlike most interfaces, we don't keep zwp_primary_selection stuff in a wayland_protocol_t because we use wl_data_device as a fallback and want to have it share memory space.*/

View file

@ -43,6 +43,7 @@ if (grep(/^wayland$/, @backends)) {
scan_wayland_protocol("unstable", "xdg-decoration", "-unstable-v1");
scan_wayland_protocol("unstable", "primary-selection", "-unstable-v1");
scan_wayland_protocol("unstable", "pointer-constraints", "-unstable-v1");
scan_wayland_protocol("unstable", "relative-pointer", "-unstable-v1");
$gl_libs = "-lGL -lGLU";
}

View file

@ -118,15 +118,15 @@ static void recursive_dispatch_resize(MwLL handle) {
}
};
/* Recursively dispatch a draw event to a widget and its children */
static void recursive_dispatch_draw(MwLL handle) {
/* Recursively dispatch a move event to a widget and its children */
static void recursive_dispatch_move(MwLL handle, MwLLMouse* p) {
MwWidget h = (MwWidget)handle->common.user;
if(h) {
int i;
for(i = 0; i < arrlen(h->children); i++) {
MwDispatch(h->children[i], draw);
MwLLDispatch(h->children[i]->lowlevel, move, p);
if(arrlen(h->children[i]->children) > 0) {
recursive_dispatch_draw(h->children[i]->lowlevel);
recursive_dispatch_move(h->children[i]->lowlevel, p);
}
}
}
@ -531,24 +531,59 @@ static void xdg_borderless_step(MwLL self, MwLLMouse p, MwU32 serial) {
static MwLL currentlyHeldWidget = NULL;
static void relative_pointer_motion(void* data,
struct zwp_relative_pointer_v1* pointer,
uint32_t timeHi,
uint32_t timeLo,
wl_fixed_t dx,
wl_fixed_t dy,
wl_fixed_t dxUnaccel,
wl_fixed_t dyUnaccel) {
MwLL self = data;
MwLLMouse p;
WAYLAND_EVENT_OP_START(self);
p.point.x = wl_fixed_to_int(dxUnaccel);
p.point.y = wl_fixed_to_int(dyUnaccel);
recursive_dispatch_move(self, &p);
if(self->wayland.locked_pointer) zwp_locked_pointer_v1_set_cursor_position_hint(self->wayland.locked_pointer, 0,CSD_BORDER_FRAME_TOP);
WAYLAND_EVENT_OP_END(self);
}
struct zwp_relative_pointer_v1_listener relative_pointer_listener =
{
relative_pointer_motion};
/* zwp_primary_selection_device_manager_v1 setup function */
static wayland_protocol_t* zwp_relative_pointer_manager_v1_setup(MwU32 name, struct _MwLLWayland* wayland) {
printf("Relative pointer\n");
wayland->relative_pointer_manager = wl_registry_bind(wayland->registry, name, &zwp_relative_pointer_manager_v1_interface, 1);
return NULL;
}
static void zwp_relative_pointer_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
(void)wayland;
(void)data;
}
/* `wl_pointer.motion` callback */
static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time,
wl_fixed_t surface_x, wl_fixed_t surface_y) {
MwLL self = data;
MwLL topmost_parent = self;
MwLL self = data;
MwLLMouse p;
(void)time;
(void)wl_pointer;
WAYLAND_EVENT_OP_START(self);
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
if(self->wayland.do_lock_pointer) {
return;
}
self->wayland.cur_mouse_pos.x = wl_fixed_to_int(surface_x);
self->wayland.cur_mouse_pos.y = wl_fixed_to_int(surface_y);
if(self->wayland.do_lock_pointer) {
self->wayland.cur_mouse_pos.x -= topmost_parent->wayland.ww / 2.;
self->wayland.cur_mouse_pos.y -= topmost_parent->wayland.wh / 2.;
}
p.point = self->wayland.cur_mouse_pos;
MwLLDispatch(self, move, &p);
@ -556,13 +591,6 @@ static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time
MwLLDispatch(currentlyHeldWidget, down, &p);
}
if(self->wayland.do_lock_pointer) {
topmost_parent->wayland.locked_pointer = zwp_pointer_constraints_v1_lock_pointer(topmost_parent->wayland.pointer_constraints, topmost_parent->wayland.backbuffer.surface, topmost_parent->wayland.pointer, topmost_parent->wayland.region, ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
zwp_locked_pointer_v1_set_cursor_position_hint(topmost_parent->wayland.locked_pointer, wl_fixed_from_double(topmost_parent->wayland.ww / 2.), wl_fixed_from_double(topmost_parent->wayland.wh / 2.));
wl_surface_commit(topmost_parent->wayland.backbuffer.surface);
zwp_locked_pointer_v1_destroy(topmost_parent->wayland.locked_pointer);
}
WAYLAND_EVENT_OP_END(self);
};
@ -735,6 +763,10 @@ static void keyboard_key(void* data,
if(self->wayland.framebuffer.surface) {
inArea |= self->wayland.framebuffer.surface == curSurface;
}
if(self->wayland.backbuffer.surface) {
inArea |= self->wayland.backbuffer.surface == curSurface;
}
if(inArea) {
xkb_layout_index_t layout;
MwU32 levels;
@ -1183,7 +1215,7 @@ static void xdg_toplevel_configure(void* data,
recursive_dispatch_resize(self);
if(self->wayland.pointer_constrained) {
zwp_locked_pointer_v1_set_cursor_position_hint(self->wayland.locked_pointer, wl_fixed_from_double(self->wayland.ww / 2.), wl_fixed_from_double(self->wayland.wh / 2.));
zwp_locked_pointer_v1_set_cursor_position_hint(self->wayland.locked_pointer, 0,CSD_BORDER_FRAME_TOP);
wl_surface_commit(self->wayland.framebuffer.surface);
}
};
@ -1290,10 +1322,10 @@ static void buffer_destroy(struct _MwLLWaylandShmBuffer* buffer) {
if(!buffer->setup) {
return;
}
wl_buffer_destroy(buffer->shm_buffer);
wl_buffer_destroy(buffer->shm_buffer_back);
wl_shm_pool_destroy(buffer->shm_pool);
wl_shm_pool_destroy(buffer->shm_pool_back);
if(buffer->shm_buffer) wl_buffer_destroy(buffer->shm_buffer);
if(buffer->shm_buffer_back) wl_buffer_destroy(buffer->shm_buffer_back);
if(buffer->shm_pool) wl_shm_pool_destroy(buffer->shm_pool);
if(buffer->shm_pool_back) wl_shm_pool_destroy(buffer->shm_pool_back);
close(buffer->fd);
close(buffer->fd_back);
buffer->setup = MwFALSE;
@ -1426,6 +1458,7 @@ static void setup_callbacks(struct _MwLLWayland* wayland) {
WL_INTERFACE(wl_data_device_manager);
WL_INTERFACE(zwp_primary_selection_device_manager_v1);
WL_INTERFACE(zwp_pointer_constraints_v1);
WL_INTERFACE(zwp_relative_pointer_manager_v1);
WL_INTERFACE(xdg_wm_base);
if(wayland->type == MWLL_WAYLAND_TOPLEVEL) {
WL_INTERFACE(wp_viewporter);
@ -1563,6 +1596,12 @@ static void setup_sublevel(MwLL parent, MwLL r, int x, int y) {
r->wayland.registry = wl_display_get_registry(parent->wayland.display);
r->wayland.display = parent->wayland.display;
if(parent->wayland.type == MWLL_WAYLAND_TOPLEVEL) {
r->wayland.sublevel->xdg_surface = parent->wayland.toplevel->xdg_surface;
} else {
r->wayland.sublevel->xdg_surface = parent->wayland.sublevel->xdg_surface;
}
wl_registry_add_listener(r->wayland.registry, &r->wayland.registry_listener, r);
if(wl_display_roundtrip(r->wayland.display) == -1) {
printf("roundtrip failed\n");
@ -1571,8 +1610,6 @@ static void setup_sublevel(MwLL parent, MwLL r, int x, int y) {
}
r->wayland.framebuffer.surface = wl_compositor_create_surface(compositor);
r->wayland.sublevel->xdg_surface =
xdg_wm_base_get_xdg_surface(WAYLAND_GET_INTERFACE(r->wayland, xdg_wm_base)->context, r->wayland.framebuffer.surface);
r->wayland.sublevel->subsurface = wl_subcompositor_get_subsurface(r->wayland.sublevel->subcompositor, r->wayland.framebuffer.surface, parent_surface);
@ -2400,10 +2437,29 @@ static void MwLLFocusImpl(MwLL handle) {
}
static void MwLLGrabPointerImpl(MwLL handle, int toggle) {
if(handle->wayland.pointer_constraints) {
MwLL topmost_parent = handle;
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
if(handle->wayland.pointer_constraints && handle->wayland.relative_pointer_manager) {
if(toggle) {
topmost_parent->wayland.locked_pointer = zwp_pointer_constraints_v1_lock_pointer(topmost_parent->wayland.pointer_constraints, topmost_parent->wayland.backbuffer.surface, topmost_parent->wayland.pointer, topmost_parent->wayland.region, ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
wl_surface_commit(topmost_parent->wayland.backbuffer.surface);
zwp_locked_pointer_v1_set_cursor_position_hint(topmost_parent->wayland.locked_pointer, 0,CSD_BORDER_FRAME_TOP);
handle->wayland.relative_pointer = zwp_relative_pointer_manager_v1_get_relative_pointer(handle->wayland.relative_pointer_manager, handle->wayland.pointer);
zwp_relative_pointer_v1_add_listener(handle->wayland.relative_pointer, &relative_pointer_listener, topmost_parent);
printf("%p\n", handle->wayland.relative_pointer);
} else {
if(topmost_parent->wayland.locked_pointer) {
zwp_locked_pointer_v1_destroy(topmost_parent->wayland.locked_pointer);
topmost_parent->wayland.locked_pointer = NULL;
}
if(topmost_parent->wayland.relative_pointer) {
zwp_relative_pointer_v1_destroy(topmost_parent->wayland.relative_pointer);
topmost_parent->wayland.relative_pointer = NULL;
}
}
handle->wayland.do_lock_pointer = toggle;
} else {
printf("[WARNING] MwLLGrabPointer not supported in Wayland session, zwp_pointer_constraints_v1 required.\n");
printf("[WARNING] MwLLGrabPointer not supported in Wayland session, zwp_pointer_constraints_v1 and relative_pointer_manager_v1 are required.\n");
}
}

View file

@ -316,6 +316,7 @@ static int create(MwWidget handle) {
if(!eglMakeCurrent(display, surface, surface, context)) {
printf("ERROR: eglMakeCurrent (setup): %0X\n", eglGetError());
}
eglSwapInterval(o->egl_display, 0);
o->egl_display = display;
o->egl_surface = surface;
@ -425,8 +426,6 @@ static void mwOpenGLMakeCurrentImpl(MwWidget handle) {
o->egl_context)) {
printf("ERROR: eglMakeCurrent, %0X\n", eglGetError());
}
eglSwapInterval(o->egl_display, 1);
}
#endif
}
@ -450,6 +449,7 @@ static void mwOpenGLSwapBufferImpl(MwWidget handle) {
#ifdef USE_WAYLAND
if(handle->lowlevel->common.type == MwLLBackendWayland) {
waylandopengl_t* o = handle->internal;
eglSwapInterval(o->egl_display, 0);
if(!eglSwapBuffers(o->egl_display, o->egl_surface)) {
printf("ERROR: eglSwapBuffers, %0X\n", eglGetError());
};