2020-05-29 21:36:12 +01:00
|
|
|
#include "labwc.h"
|
2020-10-19 22:14:17 +01:00
|
|
|
#include "menu/menu.h"
|
2020-05-29 21:36:12 +01:00
|
|
|
|
2020-10-02 21:19:56 +01:00
|
|
|
static void
|
|
|
|
|
request_cursor_notify(struct wl_listener *listener, void *data)
|
|
|
|
|
{
|
|
|
|
|
struct seat *seat = wl_container_of(listener, seat, request_cursor);
|
|
|
|
|
/*
|
|
|
|
|
* This event is rasied by the seat when a client provides a cursor
|
|
|
|
|
* image
|
|
|
|
|
*/
|
|
|
|
|
struct wlr_seat_pointer_request_set_cursor_event *event = data;
|
|
|
|
|
struct wlr_seat_client *focused_client =
|
|
|
|
|
seat->seat->pointer_state.focused_client;
|
|
|
|
|
|
|
|
|
|
/* This can be sent by any client, so we check to make sure this one is
|
|
|
|
|
* actually has pointer focus first. */
|
|
|
|
|
if (focused_client == event->seat_client) {
|
|
|
|
|
/* Once we've vetted the client, we can tell the cursor to use
|
|
|
|
|
* the provided surface as the cursor image. It will set the
|
|
|
|
|
* hardware cursor on the output that it's currently on and
|
|
|
|
|
* continue to do so as the cursor moves between outputs. */
|
|
|
|
|
wlr_cursor_set_surface(seat->cursor, event->surface,
|
|
|
|
|
event->hotspot_x, event->hotspot_y);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
request_set_selection_notify(struct wl_listener *listener, void *data)
|
|
|
|
|
{
|
|
|
|
|
struct seat *seat = wl_container_of(
|
|
|
|
|
listener, seat, request_set_selection);
|
|
|
|
|
struct wlr_seat_request_set_selection_event *event = data;
|
|
|
|
|
wlr_seat_set_selection(seat->seat, event->source,
|
|
|
|
|
event->serial);
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-28 20:41:41 +01:00
|
|
|
static void
|
|
|
|
|
process_cursor_move(struct server *server, uint32_t time)
|
2020-05-29 21:36:12 +01:00
|
|
|
{
|
|
|
|
|
/* Move the grabbed view to the new position. */
|
2020-10-02 21:19:56 +01:00
|
|
|
double dx = server->seat.cursor->x - server->grab_x;
|
|
|
|
|
double dy = server->seat.cursor->y - server->grab_y;
|
2020-05-29 21:36:12 +01:00
|
|
|
server->grabbed_view->x = server->grab_box.x + dx;
|
|
|
|
|
server->grabbed_view->y = server->grab_box.y + dy;
|
|
|
|
|
|
2020-09-28 20:41:41 +01:00
|
|
|
if (server->grabbed_view->type != LAB_XWAYLAND_VIEW) {
|
2020-05-29 21:36:12 +01:00
|
|
|
return;
|
2020-09-28 20:41:41 +01:00
|
|
|
}
|
2020-05-29 21:36:12 +01:00
|
|
|
|
|
|
|
|
struct view *view = server->grabbed_view;
|
|
|
|
|
wlr_xwayland_surface_configure(view->xwayland_surface, view->x, view->y,
|
|
|
|
|
view->xwayland_surface->width,
|
|
|
|
|
view->xwayland_surface->height);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define MIN_VIEW_WIDTH (100)
|
|
|
|
|
#define MIN_VIEW_HEIGHT (60)
|
|
|
|
|
|
2020-09-28 20:41:41 +01:00
|
|
|
static void
|
|
|
|
|
process_cursor_resize(struct server *server, uint32_t time)
|
2020-05-29 21:36:12 +01:00
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
* TODO: Wait for the client to prepare a buffer at the new size, then
|
|
|
|
|
* commit any movement that was prepared.
|
|
|
|
|
*/
|
2020-10-02 21:19:56 +01:00
|
|
|
double dx = server->seat.cursor->x - server->grab_x;
|
|
|
|
|
double dy = server->seat.cursor->y - server->grab_y;
|
2020-05-29 21:36:12 +01:00
|
|
|
|
|
|
|
|
struct view *view = server->grabbed_view;
|
2020-09-15 20:41:01 +01:00
|
|
|
struct wlr_box new_view_geo = {
|
|
|
|
|
.x = view->x, .y = view->y, .width = view->w, .height = view->h
|
|
|
|
|
};
|
2020-05-29 21:36:12 +01:00
|
|
|
|
|
|
|
|
if (server->resize_edges & WLR_EDGE_TOP) {
|
|
|
|
|
new_view_geo.y = server->grab_box.y + dy;
|
|
|
|
|
new_view_geo.height = server->grab_box.height - dy;
|
|
|
|
|
} else if (server->resize_edges & WLR_EDGE_BOTTOM) {
|
|
|
|
|
new_view_geo.height = server->grab_box.height + dy;
|
|
|
|
|
}
|
|
|
|
|
if (server->resize_edges & WLR_EDGE_LEFT) {
|
|
|
|
|
new_view_geo.x = server->grab_box.x + dx;
|
|
|
|
|
new_view_geo.width = server->grab_box.width - dx;
|
|
|
|
|
} else if (server->resize_edges & WLR_EDGE_RIGHT) {
|
|
|
|
|
new_view_geo.width = server->grab_box.width + dx;
|
|
|
|
|
}
|
|
|
|
|
if ((new_view_geo.height < MIN_VIEW_HEIGHT) ||
|
2020-09-28 20:41:41 +01:00
|
|
|
(new_view_geo.width < MIN_VIEW_WIDTH)) {
|
2020-05-29 21:36:12 +01:00
|
|
|
return;
|
2020-09-28 20:41:41 +01:00
|
|
|
}
|
2020-05-29 21:36:12 +01:00
|
|
|
|
|
|
|
|
/* Move */
|
|
|
|
|
view->x = new_view_geo.x;
|
|
|
|
|
view->y = new_view_geo.y;
|
|
|
|
|
|
|
|
|
|
/* Resize */
|
2020-09-15 20:41:01 +01:00
|
|
|
new_view_geo.width -= 2 * view->xdg_grab_offset;
|
|
|
|
|
new_view_geo.height -= 2 * view->xdg_grab_offset;
|
2020-05-29 21:36:12 +01:00
|
|
|
view_resize(view, new_view_geo);
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-28 20:41:41 +01:00
|
|
|
static void
|
|
|
|
|
process_cursor_motion(struct server *server, uint32_t time)
|
2020-05-29 21:36:12 +01:00
|
|
|
{
|
|
|
|
|
/* If the mode is non-passthrough, delegate to those functions. */
|
2020-10-21 20:30:06 +01:00
|
|
|
if (server->input_mode == LAB_INPUT_STATE_MOVE) {
|
2020-05-29 21:36:12 +01:00
|
|
|
process_cursor_move(server, time);
|
|
|
|
|
return;
|
2020-10-21 20:30:06 +01:00
|
|
|
} else if (server->input_mode == LAB_INPUT_STATE_RESIZE) {
|
2020-05-29 21:36:12 +01:00
|
|
|
process_cursor_resize(server, time);
|
|
|
|
|
return;
|
2020-10-21 20:30:06 +01:00
|
|
|
} else if (server->input_mode == LAB_INPUT_STATE_MENU) {
|
2020-10-19 22:14:17 +01:00
|
|
|
menu_set_selected(server->rootmenu,
|
|
|
|
|
server->seat.cursor->x, server->seat.cursor->y);
|
|
|
|
|
return;
|
2020-05-29 21:36:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Otherwise, find the view under the pointer and send the event along.
|
|
|
|
|
*/
|
|
|
|
|
double sx, sy;
|
2020-10-02 21:19:56 +01:00
|
|
|
struct wlr_seat *wlr_seat = server->seat.seat;
|
2020-05-29 21:36:12 +01:00
|
|
|
struct wlr_surface *surface = NULL;
|
|
|
|
|
int view_area;
|
2020-09-28 20:41:41 +01:00
|
|
|
struct view *view =
|
2020-10-02 21:19:56 +01:00
|
|
|
desktop_view_at(server, server->seat.cursor->x, server->seat.cursor->y,
|
2020-09-28 20:41:41 +01:00
|
|
|
&surface, &sx, &sy, &view_area);
|
2020-05-29 21:36:12 +01:00
|
|
|
if (!view) {
|
2020-09-28 20:41:41 +01:00
|
|
|
/*
|
|
|
|
|
* If there's no view under the cursor, set the cursor image to
|
2020-05-29 21:36:12 +01:00
|
|
|
* a default. This is what makes the cursor image appear when
|
2020-09-28 20:41:41 +01:00
|
|
|
* you move it around the screen, not over any views.
|
|
|
|
|
*/
|
2020-05-29 21:36:12 +01:00
|
|
|
wlr_xcursor_manager_set_cursor_image(
|
2020-10-02 21:19:56 +01:00
|
|
|
server->seat.xcursor_manager, XCURSOR_DEFAULT, server->seat.cursor);
|
2020-05-29 21:36:12 +01:00
|
|
|
}
|
2020-09-15 20:41:01 +01:00
|
|
|
|
|
|
|
|
/* TODO: Could we use wlr_xcursor_get_resize_name() here?? */
|
2020-05-29 21:36:12 +01:00
|
|
|
switch (view_area) {
|
2020-09-21 19:24:27 +01:00
|
|
|
case LAB_DECO_NONE:
|
2020-05-29 21:36:12 +01:00
|
|
|
break;
|
2020-05-30 21:28:17 +01:00
|
|
|
case LAB_DECO_PART_TOP:
|
|
|
|
|
wlr_xcursor_manager_set_cursor_image(
|
2020-10-02 21:19:56 +01:00
|
|
|
server->seat.xcursor_manager, "top_side", server->seat.cursor);
|
2020-05-30 21:28:17 +01:00
|
|
|
break;
|
|
|
|
|
case LAB_DECO_PART_RIGHT:
|
|
|
|
|
wlr_xcursor_manager_set_cursor_image(
|
2020-10-02 21:19:56 +01:00
|
|
|
server->seat.xcursor_manager, "right_side", server->seat.cursor);
|
2020-05-30 21:28:17 +01:00
|
|
|
break;
|
|
|
|
|
case LAB_DECO_PART_BOTTOM:
|
|
|
|
|
wlr_xcursor_manager_set_cursor_image(
|
2020-10-02 21:19:56 +01:00
|
|
|
server->seat.xcursor_manager, "bottom_side", server->seat.cursor);
|
2020-05-30 21:28:17 +01:00
|
|
|
break;
|
2020-05-29 21:36:12 +01:00
|
|
|
case LAB_DECO_PART_LEFT:
|
|
|
|
|
wlr_xcursor_manager_set_cursor_image(
|
2020-10-02 21:19:56 +01:00
|
|
|
server->seat.xcursor_manager, "left_side", server->seat.cursor);
|
2020-05-29 21:36:12 +01:00
|
|
|
break;
|
2020-09-21 19:24:27 +01:00
|
|
|
default:
|
|
|
|
|
wlr_xcursor_manager_set_cursor_image(
|
2020-10-02 21:19:56 +01:00
|
|
|
server->seat.xcursor_manager, XCURSOR_DEFAULT, server->seat.cursor);
|
2020-09-21 19:24:27 +01:00
|
|
|
break;
|
2020-05-29 21:36:12 +01:00
|
|
|
}
|
|
|
|
|
if (surface) {
|
2020-09-28 20:41:41 +01:00
|
|
|
bool focus_changed =
|
2020-10-02 21:19:56 +01:00
|
|
|
wlr_seat->pointer_state.focused_surface != surface;
|
2020-05-29 21:36:12 +01:00
|
|
|
/*
|
|
|
|
|
* "Enter" the surface if necessary. This lets the client know
|
|
|
|
|
* that the cursor has entered one of its surfaces.
|
|
|
|
|
*
|
|
|
|
|
* Note that this gives the surface "pointer focus", which is
|
|
|
|
|
* distinct from keyboard focus. You get pointer focus by moving
|
|
|
|
|
* the pointer over a window.
|
|
|
|
|
*/
|
2020-10-02 21:19:56 +01:00
|
|
|
wlr_seat_pointer_notify_enter(wlr_seat, surface, sx, sy);
|
2020-05-29 21:36:12 +01:00
|
|
|
if (!focus_changed) {
|
2020-09-28 20:41:41 +01:00
|
|
|
/*
|
|
|
|
|
* The enter event contains coordinates, so we only need
|
|
|
|
|
* to notify on motion if the focus did not change.
|
|
|
|
|
*/
|
2020-10-02 21:19:56 +01:00
|
|
|
wlr_seat_pointer_notify_motion(wlr_seat, time, sx, sy);
|
2020-05-29 21:36:12 +01:00
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
/* Clear pointer focus so future button events and such are not
|
|
|
|
|
* sent to the last client to have the cursor over it. */
|
2020-10-02 21:19:56 +01:00
|
|
|
wlr_seat_pointer_clear_focus(wlr_seat);
|
2020-05-29 21:36:12 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-28 20:41:41 +01:00
|
|
|
void
|
|
|
|
|
cursor_motion(struct wl_listener *listener, void *data)
|
2020-05-29 21:36:12 +01:00
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
* This event is forwarded by the cursor when a pointer emits a
|
|
|
|
|
* _relative_ pointer motion event (i.e. a delta)
|
|
|
|
|
*/
|
2020-10-02 21:19:56 +01:00
|
|
|
struct seat *seat = wl_container_of(listener, seat, cursor_motion);
|
2020-05-29 21:36:12 +01:00
|
|
|
struct wlr_event_pointer_motion *event = data;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* The cursor doesn't move unless we tell it to. The cursor
|
|
|
|
|
* automatically handles constraining the motion to the output layout,
|
|
|
|
|
* as well as any special configuration applied for the specific input
|
|
|
|
|
* device which generated the event. You can pass NULL for the device
|
|
|
|
|
* if you want to move the cursor around without any input.
|
|
|
|
|
*/
|
2020-10-02 21:19:56 +01:00
|
|
|
wlr_cursor_move(seat->cursor, event->device, event->delta_x,
|
|
|
|
|
event->delta_y);
|
|
|
|
|
process_cursor_motion(seat->server, event->time_msec);
|
2020-05-29 21:36:12 +01:00
|
|
|
}
|
|
|
|
|
|
2020-09-28 20:41:41 +01:00
|
|
|
void
|
|
|
|
|
cursor_motion_absolute(struct wl_listener *listener, void *data)
|
2020-05-29 21:36:12 +01:00
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
* This event is forwarded by the cursor when a pointer emits an
|
|
|
|
|
* _absolute_ motion event, from 0..1 on each axis. This happens, for
|
|
|
|
|
* example, when wlroots is running under a Wayland window rather than
|
|
|
|
|
* KMS+DRM, and you move the mouse over the window. You could enter the
|
|
|
|
|
* window from any edge, so we have to warp the mouse there. There is
|
|
|
|
|
* also some hardware which emits these events.
|
|
|
|
|
*/
|
2020-10-02 21:19:56 +01:00
|
|
|
struct seat *seat = wl_container_of(
|
|
|
|
|
listener, seat, cursor_motion_absolute);
|
2020-05-29 21:36:12 +01:00
|
|
|
struct wlr_event_pointer_motion_absolute *event = data;
|
2020-10-02 21:19:56 +01:00
|
|
|
wlr_cursor_warp_absolute(seat->cursor, event->device, event->x, event->y);
|
|
|
|
|
process_cursor_motion(seat->server, event->time_msec);
|
2020-05-29 21:36:12 +01:00
|
|
|
}
|
|
|
|
|
|
2020-09-28 20:41:41 +01:00
|
|
|
void
|
|
|
|
|
cursor_button(struct wl_listener *listener, void *data)
|
2020-05-29 21:36:12 +01:00
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
* This event is forwarded by the cursor when a pointer emits a button
|
|
|
|
|
* event.
|
|
|
|
|
*/
|
2020-10-02 21:19:56 +01:00
|
|
|
struct seat *seat = wl_container_of(listener, seat, cursor_button);
|
|
|
|
|
struct server *server = seat->server;
|
2020-05-29 21:36:12 +01:00
|
|
|
struct wlr_event_pointer_button *event = data;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Notify the client with pointer focus that a button press has
|
|
|
|
|
* occurred.
|
|
|
|
|
*/
|
2020-10-02 21:19:56 +01:00
|
|
|
wlr_seat_pointer_notify_button(seat->seat, event->time_msec,
|
|
|
|
|
event->button, event->state);
|
2020-05-29 21:36:12 +01:00
|
|
|
double sx, sy;
|
|
|
|
|
struct wlr_surface *surface;
|
|
|
|
|
int view_area;
|
2020-10-19 22:14:17 +01:00
|
|
|
struct view *view = desktop_view_at(server, server->seat.cursor->x,
|
|
|
|
|
server->seat.cursor->y, &surface, &sx, &sy, &view_area);
|
|
|
|
|
|
|
|
|
|
/* handle _release_ */
|
2020-05-29 21:36:12 +01:00
|
|
|
if (event->state == WLR_BUTTON_RELEASED) {
|
2020-10-21 20:30:06 +01:00
|
|
|
if (server->input_mode == LAB_INPUT_STATE_MENU) {
|
2020-10-19 22:14:17 +01:00
|
|
|
return;
|
2020-05-29 21:36:12 +01:00
|
|
|
}
|
2020-10-19 22:14:17 +01:00
|
|
|
/* Exit interactive move/resize/menu mode. */
|
2020-10-21 20:30:06 +01:00
|
|
|
server->input_mode = LAB_INPUT_STATE_PASSTHROUGH;
|
2020-10-19 22:14:17 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-21 20:30:06 +01:00
|
|
|
if (server->input_mode == LAB_INPUT_STATE_MENU) {
|
2020-10-19 22:14:17 +01:00
|
|
|
menu_action_selected(server, server->rootmenu);
|
2020-10-21 20:30:06 +01:00
|
|
|
server->input_mode = LAB_INPUT_STATE_PASSTHROUGH;
|
2020-10-19 22:14:17 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* handle _press_ on desktop */
|
|
|
|
|
if (!view) {
|
|
|
|
|
/* launch root-menu */
|
2020-10-21 20:30:06 +01:00
|
|
|
server->input_mode = LAB_INPUT_STATE_MENU;
|
2020-10-19 22:14:17 +01:00
|
|
|
menu_move(server->rootmenu, server->seat.cursor->x,
|
|
|
|
|
server->seat.cursor->y);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Handle _press_ on view */
|
|
|
|
|
desktop_focus_view(&server->seat, view);
|
|
|
|
|
switch (view_area) {
|
|
|
|
|
case LAB_DECO_BUTTON_CLOSE:
|
|
|
|
|
view->impl->close(view);
|
|
|
|
|
break;
|
|
|
|
|
case LAB_DECO_BUTTON_ICONIFY:
|
|
|
|
|
view_minimize(view);
|
|
|
|
|
break;
|
|
|
|
|
case LAB_DECO_PART_TITLE:
|
2020-10-21 20:30:06 +01:00
|
|
|
interactive_begin(view, LAB_INPUT_STATE_MOVE, 0);
|
2020-10-19 22:14:17 +01:00
|
|
|
break;
|
|
|
|
|
case LAB_DECO_PART_TOP:
|
2020-10-21 20:30:06 +01:00
|
|
|
interactive_begin(view, LAB_INPUT_STATE_RESIZE,
|
2020-10-19 22:14:17 +01:00
|
|
|
WLR_EDGE_TOP);
|
|
|
|
|
break;
|
|
|
|
|
case LAB_DECO_PART_RIGHT:
|
2020-10-21 20:30:06 +01:00
|
|
|
interactive_begin(view, LAB_INPUT_STATE_RESIZE,
|
2020-10-19 22:14:17 +01:00
|
|
|
WLR_EDGE_RIGHT);
|
|
|
|
|
break;
|
|
|
|
|
case LAB_DECO_PART_BOTTOM:
|
2020-10-21 20:30:06 +01:00
|
|
|
interactive_begin(view, LAB_INPUT_STATE_RESIZE,
|
2020-10-19 22:14:17 +01:00
|
|
|
WLR_EDGE_BOTTOM);
|
|
|
|
|
break;
|
|
|
|
|
case LAB_DECO_PART_LEFT:
|
2020-10-21 20:30:06 +01:00
|
|
|
interactive_begin(view, LAB_INPUT_STATE_RESIZE,
|
2020-10-19 22:14:17 +01:00
|
|
|
WLR_EDGE_LEFT);
|
|
|
|
|
break;
|
2020-05-29 21:36:12 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-28 20:41:41 +01:00
|
|
|
void
|
|
|
|
|
cursor_axis(struct wl_listener *listener, void *data)
|
2020-05-29 21:36:12 +01:00
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
* This event is forwarded by the cursor when a pointer emits an axis
|
|
|
|
|
* event, for example when you move the scroll wheel.
|
|
|
|
|
*/
|
2020-10-02 21:19:56 +01:00
|
|
|
struct seat *seat = wl_container_of(listener, seat, cursor_axis);
|
2020-05-29 21:36:12 +01:00
|
|
|
struct wlr_event_pointer_axis *event = data;
|
|
|
|
|
|
|
|
|
|
/* Notify the client with pointer focus of the axis event. */
|
2020-10-02 21:19:56 +01:00
|
|
|
wlr_seat_pointer_notify_axis(seat->seat, event->time_msec,
|
|
|
|
|
event->orientation, event->delta, event->delta_discrete,
|
|
|
|
|
event->source);
|
2020-05-29 21:36:12 +01:00
|
|
|
}
|
|
|
|
|
|
2020-09-28 20:41:41 +01:00
|
|
|
void
|
|
|
|
|
cursor_frame(struct wl_listener *listener, void *data)
|
2020-05-29 21:36:12 +01:00
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
* This event is forwarded by the cursor when a pointer emits an frame
|
|
|
|
|
* event. Frame events are sent after regular pointer events to group
|
|
|
|
|
* multiple events together. For instance, two axis events may happen
|
|
|
|
|
* at the same time, in which case a frame event won't be sent in
|
|
|
|
|
* between.
|
|
|
|
|
*/
|
2020-10-02 21:19:56 +01:00
|
|
|
struct seat *seat = wl_container_of(listener, seat, cursor_frame);
|
2020-05-29 21:36:12 +01:00
|
|
|
/* Notify the client with pointer focus of the frame event. */
|
2020-10-02 21:19:56 +01:00
|
|
|
wlr_seat_pointer_notify_frame(seat->seat);
|
2020-05-29 21:36:12 +01:00
|
|
|
}
|
2020-05-29 22:18:03 +01:00
|
|
|
|
2020-09-28 20:41:41 +01:00
|
|
|
void
|
2020-10-02 21:19:56 +01:00
|
|
|
cursor_init(struct seat *seat)
|
2020-05-29 22:18:03 +01:00
|
|
|
{
|
2020-10-02 21:19:56 +01:00
|
|
|
seat->xcursor_manager = wlr_xcursor_manager_create(NULL, 24);
|
|
|
|
|
wlr_xcursor_manager_load(seat->xcursor_manager, 1);
|
|
|
|
|
|
|
|
|
|
seat->cursor_motion.notify = cursor_motion;
|
|
|
|
|
wl_signal_add(&seat->cursor->events.motion, &seat->cursor_motion);
|
|
|
|
|
seat->cursor_motion_absolute.notify = cursor_motion_absolute;
|
|
|
|
|
wl_signal_add(&seat->cursor->events.motion_absolute,
|
|
|
|
|
&seat->cursor_motion_absolute);
|
|
|
|
|
seat->cursor_button.notify = cursor_button;
|
|
|
|
|
wl_signal_add(&seat->cursor->events.button, &seat->cursor_button);
|
|
|
|
|
seat->cursor_axis.notify = cursor_axis;
|
|
|
|
|
wl_signal_add(&seat->cursor->events.axis, &seat->cursor_axis);
|
|
|
|
|
seat->cursor_frame.notify = cursor_frame;
|
|
|
|
|
wl_signal_add(&seat->cursor->events.frame, &seat->cursor_frame);
|
|
|
|
|
|
|
|
|
|
seat->request_cursor.notify = request_cursor_notify;
|
|
|
|
|
wl_signal_add(&seat->seat->events.request_set_cursor, &seat->request_cursor);
|
|
|
|
|
seat->request_set_selection.notify = request_set_selection_notify;
|
|
|
|
|
wl_signal_add(&seat->seat->events.request_set_selection, &seat->request_set_selection);
|
|
|
|
|
|
|
|
|
|
/* TODO:
|
|
|
|
|
* seat->request_set_primary_selection.notify =
|
|
|
|
|
* request_set_primary_selectioni_notify;
|
|
|
|
|
* wl_signal_add(&seat->seat->events.request_set_primary_selection,
|
|
|
|
|
* &seat->request_set_primary_selection);
|
|
|
|
|
*/
|
2020-05-29 22:18:03 +01:00
|
|
|
}
|