wayland: Implement the cursor_shape_v1 protocol
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3668>
This commit is contained in:
parent
25bb319ec2
commit
005b969227
@ -604,6 +604,8 @@ if have_wayland
|
||||
'wayland/meta-wayland-color-management.c',
|
||||
'wayland/meta-wayland-color-management.h',
|
||||
'wayland/meta-wayland-commit-timing.c',
|
||||
'wayland/meta-wayland-cursor-shape.c',
|
||||
'wayland/meta-wayland-cursor-shape.h',
|
||||
'wayland/meta-wayland-fifo.c',
|
||||
'wayland/meta-wayland-cursor-surface.c',
|
||||
'wayland/meta-wayland-cursor-surface.h',
|
||||
@ -1107,6 +1109,7 @@ if have_wayland
|
||||
# - protocol stability ('private', 'stable' or 'unstable')
|
||||
# - protocol version (if stability is 'unstable')
|
||||
wayland_protocols = [
|
||||
['cursor-shape-v1', 'private', ],
|
||||
['drm-lease', 'staging', 'v1', ],
|
||||
['fractional-scale', 'staging', 'v1', ],
|
||||
['gtk-shell', 'private', ],
|
||||
|
330
src/wayland/meta-wayland-cursor-shape.c
Normal file
330
src/wayland/meta-wayland-cursor-shape.c
Normal file
@ -0,0 +1,330 @@
|
||||
/*
|
||||
* Copyright 2024 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "wayland/meta-wayland-cursor-shape.h"
|
||||
|
||||
#include "core/meta-debug-control-private.h"
|
||||
#include "core/window-private.h"
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
#include "wayland/meta-wayland-xdg-shell.h"
|
||||
#include "wayland/meta-wayland-versions.h"
|
||||
|
||||
#include "cursor-shape-v1-server-protocol.h"
|
||||
|
||||
typedef enum _MetaWaylandCursorShapeDeviceType
|
||||
{
|
||||
META_WAYLAND_CURSOR_SHAPE_DEVICE_TYPE_POINTER,
|
||||
META_WAYLAND_CURSOR_SHAPE_DEVICE_TYPE_TOOL,
|
||||
} MetaWaylandCursorShapeDeviceType;
|
||||
|
||||
typedef struct _MetaWaylandCursorShapeDevice
|
||||
{
|
||||
MetaWaylandCursorShapeDeviceType type;
|
||||
union {
|
||||
MetaWaylandPointer *pointer;
|
||||
MetaWaylandTabletTool *tool;
|
||||
};
|
||||
} MetaWaylandCursorShapeDevice;
|
||||
|
||||
static const struct
|
||||
{
|
||||
enum wp_cursor_shape_device_v1_shape shape;
|
||||
MetaCursor cursor;
|
||||
} shape_map[] = {
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_DEFAULT, META_CURSOR_DEFAULT },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_CONTEXT_MENU, META_CURSOR_CONTEXT_MENU },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_HELP, META_CURSOR_HELP },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_POINTER, META_CURSOR_POINTER },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_PROGRESS, META_CURSOR_PROGRESS },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_WAIT, META_CURSOR_WAIT },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_CELL, META_CURSOR_CELL },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_CROSSHAIR, META_CURSOR_CROSSHAIR },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_TEXT, META_CURSOR_TEXT },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_VERTICAL_TEXT, META_CURSOR_VERTICAL_TEXT },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_ALIAS, META_CURSOR_ALIAS },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_COPY, META_CURSOR_COPY },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_MOVE, META_CURSOR_MOVE },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NO_DROP, META_CURSOR_NO_DROP },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NOT_ALLOWED, META_CURSOR_NOT_ALLOWED },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_GRAB, META_CURSOR_GRAB },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_GRABBING, META_CURSOR_GRABBING },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_E_RESIZE, META_CURSOR_E_RESIZE },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_N_RESIZE, META_CURSOR_N_RESIZE },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NE_RESIZE, META_CURSOR_NE_RESIZE },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NW_RESIZE, META_CURSOR_NW_RESIZE },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_S_RESIZE, META_CURSOR_S_RESIZE },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_SE_RESIZE, META_CURSOR_SE_RESIZE },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_SW_RESIZE, META_CURSOR_SW_RESIZE },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_W_RESIZE, META_CURSOR_W_RESIZE },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_EW_RESIZE, META_CURSOR_EW_RESIZE },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NS_RESIZE, META_CURSOR_NS_RESIZE },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NESW_RESIZE, META_CURSOR_NESW_RESIZE },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NWSE_RESIZE, META_CURSOR_NWSE_RESIZE },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_COL_RESIZE, META_CURSOR_COL_RESIZE },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_ROW_RESIZE, META_CURSOR_ROW_RESIZE },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_ALL_SCROLL, META_CURSOR_ALL_SCROLL },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_ZOOM_IN, META_CURSOR_ZOOM_IN },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_ZOOM_OUT, META_CURSOR_ZOOM_OUT },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_DND_ASK, META_CURSOR_DND_ASK },
|
||||
{ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_ALL_RESIZE, META_CURSOR_ALL_RESIZE },
|
||||
};
|
||||
|
||||
static MetaCursor
|
||||
cursor_from_shape (enum wp_cursor_shape_device_v1_shape shape,
|
||||
int version)
|
||||
{
|
||||
if (shape < WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_DEFAULT)
|
||||
return META_CURSOR_INVALID;
|
||||
|
||||
if (version <= 1 && shape > WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_ZOOM_OUT)
|
||||
return META_CURSOR_INVALID;
|
||||
|
||||
if (shape >= G_N_ELEMENTS (shape_map))
|
||||
return META_CURSOR_INVALID;
|
||||
|
||||
return shape_map[shape].cursor;
|
||||
}
|
||||
|
||||
static MetaWaylandCursorShapeDevice *
|
||||
meta_wayland_cursor_shape_device_new_pointer (MetaWaylandPointer *pointer)
|
||||
{
|
||||
MetaWaylandCursorShapeDevice *cursor_shape_device =
|
||||
g_new0 (MetaWaylandCursorShapeDevice, 1);
|
||||
|
||||
cursor_shape_device->type = META_WAYLAND_CURSOR_SHAPE_DEVICE_TYPE_POINTER;
|
||||
cursor_shape_device->pointer = pointer;
|
||||
g_object_add_weak_pointer (G_OBJECT (pointer),
|
||||
(gpointer *) &cursor_shape_device->pointer);
|
||||
|
||||
return cursor_shape_device;
|
||||
}
|
||||
|
||||
|
||||
static MetaWaylandCursorShapeDevice *
|
||||
meta_wayland_cursor_shape_device_new_tool (MetaWaylandTabletTool *tool)
|
||||
{
|
||||
MetaWaylandCursorShapeDevice *cursor_shape_device =
|
||||
g_new0 (MetaWaylandCursorShapeDevice, 1);
|
||||
|
||||
cursor_shape_device->type = META_WAYLAND_CURSOR_SHAPE_DEVICE_TYPE_TOOL;
|
||||
cursor_shape_device->tool = tool;
|
||||
g_object_add_weak_pointer (G_OBJECT (tool),
|
||||
(gpointer *) &cursor_shape_device->tool);
|
||||
|
||||
return cursor_shape_device;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_cursor_shape_device_free (MetaWaylandCursorShapeDevice *cursor_shape_device)
|
||||
{
|
||||
if (cursor_shape_device->type == META_WAYLAND_CURSOR_SHAPE_DEVICE_TYPE_POINTER)
|
||||
g_clear_weak_pointer ((gpointer *) &cursor_shape_device->pointer);
|
||||
if (cursor_shape_device->type == META_WAYLAND_CURSOR_SHAPE_DEVICE_TYPE_TOOL)
|
||||
g_clear_weak_pointer ((gpointer *) &cursor_shape_device->tool);
|
||||
|
||||
g_free (cursor_shape_device);
|
||||
}
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaWaylandCursorShapeDevice,
|
||||
meta_wayland_cursor_shape_device_free)
|
||||
|
||||
static void
|
||||
cursor_shape_device_destructor (struct wl_resource *resource)
|
||||
{
|
||||
MetaWaylandCursorShapeDevice *cursor_shape_device =
|
||||
wl_resource_get_user_data (resource);
|
||||
|
||||
meta_wayland_cursor_shape_device_free (cursor_shape_device);
|
||||
}
|
||||
|
||||
static void
|
||||
cursor_shape_device_destroy (struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
wl_resource_destroy (resource);
|
||||
}
|
||||
|
||||
static void
|
||||
cursor_shape_device_set_shape (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t serial,
|
||||
enum wp_cursor_shape_device_v1_shape shape)
|
||||
{
|
||||
MetaWaylandCursorShapeDevice *cursor_shape_device =
|
||||
wl_resource_get_user_data (resource);
|
||||
MetaCursor cursor = cursor_from_shape (shape,
|
||||
wl_resource_get_version (resource));
|
||||
|
||||
if (cursor == META_CURSOR_INVALID)
|
||||
{
|
||||
wl_resource_post_error (resource,
|
||||
WP_CURSOR_SHAPE_DEVICE_V1_ERROR_INVALID_SHAPE,
|
||||
"wp_cursor_shape_device_v1@%d: "
|
||||
"the specified shape value is invalid",
|
||||
wl_resource_get_id (resource));
|
||||
return;
|
||||
}
|
||||
|
||||
if (cursor_shape_device->type == META_WAYLAND_CURSOR_SHAPE_DEVICE_TYPE_POINTER &&
|
||||
cursor_shape_device->pointer)
|
||||
{
|
||||
MetaWaylandPointer *pointer = cursor_shape_device->pointer;
|
||||
|
||||
if (!meta_wayland_pointer_check_focus_serial (pointer, client, serial))
|
||||
return;
|
||||
|
||||
meta_wayland_pointer_set_cursor_shape (pointer, cursor);
|
||||
}
|
||||
|
||||
if (cursor_shape_device->type == META_WAYLAND_CURSOR_SHAPE_DEVICE_TYPE_TOOL &&
|
||||
cursor_shape_device->tool)
|
||||
{
|
||||
MetaWaylandTabletTool *tool = cursor_shape_device->tool;
|
||||
|
||||
if (!meta_wayland_tablet_tool_check_focus_serial (tool, client, serial))
|
||||
return;
|
||||
|
||||
meta_wayland_tablet_tool_set_cursor_shape (tool, cursor);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct wp_cursor_shape_device_v1_interface cursor_shape_device_interface = {
|
||||
cursor_shape_device_destroy,
|
||||
cursor_shape_device_set_shape,
|
||||
};
|
||||
|
||||
static void
|
||||
cursor_manager_destroy (struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
wl_resource_destroy (resource);
|
||||
}
|
||||
|
||||
static void
|
||||
cursor_manager_get_pointer (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t id,
|
||||
struct wl_resource *pointer_resource)
|
||||
{
|
||||
MetaWaylandPointer *pointer = wl_resource_get_user_data (pointer_resource);
|
||||
g_autoptr (MetaWaylandCursorShapeDevice) cursor_shape_device = NULL;
|
||||
struct wl_resource *shape_device_resource;
|
||||
|
||||
cursor_shape_device = meta_wayland_cursor_shape_device_new_pointer (pointer);
|
||||
|
||||
shape_device_resource =
|
||||
wl_resource_create (client,
|
||||
&wp_cursor_shape_device_v1_interface,
|
||||
wl_resource_get_version (resource),
|
||||
id);
|
||||
wl_resource_set_implementation (shape_device_resource,
|
||||
&cursor_shape_device_interface,
|
||||
g_steal_pointer (&cursor_shape_device),
|
||||
cursor_shape_device_destructor);
|
||||
}
|
||||
|
||||
static void
|
||||
cursor_manager_get_tablet_tool_v2 (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t id,
|
||||
struct wl_resource *pointer_resource)
|
||||
{
|
||||
MetaWaylandTabletTool *tool = wl_resource_get_user_data (resource);
|
||||
g_autoptr (MetaWaylandCursorShapeDevice) cursor_shape_device = NULL;
|
||||
struct wl_resource *shape_device_resource;
|
||||
|
||||
cursor_shape_device = meta_wayland_cursor_shape_device_new_tool (tool);
|
||||
|
||||
shape_device_resource =
|
||||
wl_resource_create (client,
|
||||
&wp_cursor_shape_device_v1_interface,
|
||||
wl_resource_get_version (resource),
|
||||
id);
|
||||
wl_resource_set_implementation (shape_device_resource,
|
||||
&cursor_shape_device_interface,
|
||||
g_steal_pointer (&cursor_shape_device),
|
||||
cursor_shape_device_destructor);
|
||||
}
|
||||
|
||||
static const struct wp_cursor_shape_manager_v1_interface cursor_shape_manager_interface = {
|
||||
cursor_manager_destroy,
|
||||
cursor_manager_get_pointer,
|
||||
cursor_manager_get_tablet_tool_v2,
|
||||
};
|
||||
|
||||
static void
|
||||
bind_cursor_shape (struct wl_client *client,
|
||||
void *data,
|
||||
uint32_t version,
|
||||
uint32_t id)
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
|
||||
resource = wl_resource_create (client, &wp_cursor_shape_manager_v1_interface,
|
||||
version, id);
|
||||
wl_resource_set_implementation (resource, &cursor_shape_manager_interface,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
update_enabled (MetaWaylandCompositor *compositor)
|
||||
{
|
||||
MetaDebugControl *debug_control =
|
||||
meta_context_get_debug_control (compositor->context);
|
||||
gboolean is_enabled =
|
||||
meta_debug_control_is_cursor_shape_protocol_enabled (debug_control);
|
||||
struct wl_global *global;
|
||||
|
||||
global = g_object_get_data (G_OBJECT (compositor),
|
||||
"-meta-wayland-cursor-shape");
|
||||
|
||||
if (is_enabled && global == NULL)
|
||||
{
|
||||
|
||||
global = wl_global_create (compositor->wayland_display,
|
||||
&wp_cursor_shape_manager_v1_interface,
|
||||
META_WP_CURSOR_SHAPE_VERSION,
|
||||
NULL, bind_cursor_shape);
|
||||
if (global == NULL)
|
||||
g_error ("Failed to register a global cursor-shape object");
|
||||
}
|
||||
else if (!is_enabled)
|
||||
{
|
||||
g_clear_pointer (&global, wl_global_destroy);
|
||||
}
|
||||
|
||||
g_object_set_data (G_OBJECT (compositor),
|
||||
"-meta-wayland-cursor-shape",
|
||||
global);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_init_cursor_shape (MetaWaylandCompositor *compositor)
|
||||
{
|
||||
MetaDebugControl *debug_control =
|
||||
meta_context_get_debug_control (compositor->context);
|
||||
|
||||
g_signal_connect_data (debug_control, "notify::cursor-shape-protocol",
|
||||
G_CALLBACK (update_enabled),
|
||||
compositor, NULL,
|
||||
G_CONNECT_SWAPPED | G_CONNECT_AFTER);
|
||||
|
||||
update_enabled (compositor);
|
||||
}
|
23
src/wayland/meta-wayland-cursor-shape.h
Normal file
23
src/wayland/meta-wayland-cursor-shape.h
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2024 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "wayland/meta-wayland.h"
|
||||
|
||||
void meta_wayland_init_cursor_shape (MetaWaylandCompositor *compositor);
|
@ -101,6 +101,8 @@ struct _MetaWaylandPointer
|
||||
MetaWaylandSurface *cursor_surface;
|
||||
gulong cursor_surface_destroy_id;
|
||||
|
||||
MetaCursor cursor_shape;
|
||||
|
||||
guint32 grab_button;
|
||||
guint32 grab_serial;
|
||||
guint32 grab_time;
|
||||
@ -1150,14 +1152,24 @@ meta_wayland_pointer_update_cursor_surface (MetaWaylandPointer *pointer)
|
||||
|
||||
if (surface)
|
||||
{
|
||||
MetaCursorSprite *cursor_sprite = NULL;
|
||||
g_autoptr (MetaCursorSprite) cursor_sprite = NULL;
|
||||
|
||||
if (pointer->cursor_surface)
|
||||
{
|
||||
MetaWaylandCursorSurface *cursor_surface =
|
||||
META_WAYLAND_CURSOR_SURFACE (pointer->cursor_surface->role);
|
||||
MetaCursorSprite *sprite;
|
||||
|
||||
cursor_sprite = meta_wayland_cursor_surface_get_sprite (cursor_surface);
|
||||
sprite = meta_wayland_cursor_surface_get_sprite (cursor_surface);
|
||||
cursor_sprite = g_object_ref (sprite);
|
||||
}
|
||||
else if (pointer->cursor_shape != META_CURSOR_INVALID)
|
||||
{
|
||||
MetaCursorSpriteXcursor *sprite;
|
||||
|
||||
sprite = meta_cursor_sprite_xcursor_new (pointer->cursor_shape,
|
||||
cursor_tracker);
|
||||
cursor_sprite = META_CURSOR_SPRITE (sprite);
|
||||
}
|
||||
|
||||
meta_cursor_tracker_set_window_cursor (cursor_tracker, cursor_sprite);
|
||||
@ -1191,6 +1203,7 @@ meta_wayland_pointer_set_cursor_surface (MetaWaylandPointer *pointer,
|
||||
return;
|
||||
|
||||
pointer->cursor_surface = cursor_surface;
|
||||
pointer->cursor_shape = META_CURSOR_INVALID;
|
||||
|
||||
if (prev_cursor_surface)
|
||||
{
|
||||
@ -1210,6 +1223,23 @@ meta_wayland_pointer_set_cursor_surface (MetaWaylandPointer *pointer,
|
||||
meta_wayland_pointer_update_cursor_surface (pointer);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_pointer_set_cursor_shape (MetaWaylandPointer *pointer,
|
||||
MetaCursor shape)
|
||||
{
|
||||
if (pointer->cursor_surface)
|
||||
{
|
||||
meta_wayland_surface_update_outputs (pointer->cursor_surface);
|
||||
g_clear_signal_handler (&pointer->cursor_surface_destroy_id,
|
||||
pointer->cursor_surface);
|
||||
}
|
||||
|
||||
pointer->cursor_surface = NULL;
|
||||
pointer->cursor_shape = shape;
|
||||
|
||||
meta_wayland_pointer_update_cursor_surface (pointer);
|
||||
}
|
||||
|
||||
static void
|
||||
pointer_set_cursor (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
|
@ -103,6 +103,9 @@ MetaWaylandSurface * meta_wayland_pointer_get_implicit_grab_surface (MetaWayland
|
||||
|
||||
MetaWaylandPointerClient * meta_wayland_pointer_get_focus_client (MetaWaylandPointer *pointer);
|
||||
|
||||
void meta_wayland_pointer_set_cursor_shape (MetaWaylandPointer *pointer,
|
||||
MetaCursor shape);
|
||||
|
||||
gboolean meta_wayland_pointer_check_focus_serial (MetaWaylandPointer *pointer,
|
||||
struct wl_client *client,
|
||||
uint32_t serial);
|
||||
|
@ -53,6 +53,8 @@ struct _MetaWaylandTabletTool
|
||||
MetaCursorRenderer *cursor_renderer;
|
||||
MetaCursorSpriteXcursor *default_sprite;
|
||||
|
||||
MetaCursor cursor_shape;
|
||||
|
||||
MetaWaylandSurface *current;
|
||||
guint32 pressed_buttons;
|
||||
guint32 button_count;
|
||||
@ -115,7 +117,10 @@ move_resources_for_client (struct wl_list *destination,
|
||||
static void
|
||||
meta_wayland_tablet_tool_update_cursor_surface (MetaWaylandTabletTool *tool)
|
||||
{
|
||||
MetaCursorSprite *cursor = NULL;
|
||||
MetaBackend *backend = backend_from_tool (tool);
|
||||
MetaCursorTracker *cursor_tracker =
|
||||
meta_backend_get_cursor_tracker (backend);
|
||||
g_autoptr (MetaCursorSprite) cursor_sprite = NULL;
|
||||
|
||||
if (tool->cursor_renderer == NULL)
|
||||
return;
|
||||
@ -127,18 +132,29 @@ meta_wayland_tablet_tool_update_cursor_surface (MetaWaylandTabletTool *tool)
|
||||
{
|
||||
MetaWaylandCursorSurface *cursor_surface =
|
||||
META_WAYLAND_CURSOR_SURFACE (tool->cursor_surface->role);
|
||||
MetaCursorSprite *sprite;
|
||||
|
||||
cursor = meta_wayland_cursor_surface_get_sprite (cursor_surface);
|
||||
sprite = meta_wayland_cursor_surface_get_sprite (cursor_surface);
|
||||
cursor_sprite = g_object_ref (sprite);
|
||||
}
|
||||
else if (tool->cursor_shape != META_CURSOR_INVALID)
|
||||
{
|
||||
MetaCursorSpriteXcursor *sprite;
|
||||
|
||||
sprite = meta_cursor_sprite_xcursor_new (tool->cursor_shape,
|
||||
cursor_tracker);
|
||||
cursor_sprite = META_CURSOR_SPRITE (sprite);
|
||||
}
|
||||
else
|
||||
cursor = NULL;
|
||||
}
|
||||
else if (tool->current_tablet)
|
||||
cursor = META_CURSOR_SPRITE (tool->default_sprite);
|
||||
else
|
||||
cursor = NULL;
|
||||
{
|
||||
MetaCursorSprite *sprite;
|
||||
|
||||
meta_cursor_renderer_set_cursor (tool->cursor_renderer, cursor);
|
||||
sprite = META_CURSOR_SPRITE (tool->default_sprite);
|
||||
cursor_sprite = g_object_ref (sprite);
|
||||
}
|
||||
|
||||
meta_cursor_renderer_set_cursor (tool->cursor_renderer, cursor_sprite);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -160,6 +176,7 @@ meta_wayland_tablet_tool_set_cursor_surface (MetaWaylandTabletTool *tool,
|
||||
}
|
||||
|
||||
tool->cursor_surface = surface;
|
||||
tool->cursor_shape = META_CURSOR_INVALID;
|
||||
|
||||
if (tool->cursor_surface)
|
||||
{
|
||||
@ -171,6 +188,27 @@ meta_wayland_tablet_tool_set_cursor_surface (MetaWaylandTabletTool *tool,
|
||||
meta_wayland_tablet_tool_update_cursor_surface (tool);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_tablet_tool_set_cursor_shape (MetaWaylandTabletTool *tool,
|
||||
MetaCursor shape)
|
||||
{
|
||||
if (tool->cursor_surface)
|
||||
{
|
||||
MetaWaylandCursorSurface *cursor_surface;
|
||||
|
||||
cursor_surface = META_WAYLAND_CURSOR_SURFACE (tool->cursor_surface->role);
|
||||
meta_wayland_cursor_surface_set_renderer (cursor_surface, NULL);
|
||||
|
||||
meta_wayland_surface_update_outputs (tool->cursor_surface);
|
||||
wl_list_remove (&tool->cursor_surface_destroy_listener.link);
|
||||
}
|
||||
|
||||
tool->cursor_surface = NULL;
|
||||
tool->cursor_shape = shape;
|
||||
|
||||
meta_wayland_tablet_tool_update_cursor_surface (tool);
|
||||
}
|
||||
|
||||
static enum zwp_tablet_tool_v2_type
|
||||
input_device_tool_get_type (ClutterInputDeviceTool *device_tool)
|
||||
{
|
||||
|
@ -65,6 +65,9 @@ MetaWaylandSurface * meta_wayland_tablet_tool_get_current_surface (MetaWaylandTa
|
||||
void meta_wayland_tablet_tool_focus_surface (MetaWaylandTabletTool *tool,
|
||||
MetaWaylandSurface *surface);
|
||||
|
||||
void meta_wayland_tablet_tool_set_cursor_shape (MetaWaylandTabletTool *tool,
|
||||
MetaCursor shape);
|
||||
|
||||
gboolean meta_wayland_tablet_tool_check_focus_serial (MetaWaylandTabletTool *tool,
|
||||
struct wl_client *client,
|
||||
uint32_t serial);
|
||||
|
@ -65,3 +65,4 @@
|
||||
#define META_XDG_TOPLEVEL_DRAG_VERSION 1
|
||||
#define META_WP_COMMIT_TIMING_V1_VERSION 1
|
||||
#define META_WP_FIFO_V1_VERSION 1
|
||||
#define META_WP_CURSOR_SHAPE_VERSION 2
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "wayland/meta-wayland-buffer.h"
|
||||
#include "wayland/meta-wayland-color-management.h"
|
||||
#include "wayland/meta-wayland-commit-timing.h"
|
||||
#include "wayland/meta-wayland-cursor-shape.h"
|
||||
#include "wayland/meta-wayland-fifo.h"
|
||||
#include "wayland/meta-wayland-data-device.h"
|
||||
#include "wayland/meta-wayland-dma-buf.h"
|
||||
@ -999,7 +1000,6 @@ meta_wayland_compositor_new (MetaContext *context)
|
||||
|
||||
meta_wayland_init_egl (compositor);
|
||||
meta_wayland_init_shm (compositor);
|
||||
|
||||
meta_wayland_outputs_init (compositor);
|
||||
meta_wayland_data_device_manager_init (compositor);
|
||||
meta_wayland_data_device_primary_manager_init (compositor);
|
||||
@ -1026,12 +1026,12 @@ meta_wayland_compositor_new (MetaContext *context)
|
||||
meta_wayland_init_color_management (compositor);
|
||||
meta_wayland_xdg_session_management_init (compositor);
|
||||
meta_wayland_init_system_bell (compositor);
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
meta_wayland_drm_lease_manager_init (compositor);
|
||||
#endif
|
||||
meta_wayland_commit_timing_init (compositor);
|
||||
meta_wayland_fifo_init (compositor);
|
||||
meta_wayland_init_cursor_shape (compositor);
|
||||
|
||||
#ifdef HAVE_WAYLAND_EGLSTREAM
|
||||
{
|
||||
|
163
src/wayland/protocol/cursor-shape-v1.xml
Normal file
163
src/wayland/protocol/cursor-shape-v1.xml
Normal file
@ -0,0 +1,163 @@
|
||||
<?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="2">
|
||||
<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.
|
||||
|
||||
When the pointer capability is removed from the wl_seat, the
|
||||
wp_cursor_shape_device_v1 object becomes inert.
|
||||
</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.
|
||||
|
||||
When the zwp_tablet_tool_v2 is removed, the wp_cursor_shape_device_v1
|
||||
object becomes inert.
|
||||
</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="2">
|
||||
<description summary="cursor shape for a device">
|
||||
This interface 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
|
||||
with a few additions.
|
||||
|
||||
Note that there are some groups of cursor shapes that are related:
|
||||
The first group is drag-and-drop cursors which are used to indicate
|
||||
the selected action during dnd operations. The second group is resize
|
||||
cursors which are used to indicate resizing and moving possibilities
|
||||
on window borders. It is recommended that the shapes in these groups
|
||||
should use visually compatible images and metaphors.
|
||||
</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"/>
|
||||
<entry name="dnd_ask" value="35" summary="drag-and-drop: selected drag action is ASK (non-css value)" since="2"/>
|
||||
<entry name="all_resize" value="36" summary="resizing: something can be moved or resized in any direction (non-css value)" since="2"/>
|
||||
|
||||
</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>
|
Loading…
x
Reference in New Issue
Block a user