Opening this issue to start a discussion about some high level API designs I have in mind. Feel free to propose more high level APIs here as well.
This should encapsulate some of the concepts required for a virtual desktop of multiple outputs.
struct wlr_output_layout_state;
struct wlr_output_layout_impl;
struct wlr_output_layout {
struct wlr_output_layout_state *state;
struct wlr_output_layout_impl *impl;
list_t outputs;
};
struct wlr_output_layout_output {
struct wlr_output *output;
int x, y;
};
void wlr_output_layout_add(struct wlr_output_layout *layout,
struct wlr_output *output, int x, int y);
void wlr_output_layout_move(struct wlr_output_layout *layout,
struct wlr_output *output, int x, int y);
void wlr_output_layout_remove(struct wlr_output_layout *layout,
struct wlr_output *output);
/**
* Given x and y as pointers to global coordinates, adjusts them to local output
* coordinates relative to the given reference output.
*/
void wlr_output_layout_output_coords(struct wlr_output_layout *layout,
struct wlr_output *reference, int *x, int *y);
/**
* Finds the next output in the given direction.
* x and y should each be 1, 0, or -1.
*/
struct wlr_output *wlr_output_layout_output_towards(struct wlr_output_layout *layout,
struct wlr_output *output, int x, int y);
We could use wlr_output_layout_intersections during output_frame to find each wayland surface that needs to be rendered to this output. This would also make output mirroring just werk.
Also: kde_output_layout_protocol_attach(kde_ol_ref, output_layout)
This would represent an individual cursor (as in
), which might have one or more input devices attached.
struct wlr_cursor_state *;
struct wlr_cursor_impl *;
struct wlr_cursor {
struct wlr_cursor_state *state;
struct wlr_cursor_impl *impl;
int x, y;
struct {
struct wl_signal motion;
} events;
};
/**
* 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 wlr_output_layout.
*/
void wlr_cursor_map_to_region(struct wlr_cursor *cur, struct wlr_geometry *geo);
/**
* Maps inputs from this input device to an arbitrary region on the associated
* wlr_output_layout.
*/
void wlr_cursor_map_input_to_region(struct wlr_cursor *cur,
struct wlr_input_device *dev, struct wlr_geometry *geo);
This should allow you to attach several devices to one cursor, have several cursors at once, map one input device to multiple cursors, etc
Why is the wlr_input_device separate from the wlr_cursor, couldn't they both be contained in the wl_cursor? Because right now I find it a little confusing (e.g, which struct contains the libinput data, and which is just meta-data from wlroots? Does the cursor just apply to pointer inputs, or does it also apply to touch and tablet? If it affects both, why can't they both in one struct instead of two separate ones that need to be kept together?).
I like the output layout design.
They're separate because they're separate things. By splitting them up you gain the flexiblity to have multiple cursors, multiple pointers controlling one cursor, a drawing tablet controlling a cursor, etc. You also get the ability to do things like bind a pointer and a drawing tablet to a cursor and restrict the drawing tablet to one output and the mouse to all outputs.
I'm working on wlr_output_layout now.
I'm working on wlr_cursor now.
fixed in #120 and #97
Most helpful comment
They're separate because they're separate things. By splitting them up you gain the flexiblity to have multiple cursors, multiple pointers controlling one cursor, a drawing tablet controlling a cursor, etc. You also get the ability to do things like bind a pointer and a drawing tablet to a cursor and restrict the drawing tablet to one output and the mouse to all outputs.