Merge branch 'simplify-cursor' into 'master'

Draft: cursor: overhaul

See merge request wlroots/wlroots!3974
This commit is contained in:
Kirill Primak 2023-01-31 17:48:36 +00:00
commit 063bade7df
10 changed files with 890 additions and 1420 deletions

View file

@ -11,129 +11,49 @@
#include <wayland-server-core.h>
#include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_output.h>
struct wlr_input_device;
/**
* wlr_cursor implements the behavior of the "cursor", that is, the image on the
* screen typically moved about with a mouse or so. It provides tracking for
* this in global coordinates, and integrates with struct wlr_output,
* struct wlr_output_layout, and struct wlr_input_device. You can use it to
* abstract multiple input devices over a single cursor, constrain cursor
* movement to the usable area of a struct wlr_output_layout and communicate
* position updates to the hardware cursor, constrain specific input devices to
* specific outputs or regions of the screen, and so on.
* A helper to keep track of a cursor's position in an output layout and
* manage output cursors.
*
* When the output layout is destroyed, the cursor is destroyed as well.
*/
struct wlr_box;
struct wlr_cursor_state;
struct wlr_cursor {
struct wlr_cursor_state *state;
double x, y;
/**
* The interpretation of these signals is the responsibility of the
* compositor, but some helpers are provided for your benefit. If you
* receive a relative motion event, for example, you may want to call
* wlr_cursor_move(). If you receive an absolute event, call
* wlr_cursor_warp_absolute(). If you pass an input device into these
* functions, it will apply the region/output constraints associated with
* that device to the resulting cursor motion. If an output layout is
* attached, these functions will constrain the resulting cursor motion to
* within the usable space of the output layout.
*
* Re-broadcasting these signals to, for example, a struct wlr_seat, is also
* your responsibility.
*/
struct wl_list output_cursors; // wlr_cursor_output_cursor.link
struct wlr_output_layout *layout;
struct {
struct wl_signal motion;
struct wl_signal motion_absolute;
struct wl_signal button;
struct wl_signal axis;
struct wl_signal frame;
struct wl_signal swipe_begin;
struct wl_signal swipe_update;
struct wl_signal swipe_end;
struct wl_signal pinch_begin;
struct wl_signal pinch_update;
struct wl_signal pinch_end;
struct wl_signal hold_begin;
struct wl_signal hold_end;
struct wl_signal touch_up;
struct wl_signal touch_down;
struct wl_signal touch_motion;
struct wl_signal touch_cancel;
struct wl_signal touch_frame;
struct wl_signal tablet_tool_axis;
struct wl_signal tablet_tool_proximity;
struct wl_signal tablet_tool_tip;
struct wl_signal tablet_tool_button;
struct wl_signal destroy;
} events;
void *data;
// private state
struct wl_listener layout_add;
struct wl_listener layout_destroy;
};
struct wlr_cursor *wlr_cursor_create(void);
struct wlr_cursor_output_cursor {
struct wlr_cursor *cursor;
struct wlr_output_cursor *output_cursor;
struct wl_list link; // wlr_cursor.output_cursors
void wlr_cursor_destroy(struct wlr_cursor *cur);
// private state
struct wl_listener layout_output_destroy;
};
struct wlr_cursor *wlr_cursor_create(struct wlr_output_layout *layout);
void wlr_cursor_destroy(struct wlr_cursor *cursor);
/**
* Warp the cursor to the given x and y in layout coordinates. If x and y are
* out of the layout boundaries or constraints, no warp will happen.
*
* `dev` may be passed to respect device mapping constraints. If `dev` is NULL,
* device mapping constraints will be ignored.
*
* Returns true when the cursor warp was successful.
* Warp the cursor to the given x and y in layout coordinates.
*/
bool wlr_cursor_warp(struct wlr_cursor *cur, struct wlr_input_device *dev,
double lx, double ly);
/**
* Convert absolute 0..1 coordinates to layout coordinates.
*
* `dev` may be passed to respect device mapping constraints. If `dev` is NULL,
* device mapping constraints will be ignored.
*/
void wlr_cursor_absolute_to_layout_coords(struct wlr_cursor *cur,
struct wlr_input_device *dev, double x, double y, double *lx, double *ly);
/**
* Warp the cursor to the given x and y coordinates. If the given point is out
* of the layout boundaries or constraints, the closest point will be used.
* If one coordinate is NAN, it will be ignored.
*
* `dev` may be passed to respect device mapping constraints. If `dev` is NULL,
* device mapping constraints will be ignored.
*/
void wlr_cursor_warp_closest(struct wlr_cursor *cur,
struct wlr_input_device *dev, double x, double y);
/**
* Warp the cursor to the given x and y in absolute 0..1 coordinates. If the
* given point is out of the layout boundaries or constraints, the closest point
* will be used. If one coordinate is NAN, it will be ignored.
*
* `dev` may be passed to respect device mapping constraints. If `dev` is NULL,
* device mapping constraints will be ignored.
*/
void wlr_cursor_warp_absolute(struct wlr_cursor *cur,
struct wlr_input_device *dev, double x, double y);
/**
* Move the cursor in the direction of the given x and y layout coordinates. If
* one coordinate is NAN, it will be ignored.
*
* `dev` may be passed to respect device mapping constraints. If `dev` is NULL,
* device mapping constraints will be ignored.
*/
void wlr_cursor_move(struct wlr_cursor *cur, struct wlr_input_device *dev,
double delta_x, double delta_y);
void wlr_cursor_warp(struct wlr_cursor *cursor, double lx, double ly);
/**
* Set the cursor image. stride is given in bytes. If pixels is NULL, hides the
@ -142,7 +62,7 @@ void wlr_cursor_move(struct wlr_cursor *cur, struct wlr_input_device *dev,
* If scale isn't zero, the image is only set on outputs having the provided
* scale.
*/
void wlr_cursor_set_image(struct wlr_cursor *cur, const uint8_t *pixels,
void wlr_cursor_set_image(struct wlr_cursor *cursor, const uint8_t *pixels,
int32_t stride, uint32_t width, uint32_t height, int32_t hotspot_x,
int32_t hotspot_y, float scale);
@ -151,56 +71,7 @@ void wlr_cursor_set_image(struct wlr_cursor *cur, const uint8_t *pixels,
* image. The surface position is subtracted from the hotspot. A NULL surface
* commit hides the cursor.
*/
void wlr_cursor_set_surface(struct wlr_cursor *cur, struct wlr_surface *surface,
void wlr_cursor_set_surface(struct wlr_cursor *cursor, struct wlr_surface *surface,
int32_t hotspot_x, int32_t hotspot_y);
/**
* Attaches this input device to this cursor. The input device must be one of:
*
* - WLR_INPUT_DEVICE_POINTER
* - WLR_INPUT_DEVICE_TOUCH
* - WLR_INPUT_DEVICE_TABLET_TOOL
*/
void wlr_cursor_attach_input_device(struct wlr_cursor *cur,
struct wlr_input_device *dev);
void wlr_cursor_detach_input_device(struct wlr_cursor *cur,
struct wlr_input_device *dev);
/**
* Uses the given layout to establish the boundaries and movement semantics of
* this cursor. Cursors without an output layout allow infinite movement in any
* direction and do not support absolute input events.
*/
void wlr_cursor_attach_output_layout(struct wlr_cursor *cur,
struct wlr_output_layout *l);
/**
* Attaches this cursor to the given output, which must be among the outputs in
* the current output_layout for this cursor. This call is invalid for a cursor
* without an associated output layout.
*/
void wlr_cursor_map_to_output(struct wlr_cursor *cur,
struct wlr_output *output);
/**
* Maps all input from a specific input device to a given output. The input
* device must be attached to this cursor and the output must be among the
* outputs in the attached output layout.
*/
void wlr_cursor_map_input_to_output(struct wlr_cursor *cur,
struct wlr_input_device *dev, struct wlr_output *output);
/**
* Maps this cursor to an arbitrary region on the associated
* struct wlr_output_layout.
*/
void wlr_cursor_map_to_region(struct wlr_cursor *cur, const struct wlr_box *box);
/**
* Maps inputs from this input device to an arbitrary region on the associated
* struct wlr_output_layout.
*/
void wlr_cursor_map_input_to_region(struct wlr_cursor *cur,
struct wlr_input_device *dev, const struct wlr_box *box);
#endif

View file

@ -10,6 +10,7 @@
#define WLR_TYPES_WLR_INPUT_DEVICE_H
#include <wayland-server-core.h>
#include <wlr/util/addon.h>
enum wlr_button_state {
WLR_BUTTON_RELEASED,
@ -34,6 +35,8 @@ struct wlr_input_device {
struct wl_signal destroy;
} events;
struct wlr_addon_set addons;
void *data;
};

View file

@ -0,0 +1,123 @@
/*
* This an unstable interface of wlroots. No guarantees are made regarding the
* future consistency of this API.
*/
#ifndef WLR_USE_UNSTABLE
#error "Add -DWLR_USE_UNSTABLE to enable unstable wlroots features"
#endif
#ifndef WLR_TYPES_WLR_INPUT_MAPPER_H
#define WLR_TYPES_WLR_INPUT_MAPPER_H
#include <wayland-server-core.h>
#include <wlr/types/wlr_output.h>
#include <wlr/types/wlr_output_layout.h>
#include <wlr/util/addon.h>
#include <wlr/util/box.h>
struct wlr_input_device;
struct wlr_input_constraint {
struct wlr_output *output; // NULL if unset
struct wlr_box box; // Empty if unset
// private state
struct wl_listener output_destroy;
};
/**
* A helper for converting absolute coordinates received from input devices to
* layout-local coordinates and applying coordinate constraints.
*
* The constraints precendence is as follows:
* 1) Device-specific box
* 2) Device-specific output
* 3) Global box
* 4) Global output
*
* If no output layout is attached to the input mapper, all output constraints
* are ignored.
*/
struct wlr_input_mapper {
struct wlr_output_layout *layout;
struct wlr_input_constraint global;
struct wl_list mappings; // wlr_input_mapping.link
struct {
struct wl_signal destroy;
} events;
// private state
struct wl_listener layout_destroy;
};
struct wlr_input_mapping {
struct wlr_input_constraint constraint;
struct wl_list link; // wlr_input_mapper.mappings
// private state
struct wlr_addon addon; // wlr_input_device.addons
};
struct wlr_input_mapper *wlr_input_mapper_create(void);
void wlr_input_mapper_destroy(struct wlr_input_mapper *mapper);
/**
* Attach an output layout to the input mapper. This detaches the previous
* output layout, if any.
*
* layout may be NULL.
*/
void wlr_input_mapper_attach_output_layout(struct wlr_input_mapper *mapper,
struct wlr_output_layout *layout);
/**
* Convert absolute coordinates in 0..1 range to layout-local coordinates.
*
* If device is not NULL, its constraints are used, if any.
*
* If no matching constraint is found, the absolute coordinates are mapped to
* the entire layout, unless none is attached, in which case lx and ly are set
* to 0.
*/
void wlr_input_mapper_absolute_to_layout(struct wlr_input_mapper *mapper,
struct wlr_input_device *device, double x, double y,
double *lx, double *ly);
/**
* Get the closest point satisfying constraints from the given point.
*
* If device is not NULL, its constraints are used, if any.
*
* If no matching constraint is found, get the closest point from the layout.
*/
void wlr_input_mapper_closest_point(struct wlr_input_mapper *mapper,
struct wlr_input_device *device, double lx, double ly,
double *closest_lx, double *closest_ly);
/**
* Map device to output.
*
* If device is NULL, sets the default output constraint.
* If output is NULL, the output constraint is reset.
*
* When the output is destroyed, the output constraint is reset.
*/
void wlr_input_mapper_map_to_output(struct wlr_input_mapper *mapper,
struct wlr_input_device *device, struct wlr_output *output);
/**
* Map device to box.
*
* If device is NULL, sets the default box constraint.
* If box is empty, the box constraint is reset.
*/
void wlr_input_mapper_map_to_box(struct wlr_input_mapper *mapper,
struct wlr_input_device *device, const struct wlr_box *box);
#endif