swayfx/include/sway/input/cursor.h
Ryan Dwyer 7b9ae42331 Introduce default seatop
This introduces a `default` seat operation which is used when no mouse
buttons are being held. This means there is now always a seat operation
in progress. It allows us to separate `default` code from the standard
cursor management code.

The sway_seatop_impl struct has gained callbacks `axis`, `rebase` and
`end`, and lost callbacks `finish` and `abort`. `axis` and `rebase` are
only used by the default seatop. `end` is called when a seatop is being
replaced by another one and allows the seatop to free any resources,
though no seatop currently needs to do this. `finish` is no longer
required, as each seatop can gracefully finish in their `button`
callback. And `abort` is not needed, as calling `end` would achieve the
same thing. The struct has also gained a bool named allow_set_cursor
which allows the client to set a new cursor during `default` and `down`
seatops.

Seatops would previously store which button they were started with and
stop when that button was released. This behaviour is changed so that it
only ends once all buttons are released. So you can start a drag with
$mod+left, then click and hold right, release left and it'll continue
dragging while the right button is held.

The motion callback now accepts dx and dy. Most seatops don't use this
as they store the cursor position when the seatop is started and compare
it with the current cursor position. This approach doesn't make sense
for the default seatop though, hence why dx and dy are needed.

The pressed_buttons array has been moved from the sway_cursor struct to
the default seatop's data. This is only used for the default seatop to
check bindings. The total pressed button count remains in the
sway_cursor struct though, because all the other seatops check it to
know if they should end.

The `down` seatop no longer has a `moved` property. This was used to
track if the cursor moved and to recheck focus_follows_mouse, but seems
to work without it.

The logic for focus_follows_mouse has been refactored. As part of this
I've removed the call to wlr_seat_keyboard_has_grab as we don't appear
to use keyboard grabs.

The functions for handling relative motion, absolute motion and tool
axis have been changed. Previously the handler functions were
handle_cursor_motion, handle_cursor_motion_absolute and
handle_tool_axis. The latter two both called cursor_motion_absolute.
Both handle_cursor_motion and cursor_motion_absolute did very similar
things. These are now simplified into three handlers and a single common
function called cursor_motion. All three handlers call cursor_motion. As
cursor_motion works with relative distances, the absolute and tool axis
handlers convert them to relative first.
2019-03-17 10:02:04 -06:00

113 lines
3 KiB
C

#ifndef _SWAY_INPUT_CURSOR_H
#define _SWAY_INPUT_CURSOR_H
#include <stdbool.h>
#include <stdint.h>
#include <wlr/types/wlr_pointer_constraints_v1.h>
#include <wlr/types/wlr_surface.h>
#include "sway/input/seat.h"
#define SWAY_CURSOR_PRESSED_BUTTONS_CAP 32
#define SWAY_SCROLL_UP KEY_MAX + 1
#define SWAY_SCROLL_DOWN KEY_MAX + 2
#define SWAY_SCROLL_LEFT KEY_MAX + 3
#define SWAY_SCROLL_RIGHT KEY_MAX + 4
struct sway_cursor {
struct sway_seat *seat;
struct wlr_cursor *cursor;
struct {
double x, y;
struct sway_node *node;
} previous;
struct wlr_xcursor_manager *xcursor_manager;
const char *image;
struct wl_client *image_client;
struct wlr_surface *image_surface;
int hotspot_x, hotspot_y;
struct wlr_pointer_constraint_v1 *active_constraint;
pixman_region32_t confine; // invalid if active_constraint == NULL
struct wl_listener motion;
struct wl_listener motion_absolute;
struct wl_listener button;
struct wl_listener axis;
struct wl_listener frame;
struct wl_listener touch_down;
struct wl_listener touch_up;
struct wl_listener touch_motion;
struct wl_listener tool_axis;
struct wl_listener tool_tip;
struct wl_listener tool_button;
uint32_t tool_buttons;
struct wl_listener request_set_cursor;
struct wl_listener constraint_commit;
struct wl_event_source *hide_source;
bool hidden;
size_t pressed_button_count;
};
struct sway_node;
struct sway_node *node_at_coords(
struct sway_seat *seat, double lx, double ly,
struct wlr_surface **surface, double *sx, double *sy);
void sway_cursor_destroy(struct sway_cursor *cursor);
struct sway_cursor *sway_cursor_create(struct sway_seat *seat);
/**
* "Rebase" a cursor on top of whatever view is underneath it.
*
* This chooses a cursor icon and sends a motion event to the surface.
*/
void cursor_rebase(struct sway_cursor *cursor);
void cursor_rebase_all(void);
void cursor_handle_activity(struct sway_cursor *cursor);
void cursor_unhide(struct sway_cursor *cursor);
int cursor_get_timeout(struct sway_cursor *cursor);
void dispatch_cursor_button(struct sway_cursor *cursor,
struct wlr_input_device *device, uint32_t time_msec, uint32_t button,
enum wlr_button_state state);
void dispatch_cursor_axis(struct sway_cursor *cursor,
struct wlr_event_pointer_axis *event);
void cursor_set_image(struct sway_cursor *cursor, const char *image,
struct wl_client *client);
void cursor_set_image_surface(struct sway_cursor *cursor,
struct wlr_surface *surface, int32_t hotspot_x, int32_t hotspot_y,
struct wl_client *client);
void cursor_warp_to_container(struct sway_cursor *cursor,
struct sway_container *container);
void cursor_warp_to_workspace(struct sway_cursor *cursor,
struct sway_workspace *workspace);
void sway_cursor_constrain(struct sway_cursor *cursor,
struct wlr_pointer_constraint_v1 *constraint);
uint32_t get_mouse_bindsym(const char *name, char **error);
uint32_t get_mouse_bindcode(const char *name, char **error);
// Considers both bindsym and bindcode
uint32_t get_mouse_button(const char *name, char **error);
const char *get_mouse_button_name(uint32_t button);
#endif