mirror of
https://github.com/kovidgoyal/kitty.git
synced 2024-09-11 14:45:31 +03: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:
parent
7d8c017215
commit
cff490f881
@ -70,6 +70,7 @@ def main(args: List[str]=sys.argv) -> None:
|
||||
glfw_css_map = {}
|
||||
css_to_enum = {}
|
||||
xc_to_enum = {}
|
||||
glfw_wayland = {}
|
||||
for line in cursors.splitlines():
|
||||
line = line.strip()
|
||||
if line:
|
||||
@ -83,6 +84,7 @@ def main(args: List[str]=sys.argv) -> None:
|
||||
glfw_css_map[glfw_name] = css
|
||||
css_to_enum[css] = enum_name
|
||||
css_names.append(css)
|
||||
glfw_wayland[glfw_name] = 'WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_' + wayland.replace('-', '_').upper()
|
||||
for n in names:
|
||||
kitty_to_enum_map[n] = enum_name
|
||||
glfw_enum.append(glfw_name)
|
||||
@ -112,6 +114,7 @@ def main(args: List[str]=sys.argv) -> None:
|
||||
|
||||
glfw_enum.append('GLFW_INVALID_CURSOR')
|
||||
patch_file('glfw/glfw3.h', 'mouse cursor shapes', '\n'.join(f' {x},' for x in glfw_enum))
|
||||
patch_file('glfw/wl_window.c', 'glfw to wayland mapping', '\n'.join(f' C({g}, {x});' for g, x in glfw_wayland.items()))
|
||||
patch_file('glfw/wl_window.c', 'glfw to xc mapping', '\n'.join(f' C({g}, {x});' for g, x in glfw_xc_map.items()))
|
||||
patch_file('glfw/x11_window.c', 'glfw to xc mapping', '\n'.join(f' {x}' for x in glfw_xfont_map))
|
||||
patch_file('kitty/data-types.h', 'mouse shapes', '\n'.join(f' {x},' for x in enum_to_glfw_map))
|
||||
@ -139,7 +142,7 @@ def main(args: List[str]=sys.argv) -> None:
|
||||
f'\t{x} PointerShape = {i}' for i, x in enumerate(enum_to_glfw_map)), start_marker='// ', end_marker='')
|
||||
patch_file('tools/tui/loop/mouse.go', 'pointer shape tostring', '\n'.join(
|
||||
f'''\tcase {x}: return "{x.lower().rpartition('_')[0].replace('_', '-')}"''' for x in enum_to_glfw_map), start_marker='// ', end_marker='')
|
||||
patch_file('kittens/mouse_demo/main.go', 'all pointer shapes', '\n'.join(
|
||||
patch_file('tools/cmd/mouse_demo/main.go', 'all pointer shapes', '\n'.join(
|
||||
f'\tloop.{x},' for x in enum_to_glfw_map), start_marker='// ', end_marker='')
|
||||
|
||||
subprocess.check_call(['glfw/glfw.py'])
|
||||
|
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;
|
||||
|
Loading…
Reference in New Issue
Block a user