mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-03-30 11:10:23 -04:00
cursor-shape: add support for server side cursor shapes
This implements support for the new cursor-shape-v1 protocol. When available, we use it, instead of client-side cursor surfaces, to select the xcursor shape. Note that we still need to keep client side pointers, for: * backward compatibility * to be able to "hide" the cursor Closes #1379
This commit is contained in:
parent
ee794a121e
commit
c8e13ad393
8 changed files with 280 additions and 20 deletions
|
|
@ -53,6 +53,10 @@
|
||||||
* Support for the new fractional-scaling-v1 Wayland protocol. This
|
* Support for the new fractional-scaling-v1 Wayland protocol. This
|
||||||
brings true fractional scaling to Wayland in general, and with this
|
brings true fractional scaling to Wayland in general, and with this
|
||||||
release, foot.
|
release, foot.
|
||||||
|
* Support for the new `cursor-shape-v1` Wayland protocol, i.e. server
|
||||||
|
side cursor shapes ([#1379][1379]).
|
||||||
|
|
||||||
|
[1379]: https://codeberg.org/dnkl/foot/issues/1379
|
||||||
|
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
|
||||||
147
cursor-shape-v1.xml
Normal file
147
cursor-shape-v1.xml
Normal file
|
|
@ -0,0 +1,147 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<protocol name="cursor_shape_v1">
|
||||||
|
<copyright>
|
||||||
|
Copyright 2018 The Chromium Authors
|
||||||
|
Copyright 2023 Simon Ser
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
The above copyright notice and this permission notice (including the next
|
||||||
|
paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
Software.
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
</copyright>
|
||||||
|
|
||||||
|
<interface name="wp_cursor_shape_manager_v1" version="1">
|
||||||
|
<description summary="cursor shape manager">
|
||||||
|
This global offers an alternative, optional way to set cursor images. This
|
||||||
|
new way uses enumerated cursors instead of a wl_surface like
|
||||||
|
wl_pointer.set_cursor does.
|
||||||
|
|
||||||
|
Warning! The protocol described in this file is currently in the testing
|
||||||
|
phase. Backward compatible changes may be added together with the
|
||||||
|
corresponding interface version bump. Backward incompatible changes can
|
||||||
|
only be done by creating a new major version of the extension.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<request name="destroy" type="destructor">
|
||||||
|
<description summary="destroy the manager">
|
||||||
|
Destroy the cursor shape manager.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="get_pointer">
|
||||||
|
<description summary="manage the cursor shape of a pointer device">
|
||||||
|
Obtain a wp_cursor_shape_device_v1 for a wl_pointer object.
|
||||||
|
</description>
|
||||||
|
<arg name="cursor_shape_device" type="new_id" interface="wp_cursor_shape_device_v1"/>
|
||||||
|
<arg name="pointer" type="object" interface="wl_pointer"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="get_tablet_tool_v2">
|
||||||
|
<description summary="manage the cursor shape of a tablet tool device">
|
||||||
|
Obtain a wp_cursor_shape_device_v1 for a zwp_tablet_tool_v2 object.
|
||||||
|
</description>
|
||||||
|
<arg name="cursor_shape_device" type="new_id" interface="wp_cursor_shape_device_v1"/>
|
||||||
|
<arg name="tablet_tool" type="object" interface="zwp_tablet_tool_v2"/>
|
||||||
|
</request>
|
||||||
|
</interface>
|
||||||
|
|
||||||
|
<interface name="wp_cursor_shape_device_v1" version="1">
|
||||||
|
<description summary="cursor shape for a device">
|
||||||
|
This interface advertises the list of supported cursor shapes for a
|
||||||
|
device, and allows clients to set the cursor shape.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<enum name="shape">
|
||||||
|
<description summary="cursor shapes">
|
||||||
|
This enum describes cursor shapes.
|
||||||
|
|
||||||
|
The names are taken from the CSS W3C specification:
|
||||||
|
https://w3c.github.io/csswg-drafts/css-ui/#cursor
|
||||||
|
</description>
|
||||||
|
<entry name="default" value="1" summary="default cursor"/>
|
||||||
|
<entry name="context_menu" value="2" summary="a context menu is available for the object under the cursor"/>
|
||||||
|
<entry name="help" value="3" summary="help is available for the object under the cursor"/>
|
||||||
|
<entry name="pointer" value="4" summary="pointer that indicates a link or another interactive element"/>
|
||||||
|
<entry name="progress" value="5" summary="progress indicator"/>
|
||||||
|
<entry name="wait" value="6" summary="program is busy, user should wait"/>
|
||||||
|
<entry name="cell" value="7" summary="a cell or set of cells may be selected"/>
|
||||||
|
<entry name="crosshair" value="8" summary="simple crosshair"/>
|
||||||
|
<entry name="text" value="9" summary="text may be selected"/>
|
||||||
|
<entry name="vertical_text" value="10" summary="vertical text may be selected"/>
|
||||||
|
<entry name="alias" value="11" summary="drag-and-drop: alias of/shortcut to something is to be created"/>
|
||||||
|
<entry name="copy" value="12" summary="drag-and-drop: something is to be copied"/>
|
||||||
|
<entry name="move" value="13" summary="drag-and-drop: something is to be moved"/>
|
||||||
|
<entry name="no_drop" value="14" summary="drag-and-drop: the dragged item cannot be dropped at the current cursor location"/>
|
||||||
|
<entry name="not_allowed" value="15" summary="drag-and-drop: the requested action will not be carried out"/>
|
||||||
|
<entry name="grab" value="16" summary="drag-and-drop: something can be grabbed"/>
|
||||||
|
<entry name="grabbing" value="17" summary="drag-and-drop: something is being grabbed"/>
|
||||||
|
<entry name="e_resize" value="18" summary="resizing: the east border is to be moved"/>
|
||||||
|
<entry name="n_resize" value="19" summary="resizing: the north border is to be moved"/>
|
||||||
|
<entry name="ne_resize" value="20" summary="resizing: the north-east corner is to be moved"/>
|
||||||
|
<entry name="nw_resize" value="21" summary="resizing: the north-west corner is to be moved"/>
|
||||||
|
<entry name="s_resize" value="22" summary="resizing: the south border is to be moved"/>
|
||||||
|
<entry name="se_resize" value="23" summary="resizing: the south-east corner is to be moved"/>
|
||||||
|
<entry name="sw_resize" value="24" summary="resizing: the south-west corner is to be moved"/>
|
||||||
|
<entry name="w_resize" value="25" summary="resizing: the west border is to be moved"/>
|
||||||
|
<entry name="ew_resize" value="26" summary="resizing: the east and west borders are to be moved"/>
|
||||||
|
<entry name="ns_resize" value="27" summary="resizing: the north and south borders are to be moved"/>
|
||||||
|
<entry name="nesw_resize" value="28" summary="resizing: the north-east and south-west corners are to be moved"/>
|
||||||
|
<entry name="nwse_resize" value="29" summary="resizing: the north-west and south-east corners are to be moved"/>
|
||||||
|
<entry name="col_resize" value="30" summary="resizing: that the item/column can be resized horizontally"/>
|
||||||
|
<entry name="row_resize" value="31" summary="resizing: that the item/row can be resized vertically"/>
|
||||||
|
<entry name="all_scroll" value="32" summary="something can be scrolled in any direction"/>
|
||||||
|
<entry name="zoom_in" value="33" summary="something can be zoomed in"/>
|
||||||
|
<entry name="zoom_out" value="34" summary="something can be zoomed out"/>
|
||||||
|
</enum>
|
||||||
|
|
||||||
|
<enum name="error">
|
||||||
|
<entry name="invalid_shape" value="1"
|
||||||
|
summary="the specified shape value is invalid"/>
|
||||||
|
</enum>
|
||||||
|
|
||||||
|
<request name="destroy" type="destructor">
|
||||||
|
<description summary="destroy the cursor shape device">
|
||||||
|
Destroy the cursor shape device.
|
||||||
|
|
||||||
|
The device cursor shape remains unchanged.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="set_shape">
|
||||||
|
<description summary="set device cursor to the shape">
|
||||||
|
Sets the device cursor to the specified shape. The compositor will
|
||||||
|
change the cursor image based on the specified shape.
|
||||||
|
|
||||||
|
The cursor actually changes only if the input device focus is one of
|
||||||
|
the requesting client's surfaces. If any, the previous cursor image
|
||||||
|
(surface or shape) is replaced.
|
||||||
|
|
||||||
|
The "shape" argument must be a valid enum entry, otherwise the
|
||||||
|
invalid_shape protocol error is raised.
|
||||||
|
|
||||||
|
This is similar to the wl_pointer.set_cursor and
|
||||||
|
zwp_tablet_tool_v2.set_cursor requests, but this request accepts a
|
||||||
|
shape instead of contents in the form of a surface. Clients can mix
|
||||||
|
set_cursor and set_shape requests.
|
||||||
|
|
||||||
|
The serial parameter must match the latest wl_pointer.enter or
|
||||||
|
zwp_tablet_tool_v2.proximity_in serial number sent to the client.
|
||||||
|
Otherwise the request will be ignored.
|
||||||
|
</description>
|
||||||
|
<arg name="serial" type="uint" summary="serial number of the enter event"/>
|
||||||
|
<arg name="shape" type="uint" enum="shape"/>
|
||||||
|
</request>
|
||||||
|
</interface>
|
||||||
|
</protocol>
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
const char *
|
const char *
|
||||||
cursor_shape_to_string(enum cursor_shape shape)
|
cursor_shape_to_string(enum cursor_shape shape)
|
||||||
{
|
{
|
||||||
static const char *const table[] = {
|
static const char *const table[CURSOR_SHAPE_COUNT] = {
|
||||||
[CURSOR_SHAPE_NONE] = NULL,
|
[CURSOR_SHAPE_NONE] = NULL,
|
||||||
[CURSOR_SHAPE_HIDDEN] = "hidden",
|
[CURSOR_SHAPE_HIDDEN] = "hidden",
|
||||||
[CURSOR_SHAPE_LEFT_PTR] = "left_ptr",
|
[CURSOR_SHAPE_LEFT_PTR] = "left_ptr",
|
||||||
|
|
@ -27,3 +27,26 @@ cursor_shape_to_string(enum cursor_shape shape)
|
||||||
xassert(shape <= ALEN(table));
|
xassert(shape <= ALEN(table));
|
||||||
return table[shape];
|
return table[shape];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_CURSOR_SHAPE)
|
||||||
|
enum wp_cursor_shape_device_v1_shape
|
||||||
|
cursor_shape_to_server_shape(enum cursor_shape shape)
|
||||||
|
{
|
||||||
|
static const enum wp_cursor_shape_device_v1_shape table[CURSOR_SHAPE_COUNT] = {
|
||||||
|
[CURSOR_SHAPE_LEFT_PTR] = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_DEFAULT,
|
||||||
|
[CURSOR_SHAPE_TEXT] = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_TEXT,
|
||||||
|
[CURSOR_SHAPE_TEXT_FALLBACK] = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_TEXT,
|
||||||
|
[CURSOR_SHAPE_TOP_LEFT_CORNER] = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NW_RESIZE,
|
||||||
|
[CURSOR_SHAPE_TOP_RIGHT_CORNER] = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NE_RESIZE,
|
||||||
|
[CURSOR_SHAPE_BOTTOM_LEFT_CORNER] = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_SW_RESIZE,
|
||||||
|
[CURSOR_SHAPE_BOTTOM_RIGHT_CORNER] = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_SE_RESIZE,
|
||||||
|
[CURSOR_SHAPE_LEFT_SIDE] = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_W_RESIZE,
|
||||||
|
[CURSOR_SHAPE_RIGHT_SIDE] = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_E_RESIZE,
|
||||||
|
[CURSOR_SHAPE_TOP_SIDE] = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_N_RESIZE,
|
||||||
|
[CURSOR_SHAPE_BOTTOM_SIDE] = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_S_RESIZE,
|
||||||
|
};
|
||||||
|
|
||||||
|
xassert(shape <= ALEN(table));
|
||||||
|
return table[shape];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,14 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#if defined(HAVE_CURSOR_SHAPE)
|
||||||
|
#include <cursor-shape-v1.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
enum cursor_shape {
|
enum cursor_shape {
|
||||||
CURSOR_SHAPE_NONE,
|
CURSOR_SHAPE_NONE,
|
||||||
CURSOR_SHAPE_CUSTOM,
|
CURSOR_SHAPE_CUSTOM,
|
||||||
|
|
||||||
CURSOR_SHAPE_HIDDEN,
|
CURSOR_SHAPE_HIDDEN,
|
||||||
|
|
||||||
CURSOR_SHAPE_LEFT_PTR,
|
CURSOR_SHAPE_LEFT_PTR,
|
||||||
CURSOR_SHAPE_TEXT,
|
CURSOR_SHAPE_TEXT,
|
||||||
CURSOR_SHAPE_TEXT_FALLBACK,
|
CURSOR_SHAPE_TEXT_FALLBACK,
|
||||||
|
|
@ -16,6 +20,13 @@ enum cursor_shape {
|
||||||
CURSOR_SHAPE_RIGHT_SIDE,
|
CURSOR_SHAPE_RIGHT_SIDE,
|
||||||
CURSOR_SHAPE_TOP_SIDE,
|
CURSOR_SHAPE_TOP_SIDE,
|
||||||
CURSOR_SHAPE_BOTTOM_SIDE,
|
CURSOR_SHAPE_BOTTOM_SIDE,
|
||||||
|
|
||||||
|
CURSOR_SHAPE_COUNT,
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *cursor_shape_to_string(enum cursor_shape shape);
|
const char *cursor_shape_to_string(enum cursor_shape shape);
|
||||||
|
|
||||||
|
#if defined(HAVE_CURSOR_SHAPE)
|
||||||
|
enum wp_cursor_shape_device_v1_shape cursor_shape_to_server_shape(
|
||||||
|
enum cursor_shape shape);
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -170,6 +170,12 @@ else
|
||||||
fractional_scale = false
|
fractional_scale = false
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# TODO: check wayland-protocols version
|
||||||
|
wl_proto_xml += [wayland_protocols_datadir + '/unstable/tablet/tablet-unstable-v2.xml', # required by cursor-shape-v1
|
||||||
|
'cursor-shape-v1.xml', # TODO: use wayland-protocols
|
||||||
|
]
|
||||||
|
add_project_arguments('-DHAVE_CURSOR_SHAPE', language: 'c')
|
||||||
|
|
||||||
foreach prot : wl_proto_xml
|
foreach prot : wl_proto_xml
|
||||||
wl_proto_headers += custom_target(
|
wl_proto_headers += custom_target(
|
||||||
prot.underscorify() + '-client-header',
|
prot.underscorify() + '-client-header',
|
||||||
|
|
|
||||||
47
render.c
47
render.c
|
|
@ -31,6 +31,7 @@
|
||||||
#include "box-drawing.h"
|
#include "box-drawing.h"
|
||||||
#include "char32.h"
|
#include "char32.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "cursor-shape.h"
|
||||||
#include "grid.h"
|
#include "grid.h"
|
||||||
#include "hsl.h"
|
#include "hsl.h"
|
||||||
#include "ime.h"
|
#include "ime.h"
|
||||||
|
|
@ -4259,35 +4260,46 @@ render_xcursor_update(struct seat *seat)
|
||||||
if (seat->pointer.shape == CURSOR_SHAPE_HIDDEN) {
|
if (seat->pointer.shape == CURSOR_SHAPE_HIDDEN) {
|
||||||
/* Hide cursor */
|
/* Hide cursor */
|
||||||
wl_surface_attach(seat->pointer.surface.surf, NULL, 0, 0);
|
wl_surface_attach(seat->pointer.surface.surf, NULL, 0, 0);
|
||||||
|
wl_pointer_set_cursor(
|
||||||
|
seat->wl_pointer, seat->pointer.serial, seat->pointer.surface.surf,
|
||||||
|
0, 0);
|
||||||
wl_surface_commit(seat->pointer.surface.surf);
|
wl_surface_commit(seat->pointer.surface.surf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
xassert(seat->pointer.cursor != NULL);
|
xassert(seat->pointer.cursor != NULL);
|
||||||
|
|
||||||
const float scale = seat->pointer.scale;
|
#if defined(HAVE_CURSOR_SHAPE)
|
||||||
struct wl_cursor_image *image = seat->pointer.cursor->images[0];
|
if (seat->pointer.shape_device != NULL) {
|
||||||
struct wl_buffer *buf = wl_cursor_image_get_buffer(image);
|
wp_cursor_shape_device_v1_set_shape(
|
||||||
|
seat->pointer.shape_device,
|
||||||
|
seat->pointer.serial,
|
||||||
|
cursor_shape_to_server_shape(seat->pointer.shape));
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
const int scale = seat->pointer.scale;
|
||||||
|
struct wl_cursor_image *image = seat->pointer.cursor->images[0];
|
||||||
|
|
||||||
wayl_surface_scale_explicit_width_height(
|
wl_surface_attach(
|
||||||
seat->mouse_focus->window,
|
seat->pointer.surface.surf, wl_cursor_image_get_buffer(image), 0, 0);
|
||||||
&seat->pointer.surface, image->width, image->height, scale);
|
|
||||||
|
|
||||||
wl_surface_attach(seat->pointer.surface.surf, buf, 0, 0);
|
wl_pointer_set_cursor(
|
||||||
|
seat->wl_pointer, seat->pointer.serial,
|
||||||
|
seat->pointer.surface.surf,
|
||||||
|
image->hotspot_x / scale, image->hotspot_y / scale);
|
||||||
|
|
||||||
wl_pointer_set_cursor(
|
wl_surface_damage_buffer(
|
||||||
seat->wl_pointer, seat->pointer.serial,
|
seat->pointer.surface.surf, 0, 0, INT32_MAX, INT32_MAX);
|
||||||
seat->pointer.surface.surf,
|
|
||||||
image->hotspot_x / scale, image->hotspot_y / scale);
|
|
||||||
|
|
||||||
wl_surface_damage_buffer(
|
wl_surface_set_buffer_scale(seat->pointer.surface.surf, scale);
|
||||||
seat->pointer.surface.surf, 0, 0, INT32_MAX, INT32_MAX);
|
|
||||||
|
|
||||||
xassert(seat->pointer.xcursor_callback == NULL);
|
xassert(seat->pointer.xcursor_callback == NULL);
|
||||||
seat->pointer.xcursor_callback = wl_surface_frame(seat->pointer.surface.surf);
|
seat->pointer.xcursor_callback = wl_surface_frame(seat->pointer.surface.surf);
|
||||||
wl_callback_add_listener(seat->pointer.xcursor_callback, &xcursor_listener, seat);
|
wl_callback_add_listener(seat->pointer.xcursor_callback, &xcursor_listener, seat);
|
||||||
|
|
||||||
wl_surface_commit(seat->pointer.surface.surf);
|
wl_surface_commit(seat->pointer.surface.surf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -4452,6 +4464,7 @@ render_xcursor_set(struct seat *seat, struct terminal *term, enum cursor_shape s
|
||||||
if (seat->pointer.shape == shape)
|
if (seat->pointer.shape == shape)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
/* TODO: skip this when using server-side cursors */
|
||||||
if (shape != CURSOR_SHAPE_HIDDEN) {
|
if (shape != CURSOR_SHAPE_HIDDEN) {
|
||||||
const char *const xcursor = cursor_shape_to_string(shape);
|
const char *const xcursor = cursor_shape_to_string(shape);
|
||||||
const char *const fallback =
|
const char *const fallback =
|
||||||
|
|
|
||||||
46
wayland.c
46
wayland.c
|
|
@ -14,6 +14,10 @@
|
||||||
#include <wayland-cursor.h>
|
#include <wayland-cursor.h>
|
||||||
#include <xkbcommon/xkbcommon-compose.h>
|
#include <xkbcommon/xkbcommon-compose.h>
|
||||||
|
|
||||||
|
#if defined(HAVE_CURSOR_SHAPE)
|
||||||
|
#include <cursor-shape-v1.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <tllist.h>
|
#include <tllist.h>
|
||||||
|
|
||||||
#define LOG_MODULE "wayland"
|
#define LOG_MODULE "wayland"
|
||||||
|
|
@ -209,6 +213,11 @@ seat_destroy(struct seat *seat)
|
||||||
if (seat->data_device != NULL)
|
if (seat->data_device != NULL)
|
||||||
wl_data_device_release(seat->data_device);
|
wl_data_device_release(seat->data_device);
|
||||||
|
|
||||||
|
#if defined(HAVE_CURSOR_SHAPE)
|
||||||
|
if (seat->pointer.shape_device != NULL)
|
||||||
|
wp_cursor_shape_device_v1_destroy(seat->pointer.shape_device);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (seat->wl_keyboard != NULL)
|
if (seat->wl_keyboard != NULL)
|
||||||
wl_keyboard_release(seat->wl_keyboard);
|
wl_keyboard_release(seat->wl_keyboard);
|
||||||
if (seat->wl_pointer != NULL)
|
if (seat->wl_pointer != NULL)
|
||||||
|
|
@ -316,9 +325,22 @@ seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
|
||||||
|
|
||||||
seat->wl_pointer = wl_seat_get_pointer(wl_seat);
|
seat->wl_pointer = wl_seat_get_pointer(wl_seat);
|
||||||
wl_pointer_add_listener(seat->wl_pointer, &pointer_listener, seat);
|
wl_pointer_add_listener(seat->wl_pointer, &pointer_listener, seat);
|
||||||
|
|
||||||
|
#if defined(HAVE_CURSOR_SHAPE)
|
||||||
|
if (seat->wayl->cursor_shape_manager != NULL) {
|
||||||
|
xassert(seat->pointer.shape_device == NULL);
|
||||||
|
seat->pointer.shape_device = wp_cursor_shape_manager_v1_get_pointer(
|
||||||
|
seat->wayl->cursor_shape_manager, seat->wl_pointer);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (seat->wl_pointer != NULL) {
|
if (seat->wl_pointer != NULL) {
|
||||||
|
#if defined(HAVE_CURSOR_SHAPE)
|
||||||
|
wp_cursor_shape_device_v1_destroy(seat->pointer.shape_device);
|
||||||
|
seat->pointer.shape_device = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
wl_pointer_release(seat->wl_pointer);
|
wl_pointer_release(seat->wl_pointer);
|
||||||
wl_surface_destroy(seat->pointer.surface.surf);
|
wl_surface_destroy(seat->pointer.surface.surf);
|
||||||
|
|
||||||
|
|
@ -1167,6 +1189,17 @@ handle_global(void *data, struct wl_registry *registry,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_CURSOR_SHAPE)
|
||||||
|
else if (strcmp(interface, wp_cursor_shape_manager_v1_interface.name) == 0) {
|
||||||
|
const uint32_t required = 1;
|
||||||
|
if (!verify_iface_version(interface, version, required))
|
||||||
|
return;
|
||||||
|
|
||||||
|
wayl->cursor_shape_manager = wl_registry_bind(
|
||||||
|
wayl->registry, name, &wp_cursor_shape_manager_v1_interface, required);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(FOOT_IME_ENABLED) && FOOT_IME_ENABLED
|
#if defined(FOOT_IME_ENABLED) && FOOT_IME_ENABLED
|
||||||
else if (strcmp(interface, zwp_text_input_manager_v3_interface.name) == 0) {
|
else if (strcmp(interface, zwp_text_input_manager_v3_interface.name) == 0) {
|
||||||
const uint32_t required = 1;
|
const uint32_t required = 1;
|
||||||
|
|
@ -1401,6 +1434,15 @@ wayl_init(struct fdm *fdm, struct key_binding_manager *key_binding_manager,
|
||||||
LOG_WARN("fractional scaling not available");
|
LOG_WARN("fractional scaling not available");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_CURSOR_SHAPE)
|
||||||
|
if (wayl->cursor_shape_manager == NULL) {
|
||||||
|
#else
|
||||||
|
if (true) {
|
||||||
|
#endif
|
||||||
|
LOG_WARN("no server-side cursors available, "
|
||||||
|
"falling back to client-side cursors");
|
||||||
|
}
|
||||||
|
|
||||||
if (presentation_timings && wayl->presentation == NULL) {
|
if (presentation_timings && wayl->presentation == NULL) {
|
||||||
LOG_ERR("presentation time interface not implemented by compositor");
|
LOG_ERR("presentation time interface not implemented by compositor");
|
||||||
goto out;
|
goto out;
|
||||||
|
|
@ -1495,6 +1537,10 @@ wayl_destroy(struct wayland *wayl)
|
||||||
if (wayl->viewporter != NULL)
|
if (wayl->viewporter != NULL)
|
||||||
wp_viewporter_destroy(wayl->viewporter);
|
wp_viewporter_destroy(wayl->viewporter);
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(HAVE_CURSOR_SHAPE)
|
||||||
|
if (wayl->cursor_shape_manager != NULL)
|
||||||
|
wp_cursor_shape_manager_v1_destroy(wayl->cursor_shape_manager);
|
||||||
|
#endif
|
||||||
#if defined(HAVE_XDG_ACTIVATION)
|
#if defined(HAVE_XDG_ACTIVATION)
|
||||||
if (wayl->xdg_activation != NULL)
|
if (wayl->xdg_activation != NULL)
|
||||||
xdg_activation_v1_destroy(wayl->xdg_activation);
|
xdg_activation_v1_destroy(wayl->xdg_activation);
|
||||||
|
|
|
||||||
12
wayland.h
12
wayland.h
|
|
@ -146,12 +146,18 @@ struct seat {
|
||||||
struct {
|
struct {
|
||||||
uint32_t serial;
|
uint32_t serial;
|
||||||
|
|
||||||
|
/* Client-side cursor */
|
||||||
struct wayl_surface surface;
|
struct wayl_surface surface;
|
||||||
struct wl_cursor_theme *theme;
|
struct wl_cursor_theme *theme;
|
||||||
struct wl_cursor *cursor;
|
struct wl_cursor *cursor;
|
||||||
|
|
||||||
|
/* Server-side cursor */
|
||||||
|
#if defined(HAVE_CURSOR_SHAPE)
|
||||||
|
struct wp_cursor_shape_device_v1 *shape_device;
|
||||||
|
#endif
|
||||||
|
|
||||||
float scale;
|
float scale;
|
||||||
bool hidden;
|
bool hidden;
|
||||||
|
|
||||||
enum cursor_shape shape;
|
enum cursor_shape shape;
|
||||||
struct wl_callback *xcursor_callback;
|
struct wl_callback *xcursor_callback;
|
||||||
bool xcursor_pending;
|
bool xcursor_pending;
|
||||||
|
|
@ -426,6 +432,10 @@ struct wayland {
|
||||||
struct xdg_activation_v1 *xdg_activation;
|
struct xdg_activation_v1 *xdg_activation;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_CURSOR_SHAPE)
|
||||||
|
struct wp_cursor_shape_manager_v1 *cursor_shape_manager;
|
||||||
|
#endif
|
||||||
|
|
||||||
bool presentation_timings;
|
bool presentation_timings;
|
||||||
struct wp_presentation *presentation;
|
struct wp_presentation *presentation;
|
||||||
uint32_t presentation_clock_id;
|
uint32_t presentation_clock_id;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue