mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-26 02:02:14 +02:00
Wayland: Add support for the new cursor-shape protocol
It is currently disabled because no compositor seems to support it. Hyprland reports it as available but using it causes Hyprland to crash. Plasma 6 is supposed to have it but I am not installing a beta just for this. Typical Wayland.
This commit is contained in:
13
glfw/wl_init.c
vendored
13
glfw/wl_init.c
vendored
@@ -572,9 +572,16 @@ static void seatHandleCapabilities(void* data UNUSED,
|
||||
{
|
||||
_glfw.wl.pointer = wl_seat_get_pointer(seat);
|
||||
wl_pointer_add_listener(_glfw.wl.pointer, &pointerListener, NULL);
|
||||
if (_glfw.wl.wp_cursor_shape_manager_v1) {
|
||||
if (_glfw.wl.wp_cursor_shape_device_v1) wp_cursor_shape_device_v1_destroy(_glfw.wl.wp_cursor_shape_device_v1);
|
||||
_glfw.wl.wp_cursor_shape_device_v1 = NULL;
|
||||
_glfw.wl.wp_cursor_shape_device_v1 = wp_cursor_shape_manager_v1_get_pointer(_glfw.wl.wp_cursor_shape_manager_v1, _glfw.wl.pointer);
|
||||
}
|
||||
}
|
||||
else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && _glfw.wl.pointer)
|
||||
{
|
||||
if (_glfw.wl.wp_cursor_shape_device_v1) wp_cursor_shape_device_v1_destroy(_glfw.wl.wp_cursor_shape_device_v1);
|
||||
_glfw.wl.wp_cursor_shape_device_v1 = NULL;
|
||||
wl_pointer_destroy(_glfw.wl.pointer);
|
||||
_glfw.wl.pointer = NULL;
|
||||
if (_glfw.wl.cursorAnimationTimer) toggleTimer(&_glfw.wl.eventLoopData, _glfw.wl.cursorAnimationTimer, 0);
|
||||
@@ -716,6 +723,9 @@ static void registryHandleGlobal(void* data UNUSED,
|
||||
else if (is(xdg_activation_v1)) {
|
||||
_glfw.wl.xdg_activation_v1 = wl_registry_bind(registry, name, &xdg_activation_v1_interface, 1);
|
||||
}
|
||||
else if (false && is(wp_cursor_shape_manager_v1)) {
|
||||
_glfw.wl.wp_cursor_shape_manager_v1 = wl_registry_bind(registry, name, &wp_cursor_shape_manager_v1_interface, 1);
|
||||
}
|
||||
#undef is
|
||||
}
|
||||
|
||||
@@ -950,6 +960,9 @@ void _glfwPlatformTerminate(void)
|
||||
zwp_primary_selection_device_manager_v1_destroy(_glfw.wl.primarySelectionDeviceManager);
|
||||
if (_glfw.wl.xdg_activation_v1)
|
||||
xdg_activation_v1_destroy(_glfw.wl.xdg_activation_v1);
|
||||
if (_glfw.wl.wp_cursor_shape_manager_v1)
|
||||
wp_cursor_shape_manager_v1_destroy(_glfw.wl.wp_cursor_shape_manager_v1);
|
||||
|
||||
if (_glfw.wl.registry)
|
||||
wl_registry_destroy(_glfw.wl.registry);
|
||||
if (_glfw.wl.display)
|
||||
|
||||
3
glfw/wl_platform.h
vendored
3
glfw/wl_platform.h
vendored
@@ -60,6 +60,7 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
|
||||
#include "wayland-primary-selection-unstable-v1-client-protocol.h"
|
||||
#include "wl_text_input.h"
|
||||
#include "wayland-xdg-activation-v1-client-protocol.h"
|
||||
#include "wayland-cursor-shape-v1-client-protocol.h"
|
||||
|
||||
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
|
||||
#define _glfw_dlclose(handle) dlclose(handle)
|
||||
@@ -286,6 +287,8 @@ typedef struct _GLFWlibraryWayland
|
||||
struct zwp_primary_selection_device_v1* primarySelectionDevice;
|
||||
struct zwp_primary_selection_source_v1* dataSourceForPrimarySelection;
|
||||
struct xdg_activation_v1* xdg_activation_v1;
|
||||
struct wp_cursor_shape_manager_v1* wp_cursor_shape_manager_v1;
|
||||
struct wp_cursor_shape_device_v1* wp_cursor_shape_device_v1;
|
||||
|
||||
int compositorVersion;
|
||||
int seatVersion;
|
||||
|
||||
50
glfw/wl_window.c
vendored
50
glfw/wl_window.c
vendored
@@ -152,10 +152,58 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image, bool is_opaque,
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static int
|
||||
glfw_cursor_shape_to_wayland_cursor_shape(GLFWCursorShape g) {
|
||||
#define C(g, w) case g: return w;
|
||||
switch(g) {
|
||||
/* start glfw to wayland mapping (auto generated by gen-key-constants.py do not edit) */
|
||||
C(GLFW_DEFAULT_CURSOR, WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_DEFAULT);
|
||||
C(GLFW_TEXT_CURSOR, WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_TEXT);
|
||||
C(GLFW_POINTER_CURSOR, WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_POINTER);
|
||||
C(GLFW_HELP_CURSOR, WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_HELP);
|
||||
C(GLFW_WAIT_CURSOR, WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_WAIT);
|
||||
C(GLFW_PROGRESS_CURSOR, WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_PROGRESS);
|
||||
C(GLFW_CROSSHAIR_CURSOR, WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_CROSSHAIR);
|
||||
C(GLFW_CELL_CURSOR, WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_CELL);
|
||||
C(GLFW_VERTICAL_TEXT_CURSOR, WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_VERTICAL_TEXT);
|
||||
C(GLFW_MOVE_CURSOR, WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_MOVE);
|
||||
C(GLFW_E_RESIZE_CURSOR, WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_E_RESIZE);
|
||||
C(GLFW_NE_RESIZE_CURSOR, WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NE_RESIZE);
|
||||
C(GLFW_NW_RESIZE_CURSOR, WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NW_RESIZE);
|
||||
C(GLFW_N_RESIZE_CURSOR, WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_N_RESIZE);
|
||||
C(GLFW_SE_RESIZE_CURSOR, WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_SE_RESIZE);
|
||||
C(GLFW_SW_RESIZE_CURSOR, WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_SW_RESIZE);
|
||||
C(GLFW_S_RESIZE_CURSOR, WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_S_RESIZE);
|
||||
C(GLFW_W_RESIZE_CURSOR, WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_W_RESIZE);
|
||||
C(GLFW_EW_RESIZE_CURSOR, WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_EW_RESIZE);
|
||||
C(GLFW_NS_RESIZE_CURSOR, WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NS_RESIZE);
|
||||
C(GLFW_NESW_RESIZE_CURSOR, WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NESW_RESIZE);
|
||||
C(GLFW_NWSE_RESIZE_CURSOR, WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NWSE_RESIZE);
|
||||
C(GLFW_ZOOM_IN_CURSOR, WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_ZOOM_IN);
|
||||
C(GLFW_ZOOM_OUT_CURSOR, WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_ZOOM_OUT);
|
||||
C(GLFW_ALIAS_CURSOR, WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_ALIAS);
|
||||
C(GLFW_COPY_CURSOR, WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_COPY);
|
||||
C(GLFW_NOT_ALLOWED_CURSOR, WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NOT_ALLOWED);
|
||||
C(GLFW_NO_DROP_CURSOR, WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NO_DROP);
|
||||
C(GLFW_GRAB_CURSOR, WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_GRAB);
|
||||
C(GLFW_GRABBING_CURSOR, WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_GRABBING);
|
||||
/* end glfw to wayland mapping */
|
||||
default: return -1;
|
||||
}
|
||||
#undef C
|
||||
}
|
||||
|
||||
static void
|
||||
setCursorImage(_GLFWwindow* window, bool on_theme_change) {
|
||||
_GLFWcursorWayland defaultCursor = {.shape = GLFW_DEFAULT_CURSOR};
|
||||
_GLFWcursorWayland* cursorWayland = window->cursor ? &window->cursor->wl : &defaultCursor;
|
||||
if (_glfw.wl.wp_cursor_shape_device_v1) {
|
||||
int which = glfw_cursor_shape_to_wayland_cursor_shape(cursorWayland->shape);
|
||||
if (which > -1) {
|
||||
wp_cursor_shape_device_v1_set_shape(_glfw.wl.wp_cursor_shape_device_v1, _glfw.wl.serial, (uint32_t)which);
|
||||
return;
|
||||
}
|
||||
}
|
||||
struct wl_cursor_image* image = NULL;
|
||||
struct wl_buffer* buffer = NULL;
|
||||
struct wl_surface* surface = _glfw.wl.cursorSurface;
|
||||
@@ -717,7 +765,7 @@ static void incrementCursorImage(_GLFWwindow* window)
|
||||
{
|
||||
if (window && window->wl.decorations.focus == CENTRAL_WINDOW && window->cursorMode != GLFW_CURSOR_HIDDEN) {
|
||||
_GLFWcursor* cursor = window->wl.currentCursor;
|
||||
if (cursor && cursor->wl.cursor)
|
||||
if (cursor && cursor->wl.cursor && cursor->wl.cursor->image_count)
|
||||
{
|
||||
cursor->wl.currentImage += 1;
|
||||
cursor->wl.currentImage %= cursor->wl.cursor->image_count;
|
||||
|
||||
Reference in New Issue
Block a user