From a7446792a1a0fd9fe3391f041d7bbfe9e2b11255 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sun, 22 Oct 2017 23:19:21 -0400 Subject: Consider scale factor when rendering views --- include/rootston/config.h | 1 + include/rootston/view.h | 1 + include/wlr/types/wlr_surface.h | 6 +++++- 3 files changed, 7 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/rootston/config.h b/include/rootston/config.h index 75c04619..e0466117 100644 --- a/include/rootston/config.h +++ b/include/rootston/config.h @@ -8,6 +8,7 @@ struct output_config { char *name; enum wl_output_transform transform; int x, y; + int scale; struct wl_list link; struct { int width, height; diff --git a/include/rootston/view.h b/include/rootston/view.h index 993ff654..4a5e8d08 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -48,6 +48,7 @@ enum roots_view_type { struct roots_view { struct roots_desktop *desktop; + struct roots_output *output; double x, y; float rotation; // TODO: Something for roots-enforced width/height diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h index ea4184aa..e1a07566 100644 --- a/include/wlr/types/wlr_surface.h +++ b/include/wlr/types/wlr_surface.h @@ -1,10 +1,10 @@ #ifndef WLR_TYPES_WLR_SURFACE_H #define WLR_TYPES_WLR_SURFACE_H - #include #include #include #include +#include struct wlr_frame_callback { struct wl_resource *resource; @@ -135,4 +135,8 @@ struct wlr_surface *wlr_surface_get_main_surface(struct wlr_surface *surface); */ struct wlr_subsurface *wlr_surface_subsurface_at(struct wlr_surface *surface, double sx, double sy, double *sub_x, double *sub_y); + +void wlr_surface_send_enter(struct wlr_surface *surface, + struct wlr_output *output); + #endif -- cgit v1.2.3 From a6930cd8ea2424f12aafc8d0b67426d0e5161c44 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 25 Oct 2017 22:37:02 -0400 Subject: Handle output enter/leave correctly --- include/rootston/view.h | 5 ++-- include/wlr/types/wlr_surface.h | 3 +++ rootston/desktop.c | 59 +++++++++++++++++++++++------------------ rootston/xdg_shell_v6.c | 2 +- types/wlr_output.c | 1 - types/wlr_surface.c | 13 ++++++++- 6 files changed, 51 insertions(+), 32 deletions(-) (limited to 'include') diff --git a/include/rootston/view.h b/include/rootston/view.h index 4a5e8d08..79d61ba6 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -48,7 +48,6 @@ enum roots_view_type { struct roots_view { struct roots_desktop *desktop; - struct roots_output *output; double x, y; float rotation; // TODO: Something for roots-enforced width/height @@ -72,14 +71,14 @@ struct roots_view { // configure event from the xdg_shell // If not then this should follow the typical type/impl pattern we use // elsewhere - void (*get_size)(struct roots_view *view, struct wlr_box *box); + void (*get_size)(const struct roots_view *view, struct wlr_box *box); void (*activate)(struct roots_view *view, bool active); void (*resize)(struct roots_view *view, uint32_t width, uint32_t height); void (*set_position)(struct roots_view *view, double x, double y); void (*close)(struct roots_view *view); }; -void view_get_size(struct roots_view *view, struct wlr_box *box); +void view_get_size(const struct roots_view *view, struct wlr_box *box); void view_activate(struct roots_view *view, bool active); void view_resize(struct roots_view *view, uint32_t width, uint32_t height); void view_set_position(struct roots_view *view, double x, double y); diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h index e1a07566..cea53109 100644 --- a/include/wlr/types/wlr_surface.h +++ b/include/wlr/types/wlr_surface.h @@ -139,4 +139,7 @@ struct wlr_subsurface *wlr_surface_subsurface_at(struct wlr_surface *surface, void wlr_surface_send_enter(struct wlr_surface *surface, struct wlr_output *output); +void wlr_surface_send_leave(struct wlr_surface *surface, + struct wlr_output *output); + #endif diff --git a/rootston/desktop.c b/rootston/desktop.c index 37022ca4..0cc2180d 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -35,45 +35,52 @@ void view_destroy(struct roots_view *view) { free(view); } -void view_get_size(struct roots_view *view, struct wlr_box *box) { +void view_get_size(const struct roots_view *view, struct wlr_box *box) { if (view->get_size) { view->get_size(view, box); - return; + } else { + box->width = view->wlr_surface->current->width; + box->height = view->wlr_surface->current->height; } - box->x = box->y = 0; - box->width = view->wlr_surface->current->width; - box->height = view->wlr_surface->current->height; + box->x = view->x; + box->y = view->y; } -static void view_update_output(struct roots_view *view) { +static void view_update_output(const struct roots_view *view, + const struct wlr_box *before) { struct roots_desktop *desktop = view->desktop; - struct roots_output *output = NULL, *_output; + struct roots_output *output; struct wlr_box box; view_get_size(view, &box); - wl_list_for_each(_output, &desktop->outputs, link) { - if (!wlr_output_layout_intersects(desktop->layout, _output->wlr_output, - view->x, view->y, view->x + box.width, view->x + box.height)) { - continue; + wl_list_for_each(output, &desktop->outputs, link) { + bool intersected = before->x != -1 && wlr_output_layout_intersects( + desktop->layout, output->wlr_output, + before->x, before->y, before->x + before->width, + before->y + before->height); + bool intersects = wlr_output_layout_intersects( + desktop->layout, output->wlr_output, + view->x, view->y, view->x + box.width, view->y + box.height); + if (intersected && !intersects) { + wlr_log(L_DEBUG, "Leaving output %s", output->wlr_output->name); + wlr_surface_send_leave(view->wlr_surface, output->wlr_output); } - if (output == NULL - || output->wlr_output->scale < _output->wlr_output->scale) { - output = _output; + if (!intersected && intersects) { + wlr_log(L_DEBUG, "Entering output %s", output->wlr_output->name); + wlr_surface_send_enter(view->wlr_surface, output->wlr_output); } } - if (output && output != view->output) { - view->output = output; - wlr_surface_send_enter(view->wlr_surface, output->wlr_output); - } } void view_set_position(struct roots_view *view, double x, double y) { + struct wlr_box before; + view_get_size(view, &before); if (view->set_position) { view->set_position(view, x, y); } else { view->x = x; view->y = y; } - view_update_output(view); + view_update_output(view, &before); } void view_activate(struct roots_view *view, bool activate) { @@ -83,10 +90,12 @@ void view_activate(struct roots_view *view, bool activate) { } void view_resize(struct roots_view *view, uint32_t width, uint32_t height) { + struct wlr_box before; + view_get_size(view, &before); if (view->resize) { view->resize(view, width, height); } - view_update_output(view); + view_update_output(view, &before); } void view_close(struct roots_view *view) { @@ -96,8 +105,8 @@ void view_close(struct roots_view *view) { } bool view_center(struct roots_view *view) { - struct wlr_box size; - view_get_size(view, &size); + struct wlr_box box; + view_get_size(view, &box); struct roots_desktop *desktop = view->desktop; struct wlr_cursor *cursor = desktop->server->input->cursor; @@ -122,16 +131,14 @@ bool view_center(struct roots_view *view) { double view_x = (double)(width - size.width) / 2 + l_output->x; double view_y = (double)(height - size.height) / 2 + l_output->y; - view_set_position(view, view_x, view_y); return true; } -void view_setup(struct roots_view *view) { - view_center(view); - +void view_initialize(struct roots_view *view) { struct roots_input *input = view->desktop->server->input; + view_center(view); set_view_focus(input, view->desktop, view); wlr_seat_keyboard_notify_enter(input->wl_seat, view->wlr_surface); view_update_output(view); diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 704ccb1e..2d83019f 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -10,7 +10,7 @@ #include "rootston/server.h" #include "rootston/input.h" -static void get_size(struct roots_view *view, struct wlr_box *box) { +static void get_size(const struct roots_view *view, struct wlr_box *box) { assert(view->type == ROOTS_XDG_SHELL_V6_VIEW); struct wlr_xdg_surface_v6 *surf = view->xdg_surface_v6; // TODO: surf->geometry can be NULL diff --git a/types/wlr_output.c b/types/wlr_output.c index dd7e8d6a..d6efd9bf 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -43,7 +43,6 @@ static void wl_output_send_to_resource(struct wl_resource *resource) { } } if (version >= WL_OUTPUT_SCALE_SINCE_VERSION) { - wlr_log(L_DEBUG, "Sending scale"); wl_output_send_scale(resource, output->scale); } if (version >= WL_OUTPUT_DONE_SINCE_VERSION) { diff --git a/types/wlr_surface.c b/types/wlr_surface.c index 28f3d05b..a21be8de 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -901,9 +901,20 @@ void wlr_surface_send_enter(struct wlr_surface *surface, struct wl_resource *resource; wl_resource_for_each(resource, &output->wl_resources) { if (client == wl_resource_get_client(resource)) { - wlr_log(L_DEBUG, "sending output enter"); wl_surface_send_enter(surface->resource, resource); break; } } } + +void wlr_surface_send_leave(struct wlr_surface *surface, + struct wlr_output *output) { + struct wl_client *client = wl_resource_get_client(surface->resource); + struct wl_resource *resource; + wl_resource_for_each(resource, &output->wl_resources) { + if (client == wl_resource_get_client(resource)) { + wl_surface_send_leave(surface->resource, resource); + break; + } + } +} -- cgit v1.2.3 From 53021f8ed428a1a023769339e6162bfebbe4c7a2 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Thu, 2 Nov 2017 20:13:10 -0400 Subject: rootston: break up input.h --- include/rootston/input.h | 52 ------------------------------------------ include/rootston/keyboard.h | 22 ++++++++++++++++++ include/rootston/pointer.h | 16 +++++++++++++ include/rootston/tablet_tool.h | 20 ++++++++++++++++ include/rootston/touch.h | 22 ++++++++++++++++++ rootston/config.c | 1 + rootston/cursor.c | 4 ++++ rootston/input.c | 4 ++++ rootston/keyboard.c | 1 + rootston/pointer.c | 1 + rootston/tablet_tool.c | 1 + rootston/touch.c | 1 + 12 files changed, 93 insertions(+), 52 deletions(-) create mode 100644 include/rootston/keyboard.h create mode 100644 include/rootston/pointer.h create mode 100644 include/rootston/tablet_tool.h create mode 100644 include/rootston/touch.h (limited to 'include') diff --git a/include/rootston/input.h b/include/rootston/input.h index 20b73c8a..6d07de43 100644 --- a/include/rootston/input.h +++ b/include/rootston/input.h @@ -1,6 +1,5 @@ #ifndef _ROOTSTON_INPUT_H #define _ROOTSTON_INPUT_H -#include #include #include #include @@ -10,41 +9,6 @@ #include "rootston/view.h" #include "rootston/server.h" -#define ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP 32 - -struct roots_keyboard { - struct roots_input *input; - struct wlr_input_device *device; - struct wl_listener key; - struct wl_listener modifiers; - struct wl_list link; - - xkb_keysym_t pressed_keysyms[ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP]; -}; - -struct roots_pointer { - struct roots_input *input; - struct wlr_input_device *device; - struct wl_list link; -}; - -struct roots_touch { - struct roots_input *input; - struct wlr_input_device *device; - struct wl_list link; -}; - -// TODO: tablet pad -struct roots_tablet_tool { - struct roots_input *input; - struct wlr_input_device *device; - struct wl_listener axis; - struct wl_listener proximity; - struct wl_listener tip; - struct wl_listener button; - struct wl_list link; -}; - enum roots_cursor_mode { ROOTS_CURSOR_PASSTHROUGH = 0, ROOTS_CURSOR_MOVE = 1, @@ -77,13 +41,6 @@ struct roots_drag_icon { struct wl_listener surface_commit; }; -struct roots_touch_point { - struct roots_touch *device; - int32_t slot; - double x, y; - struct wl_list link; -}; - struct roots_input { struct roots_config *config; struct roots_server *server; @@ -138,15 +95,6 @@ struct roots_input *input_create(struct roots_server *server, struct roots_config *config); void input_destroy(struct roots_input *input); -void pointer_add(struct wlr_input_device *device, struct roots_input *input); -void pointer_remove(struct wlr_input_device *device, struct roots_input *input); -void keyboard_add(struct wlr_input_device *device, struct roots_input *input); -void keyboard_remove(struct wlr_input_device *device, struct roots_input *input); -void touch_add(struct wlr_input_device *device, struct roots_input *input); -void touch_remove(struct wlr_input_device *device, struct roots_input *input); -void tablet_tool_add(struct wlr_input_device *device, struct roots_input *input); -void tablet_tool_remove(struct wlr_input_device *device, struct roots_input *input); - void cursor_initialize(struct roots_input *input); void cursor_load_config(struct roots_config *config, struct wlr_cursor *cursor, diff --git a/include/rootston/keyboard.h b/include/rootston/keyboard.h new file mode 100644 index 00000000..33017b56 --- /dev/null +++ b/include/rootston/keyboard.h @@ -0,0 +1,22 @@ +#ifndef _ROOTSTON_KEYBOARD_H +#define _ROOTSTON_KEYBOARD_H + +#include +#include "rootston/input.h" + +#define ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP 32 + +struct roots_keyboard { + struct roots_input *input; + struct wlr_input_device *device; + struct wl_listener key; + struct wl_listener modifiers; + struct wl_list link; + + xkb_keysym_t pressed_keysyms[ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP]; +}; + +void keyboard_add(struct wlr_input_device *device, struct roots_input *input); +void keyboard_remove(struct wlr_input_device *device, struct roots_input *input); + +#endif diff --git a/include/rootston/pointer.h b/include/rootston/pointer.h new file mode 100644 index 00000000..b3fc8c3a --- /dev/null +++ b/include/rootston/pointer.h @@ -0,0 +1,16 @@ +#ifndef _ROOTSTON_POINTER_H +#define _ROOTSTON_POINTER_H + +#include +#include + +struct roots_pointer { + struct roots_input *input; + struct wlr_input_device *device; + struct wl_list link; +}; + +void pointer_add(struct wlr_input_device *device, struct roots_input *input); +void pointer_remove(struct wlr_input_device *device, struct roots_input *input); + +#endif diff --git a/include/rootston/tablet_tool.h b/include/rootston/tablet_tool.h new file mode 100644 index 00000000..72ebf6d8 --- /dev/null +++ b/include/rootston/tablet_tool.h @@ -0,0 +1,20 @@ +#ifndef _ROOTSTON_TABLET_TOOL_H +#define _ROOTSTON_TABLET_TOOL_H + +#include +#include "rootston/input.h" + +struct roots_tablet_tool { + struct roots_input *input; + struct wlr_input_device *device; + struct wl_listener axis; + struct wl_listener proximity; + struct wl_listener tip; + struct wl_listener button; + struct wl_list link; +}; + +void tablet_tool_add(struct wlr_input_device *device, struct roots_input *input); +void tablet_tool_remove(struct wlr_input_device *device, struct roots_input *input); + +#endif diff --git a/include/rootston/touch.h b/include/rootston/touch.h new file mode 100644 index 00000000..1624c3ad --- /dev/null +++ b/include/rootston/touch.h @@ -0,0 +1,22 @@ +#ifndef _ROOTSTON_TOUCH_H +#define _ROOTSTON_TOUCH_H + +#include + +struct roots_touch { + struct roots_input *input; + struct wlr_input_device *device; + struct wl_list link; +}; + +struct roots_touch_point { + struct roots_touch *device; + int32_t slot; + double x, y; + struct wl_list link; +}; + +void touch_add(struct wlr_input_device *device, struct roots_input *input); +void touch_remove(struct wlr_input_device *device, struct roots_input *input); + +#endif diff --git a/rootston/config.c b/rootston/config.c index dc7a4b1d..a3ae78be 100644 --- a/rootston/config.c +++ b/rootston/config.c @@ -13,6 +13,7 @@ #include #include "rootston/config.h" #include "rootston/input.h" +#include "rootston/keyboard.h" #include "rootston/ini.h" static void usage(const char *name, int ret) { diff --git a/rootston/cursor.c b/rootston/cursor.c index 31001a9f..61dcae7a 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -18,6 +18,10 @@ #include "rootston/input.h" #include "rootston/desktop.h" #include "rootston/view.h" +#include "rootston/keyboard.h" +#include "rootston/pointer.h" +#include "rootston/tablet_tool.h" +#include "rootston/touch.h" const struct roots_input_event *get_input_event(struct roots_input *input, uint32_t serial) { diff --git a/rootston/input.c b/rootston/input.c index 5d367a5e..c8d46a69 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -8,6 +8,10 @@ #include "rootston/server.h" #include "rootston/config.h" #include "rootston/input.h" +#include "rootston/tablet_tool.h" +#include "rootston/keyboard.h" +#include "rootston/pointer.h" +#include "rootston/touch.h" static const char *device_type(enum wlr_input_device_type type) { switch (type) { diff --git a/rootston/keyboard.c b/rootston/keyboard.c index e174b731..9458a05c 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -10,6 +10,7 @@ #include #include #include "rootston/input.h" +#include "rootston/keyboard.h" static ssize_t keyboard_pressed_keysym_index(struct roots_keyboard *keyboard, xkb_keysym_t keysym) { diff --git a/rootston/pointer.c b/rootston/pointer.c index 299ecdfc..cb099264 100644 --- a/rootston/pointer.c +++ b/rootston/pointer.c @@ -3,6 +3,7 @@ #include #include #include "rootston/input.h" +#include "rootston/pointer.h" void pointer_add(struct wlr_input_device *device, struct roots_input *input) { struct roots_pointer *pointer = calloc(sizeof(struct roots_pointer), 1); diff --git a/rootston/tablet_tool.c b/rootston/tablet_tool.c index a612e683..3327115d 100644 --- a/rootston/tablet_tool.c +++ b/rootston/tablet_tool.c @@ -4,6 +4,7 @@ #include #include #include "rootston/input.h" +#include "rootston/tablet_tool.h" void tablet_tool_add(struct wlr_input_device *device, struct roots_input *input) { struct roots_tablet_tool *tool = calloc(sizeof(struct roots_tablet_tool), 1); diff --git a/rootston/touch.c b/rootston/touch.c index f6d9b11a..069853ab 100644 --- a/rootston/touch.c +++ b/rootston/touch.c @@ -3,6 +3,7 @@ #include #include #include "rootston/input.h" +#include "rootston/touch.h" // TODO: we'll likely want touch events to both control the cursor *and* be // submitted directly to the seat. -- cgit v1.2.3 From 447c561d1588226fd6aeb6668c7adb352cb77725 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Fri, 3 Nov 2017 06:08:37 -0400 Subject: rootston: seat config by device --- include/rootston/config.h | 1 + rootston/config.c | 5 +++++ 2 files changed, 6 insertions(+) (limited to 'include') diff --git a/include/rootston/config.h b/include/rootston/config.h index 75c04619..58fb1a1c 100644 --- a/include/rootston/config.h +++ b/include/rootston/config.h @@ -19,6 +19,7 @@ struct device_config { char *name; char *mapped_output; struct wlr_box *mapped_box; + char *seat; struct wl_list link; }; diff --git a/rootston/config.c b/rootston/config.c index a3ae78be..815040bf 100644 --- a/rootston/config.c +++ b/rootston/config.c @@ -289,6 +289,7 @@ static int config_ini_handler(void *user, const char *section, const char *name, if (!found) { dc = calloc(1, sizeof(struct device_config)); dc->name = strdup(device_name); + dc->seat = strdup("seat0"); wl_list_insert(&config->devices, &dc->link); } @@ -298,6 +299,9 @@ static int config_ini_handler(void *user, const char *section, const char *name, } else if (strcmp(name, "geometry") == 0) { free(dc->mapped_box); dc->mapped_box = parse_geometry(value); + } else if (strcmp(name, "seat") == 0) { + free(dc->seat); + dc->seat = strdup(value); } else { wlr_log(L_ERROR, "got unknown device config: %s", name); } @@ -387,6 +391,7 @@ void roots_config_destroy(struct roots_config *config) { struct device_config *dc, *dtmp = NULL; wl_list_for_each_safe(dc, dtmp, &config->devices, link) { free(dc->name); + free(dc->seat); free(dc->mapped_output); free(dc->mapped_box); free(dc); -- cgit v1.2.3 From 9bd0f47efd9a0c851d1715f3b9427b5f51b6d8a3 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Fri, 3 Nov 2017 06:18:20 -0400 Subject: rootston: refactor keyboard --- include/rootston/keyboard.h | 10 ++++++++-- rootston/input.c | 4 ++-- rootston/keyboard.c | 35 ++++++++++++++++++++++------------- 3 files changed, 32 insertions(+), 17 deletions(-) (limited to 'include') diff --git a/include/rootston/keyboard.h b/include/rootston/keyboard.h index 33017b56..f4acc0aa 100644 --- a/include/rootston/keyboard.h +++ b/include/rootston/keyboard.h @@ -16,7 +16,13 @@ struct roots_keyboard { xkb_keysym_t pressed_keysyms[ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP]; }; -void keyboard_add(struct wlr_input_device *device, struct roots_input *input); -void keyboard_remove(struct wlr_input_device *device, struct roots_input *input); +struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, + struct roots_input *input); +void roots_keyboard_destroy(struct wlr_input_device *device, struct roots_input *input); + +void roots_keyboard_handle_key(struct roots_keyboard *keyboard, + struct wlr_event_keyboard_key *event); + +void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard); #endif diff --git a/rootston/input.c b/rootston/input.c index c8d46a69..2f50c708 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -36,7 +36,7 @@ static void input_add_notify(struct wl_listener *listener, void *data) { device->vendor, device->product, device_type(device->type)); switch (device->type) { case WLR_INPUT_DEVICE_KEYBOARD: - keyboard_add(device, input); + roots_keyboard_create(device, input); break; case WLR_INPUT_DEVICE_POINTER: pointer_add(device, input); @@ -57,7 +57,7 @@ static void input_remove_notify(struct wl_listener *listener, void *data) { struct roots_input *input = wl_container_of(listener, input, input_remove); switch (device->type) { case WLR_INPUT_DEVICE_KEYBOARD: - keyboard_remove(device, input); + roots_keyboard_destroy(device, input); break; case WLR_INPUT_DEVICE_POINTER: pointer_remove(device, input); diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 9458a05c..ece95245 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -123,10 +123,8 @@ static void keyboard_keysym_release(struct roots_keyboard *keyboard, } } -static void keyboard_key_notify(struct wl_listener *listener, void *data) { - struct wlr_event_keyboard_key *event = data; - struct roots_keyboard *keyboard = wl_container_of(listener, keyboard, key); - +void roots_keyboard_handle_key(struct roots_keyboard *keyboard, + struct wlr_event_keyboard_key *event) { uint32_t keycode = event->keycode + 8; const xkb_keysym_t *syms; int syms_len = xkb_state_key_get_syms(keyboard->device->keyboard->xkb_state, @@ -149,9 +147,13 @@ static void keyboard_key_notify(struct wl_listener *listener, void *data) { } } -static void keyboard_modifiers_notify(struct wl_listener *listener, void *data) { - struct roots_keyboard *r_keyboard = - wl_container_of(listener, r_keyboard, modifiers); +static void handle_keyboard_key(struct wl_listener *listener, void *data) { + struct roots_keyboard *keyboard = wl_container_of(listener, keyboard, key); + struct wlr_event_keyboard_key *event = data; + roots_keyboard_handle_key(keyboard, event); +} + +void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard) { struct wlr_seat *seat = r_keyboard->input->wl_seat; struct wlr_keyboard *keyboard = r_keyboard->device->keyboard; wlr_seat_set_keyboard(seat, r_keyboard->device); @@ -160,7 +162,12 @@ static void keyboard_modifiers_notify(struct wl_listener *listener, void *data) keyboard->modifiers.latched, keyboard->modifiers.locked, keyboard->modifiers.group); +} +static void handle_keyboard_modifiers(struct wl_listener *listener, void *data) { + struct roots_keyboard *r_keyboard = + wl_container_of(listener, r_keyboard, modifiers); + roots_keyboard_handle_modifiers(r_keyboard); } static void keyboard_config_merge(struct keyboard_config *config, @@ -185,19 +192,19 @@ static void keyboard_config_merge(struct keyboard_config *config, } } -void keyboard_add(struct wlr_input_device *device, struct roots_input *input) { +struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, struct roots_input *input) { struct roots_keyboard *keyboard = calloc(sizeof(struct roots_keyboard), 1); if (keyboard == NULL) { - return; + return NULL; } device->data = keyboard; keyboard->device = device; keyboard->input = input; - keyboard->key.notify = keyboard_key_notify; + keyboard->key.notify = handle_keyboard_key; wl_signal_add(&device->keyboard->events.key, &keyboard->key); - keyboard->modifiers.notify = keyboard_modifiers_notify; + keyboard->modifiers.notify = handle_keyboard_modifiers; wl_signal_add(&device->keyboard->events.modifiers, &keyboard->modifiers); wl_list_insert(&input->keyboards, &keyboard->link); @@ -226,14 +233,16 @@ void keyboard_add(struct wlr_input_device *device, struct roots_input *input) { struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); if (context == NULL) { wlr_log(L_ERROR, "Cannot create XKB context"); - return; + return NULL; } wlr_keyboard_set_keymap(device->keyboard, xkb_map_new_from_names(context, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS)); xkb_context_unref(context); + + return keyboard; } -void keyboard_remove(struct wlr_input_device *device, struct roots_input *input) { +void roots_keyboard_destroy(struct wlr_input_device *device, struct roots_input *input) { struct roots_keyboard *keyboard = device->data; wl_list_remove(&keyboard->key.link); wl_list_remove(&keyboard->modifiers.link); -- cgit v1.2.3 From 6d8e1abfc0a266e8ff1a8c9ba1a004faeaac79d5 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sat, 4 Nov 2017 01:35:12 -0400 Subject: Improve input sensitivity We now use doubles until the last minute, which makes it so we can move the pointer more precisely. This also includes a fix for tablet tools, which move absolutely and sometimes do not update the X or Y axis. --- backend/libinput/tablet_tool.c | 2 ++ include/wlr/types/wlr_output.h | 5 +++-- rootston/cursor.c | 9 +++++++++ types/wlr_cursor.c | 4 ++-- types/wlr_output.c | 6 ++++-- 5 files changed, 20 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/backend/libinput/tablet_tool.c b/backend/libinput/tablet_tool.c index 3caaf3f7..3d5fafc3 100644 --- a/backend/libinput/tablet_tool.c +++ b/backend/libinput/tablet_tool.c @@ -70,6 +70,8 @@ void handle_tablet_tool_axis(struct libinput_event *event, wlr_event.updated_axes |= WLR_TABLET_TOOL_AXIS_WHEEL; wlr_event.wheel_delta = libinput_event_tablet_tool_get_wheel_delta(tevent); } + wlr_log(L_DEBUG, "Tablet tool axis event %d @ %f,%f", + wlr_event.updated_axes, wlr_event.x_mm, wlr_event.y_mm); wl_signal_emit(&wlr_dev->tablet_tool->events.axis, &wlr_event); } diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h index e6323f9c..df123639 100644 --- a/include/wlr/types/wlr_output.h +++ b/include/wlr/types/wlr_output.h @@ -14,7 +14,7 @@ struct wlr_output_mode { struct wlr_output_cursor { struct wlr_output *output; - int32_t x, y; + double x, y; bool enabled; uint32_t width, height; int32_t hotspot_x, hotspot_y; @@ -95,7 +95,8 @@ bool wlr_output_cursor_set_image(struct wlr_output_cursor *cursor, int32_t hotspot_x, int32_t hotspot_y); void wlr_output_cursor_set_surface(struct wlr_output_cursor *cursor, struct wlr_surface *surface, int32_t hotspot_x, int32_t hotspot_y); -bool wlr_output_cursor_move(struct wlr_output_cursor *cursor, int x, int y); +bool wlr_output_cursor_move(struct wlr_output_cursor *cursor, + double x, double y); void wlr_output_cursor_destroy(struct wlr_output_cursor *cursor); #endif diff --git a/rootston/cursor.c b/rootston/cursor.c index 31001a9f..aa8e5122 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -378,11 +378,20 @@ static void handle_touch_motion(struct wl_listener *listener, void *data) { static void handle_tool_axis(struct wl_listener *listener, void *data) { struct roots_input *input = wl_container_of(listener, input, cursor_tool_axis); struct wlr_event_tablet_tool_axis *event = data; + if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_X) && (event->updated_axes & WLR_TABLET_TOOL_AXIS_Y)) { wlr_cursor_warp_absolute(input->cursor, event->device, event->x_mm / event->width_mm, event->y_mm / event->height_mm); cursor_update_position(input, event->time_msec); + } else if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_X)) { + wlr_cursor_warp_absolute(input->cursor, event->device, + event->x_mm / event->width_mm, -1); + cursor_update_position(input, event->time_msec); + } else if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_Y)) { + wlr_cursor_warp_absolute(input->cursor, event->device, + -1, event->y_mm / event->height_mm); + cursor_update_position(input, event->time_msec); } } diff --git a/types/wlr_cursor.c b/types/wlr_cursor.c index 83d36d14..dfaccb53 100644 --- a/types/wlr_cursor.c +++ b/types/wlr_cursor.c @@ -261,8 +261,8 @@ void wlr_cursor_warp_absolute(struct wlr_cursor *cur, mapping = wlr_output_layout_get_box(cur->state->layout, NULL); } - double x = mapping->width * x_mm + mapping->x; - double y = mapping->height * y_mm + mapping->y; + double x = x_mm > 0 ? mapping->width * x_mm + mapping->x : cur->x; + double y = y_mm > 0 ? mapping->height * y_mm + mapping->y : cur->y; wlr_cursor_warp_unchecked(cur, x, y); } diff --git a/types/wlr_output.c b/types/wlr_output.c index ff8b07be..3ad69ce3 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -472,9 +472,11 @@ void wlr_output_cursor_set_surface(struct wlr_output_cursor *cursor, } } -bool wlr_output_cursor_move(struct wlr_output_cursor *cursor, int x, int y) { +bool wlr_output_cursor_move(struct wlr_output_cursor *cursor, + double x, double y) { x *= cursor->output->scale; y *= cursor->output->scale; + wlr_log(L_DEBUG, "Moving cursor to %f,%f", x, y); cursor->x = x; cursor->y = y; @@ -486,7 +488,7 @@ bool wlr_output_cursor_move(struct wlr_output_cursor *cursor, int x, int y) { if (!cursor->output->impl->move_cursor) { return false; } - return cursor->output->impl->move_cursor(cursor->output, x, y); + return cursor->output->impl->move_cursor(cursor->output, (int)x, (int)y); } struct wlr_output_cursor *wlr_output_cursor_create(struct wlr_output *output) { -- cgit v1.2.3 From 5354fe8729b8c52f8f3ff63f23f932c49bf8c880 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Fri, 3 Nov 2017 09:01:34 -0400 Subject: move keyboard to seat --- backend/libinput/keyboard.c | 1 + backend/wayland/wl_seat.c | 12 +++++-- backend/x11/backend.c | 1 + include/rootston/input.h | 1 + include/rootston/keyboard.h | 15 +++++--- include/rootston/seat.h | 26 ++++++++++++++ include/wlr/interfaces/wlr_keyboard.h | 3 +- include/wlr/types/wlr_keyboard.h | 11 ++++++ rootston/input.c | 33 ++++++++++++++++-- rootston/keyboard.c | 38 ++++++-------------- rootston/meson.build | 1 + rootston/seat.c | 66 +++++++++++++++++++++++++++++++++++ types/wlr_keyboard.c | 11 +++--- 13 files changed, 176 insertions(+), 43 deletions(-) create mode 100644 include/rootston/seat.h create mode 100644 rootston/seat.c (limited to 'include') diff --git a/backend/libinput/keyboard.c b/backend/libinput/keyboard.c index 065d8ead..9a24c791 100644 --- a/backend/libinput/keyboard.c +++ b/backend/libinput/keyboard.c @@ -54,6 +54,7 @@ void handle_keyboard_key(struct libinput_event *event, struct libinput_event_keyboard *kbevent = libinput_event_get_keyboard_event(event); struct wlr_event_keyboard_key wlr_event = { 0 }; + wlr_event.device = wlr_dev; wlr_event.time_msec = usec_to_msec(libinput_event_keyboard_get_time_usec(kbevent)); wlr_event.keycode = libinput_event_keyboard_get_key(kbevent); diff --git a/backend/wayland/wl_seat.c b/backend/wayland/wl_seat.c index deed215e..146296ae 100644 --- a/backend/wayland/wl_seat.c +++ b/backend/wayland/wl_seat.c @@ -151,6 +151,7 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard, assert(dev && dev->keyboard); struct wlr_event_keyboard_key wlr_event; + wlr_event.device = dev; wlr_event.keycode = key; wlr_event.state = state; wlr_event.time_msec = time; @@ -162,8 +163,15 @@ static void keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboar uint32_t mods_locked, uint32_t group) { struct wlr_input_device *dev = data; assert(dev && dev->keyboard); - wlr_keyboard_notify_modifiers(dev->keyboard, mods_depressed, mods_latched, - mods_locked, group); + struct wlr_event_keyboard_modifiers wlr_event; + wlr_event.device = dev; + wlr_event.keyboard = dev->keyboard; + wlr_event.mods_depressed = mods_depressed; + wlr_event.mods_latched = mods_latched; + wlr_event.mods_locked = mods_locked; + wlr_event.group = group; + + wlr_keyboard_notify_modifiers(dev->keyboard, &wlr_event); } static void keyboard_handle_repeat_info(void *data, struct wl_keyboard *wl_keyboard, diff --git a/backend/x11/backend.c b/backend/x11/backend.c index 97b0dd8c..f76b314e 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -50,6 +50,7 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e case XCB_KEY_RELEASE: { xcb_key_press_event_t *ev = (xcb_key_press_event_t *)event; struct wlr_event_keyboard_key key = { + .device = &x11->keyboard_dev, .time_msec = ev->time, .keycode = ev->detail - 8, .state = event->response_type == XCB_KEY_PRESS ? diff --git a/include/rootston/input.h b/include/rootston/input.h index 6d07de43..7b1358f8 100644 --- a/include/rootston/input.h +++ b/include/rootston/input.h @@ -67,6 +67,7 @@ struct roots_input { struct wl_list pointers; struct wl_list touch; struct wl_list tablet_tools; + struct wl_list seats; struct wl_listener input_add; struct wl_listener input_remove; diff --git a/include/rootston/keyboard.h b/include/rootston/keyboard.h index f4acc0aa..cb639ba1 100644 --- a/include/rootston/keyboard.h +++ b/include/rootston/keyboard.h @@ -8,21 +8,28 @@ struct roots_keyboard { struct roots_input *input; + struct roots_seat *seat; struct wlr_input_device *device; - struct wl_listener key; - struct wl_listener modifiers; + struct wl_list seat_link; + // XXX temporary struct wl_list link; + struct wl_listener keyboard_key; + struct wl_listener keyboard_modifiers; + xkb_keysym_t pressed_keysyms[ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP]; }; struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, struct roots_input *input); -void roots_keyboard_destroy(struct wlr_input_device *device, struct roots_input *input); + +void roots_keyboard_destroy(struct wlr_input_device *device, + struct roots_input *input); void roots_keyboard_handle_key(struct roots_keyboard *keyboard, struct wlr_event_keyboard_key *event); -void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard); +void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard, + struct wlr_event_keyboard_modifiers *event); #endif diff --git a/include/rootston/seat.h b/include/rootston/seat.h new file mode 100644 index 00000000..f6db63cc --- /dev/null +++ b/include/rootston/seat.h @@ -0,0 +1,26 @@ +#ifndef _ROOTSTON_SEAT_H +#define _ROOTSTON_SEAT_H + +#include + +#include "rootston/input.h" +#include "rootston/keyboard.h" + +struct roots_seat { + struct roots_input *input; + struct wlr_seat *seat; + struct wl_list keyboards; + struct wl_list link; +}; + +struct roots_seat *roots_seat_create(struct roots_input *input, char *name); + +void roots_seat_destroy(struct roots_seat *seat); + +void roots_seat_add_keyboard(struct roots_seat *seat, + struct roots_keyboard *keyboard); + +void roots_seat_remove_keyboard(struct roots_seat *seat, + struct roots_keyboard *keyboard); + +#endif diff --git a/include/wlr/interfaces/wlr_keyboard.h b/include/wlr/interfaces/wlr_keyboard.h index 570f5721..5848416d 100644 --- a/include/wlr/interfaces/wlr_keyboard.h +++ b/include/wlr/interfaces/wlr_keyboard.h @@ -14,7 +14,6 @@ void wlr_keyboard_destroy(struct wlr_keyboard *keyboard); void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard, struct wlr_event_keyboard_key *event); void wlr_keyboard_notify_modifiers(struct wlr_keyboard *keyboard, - uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, - uint32_t group); + struct wlr_event_keyboard_modifiers *event); #endif diff --git a/include/wlr/types/wlr_keyboard.h b/include/wlr/types/wlr_keyboard.h index af837ff5..c42cea9c 100644 --- a/include/wlr/types/wlr_keyboard.h +++ b/include/wlr/types/wlr_keyboard.h @@ -63,12 +63,23 @@ enum wlr_key_state { }; struct wlr_event_keyboard_key { + struct wlr_input_device *device; + struct wlr_keyboard *keyboard; uint32_t time_msec; uint32_t keycode; bool update_state; enum wlr_key_state state; }; +struct wlr_event_keyboard_modifiers { + struct wlr_input_device *device; + struct wlr_keyboard *keyboard; + uint32_t mods_depressed; + uint32_t mods_latched; + uint32_t mods_locked; + uint32_t group; +}; + void wlr_keyboard_set_keymap(struct wlr_keyboard *kb, struct xkb_keymap *keymap); void wlr_keyboard_led_update(struct wlr_keyboard *keyboard, uint32_t leds); diff --git a/rootston/input.c b/rootston/input.c index 2f50c708..51a64720 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -12,6 +12,7 @@ #include "rootston/keyboard.h" #include "rootston/pointer.h" #include "rootston/touch.h" +#include "rootston/seat.h" static const char *device_type(enum wlr_input_device_type type) { switch (type) { @@ -29,15 +30,42 @@ static const char *device_type(enum wlr_input_device_type type) { return NULL; } +static struct roots_seat *input_get_seat(struct roots_input *input, char *name) { + struct roots_seat *seat = NULL; + wl_list_for_each(seat, &input->seats, link) { + if (strcmp(seat->seat->name, name) == 0) { + return seat; + } + } + + seat = roots_seat_create(input, name); + return seat; +} + static void input_add_notify(struct wl_listener *listener, void *data) { struct wlr_input_device *device = data; struct roots_input *input = wl_container_of(listener, input, input_add); + + char *seat_name = "seat0"; + struct device_config *dc = config_get_device(input->config, device); + if (dc) { + seat_name = dc->seat; + } + + struct roots_seat *seat = input_get_seat(input, seat_name); + if (!seat) { + wlr_log(L_ERROR, "could not create roots seat"); + return; + } + wlr_log(L_DEBUG, "New input device: %s (%d:%d) %s", device->name, device->vendor, device->product, device_type(device->type)); switch (device->type) { - case WLR_INPUT_DEVICE_KEYBOARD: - roots_keyboard_create(device, input); + case WLR_INPUT_DEVICE_KEYBOARD: { + struct roots_keyboard *keyboard = roots_keyboard_create(device, input); + roots_seat_add_keyboard(seat, keyboard); break; + } case WLR_INPUT_DEVICE_POINTER: pointer_add(device, input); break; @@ -123,6 +151,7 @@ struct roots_input *input_create(struct roots_server *server, wl_list_init(&input->pointers); wl_list_init(&input->touch); wl_list_init(&input->tablet_tools); + wl_list_init(&input->seats); input->input_add.notify = input_add_notify; wl_signal_add(&server->backend->events.input_add, &input->input_add); diff --git a/rootston/keyboard.c b/rootston/keyboard.c index ece95245..0865f551 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -10,6 +10,7 @@ #include #include #include "rootston/input.h" +#include "rootston/seat.h" #include "rootston/keyboard.h" static ssize_t keyboard_pressed_keysym_index(struct roots_keyboard *keyboard, @@ -85,8 +86,8 @@ static bool keyboard_keysym_press(struct roots_keyboard *keyboard, } if (keysym == XKB_KEY_Escape) { - wlr_seat_pointer_end_grab(keyboard->input->wl_seat); - wlr_seat_keyboard_end_grab(keyboard->input->wl_seat); + wlr_seat_pointer_end_grab(keyboard->seat->seat); + wlr_seat_keyboard_end_grab(keyboard->seat->seat); } uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); @@ -141,20 +142,15 @@ void roots_keyboard_handle_key(struct roots_keyboard *keyboard, } if (!handled) { - wlr_seat_set_keyboard(keyboard->input->wl_seat, keyboard->device); - wlr_seat_keyboard_notify_key(keyboard->input->wl_seat, event->time_msec, + wlr_seat_set_keyboard(keyboard->seat->seat, keyboard->device); + wlr_seat_keyboard_notify_key(keyboard->seat->seat, event->time_msec, event->keycode, event->state); } } -static void handle_keyboard_key(struct wl_listener *listener, void *data) { - struct roots_keyboard *keyboard = wl_container_of(listener, keyboard, key); - struct wlr_event_keyboard_key *event = data; - roots_keyboard_handle_key(keyboard, event); -} - -void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard) { - struct wlr_seat *seat = r_keyboard->input->wl_seat; +void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard, + struct wlr_event_keyboard_modifiers *event) { + struct wlr_seat *seat = r_keyboard->seat->seat; struct wlr_keyboard *keyboard = r_keyboard->device->keyboard; wlr_seat_set_keyboard(seat, r_keyboard->device); wlr_seat_keyboard_notify_modifiers(seat, @@ -164,12 +160,6 @@ void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard) { keyboard->modifiers.group); } -static void handle_keyboard_modifiers(struct wl_listener *listener, void *data) { - struct roots_keyboard *r_keyboard = - wl_container_of(listener, r_keyboard, modifiers); - roots_keyboard_handle_modifiers(r_keyboard); -} - static void keyboard_config_merge(struct keyboard_config *config, struct keyboard_config *fallback) { if (fallback == NULL) { @@ -192,7 +182,8 @@ static void keyboard_config_merge(struct keyboard_config *config, } } -struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, struct roots_input *input) { +struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, + struct roots_input *input) { struct roots_keyboard *keyboard = calloc(sizeof(struct roots_keyboard), 1); if (keyboard == NULL) { return NULL; @@ -201,12 +192,7 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, st keyboard->device = device; keyboard->input = input; - keyboard->key.notify = handle_keyboard_key; - wl_signal_add(&device->keyboard->events.key, &keyboard->key); - - keyboard->modifiers.notify = handle_keyboard_modifiers; - wl_signal_add(&device->keyboard->events.modifiers, &keyboard->modifiers); - + // XXX temporary wl_list_insert(&input->keyboards, &keyboard->link); struct keyboard_config config; @@ -244,8 +230,6 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, st void roots_keyboard_destroy(struct wlr_input_device *device, struct roots_input *input) { struct roots_keyboard *keyboard = device->data; - wl_list_remove(&keyboard->key.link); - wl_list_remove(&keyboard->modifiers.link); wl_list_remove(&keyboard->link); free(keyboard); } diff --git a/rootston/meson.build b/rootston/meson.build index d84422d8..0367e43f 100644 --- a/rootston/meson.build +++ b/rootston/meson.build @@ -8,6 +8,7 @@ sources = [ 'main.c', 'output.c', 'pointer.c', + 'seat.c', 'tablet_tool.c', 'touch.c', 'xcursor.c', diff --git a/rootston/seat.c b/rootston/seat.c new file mode 100644 index 00000000..2103e0d2 --- /dev/null +++ b/rootston/seat.c @@ -0,0 +1,66 @@ +#include +#include + +#include "rootston/input.h" +#include "rootston/seat.h" +#include "rootston/keyboard.h" + +static void handle_keyboard_key(struct wl_listener *listener, void *data) { + struct roots_keyboard *keyboard = + wl_container_of(listener, keyboard, keyboard_key); + struct wlr_event_keyboard_key *event = data; + roots_keyboard_handle_key(keyboard, event); +} + +static void handle_keyboard_modifiers(struct wl_listener *listener, + void *data) { + struct roots_keyboard *keyboard = + wl_container_of(listener, keyboard, keyboard_modifiers); + struct wlr_event_keyboard_modifiers *event = data; + roots_keyboard_handle_modifiers(keyboard, event); +} + +struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { + struct roots_seat *seat = calloc(1, sizeof(struct roots_seat)); + if (!seat) { + return NULL; + } + + seat->seat = wlr_seat_create(input->server->wl_display, name); + wlr_seat_set_capabilities(seat->seat, + WL_SEAT_CAPABILITY_KEYBOARD | + WL_SEAT_CAPABILITY_POINTER | + WL_SEAT_CAPABILITY_TOUCH); + seat->input = input; + wl_list_insert(&input->seats, &seat->link); + wl_list_init(&seat->keyboards); + + return seat; +} + +void roots_seat_destroy(struct roots_seat *seat) { + // TODO +} + +void roots_seat_add_keyboard(struct roots_seat *seat, + struct roots_keyboard *keyboard) { + if (keyboard->seat) { + roots_seat_remove_keyboard(keyboard->seat, keyboard); + } + keyboard->seat = seat; + wl_list_insert(&seat->keyboards, &keyboard->seat_link); + + keyboard->keyboard_key.notify = handle_keyboard_key; + wl_signal_add(&keyboard->device->keyboard->events.key, + &keyboard->keyboard_key); + + keyboard->keyboard_modifiers.notify = handle_keyboard_modifiers; + wl_signal_add(&keyboard->device->keyboard->events.modifiers, + &keyboard->keyboard_modifiers); +} + +void roots_seat_remove_keyboard(struct roots_seat *seat, + struct roots_keyboard *keyboard) { + // TODO +} + diff --git a/types/wlr_keyboard.c b/types/wlr_keyboard.c index c27264ef..c2fd9e0c 100644 --- a/types/wlr_keyboard.c +++ b/types/wlr_keyboard.c @@ -41,19 +41,18 @@ static void keyboard_modifier_update(struct wlr_keyboard *keyboard) { keyboard->modifiers.latched = latched; keyboard->modifiers.locked = locked; keyboard->modifiers.group = group; - - wl_signal_emit(&keyboard->events.modifiers, keyboard); } void wlr_keyboard_notify_modifiers(struct wlr_keyboard *keyboard, - uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, - uint32_t group) { + struct wlr_event_keyboard_modifiers *event) { if (!keyboard->xkb_state) { return; } - xkb_state_update_mask(keyboard->xkb_state, mods_depressed, mods_latched, - mods_locked, 0, 0, group); + xkb_state_update_mask(keyboard->xkb_state, event->mods_depressed, + event->mods_latched, event->mods_locked, 0, 0, event->group); keyboard_modifier_update(keyboard); + + wl_signal_emit(&keyboard->events.modifiers, event); } void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard, -- cgit v1.2.3 From 704f0f158a669689b78311cde35a736057f983b4 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sat, 4 Nov 2017 13:12:35 -0400 Subject: rootston: move device init to seat --- include/rootston/pointer.h | 16 --- include/rootston/seat.h | 54 ++++++++- include/rootston/tablet_tool.h | 20 ---- include/rootston/touch.h | 22 ---- rootston/cursor.c | 4 +- rootston/input.c | 44 ++------ rootston/meson.build | 3 - rootston/pointer.c | 24 ---- rootston/seat.c | 241 +++++++++++++++++++++++++++++++++++++++-- rootston/tablet_tool.c | 25 ----- rootston/touch.c | 27 ----- 11 files changed, 292 insertions(+), 188 deletions(-) delete mode 100644 include/rootston/pointer.h delete mode 100644 include/rootston/tablet_tool.h delete mode 100644 include/rootston/touch.h delete mode 100644 rootston/pointer.c delete mode 100644 rootston/tablet_tool.c delete mode 100644 rootston/touch.c (limited to 'include') diff --git a/include/rootston/pointer.h b/include/rootston/pointer.h deleted file mode 100644 index b3fc8c3a..00000000 --- a/include/rootston/pointer.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _ROOTSTON_POINTER_H -#define _ROOTSTON_POINTER_H - -#include -#include - -struct roots_pointer { - struct roots_input *input; - struct wlr_input_device *device; - struct wl_list link; -}; - -void pointer_add(struct wlr_input_device *device, struct roots_input *input); -void pointer_remove(struct wlr_input_device *device, struct roots_input *input); - -#endif diff --git a/include/rootston/seat.h b/include/rootston/seat.h index f6db63cc..e4130e5a 100644 --- a/include/rootston/seat.h +++ b/include/rootston/seat.h @@ -9,7 +9,53 @@ struct roots_seat { struct roots_input *input; struct wlr_seat *seat; + struct wlr_cursor *cursor; + struct wl_list link; + struct wl_list keyboards; + struct wl_list pointers; + struct wl_list touch; + struct wl_list tablet_tools; + + struct wl_listener cursor_motion; + struct wl_listener cursor_motion_absolute; + struct wl_listener cursor_button; + struct wl_listener cursor_axis; + + struct wl_listener cursor_touch_down; + struct wl_listener cursor_touch_up; + struct wl_listener cursor_touch_motion; + + struct wl_listener cursor_tool_axis; + struct wl_listener cursor_tool_tip; +}; + +struct roots_pointer { + struct roots_seat *seat; + struct wlr_input_device *device; + struct wl_list link; +}; + +struct roots_touch { + struct roots_seat *seat; + struct wlr_input_device *device; + struct wl_list link; +}; + +struct roots_touch_point { + struct roots_touch *device; + int32_t slot; + double x, y; + struct wl_list link; +}; + +struct roots_tablet_tool { + struct roots_seat *seat; + struct wlr_input_device *device; + struct wl_listener axis; + struct wl_listener proximity; + struct wl_listener tip; + struct wl_listener button; struct wl_list link; }; @@ -17,10 +63,10 @@ struct roots_seat *roots_seat_create(struct roots_input *input, char *name); void roots_seat_destroy(struct roots_seat *seat); -void roots_seat_add_keyboard(struct roots_seat *seat, - struct roots_keyboard *keyboard); +void roots_seat_add_device(struct roots_seat *seat, + struct wlr_input_device *device); -void roots_seat_remove_keyboard(struct roots_seat *seat, - struct roots_keyboard *keyboard); +void roots_seat_remove_device(struct roots_seat *seat, + struct wlr_input_device *device); #endif diff --git a/include/rootston/tablet_tool.h b/include/rootston/tablet_tool.h deleted file mode 100644 index 72ebf6d8..00000000 --- a/include/rootston/tablet_tool.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef _ROOTSTON_TABLET_TOOL_H -#define _ROOTSTON_TABLET_TOOL_H - -#include -#include "rootston/input.h" - -struct roots_tablet_tool { - struct roots_input *input; - struct wlr_input_device *device; - struct wl_listener axis; - struct wl_listener proximity; - struct wl_listener tip; - struct wl_listener button; - struct wl_list link; -}; - -void tablet_tool_add(struct wlr_input_device *device, struct roots_input *input); -void tablet_tool_remove(struct wlr_input_device *device, struct roots_input *input); - -#endif diff --git a/include/rootston/touch.h b/include/rootston/touch.h deleted file mode 100644 index 1624c3ad..00000000 --- a/include/rootston/touch.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef _ROOTSTON_TOUCH_H -#define _ROOTSTON_TOUCH_H - -#include - -struct roots_touch { - struct roots_input *input; - struct wlr_input_device *device; - struct wl_list link; -}; - -struct roots_touch_point { - struct roots_touch *device; - int32_t slot; - double x, y; - struct wl_list link; -}; - -void touch_add(struct wlr_input_device *device, struct roots_input *input); -void touch_remove(struct wlr_input_device *device, struct roots_input *input); - -#endif diff --git a/rootston/cursor.c b/rootston/cursor.c index 61dcae7a..9028c5bb 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -19,9 +19,7 @@ #include "rootston/desktop.h" #include "rootston/view.h" #include "rootston/keyboard.h" -#include "rootston/pointer.h" -#include "rootston/tablet_tool.h" -#include "rootston/touch.h" +#include "rootston/seat.h" const struct roots_input_event *get_input_event(struct roots_input *input, uint32_t serial) { diff --git a/rootston/input.c b/rootston/input.c index 51a64720..4a567763 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -8,10 +8,7 @@ #include "rootston/server.h" #include "rootston/config.h" #include "rootston/input.h" -#include "rootston/tablet_tool.h" #include "rootston/keyboard.h" -#include "rootston/pointer.h" -#include "rootston/touch.h" #include "rootston/seat.h" static const char *device_type(enum wlr_input_device_type type) { @@ -60,44 +57,17 @@ static void input_add_notify(struct wl_listener *listener, void *data) { wlr_log(L_DEBUG, "New input device: %s (%d:%d) %s", device->name, device->vendor, device->product, device_type(device->type)); - switch (device->type) { - case WLR_INPUT_DEVICE_KEYBOARD: { - struct roots_keyboard *keyboard = roots_keyboard_create(device, input); - roots_seat_add_keyboard(seat, keyboard); - break; - } - case WLR_INPUT_DEVICE_POINTER: - pointer_add(device, input); - break; - case WLR_INPUT_DEVICE_TOUCH: - touch_add(device, input); - break; - case WLR_INPUT_DEVICE_TABLET_TOOL: - tablet_tool_add(device, input); - break; - default: - break; - } + + roots_seat_add_device(seat, device); } static void input_remove_notify(struct wl_listener *listener, void *data) { struct wlr_input_device *device = data; - struct roots_input *input = wl_container_of(listener, input, input_remove); - switch (device->type) { - case WLR_INPUT_DEVICE_KEYBOARD: - roots_keyboard_destroy(device, input); - break; - case WLR_INPUT_DEVICE_POINTER: - pointer_remove(device, input); - break; - case WLR_INPUT_DEVICE_TOUCH: - touch_remove(device, input); - break; - case WLR_INPUT_DEVICE_TABLET_TOOL: - tablet_tool_remove(device, input); - break; - default: - break; + struct roots_input *input = wl_container_of(listener, input, input_add); + + struct roots_seat *seat; + wl_list_for_each(seat, &input->seats, link) { + roots_seat_remove_device(seat, device); } } diff --git a/rootston/meson.build b/rootston/meson.build index 0367e43f..9c543c4f 100644 --- a/rootston/meson.build +++ b/rootston/meson.build @@ -7,10 +7,7 @@ sources = [ 'keyboard.c', 'main.c', 'output.c', - 'pointer.c', 'seat.c', - 'tablet_tool.c', - 'touch.c', 'xcursor.c', 'xdg_shell_v6.c', 'wl_shell.c', diff --git a/rootston/pointer.c b/rootston/pointer.c deleted file mode 100644 index cb099264..00000000 --- a/rootston/pointer.c +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include -#include -#include -#include "rootston/input.h" -#include "rootston/pointer.h" - -void pointer_add(struct wlr_input_device *device, struct roots_input *input) { - struct roots_pointer *pointer = calloc(sizeof(struct roots_pointer), 1); - device->data = pointer; - pointer->device = device; - pointer->input = input; - wl_list_insert(&input->pointers, &pointer->link); - wlr_cursor_attach_input_device(input->cursor, device); - cursor_load_config(input->server->config, input->cursor, - input, input->server->desktop); -} - -void pointer_remove(struct wlr_input_device *device, struct roots_input *input) { - struct roots_pointer *pointer = device->data; - wlr_cursor_detach_input_device(input->cursor, device); - wl_list_remove(&pointer->link); - free(pointer); -} diff --git a/rootston/seat.c b/rootston/seat.c index 2103e0d2..c8f689bc 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -1,5 +1,8 @@ #include #include +#include + +#include #include "rootston/input.h" #include "rootston/seat.h" @@ -20,18 +23,175 @@ static void handle_keyboard_modifiers(struct wl_listener *listener, roots_keyboard_handle_modifiers(keyboard, event); } +static void handle_cursor_motion(struct wl_listener *listener, void *data) { + // TODO +} + +static void handle_cursor_motion_absolute(struct wl_listener *listener, void *data) { + // TODO +} + +static void handle_cursor_button(struct wl_listener *listener, void *data) { + // TODO +} + +static void handle_cursor_axis(struct wl_listener *listener, void *data) { + // TODO +} + +static void handle_touch_down(struct wl_listener *listener, void *data) { + // TODO +} + +static void handle_touch_up(struct wl_listener *listener, void *data) { + // TODO +} + +static void handle_touch_motion(struct wl_listener *listener, void *data) { + // TODO +} + +static void handle_tool_axis(struct wl_listener *listener, void *data) { + // TODO +} + +static void handle_tool_tip(struct wl_listener *listener, void *data) { + // TODO +} + +static void seat_reset_device_mappings(struct roots_seat *seat, struct wlr_input_device *device) { + struct wlr_cursor *cursor = seat->cursor; + struct roots_config *config = seat->input->config; + + wlr_cursor_map_input_to_output(cursor, device, NULL); + struct device_config *dconfig; + if ((dconfig = config_get_device(config, device))) { + wlr_cursor_map_input_to_region(cursor, device, dconfig->mapped_box); + } +} + +static void seat_set_device_output_mappings(struct roots_seat *seat, + struct wlr_input_device *device, struct wlr_output *output) { + struct wlr_cursor *cursor = seat->cursor; + struct roots_config *config = seat->input->config; + struct device_config *dconfig; + dconfig = config_get_device(config, device); + if (dconfig && dconfig->mapped_output && + strcmp(dconfig->mapped_output, output->name) == 0) { + wlr_cursor_map_input_to_output(cursor, device, output); + } +} + +static void roots_seat_configure_cursor(struct roots_seat *seat) { + struct roots_config *config = seat->input->config; + struct roots_desktop *desktop = seat->input->server->desktop; + struct wlr_cursor *cursor = seat->cursor; + + struct roots_pointer *pointer; + struct roots_touch *touch; + struct roots_tablet_tool *tablet_tool; + struct roots_output *output; + + // reset mappings + wlr_cursor_map_to_output(cursor, NULL); + wl_list_for_each(pointer, &seat->pointers, link) { + seat_reset_device_mappings(seat, pointer->device); + } + wl_list_for_each(touch, &seat->touch, link) { + seat_reset_device_mappings(seat, touch->device); + } + wl_list_for_each(tablet_tool, &seat->tablet_tools, link) { + seat_reset_device_mappings(seat, tablet_tool->device); + } + + // configure device to output mappings + const char *mapped_output = config->cursor.mapped_output; + wl_list_for_each(output, &desktop->outputs, link) { + if (mapped_output && strcmp(mapped_output, output->wlr_output->name) == 0) { + wlr_cursor_map_to_output(cursor, output->wlr_output); + } + + wl_list_for_each(pointer, &seat->pointers, link) { + seat_set_device_output_mappings(seat, pointer->device, output->wlr_output); + } + wl_list_for_each(tablet_tool, &seat->tablet_tools, link) { + seat_set_device_output_mappings(seat, tablet_tool->device, output->wlr_output); + } + wl_list_for_each(touch, &seat->touch, link) { + seat_set_device_output_mappings(seat, touch->device, output->wlr_output); + } + } +} + +static void roots_seat_init_cursor(struct roots_seat *seat) { + struct wlr_cursor *cursor = wlr_cursor_create(); + if (!cursor) { + return; + } + seat->cursor = cursor; + + // add output layout and configure + struct roots_desktop *desktop = seat->input->server->desktop; + wlr_cursor_attach_output_layout(cursor, desktop->layout); + roots_seat_configure_cursor(seat); + // TODO configure cursor by seat + + // add input signals + wl_signal_add(&cursor->events.motion, &seat->cursor_motion); + seat->cursor_motion.notify = handle_cursor_motion; + + wl_signal_add(&cursor->events.motion_absolute, + &seat->cursor_motion_absolute); + seat->cursor_motion_absolute.notify = handle_cursor_motion_absolute; + + wl_signal_add(&cursor->events.button, &seat->cursor_button); + seat->cursor_button.notify = handle_cursor_button; + + wl_signal_add(&cursor->events.axis, &seat->cursor_axis); + seat->cursor_axis.notify = handle_cursor_axis; + + wl_signal_add(&cursor->events.touch_down, &seat->cursor_touch_down); + seat->cursor_touch_down.notify = handle_touch_down; + + wl_signal_add(&cursor->events.touch_up, &seat->cursor_touch_up); + seat->cursor_touch_up.notify = handle_touch_up; + + wl_signal_add(&cursor->events.touch_motion, &seat->cursor_touch_motion); + seat->cursor_touch_motion.notify = handle_touch_motion; + + wl_signal_add(&cursor->events.tablet_tool_axis, &seat->cursor_tool_axis); + seat->cursor_tool_axis.notify = handle_tool_axis; + + wl_signal_add(&cursor->events.tablet_tool_tip, &seat->cursor_tool_tip); + seat->cursor_tool_tip.notify = handle_tool_tip; +} + struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { struct roots_seat *seat = calloc(1, sizeof(struct roots_seat)); if (!seat) { return NULL; } + roots_seat_init_cursor(seat); + if (!seat->cursor) { + free(seat); + return NULL; + } + seat->seat = wlr_seat_create(input->server->wl_display, name); + if (!seat->seat) { + free(seat); + wlr_cursor_destroy(seat->cursor); + return NULL; + } + wlr_seat_set_capabilities(seat->seat, WL_SEAT_CAPABILITY_KEYBOARD | WL_SEAT_CAPABILITY_POINTER | WL_SEAT_CAPABILITY_TOUCH); + seat->input = input; + wl_list_insert(&input->seats, &seat->link); wl_list_init(&seat->keyboards); @@ -42,12 +202,10 @@ void roots_seat_destroy(struct roots_seat *seat) { // TODO } -void roots_seat_add_keyboard(struct roots_seat *seat, - struct roots_keyboard *keyboard) { - if (keyboard->seat) { - roots_seat_remove_keyboard(keyboard->seat, keyboard); - } +static void seat_add_keyboard(struct roots_seat *seat, struct wlr_input_device *device) { + struct roots_keyboard *keyboard = roots_keyboard_create(device, seat->input); keyboard->seat = seat; + wl_list_insert(&seat->keyboards, &keyboard->seat_link); keyboard->keyboard_key.notify = handle_keyboard_key; @@ -59,8 +217,77 @@ void roots_seat_add_keyboard(struct roots_seat *seat, &keyboard->keyboard_modifiers); } -void roots_seat_remove_keyboard(struct roots_seat *seat, - struct roots_keyboard *keyboard) { +static void seat_add_pointer(struct roots_seat *seat, struct wlr_input_device *device) { + struct roots_pointer *pointer = calloc(sizeof(struct roots_pointer), 1); + if (!pointer) { + wlr_log(L_ERROR, "could not allocate pointer for seat"); + return; + } + + device->data = pointer; + pointer->device = device; + pointer->seat = seat; + wl_list_insert(&seat->pointers, &pointer->link); + wlr_cursor_attach_input_device(seat->cursor, device); + roots_seat_configure_cursor(seat); +} + +static void seat_add_touch(struct roots_seat *seat, struct wlr_input_device *device) { + struct roots_touch *touch = calloc(sizeof(struct roots_touch), 1); + if (!touch) { + wlr_log(L_ERROR, "could not allocate touch for seat"); + return; + } + + device->data = touch; + touch->device = device; + touch->seat = seat; + wl_list_insert(&seat->touch, &touch->link); + wlr_cursor_attach_input_device(seat->cursor, device); + roots_seat_configure_cursor(seat); +} + +static void seat_add_tablet_pad(struct roots_seat *seat, struct wlr_input_device *device) { // TODO } +static void seat_add_tablet_tool(struct roots_seat *seat, struct wlr_input_device *device) { + struct roots_tablet_tool *tablet_tool = calloc(sizeof(struct roots_tablet_tool), 1); + if (!tablet_tool) { + wlr_log(L_ERROR, "could not allocate tablet_tool for seat"); + return; + } + + device->data = tablet_tool; + tablet_tool->device = device; + tablet_tool->seat = seat; + wl_list_insert(&seat->tablet_tools, &tablet_tool->link); + wlr_cursor_attach_input_device(seat->cursor, device); + roots_seat_configure_cursor(seat); +} + +void roots_seat_add_device(struct roots_seat *seat, + struct wlr_input_device *device) { + switch (device->type) { + case WLR_INPUT_DEVICE_KEYBOARD: + seat_add_keyboard(seat, device); + break; + case WLR_INPUT_DEVICE_POINTER: + seat_add_pointer(seat, device); + break; + case WLR_INPUT_DEVICE_TOUCH: + seat_add_touch(seat, device); + break; + case WLR_INPUT_DEVICE_TABLET_PAD: + seat_add_tablet_pad(seat, device); + break; + case WLR_INPUT_DEVICE_TABLET_TOOL: + seat_add_tablet_tool(seat, device); + break; + } +} + +void roots_seat_remove_device(struct roots_seat *seat, + struct wlr_input_device *device) { + // TODO +} diff --git a/rootston/tablet_tool.c b/rootston/tablet_tool.c deleted file mode 100644 index 3327115d..00000000 --- a/rootston/tablet_tool.c +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include -#include -#include -#include -#include "rootston/input.h" -#include "rootston/tablet_tool.h" - -void tablet_tool_add(struct wlr_input_device *device, struct roots_input *input) { - struct roots_tablet_tool *tool = calloc(sizeof(struct roots_tablet_tool), 1); - device->data = tool; - tool->device = device; - tool->input = input; - wl_list_insert(&input->tablet_tools, &tool->link); - wlr_cursor_attach_input_device(input->cursor, device); - cursor_load_config(input->server->config, input->cursor, - input, input->server->desktop); -} - -void tablet_tool_remove(struct wlr_input_device *device, struct roots_input *input) { - struct roots_tablet_tool *tablet_tool = device->data; - wlr_cursor_detach_input_device(input->cursor, device); - wl_list_remove(&tablet_tool->link); - free(tablet_tool); -} diff --git a/rootston/touch.c b/rootston/touch.c deleted file mode 100644 index 069853ab..00000000 --- a/rootston/touch.c +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include -#include -#include -#include "rootston/input.h" -#include "rootston/touch.h" - -// TODO: we'll likely want touch events to both control the cursor *and* be -// submitted directly to the seat. - -void touch_add(struct wlr_input_device *device, struct roots_input *input) { - struct roots_touch *touch = calloc(sizeof(struct roots_touch), 1); - device->data = touch; - touch->device = device; - touch->input = input; - wl_list_insert(&input->touch, &touch->link); - wlr_cursor_attach_input_device(input->cursor, device); - cursor_load_config(input->server->config, input->cursor, - input, input->server->desktop); -} - -void touch_remove(struct wlr_input_device *device, struct roots_input *input) { - struct roots_touch *touch = device->data; - wlr_cursor_detach_input_device(input->cursor, device); - wl_list_remove(&touch->link); - free(touch); -} -- cgit v1.2.3 From 2280928bb2859b8a5e71e81b99a396ff7a3f9efa Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sun, 5 Nov 2017 09:20:11 -0500 Subject: rootston: roots_cursor --- include/rootston/cursor.h | 54 +++++++++++++++++++++ include/rootston/seat.h | 14 +----- rootston/meson.build | 1 + rootston/roots_cursor.c | 65 +++++++++++++++++++++++++ rootston/seat.c | 118 ++++++++++++++++++++++++++++------------------ 5 files changed, 194 insertions(+), 58 deletions(-) create mode 100644 include/rootston/cursor.h create mode 100644 rootston/roots_cursor.c (limited to 'include') diff --git a/include/rootston/cursor.h b/include/rootston/cursor.h new file mode 100644 index 00000000..8a8d33f2 --- /dev/null +++ b/include/rootston/cursor.h @@ -0,0 +1,54 @@ +#ifndef _ROOTSTON_CURSOR_H +#define _ROOTSTON_CURSOR_H + +#include "rootston/seat.h" + +struct roots_cursor { + struct roots_seat *seat; + struct wlr_cursor *cursor; + + struct wl_listener motion; + struct wl_listener motion_absolute; + struct wl_listener button; + struct wl_listener axis; + + 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 roots_cursor *roots_cursor_create(struct roots_seat *seat); + +void roots_cursor_destroy(struct roots_cursor *cursor); + +void roots_cursor_handle_motion(struct roots_cursor *cursor, + struct wlr_event_pointer_motion *event); + +void roots_cursor_handle_motion_absolute(struct roots_cursor *cursor, + struct wlr_event_pointer_motion_absolute *event); + +void roots_cursor_handle_button(struct roots_cursor *cursor, + struct wlr_event_pointer_button *event); + +void roots_cursor_handle_axis(struct roots_cursor *cursor, + struct wlr_event_pointer_axis *event); + +void roots_cursor_handle_touch_down(struct roots_cursor *cursor, + struct wlr_event_touch_down *event); + +void roots_cursor_handle_touch_up(struct roots_cursor *cursor, + struct wlr_event_touch_up *event); + +void roots_cursor_handle_touch_motion(struct roots_cursor *cursor, + struct wlr_event_touch_motion *event); + +void roots_cursor_handle_tool_axis(struct roots_cursor *cursor, + struct wlr_event_tablet_tool_axis *event); + +void roots_cursor_handle_tool_tip(struct roots_cursor *cursor, + struct wlr_event_tablet_tool_tip *event); + +#endif diff --git a/include/rootston/seat.h b/include/rootston/seat.h index e4130e5a..b7c8b477 100644 --- a/include/rootston/seat.h +++ b/include/rootston/seat.h @@ -9,25 +9,13 @@ struct roots_seat { struct roots_input *input; struct wlr_seat *seat; - struct wlr_cursor *cursor; + struct roots_cursor *cursor; struct wl_list link; struct wl_list keyboards; struct wl_list pointers; struct wl_list touch; struct wl_list tablet_tools; - - struct wl_listener cursor_motion; - struct wl_listener cursor_motion_absolute; - struct wl_listener cursor_button; - struct wl_listener cursor_axis; - - struct wl_listener cursor_touch_down; - struct wl_listener cursor_touch_up; - struct wl_listener cursor_touch_motion; - - struct wl_listener cursor_tool_axis; - struct wl_listener cursor_tool_tip; }; struct roots_pointer { diff --git a/rootston/meson.build b/rootston/meson.build index 9c543c4f..baed5330 100644 --- a/rootston/meson.build +++ b/rootston/meson.build @@ -1,6 +1,7 @@ sources = [ 'config.c', 'cursor.c', + 'roots_cursor.c', 'desktop.c', 'ini.c', 'input.c', diff --git a/rootston/roots_cursor.c b/rootston/roots_cursor.c new file mode 100644 index 00000000..72eff996 --- /dev/null +++ b/rootston/roots_cursor.c @@ -0,0 +1,65 @@ +#include +#include +#include "rootston/cursor.h" + +struct roots_cursor *roots_cursor_create(struct roots_seat *seat) { + struct roots_cursor *cursor = calloc(1, sizeof(struct roots_cursor)); + if (!cursor) { + return NULL; + } + cursor->cursor = wlr_cursor_create(); + if (!cursor->cursor) { + return NULL; + } + + return cursor; +} + +void roots_cursor_destroy(struct roots_cursor *cursor) { + // TODO +} + +void roots_cursor_handle_motion(struct roots_cursor *cursor, + struct wlr_event_pointer_motion *event) { + wlr_log(L_DEBUG, "TODO: cursor handle motion"); +} + +void roots_cursor_handle_motion_absolute(struct roots_cursor *cursor, + struct wlr_event_pointer_motion_absolute *event) { + wlr_log(L_DEBUG, "TODO: cursor handle motion absolute"); +} + +void roots_cursor_handle_button(struct roots_cursor *cursor, + struct wlr_event_pointer_button *event) { + wlr_log(L_DEBUG, "TODO: cursor handle button"); +} + +void roots_cursor_handle_axis(struct roots_cursor *cursor, + struct wlr_event_pointer_axis *event) { + wlr_log(L_DEBUG, "TODO: cursor handle axis"); +} + +void roots_cursor_handle_touch_down(struct roots_cursor *cursor, + struct wlr_event_touch_down *event) { + wlr_log(L_DEBUG, "TODO: cursor handle touch down"); +} + +void roots_cursor_handle_touch_up(struct roots_cursor *cursor, + struct wlr_event_touch_up *event) { + wlr_log(L_DEBUG, "TODO: cursor handle touch up"); +} + +void roots_cursor_handle_touch_motion(struct roots_cursor *cursor, + struct wlr_event_touch_motion *event) { + wlr_log(L_DEBUG, "TODO: cursor handle touch motion"); +} + +void roots_cursor_handle_tool_axis(struct roots_cursor *cursor, + struct wlr_event_tablet_tool_axis *event) { + wlr_log(L_DEBUG, "TODO: cursor handle tool axis"); +} + +void roots_cursor_handle_tool_tip(struct roots_cursor *cursor, + struct wlr_event_tablet_tool_tip *event) { + wlr_log(L_DEBUG, "TODO: cursor handle tool tip"); +} diff --git a/rootston/seat.c b/rootston/seat.c index c8f689bc..957843ec 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -7,6 +7,7 @@ #include "rootston/input.h" #include "rootston/seat.h" #include "rootston/keyboard.h" +#include "rootston/cursor.h" static void handle_keyboard_key(struct wl_listener *listener, void *data) { struct roots_keyboard *keyboard = @@ -24,43 +25,70 @@ static void handle_keyboard_modifiers(struct wl_listener *listener, } static void handle_cursor_motion(struct wl_listener *listener, void *data) { - // TODO + struct roots_cursor *cursor = + wl_container_of(listener, cursor, motion); + struct wlr_event_pointer_motion *event = data; + roots_cursor_handle_motion(cursor, event); } static void handle_cursor_motion_absolute(struct wl_listener *listener, void *data) { - // TODO + struct roots_cursor *cursor = + wl_container_of(listener, cursor, motion_absolute); + struct wlr_event_pointer_motion_absolute *event = data; + roots_cursor_handle_motion_absolute(cursor, event); } static void handle_cursor_button(struct wl_listener *listener, void *data) { - // TODO + struct roots_cursor *cursor = + wl_container_of(listener, cursor, button); + struct wlr_event_pointer_button *event = data; + roots_cursor_handle_button(cursor, event); } static void handle_cursor_axis(struct wl_listener *listener, void *data) { - // TODO + struct roots_cursor *cursor = + wl_container_of(listener, cursor, axis); + struct wlr_event_pointer_axis *event = data; + roots_cursor_handle_axis(cursor, event); } static void handle_touch_down(struct wl_listener *listener, void *data) { - // TODO + struct roots_cursor *cursor = + wl_container_of(listener, cursor, touch_down); + struct wlr_event_touch_down *event = data; + roots_cursor_handle_touch_down(cursor, event); } static void handle_touch_up(struct wl_listener *listener, void *data) { - // TODO + struct roots_cursor *cursor = + wl_container_of(listener, cursor, touch_up); + struct wlr_event_touch_up *event = data; + roots_cursor_handle_touch_up(cursor, event); } static void handle_touch_motion(struct wl_listener *listener, void *data) { - // TODO + struct roots_cursor *cursor = + wl_container_of(listener, cursor, touch_motion); + struct wlr_event_touch_motion *event = data; + roots_cursor_handle_touch_motion(cursor, event); } static void handle_tool_axis(struct wl_listener *listener, void *data) { - // TODO + struct roots_cursor *cursor = + wl_container_of(listener, cursor, tool_axis); + struct wlr_event_tablet_tool_axis *event = data; + roots_cursor_handle_tool_axis(cursor, event); } static void handle_tool_tip(struct wl_listener *listener, void *data) { - // TODO + struct roots_cursor *cursor = + wl_container_of(listener, cursor, tool_tip); + struct wlr_event_tablet_tool_tip *event = data; + roots_cursor_handle_tool_tip(cursor, event); } static void seat_reset_device_mappings(struct roots_seat *seat, struct wlr_input_device *device) { - struct wlr_cursor *cursor = seat->cursor; + struct wlr_cursor *cursor = seat->cursor->cursor; struct roots_config *config = seat->input->config; wlr_cursor_map_input_to_output(cursor, device, NULL); @@ -72,7 +100,7 @@ static void seat_reset_device_mappings(struct roots_seat *seat, struct wlr_input static void seat_set_device_output_mappings(struct roots_seat *seat, struct wlr_input_device *device, struct wlr_output *output) { - struct wlr_cursor *cursor = seat->cursor; + struct wlr_cursor *cursor = seat->cursor->cursor; struct roots_config *config = seat->input->config; struct device_config *dconfig; dconfig = config_get_device(config, device); @@ -85,7 +113,7 @@ static void seat_set_device_output_mappings(struct roots_seat *seat, static void roots_seat_configure_cursor(struct roots_seat *seat) { struct roots_config *config = seat->input->config; struct roots_desktop *desktop = seat->input->server->desktop; - struct wlr_cursor *cursor = seat->cursor; + struct wlr_cursor *cursor = seat->cursor->cursor; struct roots_pointer *pointer; struct roots_touch *touch; @@ -124,46 +152,42 @@ static void roots_seat_configure_cursor(struct roots_seat *seat) { } static void roots_seat_init_cursor(struct roots_seat *seat) { - struct wlr_cursor *cursor = wlr_cursor_create(); - if (!cursor) { + seat->cursor = roots_cursor_create(seat); + if (!seat->cursor) { return; } - seat->cursor = cursor; - - // add output layout and configure + struct wlr_cursor *wlr_cursor = seat->cursor->cursor; struct roots_desktop *desktop = seat->input->server->desktop; - wlr_cursor_attach_output_layout(cursor, desktop->layout); - roots_seat_configure_cursor(seat); - // TODO configure cursor by seat + wlr_cursor_attach_output_layout(wlr_cursor, desktop->layout); // add input signals - wl_signal_add(&cursor->events.motion, &seat->cursor_motion); - seat->cursor_motion.notify = handle_cursor_motion; + wl_signal_add(&wlr_cursor->events.motion, &seat->cursor->motion); + seat->cursor->motion.notify = handle_cursor_motion; - wl_signal_add(&cursor->events.motion_absolute, - &seat->cursor_motion_absolute); - seat->cursor_motion_absolute.notify = handle_cursor_motion_absolute; + wl_signal_add(&wlr_cursor->events.motion_absolute, + &seat->cursor->motion_absolute); + seat->cursor->motion_absolute.notify = handle_cursor_motion_absolute; - wl_signal_add(&cursor->events.button, &seat->cursor_button); - seat->cursor_button.notify = handle_cursor_button; + wl_signal_add(&wlr_cursor->events.button, &seat->cursor->button); + seat->cursor->button.notify = handle_cursor_button; - wl_signal_add(&cursor->events.axis, &seat->cursor_axis); - seat->cursor_axis.notify = handle_cursor_axis; + wl_signal_add(&wlr_cursor->events.axis, &seat->cursor->axis); + seat->cursor->axis.notify = handle_cursor_axis; - wl_signal_add(&cursor->events.touch_down, &seat->cursor_touch_down); - seat->cursor_touch_down.notify = handle_touch_down; + wl_signal_add(&wlr_cursor->events.touch_down, &seat->cursor->touch_down); + seat->cursor->touch_down.notify = handle_touch_down; - wl_signal_add(&cursor->events.touch_up, &seat->cursor_touch_up); - seat->cursor_touch_up.notify = handle_touch_up; + wl_signal_add(&wlr_cursor->events.touch_up, &seat->cursor->touch_up); + seat->cursor->touch_up.notify = handle_touch_up; - wl_signal_add(&cursor->events.touch_motion, &seat->cursor_touch_motion); - seat->cursor_touch_motion.notify = handle_touch_motion; + wl_signal_add(&wlr_cursor->events.touch_motion, &seat->cursor->touch_motion); + seat->cursor->touch_motion.notify = handle_touch_motion; - wl_signal_add(&cursor->events.tablet_tool_axis, &seat->cursor_tool_axis); - seat->cursor_tool_axis.notify = handle_tool_axis; + wl_signal_add(&wlr_cursor->events.tablet_tool_axis, &seat->cursor->tool_axis); + seat->cursor->tool_axis.notify = handle_tool_axis; - wl_signal_add(&cursor->events.tablet_tool_tip, &seat->cursor_tool_tip); - seat->cursor_tool_tip.notify = handle_tool_tip; + wl_signal_add(&wlr_cursor->events.tablet_tool_tip, &seat->cursor->tool_tip); + seat->cursor->tool_tip.notify = handle_tool_tip; } struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { @@ -172,6 +196,8 @@ struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { return NULL; } + seat->input = input; + roots_seat_init_cursor(seat); if (!seat->cursor) { free(seat); @@ -181,7 +207,7 @@ struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { seat->seat = wlr_seat_create(input->server->wl_display, name); if (!seat->seat) { free(seat); - wlr_cursor_destroy(seat->cursor); + roots_cursor_destroy(seat->cursor); return NULL; } @@ -190,10 +216,12 @@ struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { WL_SEAT_CAPABILITY_POINTER | WL_SEAT_CAPABILITY_TOUCH); - seat->input = input; - wl_list_insert(&input->seats, &seat->link); + wl_list_init(&seat->keyboards); + wl_list_init(&seat->pointers); + wl_list_init(&seat->touch); + wl_list_init(&seat->tablet_tools); return seat; } @@ -228,7 +256,7 @@ static void seat_add_pointer(struct roots_seat *seat, struct wlr_input_device *d pointer->device = device; pointer->seat = seat; wl_list_insert(&seat->pointers, &pointer->link); - wlr_cursor_attach_input_device(seat->cursor, device); + wlr_cursor_attach_input_device(seat->cursor->cursor, device); roots_seat_configure_cursor(seat); } @@ -243,7 +271,7 @@ static void seat_add_touch(struct roots_seat *seat, struct wlr_input_device *dev touch->device = device; touch->seat = seat; wl_list_insert(&seat->touch, &touch->link); - wlr_cursor_attach_input_device(seat->cursor, device); + wlr_cursor_attach_input_device(seat->cursor->cursor, device); roots_seat_configure_cursor(seat); } @@ -262,7 +290,7 @@ static void seat_add_tablet_tool(struct roots_seat *seat, struct wlr_input_devic tablet_tool->device = device; tablet_tool->seat = seat; wl_list_insert(&seat->tablet_tools, &tablet_tool->link); - wlr_cursor_attach_input_device(seat->cursor, device); + wlr_cursor_attach_input_device(seat->cursor->cursor, device); roots_seat_configure_cursor(seat); } -- cgit v1.2.3 From 03d3fdc15879c6fbdd24d5fe1d60f9a77402220d Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 5 Nov 2017 16:29:43 +0100 Subject: Basic maximization implementation for xdg-shell --- include/rootston/view.h | 12 ++++++++++++ rootston/cursor.c | 9 ++++++++- rootston/desktop.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ rootston/xdg_shell_v6.c | 24 +++++++++++++++++++++++- 4 files changed, 87 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/rootston/view.h b/include/rootston/view.h index 0913b42e..67643b94 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -48,8 +48,17 @@ enum roots_view_type { struct roots_view { struct roots_desktop *desktop; + double x, y; float rotation; + + bool maximized; + struct { + double x, y; + uint32_t width, height; + float rotation; + } saved; + // TODO: Something for roots-enforced width/height enum roots_view_type type; union { @@ -67,6 +76,7 @@ struct roots_view { #endif }; struct wlr_surface *wlr_surface; + // TODO: This would probably be better as a field that's updated on a // configure event from the xdg_shell // If not then this should follow the typical type/impl pattern we use @@ -77,6 +87,7 @@ struct roots_view { void (*resize)(struct roots_view *view, uint32_t width, uint32_t height); void (*move_resize)(struct roots_view *view, double x, double y, uint32_t width, uint32_t height); + void (*maximize)(struct roots_view *view, bool maximized); void (*close)(struct roots_view *view); }; @@ -86,6 +97,7 @@ void view_move(struct roots_view *view, double x, double y); void view_resize(struct roots_view *view, uint32_t width, uint32_t height); void view_move_resize(struct roots_view *view, double x, double y, uint32_t width, uint32_t height); +void view_maximize(struct roots_view *view, bool maximized); void view_close(struct roots_view *view); bool view_center(struct roots_view *view); void view_setup(struct roots_view *view); diff --git a/rootston/cursor.c b/rootston/cursor.c index b153e8c8..d97d518e 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -39,6 +39,8 @@ static void cursor_set_xcursor_image(struct roots_input *input, void view_begin_move(struct roots_input *input, struct wlr_cursor *cursor, struct roots_view *view) { + view_maximize(view, false); + input->mode = ROOTS_CURSOR_MOVE; input->offs_x = cursor->x; input->offs_y = cursor->y; @@ -54,6 +56,8 @@ void view_begin_move(struct roots_input *input, struct wlr_cursor *cursor, void view_begin_resize(struct roots_input *input, struct wlr_cursor *cursor, struct roots_view *view, uint32_t edges) { + view_maximize(view, false); + input->mode = ROOTS_CURSOR_RESIZE; input->offs_x = cursor->x; input->offs_y = cursor->y; @@ -74,6 +78,8 @@ void view_begin_resize(struct roots_input *input, struct wlr_cursor *cursor, void view_begin_rotate(struct roots_input *input, struct wlr_cursor *cursor, struct roots_view *view) { + view_maximize(view, false); + input->mode = ROOTS_CURSOR_ROTATE; input->offs_x = cursor->x; input->offs_y = cursor->y; @@ -102,7 +108,8 @@ void cursor_update_position(struct roots_input *input, uint32_t time) { set_compositor_cursor = view_client != input->cursor_client; } if (set_compositor_cursor) { - struct wlr_xcursor *xcursor = get_default_xcursor(input->xcursor_theme); + struct wlr_xcursor *xcursor = + get_default_xcursor(input->xcursor_theme); cursor_set_xcursor_image(input, xcursor->images[0]); input->cursor_client = NULL; } diff --git a/rootston/desktop.c b/rootston/desktop.c index 29f78ac7..f5d5925b 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -78,6 +78,50 @@ void view_move_resize(struct roots_view *view, double x, double y, view_resize(view, width, height); } +void view_maximize(struct roots_view *view, bool maximized) { + if (view->maximized == maximized) { + return; + } + + if (view->maximize) { + view->maximize(view, maximized); + } + + if (!view->maximized && maximized) { + struct wlr_box view_box; + view_get_size(view, &view_box); + + view->maximized = true; + view->saved.x = view->x; + view->saved.y = view->y; + view->saved.rotation = view->rotation; + view->saved.width = view_box.width; + view->saved.height = view_box.height; + + double output_x, output_y; + wlr_output_layout_closest_point(view->desktop->layout, NULL, + view->x + (double)view_box.width/2, + view->y + (double)view_box.height/2, + &output_x, &output_y); + struct wlr_output *output = wlr_output_layout_output_at( + view->desktop->layout, output_x, output_y); + struct wlr_box *output_box = + wlr_output_layout_get_box(view->desktop->layout, output); + + view_move_resize(view, output_box->x, output_box->y, output_box->width, + output_box->height); + view->rotation = 0; + } + + if (view->maximized && !maximized) { + view->maximized = false; + + view_move_resize(view, view->saved.x, view->saved.y, view->saved.width, + view->saved.height); + view->rotation = view->saved.rotation; + } +} + void view_close(struct roots_view *view) { if (view->close) { view->close(view); diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index ca33c582..45691d16 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -84,6 +84,16 @@ static void move_resize(struct roots_view *view, double x, double y, wlr_xdg_toplevel_v6_set_size(surf, contrained_width, contrained_height); } +static void maximize(struct roots_view *view, bool maximized) { + assert(view->type == ROOTS_XDG_SHELL_V6_VIEW); + struct wlr_xdg_surface_v6 *surface = view->xdg_surface_v6; + if (surface->role != WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL) { + return; + } + + wlr_xdg_toplevel_v6_set_maximized(surface, maximized); +} + static void close(struct roots_view *view) { assert(view->type == ROOTS_XDG_SHELL_V6_VIEW); struct wlr_xdg_surface_v6 *surf = view->xdg_surface_v6; @@ -119,7 +129,18 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { } static void handle_commit(struct wl_listener *listener, void *data) { - // TODO is there anything we need to do here? + struct roots_xdg_surface_v6 *roots_xdg_surface = + wl_container_of(listener, roots_xdg_surface, commit); + struct roots_view *view = roots_xdg_surface->view; + struct wlr_xdg_surface_v6 *surface = view->xdg_surface_v6; + + if (surface->role != WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL) { + return; + } + + if (view->maximized != surface->toplevel_state->current.maximized) { + view_maximize(view, surface->toplevel_state->current.maximized); + } } static void handle_destroy(struct wl_listener *listener, void *data) { @@ -178,6 +199,7 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { view->activate = activate; view->resize = resize; view->move_resize = move_resize; + view->maximize = maximize; view->close = close; view->desktop = desktop; roots_surface->view = view; -- cgit v1.2.3 From 09c60924235805d07b7915ba879685545a3442aa Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 7 Nov 2017 15:56:11 -0500 Subject: multiseat: somewhat working --- include/rootston/cursor.h | 35 +++++ include/rootston/input.h | 54 +------- include/rootston/keyboard.h | 1 + include/rootston/seat.h | 30 +++++ include/wlr/types/wlr_wl_shell.h | 4 +- include/wlr/types/wlr_xdg_shell_v6.h | 6 +- rootston/desktop.c | 36 +++--- rootston/input.c | 62 ++------- rootston/keyboard.c | 26 ++-- rootston/meson.build | 2 +- rootston/output.c | 32 ++--- rootston/roots_cursor.c | 239 +++++++++++++++++++++++++++++++++-- rootston/seat.c | 134 +++++++++++++++++++- rootston/wl_shell.c | 13 +- rootston/xdg_shell_v6.c | 14 +- rootston/xwayland.c | 32 ++--- types/wlr_wl_shell.c | 8 +- types/wlr_xdg_shell_v6.c | 12 +- 18 files changed, 521 insertions(+), 219 deletions(-) (limited to 'include') diff --git a/include/rootston/cursor.h b/include/rootston/cursor.h index 8a8d33f2..18d5f720 100644 --- a/include/rootston/cursor.h +++ b/include/rootston/cursor.h @@ -3,10 +3,45 @@ #include "rootston/seat.h" +enum roots_cursor_mode { + ROOTS_CURSOR_PASSTHROUGH = 0, + ROOTS_CURSOR_MOVE = 1, + ROOTS_CURSOR_RESIZE = 2, + ROOTS_CURSOR_ROTATE = 3, +}; + +enum roots_cursor_resize_edge { + ROOTS_CURSOR_RESIZE_EDGE_TOP = 1, + ROOTS_CURSOR_RESIZE_EDGE_BOTTOM = 2, + ROOTS_CURSOR_RESIZE_EDGE_LEFT = 4, + ROOTS_CURSOR_RESIZE_EDGE_RIGHT = 8, +}; + +struct roots_input_event { + uint32_t serial; + struct wlr_cursor *cursor; + struct wlr_input_device *device; +}; + struct roots_cursor { struct roots_seat *seat; struct wlr_cursor *cursor; + enum roots_cursor_mode mode; + + // state from input (review if this is necessary) + struct wlr_xcursor_theme *xcursor_theme; + struct wlr_seat *wl_seat; + struct wl_client *cursor_client; + int offs_x, offs_y; + int view_x, view_y, view_width, view_height; + float view_rotation; + uint32_t resize_edges; + // Ring buffer of input events that could trigger move/resize/rotate + int input_events_idx; + struct wl_list touch_points; + struct roots_input_event input_events[16]; + struct wl_listener motion; struct wl_listener motion_absolute; struct wl_listener button; diff --git a/include/rootston/input.h b/include/rootston/input.h index 7b1358f8..7463ba3a 100644 --- a/include/rootston/input.h +++ b/include/rootston/input.h @@ -5,64 +5,15 @@ #include #include #include +#include "rootston/cursor.h" #include "rootston/config.h" #include "rootston/view.h" #include "rootston/server.h" -enum roots_cursor_mode { - ROOTS_CURSOR_PASSTHROUGH = 0, - ROOTS_CURSOR_MOVE = 1, - ROOTS_CURSOR_RESIZE = 2, - ROOTS_CURSOR_ROTATE = 3, -}; - -enum roots_cursor_resize_edge { - ROOTS_CURSOR_RESIZE_EDGE_TOP = 1, - ROOTS_CURSOR_RESIZE_EDGE_BOTTOM = 2, - ROOTS_CURSOR_RESIZE_EDGE_LEFT = 4, - ROOTS_CURSOR_RESIZE_EDGE_RIGHT = 8, -}; - -struct roots_input_event { - uint32_t serial; - struct wlr_cursor *cursor; - struct wlr_input_device *device; -}; - -struct roots_drag_icon { - struct wlr_surface *surface; - struct wl_list link; // roots_input::drag_icons - bool mapped; - - int32_t sx; - int32_t sy; - - struct wl_listener surface_destroy; - struct wl_listener surface_commit; -}; - struct roots_input { struct roots_config *config; struct roots_server *server; - // TODO: multiseat, multicursor - struct wlr_cursor *cursor; - struct wlr_xcursor_theme *xcursor_theme; - struct wlr_seat *wl_seat; - struct wl_list drag_icons; - struct wl_client *cursor_client; - - enum roots_cursor_mode mode; - struct roots_view *active_view; - int offs_x, offs_y; - int view_x, view_y, view_width, view_height; - float view_rotation; - uint32_t resize_edges; - - // Ring buffer of input events that could trigger move/resize/rotate - int input_events_idx; - struct roots_input_event input_events[16]; - struct wl_list keyboards; struct wl_list pointers; struct wl_list touch; @@ -117,4 +68,7 @@ struct wlr_xcursor *get_rotate_xcursor(struct wlr_xcursor_theme *theme); void set_view_focus(struct roots_input *input, struct roots_desktop *desktop, struct roots_view *view); +struct roots_seat *input_seat_from_wlr_seat(struct roots_input *input, + struct wlr_seat *seat); + #endif diff --git a/include/rootston/keyboard.h b/include/rootston/keyboard.h index cb639ba1..e3caf8fb 100644 --- a/include/rootston/keyboard.h +++ b/include/rootston/keyboard.h @@ -10,6 +10,7 @@ struct roots_keyboard { struct roots_input *input; struct roots_seat *seat; struct wlr_input_device *device; + struct keyboard_config *config; struct wl_list seat_link; // XXX temporary struct wl_list link; diff --git a/include/rootston/seat.h b/include/rootston/seat.h index b7c8b477..b5593651 100644 --- a/include/rootston/seat.h +++ b/include/rootston/seat.h @@ -6,11 +6,26 @@ #include "rootston/input.h" #include "rootston/keyboard.h" +struct roots_drag_icon { + struct wlr_surface *surface; + struct wl_list link; // roots_seat::drag_icons + bool mapped; + + int32_t sx; + int32_t sy; + + struct wl_listener surface_destroy; + struct wl_listener surface_commit; +}; + struct roots_seat { struct roots_input *input; struct wlr_seat *seat; struct roots_cursor *cursor; struct wl_list link; + struct wl_list drag_icons; + + struct roots_view *focus; struct wl_list keyboards; struct wl_list pointers; @@ -57,4 +72,19 @@ void roots_seat_add_device(struct roots_seat *seat, void roots_seat_remove_device(struct roots_seat *seat, struct wlr_input_device *device); +void roots_seat_configure_cursor(struct roots_seat *seat); + +void roots_seat_configure_xcursor(struct roots_seat *seat); + +bool roots_seat_has_meta_pressed(struct roots_seat *seat); + +void roots_seat_focus_view(struct roots_seat *seat, struct roots_view *view); + +void roots_seat_begin_move(struct roots_seat *seat, struct roots_view *view); + +void roots_seat_begin_resize(struct roots_seat *seat, struct roots_view *view, + uint32_t edges); + +void roots_seat_begin_rotate(struct roots_seat *seat, struct roots_view *view); + #endif diff --git a/include/wlr/types/wlr_wl_shell.h b/include/wlr/types/wlr_wl_shell.h index 4e814817..ab3b4b10 100644 --- a/include/wlr/types/wlr_wl_shell.h +++ b/include/wlr/types/wlr_wl_shell.h @@ -93,14 +93,14 @@ struct wlr_wl_shell_surface { struct wlr_wl_shell_surface_move_event { struct wl_client *client; struct wlr_wl_shell_surface *surface; - struct wlr_seat_handle *seat_handle; + struct wlr_seat_client *seat; uint32_t serial; }; struct wlr_wl_shell_surface_resize_event { struct wl_client *client; struct wlr_wl_shell_surface *surface; - struct wlr_seat_handle *seat_handle; + struct wlr_seat_client *seat; uint32_t serial; enum wl_shell_surface_resize edges; }; diff --git a/include/wlr/types/wlr_xdg_shell_v6.h b/include/wlr/types/wlr_xdg_shell_v6.h index b0de41e2..e17393f6 100644 --- a/include/wlr/types/wlr_xdg_shell_v6.h +++ b/include/wlr/types/wlr_xdg_shell_v6.h @@ -138,14 +138,14 @@ struct wlr_xdg_surface_v6 { struct wlr_xdg_toplevel_v6_move_event { struct wl_client *client; struct wlr_xdg_surface_v6 *surface; - struct wlr_seat_handle *seat_handle; + struct wlr_seat_client *seat; uint32_t serial; }; struct wlr_xdg_toplevel_v6_resize_event { struct wl_client *client; struct wlr_xdg_surface_v6 *surface; - struct wlr_seat_handle *seat_handle; + struct wlr_seat_client *seat; uint32_t serial; uint32_t edges; }; @@ -153,7 +153,7 @@ struct wlr_xdg_toplevel_v6_resize_event { struct wlr_xdg_toplevel_v6_show_window_menu_event { struct wl_client *client; struct wlr_xdg_surface_v6 *surface; - struct wlr_seat_handle *seat_handle; + struct wlr_seat_client *seat; uint32_t serial; uint32_t x; uint32_t y; diff --git a/rootston/desktop.c b/rootston/desktop.c index 29f78ac7..e752e639 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -14,15 +14,19 @@ #include #include #include "rootston/server.h" -#include "rootston/server.h" +#include "rootston/seat.h" +// TODO replace me with a signal void view_destroy(struct roots_view *view) { struct roots_desktop *desktop = view->desktop; struct roots_input *input = desktop->server->input; - if (input->active_view == view) { - input->active_view = NULL; - input->mode = ROOTS_CURSOR_PASSTHROUGH; + struct roots_seat *seat; + wl_list_for_each(seat, &input->seats, link) { + if (seat->focus == view) { + seat->focus = NULL; + seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH; + } } for (size_t i = 0; i < desktop->views->length; ++i) { @@ -89,15 +93,9 @@ bool view_center(struct roots_view *view) { view_get_size(view, &size); struct roots_desktop *desktop = view->desktop; - struct wlr_cursor *cursor = desktop->server->input->cursor; struct wlr_output *output = - wlr_output_layout_output_at(desktop->layout, cursor->x, cursor->y); - - if (!output) { - output = wlr_output_layout_get_center_output(desktop->layout); - } - + wlr_output_layout_get_center_output(desktop->layout); if (!output) { // empty layout return false; @@ -121,19 +119,15 @@ void view_setup(struct roots_view *view) { view_center(view); struct roots_input *input = view->desktop->server->input; - set_view_focus(input, view->desktop, view); + // TODO what seat gets focus? the one with the last input event? + struct roots_seat *seat; + wl_list_for_each(seat, &input->seats, link) { + roots_seat_focus_view(seat, view); + } } void view_teardown(struct roots_view *view) { - struct wlr_list *views = view->desktop->views; - if (views->length < 2 || views->items[views->length-1] != view) { - return; - } - - struct roots_view *prev_view = views->items[views->length-2]; - struct roots_input *input = prev_view->desktop->server->input; - set_view_focus(input, prev_view->desktop, prev_view); - wlr_seat_keyboard_notify_enter(input->wl_seat, prev_view->wlr_surface); + // TODO replace me with a signal } struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly, diff --git a/rootston/input.c b/rootston/input.c index 4a567763..8e45d6d3 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -84,43 +84,6 @@ struct roots_input *input_create(struct roots_server *server, input->config = config; input->server = server; - input->xcursor_theme = wlr_xcursor_theme_load("default", 16); - if (input->xcursor_theme == NULL) { - wlr_log(L_ERROR, "Cannot load xcursor theme"); - free(input); - return NULL; - } - - struct wlr_xcursor *xcursor = get_default_xcursor(input->xcursor_theme); - if (xcursor == NULL) { - wlr_log(L_ERROR, "Cannot load xcursor from theme"); - wlr_xcursor_theme_destroy(input->xcursor_theme); - free(input); - return NULL; - } - - if (server->desktop->xwayland != NULL) { - struct wlr_xcursor_image *xcursor_image = xcursor->images[0]; - wlr_xwayland_set_cursor(server->desktop->xwayland, - xcursor_image->buffer, xcursor_image->width, xcursor_image->width, - xcursor_image->height, xcursor_image->hotspot_x, - xcursor_image->hotspot_y); - } - - input->wl_seat = wlr_seat_create(server->wl_display, "seat0"); - if (input->wl_seat == NULL) { - wlr_log(L_ERROR, "Cannot create seat"); - wlr_xcursor_theme_destroy(input->xcursor_theme); - free(input); - return NULL; - } - wlr_seat_set_capabilities(input->wl_seat, WL_SEAT_CAPABILITY_KEYBOARD - | WL_SEAT_CAPABILITY_POINTER | WL_SEAT_CAPABILITY_TOUCH); - - wl_list_init(&input->keyboards); - wl_list_init(&input->pointers); - wl_list_init(&input->touch); - wl_list_init(&input->tablet_tools); wl_list_init(&input->seats); input->input_add.notify = input_add_notify; @@ -128,23 +91,20 @@ struct roots_input *input_create(struct roots_server *server, input->input_remove.notify = input_remove_notify; wl_signal_add(&server->backend->events.input_remove, &input->input_remove); - input->cursor = wlr_cursor_create(); - cursor_initialize(input); - - struct wlr_xcursor_image *image = xcursor->images[0]; - wlr_cursor_set_image(input->cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y); - - wlr_cursor_attach_output_layout(input->cursor, server->desktop->layout); - wlr_cursor_map_to_region(input->cursor, config->cursor.mapped_box); - cursor_load_config(config, input->cursor, - input, server->desktop); - - wl_list_init(&input->drag_icons); - return input; } void input_destroy(struct roots_input *input) { // TODO } + +struct roots_seat *input_seat_from_wlr_seat(struct roots_input *input, + struct wlr_seat *wlr_seat) { + struct roots_seat *seat = NULL; + wl_list_for_each(seat, &input->seats, link) { + if (seat->seat == wlr_seat) { + return seat; + } + } + return seat; +} diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 0865f551..ef5eb8ab 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -39,7 +39,7 @@ static void keyboard_binding_execute(struct roots_keyboard *keyboard, } else if (strcmp(command, "next_window") == 0) { if (server->desktop->views->length > 0) { struct roots_view *view = server->desktop->views->items[0]; - set_view_focus(keyboard->input, server->desktop, view); + roots_seat_focus_view(keyboard->seat, view); } } else if (strncmp(exec_prefix, command, strlen(exec_prefix)) == 0) { const char *shell_cmd = command + strlen(exec_prefix); @@ -192,13 +192,9 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, keyboard->device = device; keyboard->input = input; - // XXX temporary - wl_list_insert(&input->keyboards, &keyboard->link); - - struct keyboard_config config; - memset(&config, 0, sizeof(config)); - keyboard_config_merge(&config, config_get_keyboard(input->config, device)); - keyboard_config_merge(&config, config_get_keyboard(input->config, NULL)); + struct keyboard_config *config = calloc(1, sizeof(struct keyboard_config)); + keyboard_config_merge(config, config_get_keyboard(input->config, device)); + keyboard_config_merge(config, config_get_keyboard(input->config, NULL)); struct keyboard_config env_config = { .rules = getenv("XKB_DEFAULT_RULES"), @@ -207,15 +203,16 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, .variant = getenv("XKB_DEFAULT_VARIANT"), .options = getenv("XKB_DEFAULT_OPTIONS"), }; - keyboard_config_merge(&config, &env_config); + keyboard_config_merge(config, &env_config); + keyboard->config = config; struct xkb_rule_names rules; memset(&rules, 0, sizeof(rules)); - rules.rules = config.rules; - rules.model = config.model; - rules.layout = config.layout; - rules.variant = config.variant; - rules.options = config.options; + rules.rules = config->rules; + rules.model = config->model; + rules.layout = config->layout; + rules.variant = config->variant; + rules.options = config->options; struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); if (context == NULL) { wlr_log(L_ERROR, "Cannot create XKB context"); @@ -231,5 +228,6 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, void roots_keyboard_destroy(struct wlr_input_device *device, struct roots_input *input) { struct roots_keyboard *keyboard = device->data; wl_list_remove(&keyboard->link); + free(keyboard->config); free(keyboard); } diff --git a/rootston/meson.build b/rootston/meson.build index baed5330..062f56fc 100644 --- a/rootston/meson.build +++ b/rootston/meson.build @@ -1,6 +1,6 @@ sources = [ 'config.c', - 'cursor.c', + #'cursor.c', 'roots_cursor.c', 'desktop.c', 'ini.c', diff --git a/rootston/output.c b/rootston/output.c index baa7b6cc..329c29be 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -151,15 +151,18 @@ static void output_frame_notify(struct wl_listener *listener, void *data) { } struct roots_drag_icon *drag_icon = NULL; - wl_list_for_each(drag_icon, &server->input->drag_icons, link) { - if (!drag_icon->mapped) { - continue; + struct roots_seat *seat = NULL; + wl_list_for_each(seat, &server->input->seats, link) { + wl_list_for_each(drag_icon, &seat->drag_icons, link) { + if (!drag_icon->mapped) { + continue; + } + struct wlr_surface *icon = drag_icon->surface; + struct wlr_cursor *cursor = seat->cursor->cursor; + double icon_x = cursor->x + drag_icon->sx; + double icon_y = cursor->y + drag_icon->sy; + render_surface(icon, desktop, wlr_output, &now, icon_x, icon_y, 0); } - struct wlr_surface *icon = drag_icon->surface; - struct wlr_cursor *cursor = server->input->cursor; - double icon_x = cursor->x + drag_icon->sx; - double icon_y = cursor->y + drag_icon->sy; - render_surface(icon, desktop, wlr_output, &now, icon_x, icon_y, 0); } wlr_renderer_end(server->renderer); @@ -224,14 +227,11 @@ void output_add_notify(struct wl_listener *listener, void *data) { wlr_output_layout_add_auto(desktop->layout, wlr_output); } - cursor_load_config(config, input->cursor, input, desktop); - - struct wlr_xcursor *xcursor = get_default_xcursor(input->xcursor_theme); - struct wlr_xcursor_image *image = xcursor->images[0]; - wlr_cursor_set_image(input->cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y); - - wlr_cursor_warp(input->cursor, NULL, input->cursor->x, input->cursor->y); + struct roots_seat *seat; + wl_list_for_each(seat, &input->seats, link) { + roots_seat_configure_cursor(seat); + roots_seat_configure_xcursor(seat); + } } void output_remove_notify(struct wl_listener *listener, void *data) { diff --git a/rootston/roots_cursor.c b/rootston/roots_cursor.c index 72eff996..92c0cc9e 100644 --- a/rootston/roots_cursor.c +++ b/rootston/roots_cursor.c @@ -1,4 +1,11 @@ +#define _XOPEN_SOURCE 700 #include +#include +#ifdef __linux__ +#include +#elif __FreeBSD__ +#include +#endif #include #include "rootston/cursor.h" @@ -19,47 +26,261 @@ void roots_cursor_destroy(struct roots_cursor *cursor) { // TODO } +static void cursor_set_xcursor_image(struct roots_cursor *cursor, + struct wlr_xcursor_image *image) { + wlr_cursor_set_image(cursor->cursor, image->buffer, image->width, + image->width, image->height, image->hotspot_x, image->hotspot_y); +} + +static void roots_cursor_update_position(struct roots_cursor *cursor, uint32_t time) { + struct roots_desktop *desktop = cursor->seat->input->server->desktop; + struct roots_seat *seat = cursor->seat; + struct roots_view *view; + struct wlr_surface *surface; + double sx, sy; + switch (cursor->mode) { + case ROOTS_CURSOR_PASSTHROUGH: + view = view_at(desktop, cursor->cursor->x, cursor->cursor->y, + &surface, &sx, &sy); + bool set_compositor_cursor = !view && cursor->cursor_client; + if (view) { + struct wl_client *view_client = + wl_resource_get_client(view->wlr_surface->resource); + set_compositor_cursor = view_client != cursor->cursor_client; + } + if (set_compositor_cursor) { + struct wlr_xcursor *xcursor = get_default_xcursor(cursor->xcursor_theme); + cursor_set_xcursor_image(cursor, xcursor->images[0]); + cursor->cursor_client = NULL; + } + if (view) { + wlr_seat_pointer_notify_enter(seat->seat, surface, sx, sy); + wlr_seat_pointer_notify_motion(seat->seat, time, sx, sy); + } else { + wlr_seat_pointer_clear_focus(seat->seat); + } + break; + case ROOTS_CURSOR_MOVE: + if (seat->focus) { + double dx = cursor->cursor->x - cursor->offs_x; + double dy = cursor->cursor->y - cursor->offs_y; + view_move(seat->focus, cursor->view_x + dx, + cursor->view_y + dy); + } + break; + case ROOTS_CURSOR_RESIZE: + if (seat->focus) { + double dx = cursor->cursor->x - cursor->offs_x; + double dy = cursor->cursor->y - cursor->offs_y; + double active_x = seat->focus->x; + double active_y = seat->focus->y; + int width = cursor->view_width; + int height = cursor->view_height; + if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_TOP) { + active_y = cursor->view_y + dy; + height -= dy; + if (height < 0) { + active_y += height; + } + } else if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_BOTTOM) { + height += dy; + } + if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_LEFT) { + active_x = cursor->view_x + dx; + width -= dx; + if (width < 0) { + active_x += width; + } + } else if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_RIGHT) { + width += dx; + } + + if (width < 0) { + width = 0; + } + if (height < 0) { + height = 0; + } + + if (active_x != seat->focus->x || + active_y != seat->focus->y) { + view_move_resize(seat->focus, active_x, active_y, + width, height); + } else { + view_resize(seat->focus, width, height); + } + } + break; + case ROOTS_CURSOR_ROTATE: + if (seat->focus) { + struct roots_view *view = seat->focus; + int ox = view->x + view->wlr_surface->current->width/2, + oy = view->y + view->wlr_surface->current->height/2; + int ux = cursor->offs_x - ox, + uy = cursor->offs_y - oy; + int vx = cursor->cursor->x - ox, + vy = cursor->cursor->y - oy; + float angle = atan2(vx*uy - vy*ux, vx*ux + vy*uy); + int steps = 12; + angle = round(angle/M_PI*steps) / (steps/M_PI); + view->rotation = cursor->view_rotation + angle; + } + break; + } + +} + +static void roots_cursor_press_button(struct roots_cursor *cursor, + struct wlr_input_device *device, uint32_t time, uint32_t button, + uint32_t state) { + struct roots_seat *seat = cursor->seat; + struct roots_desktop *desktop = seat->input->server->desktop; + struct wlr_surface *surface; + double sx, sy; + struct roots_view *view = view_at(desktop, + cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy); + + if (state == WLR_BUTTON_PRESSED && view && roots_seat_has_meta_pressed(seat)) { + // TODO + roots_seat_focus_view(seat, view); + + uint32_t edges; + switch (button) { + case BTN_LEFT: + // TODO + roots_seat_begin_move(seat, view); + break; + case BTN_RIGHT: + edges = 0; + if (sx < view->wlr_surface->current->width/2) { + edges |= ROOTS_CURSOR_RESIZE_EDGE_LEFT; + } else { + edges |= ROOTS_CURSOR_RESIZE_EDGE_RIGHT; + } + if (sy < view->wlr_surface->current->height/2) { + edges |= ROOTS_CURSOR_RESIZE_EDGE_TOP; + } else { + edges |= ROOTS_CURSOR_RESIZE_EDGE_BOTTOM; + } + roots_seat_begin_resize(seat, view, edges); + break; + case BTN_MIDDLE: + roots_seat_begin_rotate(seat, view); + break; + } + return; + } + + // TODO + uint32_t serial = + wlr_seat_pointer_notify_button(seat->seat, time, button, state); + + int i; + switch (state) { + case WLR_BUTTON_RELEASED: + seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH; + roots_cursor_update_position(cursor, time); + break; + case WLR_BUTTON_PRESSED: + // TODO + i = cursor->input_events_idx; + cursor->input_events[i].serial = serial; + cursor->input_events[i].cursor = cursor->cursor; + cursor->input_events[i].device = device; + cursor->input_events_idx = (i + 1) + % (sizeof(cursor->input_events) / sizeof(cursor->input_events[0])); + roots_seat_focus_view(seat, view); + break; + } +} + void roots_cursor_handle_motion(struct roots_cursor *cursor, struct wlr_event_pointer_motion *event) { - wlr_log(L_DEBUG, "TODO: cursor handle motion"); + wlr_cursor_move(cursor->cursor, event->device, + event->delta_x, event->delta_y); + roots_cursor_update_position(cursor, event->time_msec); } void roots_cursor_handle_motion_absolute(struct roots_cursor *cursor, struct wlr_event_pointer_motion_absolute *event) { - wlr_log(L_DEBUG, "TODO: cursor handle motion absolute"); + wlr_cursor_warp_absolute(cursor->cursor, event->device, + event->x_mm / event->width_mm, event->y_mm / event->height_mm); + roots_cursor_update_position(cursor, event->time_msec); } void roots_cursor_handle_button(struct roots_cursor *cursor, struct wlr_event_pointer_button *event) { - wlr_log(L_DEBUG, "TODO: cursor handle button"); + roots_cursor_press_button(cursor, event->device, event->time_msec, + event->button, event->state); } void roots_cursor_handle_axis(struct roots_cursor *cursor, struct wlr_event_pointer_axis *event) { - wlr_log(L_DEBUG, "TODO: cursor handle axis"); + wlr_seat_pointer_notify_axis(cursor->seat->seat, event->time_msec, + event->orientation, event->delta); } void roots_cursor_handle_touch_down(struct roots_cursor *cursor, struct wlr_event_touch_down *event) { - wlr_log(L_DEBUG, "TODO: cursor handle touch down"); + struct roots_touch_point *point = + calloc(1, sizeof(struct roots_touch_point)); + if (!point) { + wlr_log(L_ERROR, "could not allocate memory for touch point"); + return; + } + + point->device = event->device->data; + point->slot = event->slot; + point->x = event->x_mm / event->width_mm; + point->y = event->y_mm / event->height_mm; + wlr_cursor_warp_absolute(cursor->cursor, event->device, point->x, point->y); + roots_cursor_update_position(cursor, event->time_msec); + wl_list_insert(&cursor->touch_points, &point->link); + roots_cursor_press_button(cursor, event->device, + event->time_msec, BTN_LEFT, 1); } void roots_cursor_handle_touch_up(struct roots_cursor *cursor, struct wlr_event_touch_up *event) { - wlr_log(L_DEBUG, "TODO: cursor handle touch up"); + struct roots_touch_point *point; + wl_list_for_each(point, &cursor->touch_points, link) { + if (point->slot == event->slot) { + wl_list_remove(&point->link); + free(point); + break; + } + } + roots_cursor_press_button(cursor, event->device, + event->time_msec, BTN_LEFT, 0); } void roots_cursor_handle_touch_motion(struct roots_cursor *cursor, struct wlr_event_touch_motion *event) { - wlr_log(L_DEBUG, "TODO: cursor handle touch motion"); + struct roots_touch_point *point; + wl_list_for_each(point, &cursor->touch_points, link) { + if (point->slot == event->slot) { + point->x = event->x_mm / event->width_mm; + point->y = event->y_mm / event->height_mm; + wlr_cursor_warp_absolute(cursor->cursor, event->device, + point->x, point->y); + roots_cursor_update_position(cursor, event->time_msec); + break; + } + } } void roots_cursor_handle_tool_axis(struct roots_cursor *cursor, struct wlr_event_tablet_tool_axis *event) { - wlr_log(L_DEBUG, "TODO: cursor handle tool axis"); + if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_X) && + (event->updated_axes & WLR_TABLET_TOOL_AXIS_Y)) { + wlr_cursor_warp_absolute(cursor->cursor, event->device, + event->x_mm / event->width_mm, event->y_mm / event->height_mm); + roots_cursor_update_position(cursor, event->time_msec); + } } void roots_cursor_handle_tool_tip(struct roots_cursor *cursor, struct wlr_event_tablet_tool_tip *event) { - wlr_log(L_DEBUG, "TODO: cursor handle tool tip"); + roots_cursor_press_button(cursor, event->device, + event->time_msec, BTN_LEFT, event->state); } diff --git a/rootston/seat.c b/rootston/seat.c index 957843ec..ec7709fa 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -1,6 +1,7 @@ #include #include #include +#include #include @@ -110,7 +111,7 @@ static void seat_set_device_output_mappings(struct roots_seat *seat, } } -static void roots_seat_configure_cursor(struct roots_seat *seat) { +void roots_seat_configure_cursor(struct roots_seat *seat) { struct roots_config *config = seat->input->config; struct roots_desktop *desktop = seat->input->server->desktop; struct wlr_cursor *cursor = seat->cursor->cursor; @@ -156,10 +157,44 @@ static void roots_seat_init_cursor(struct roots_seat *seat) { if (!seat->cursor) { return; } + seat->cursor->seat = seat; struct wlr_cursor *wlr_cursor = seat->cursor->cursor; struct roots_desktop *desktop = seat->input->server->desktop; wlr_cursor_attach_output_layout(wlr_cursor, desktop->layout); + seat->cursor->xcursor_theme = wlr_xcursor_theme_load("default", 16); + if (seat->cursor->xcursor_theme == NULL) { + wlr_log(L_ERROR, "Cannot load xcursor theme"); + roots_cursor_destroy(seat->cursor); + seat->cursor = NULL; + return; + } + + struct wlr_xcursor *xcursor = get_default_xcursor(seat->cursor->xcursor_theme); + if (xcursor == NULL) { + wlr_log(L_ERROR, "Cannot load xcursor from theme"); + wlr_xcursor_theme_destroy(seat->cursor->xcursor_theme); + roots_cursor_destroy(seat->cursor); + seat->cursor = NULL; + return; + } + + struct wlr_xcursor_image *image = xcursor->images[0]; + wlr_cursor_set_image(seat->cursor->cursor, image->buffer, image->width, + image->width, image->height, image->hotspot_x, image->hotspot_y); + + // XXX: xwayland will always have the theme of the last created seat + if (seat->input->server->desktop->xwayland != NULL) { + wlr_xwayland_set_cursor(seat->input->server->desktop->xwayland, + image->buffer, image->width, image->width, + image->height, image->hotspot_x, + image->hotspot_y); + } + + wl_list_init(&seat->cursor->touch_points); + + roots_seat_configure_cursor(seat); + // add input signals wl_signal_add(&wlr_cursor->events.motion, &seat->cursor->motion); seat->cursor->motion.notify = handle_cursor_motion; @@ -196,6 +231,12 @@ struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { return NULL; } + wl_list_init(&seat->keyboards); + wl_list_init(&seat->pointers); + wl_list_init(&seat->touch); + wl_list_init(&seat->tablet_tools); + wl_list_init(&seat->drag_icons); + seat->input = input; roots_seat_init_cursor(seat); @@ -218,11 +259,6 @@ struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { wl_list_insert(&input->seats, &seat->link); - wl_list_init(&seat->keyboards); - wl_list_init(&seat->pointers); - wl_list_init(&seat->touch); - wl_list_init(&seat->tablet_tools); - return seat; } @@ -231,6 +267,7 @@ void roots_seat_destroy(struct roots_seat *seat) { } static void seat_add_keyboard(struct roots_seat *seat, struct wlr_input_device *device) { + assert(device->type == WLR_INPUT_DEVICE_KEYBOARD); struct roots_keyboard *keyboard = roots_keyboard_create(device, seat->input); keyboard->seat = seat; @@ -319,3 +356,88 @@ void roots_seat_remove_device(struct roots_seat *seat, struct wlr_input_device *device) { // TODO } + +void roots_seat_configure_xcursor(struct roots_seat *seat) { + struct wlr_xcursor *xcursor = get_default_xcursor(seat->cursor->xcursor_theme); + struct wlr_xcursor_image *image = xcursor->images[0]; + wlr_cursor_set_image(seat->cursor->cursor, image->buffer, image->width, + image->width, image->height, image->hotspot_x, image->hotspot_y); + + wlr_cursor_warp(seat->cursor->cursor, NULL, seat->cursor->cursor->x, + seat->cursor->cursor->y); +} + +bool roots_seat_has_meta_pressed(struct roots_seat *seat) { + struct roots_keyboard *keyboard; + wl_list_for_each(keyboard, &seat->keyboards, seat_link) { + if (!keyboard->config->meta_key) { + continue; + } + + uint32_t modifiers = + wlr_keyboard_get_modifiers(keyboard->device->keyboard); + if ((modifiers ^ keyboard->config->meta_key) == 0) { + return true; + } + } + + return false; +} + +void roots_seat_focus_view(struct roots_seat *seat, struct roots_view *view) { + struct roots_desktop *desktop = seat->input->server->desktop; + if (seat->focus == view) { + return; + } + seat->focus = view; + seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH; + if (!view) { + return; + } + + if (view->type == ROOTS_XWAYLAND_VIEW && + view->xwayland_surface->override_redirect) { + return; + } + + size_t index = 0; + for (size_t i = 0; i < desktop->views->length; ++i) { + struct roots_view *_view = desktop->views->items[i]; + if (_view != view) { + view_activate(_view, false); + } else { + index = i; + } + } + view_activate(view, true); + // TODO: list_swap + wlr_list_del(desktop->views, index); + wlr_list_add(desktop->views, view); + wlr_seat_keyboard_notify_enter(seat->seat, view->wlr_surface); +} + +void roots_seat_begin_move(struct roots_seat *seat, struct roots_view *view) { + struct roots_cursor *cursor = seat->cursor; + cursor->mode = ROOTS_CURSOR_MOVE; + cursor->offs_x = cursor->cursor->x; + cursor->offs_y = cursor->cursor->y; + cursor->view_x = view->x; + cursor->view_y = view->y; + wlr_seat_pointer_clear_focus(seat->seat); + + struct wlr_xcursor *xcursor = get_move_xcursor(seat->cursor->xcursor_theme); + if (xcursor != NULL) { + struct wlr_xcursor_image *image = xcursor->images[0]; + wlr_cursor_set_image(cursor->cursor, image->buffer, image->width, + image->width, image->height, image->hotspot_x, image->hotspot_y); + } +} + +void roots_seat_begin_resize(struct roots_seat *seat, struct roots_view *view, + uint32_t edges) { + // TODO +} + +void roots_seat_begin_rotate(struct roots_seat *seat, struct roots_view *view) { + // TODO +} diff --git a/rootston/wl_shell.c b/rootston/wl_shell.c index e38eb697..81b9e640 100644 --- a/rootston/wl_shell.c +++ b/rootston/wl_shell.c @@ -29,11 +29,11 @@ static void handle_request_move(struct wl_listener *listener, void *data) { struct roots_view *view = roots_surface->view; struct roots_input *input = view->desktop->server->input; struct wlr_wl_shell_surface_move_event *e = data; - const struct roots_input_event *event = get_input_event(input, e->serial); - if (!event || input->mode != ROOTS_CURSOR_PASSTHROUGH) { + struct roots_seat *seat = input_seat_from_wlr_seat(input, e->seat->seat); + if (!seat || seat->cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { return; } - view_begin_move(input, event->cursor, view); + roots_seat_begin_move(seat, view); } static void handle_request_resize(struct wl_listener *listener, void *data) { @@ -42,11 +42,12 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { struct roots_view *view = roots_surface->view; struct roots_input *input = view->desktop->server->input; struct wlr_wl_shell_surface_resize_event *e = data; - const struct roots_input_event *event = get_input_event(input, e->serial); - if (!event || input->mode != ROOTS_CURSOR_PASSTHROUGH) { + struct roots_seat *seat = input_seat_from_wlr_seat(input, e->seat->seat); + // TODO verify input event + if (!seat || seat->cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { return; } - view_begin_resize(input, event->cursor, view, e->edges); + roots_seat_begin_resize(seat, view, e->edges); } static void handle_surface_commit(struct wl_listener *listener, void *data) { diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index ca33c582..4a694349 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -98,11 +98,12 @@ static void handle_request_move(struct wl_listener *listener, void *data) { struct roots_view *view = roots_xdg_surface->view; struct roots_input *input = view->desktop->server->input; struct wlr_xdg_toplevel_v6_move_event *e = data; - const struct roots_input_event *event = get_input_event(input, e->serial); - if (!event || input->mode != ROOTS_CURSOR_PASSTHROUGH) { + struct roots_seat *seat = input_seat_from_wlr_seat(input, e->seat->seat); + // TODO verify event serial + if (!seat || seat->cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { return; } - view_begin_move(input, event->cursor, view); + roots_seat_begin_move(seat, view); } static void handle_request_resize(struct wl_listener *listener, void *data) { @@ -111,11 +112,12 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { struct roots_view *view = roots_xdg_surface->view; struct roots_input *input = view->desktop->server->input; struct wlr_xdg_toplevel_v6_resize_event *e = data; - const struct roots_input_event *event = get_input_event(input, e->serial); - if (!event || input->mode != ROOTS_CURSOR_PASSTHROUGH) { + // TODO verify event serial + struct roots_seat *seat = input_seat_from_wlr_seat(input, e->seat->seat); + if (!seat || seat->cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { return; } - view_begin_resize(input, event->cursor, view, e->edges); + roots_seat_begin_resize(seat, view, e->edges); } static void handle_commit(struct wl_listener *listener, void *data) { diff --git a/rootston/xwayland.c b/rootston/xwayland.c index e3fc1c84..b53b98a9 100644 --- a/rootston/xwayland.c +++ b/rootston/xwayland.c @@ -114,22 +114,8 @@ static void handle_request_configure(struct wl_listener *listener, void *data) { // seat based on seat pointer focus, but interactive moving and resizing is not // yet seat aware. Even then, we can only guess because X11 events don't give us // enough wayland info to know for sure. -static struct wlr_cursor *guess_cursor_for_view(struct roots_view *view) { - struct roots_input *input = view->desktop->server->input; - size_t len = sizeof(input->input_events) / sizeof(*input->input_events); - for (size_t i = 0; i < len; i++) { - struct wlr_cursor *cursor = input->input_events[i].cursor; - if (cursor) { - int width = view->xwayland_surface->surface->current->width; - int height = view->xwayland_surface->surface->current->height; - if (cursor->x > view->x && cursor->y > view->y && - cursor->x < view->x + width && - cursor->y < view->y + height) { - return cursor; - } - } - } - +static struct roots_seat *guess_seat_for_view(struct roots_view *view) { + // TODO return NULL; } @@ -137,28 +123,26 @@ static void handle_request_move(struct wl_listener *listener, void *data) { struct roots_xwayland_surface *roots_surface = wl_container_of(listener, roots_surface, request_move); struct roots_view *view = roots_surface->view; - struct roots_input *input = view->desktop->server->input; - struct wlr_cursor *cursor = guess_cursor_for_view(view); + struct roots_seat *seat = guess_seat_for_view(view); - if (!cursor || input->mode != ROOTS_CURSOR_PASSTHROUGH) { + if (!seat || seat->cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { return; } - view_begin_move(input, cursor, view); + roots_seat_begin_move(seat, view); } static void handle_request_resize(struct wl_listener *listener, void *data) { struct roots_xwayland_surface *roots_surface = wl_container_of(listener, roots_surface, request_resize); struct roots_view *view = roots_surface->view; - struct roots_input *input = view->desktop->server->input; - struct wlr_cursor *cursor = guess_cursor_for_view(view); + struct roots_seat *seat = guess_seat_for_view(view); struct wlr_xwayland_resize_event *e = data; - if (!cursor || input->mode != ROOTS_CURSOR_PASSTHROUGH) { + if (!seat || seat->cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { return; } - view_begin_resize(input, cursor, view, e->edges); + roots_seat_begin_resize(seat, view, e->edges); } static void handle_map_notify(struct wl_listener *listener, void *data) { diff --git a/types/wlr_wl_shell.c b/types/wlr_wl_shell.c index fe61075e..ce32d186 100644 --- a/types/wlr_wl_shell.c +++ b/types/wlr_wl_shell.c @@ -110,7 +110,7 @@ static void shell_surface_protocol_move(struct wl_client *client, uint32_t serial) { wlr_log(L_DEBUG, "got shell surface move"); struct wlr_wl_shell_surface *surface = wl_resource_get_user_data(resource); - struct wlr_seat_handle *seat_handle = + struct wlr_seat_client *seat = wl_resource_get_user_data(seat_resource); struct wlr_wl_shell_surface_move_event *event = @@ -121,7 +121,7 @@ static void shell_surface_protocol_move(struct wl_client *client, } event->client = client; event->surface = surface; - event->seat_handle = seat_handle; + event->seat = seat; event->serial = serial; wl_signal_emit(&surface->events.request_move, event); @@ -177,7 +177,7 @@ static void shell_surface_protocol_resize(struct wl_client *client, uint32_t serial, enum wl_shell_surface_resize edges) { wlr_log(L_DEBUG, "got shell surface resize"); struct wlr_wl_shell_surface *surface = wl_resource_get_user_data(resource); - struct wlr_seat_handle *seat_handle = + struct wlr_seat_client *seat = wl_resource_get_user_data(seat_resource); struct wlr_wl_shell_surface_resize_event *event = @@ -188,7 +188,7 @@ static void shell_surface_protocol_resize(struct wl_client *client, } event->client = client; event->surface = surface; - event->seat_handle = seat_handle; + event->seat = seat; event->serial = serial; event->edges = edges; diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index fc45bc17..0c41b66f 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -557,7 +557,7 @@ static void xdg_toplevel_protocol_show_window_menu(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial, int32_t x, int32_t y) { struct wlr_xdg_surface_v6 *surface = wl_resource_get_user_data(resource); - struct wlr_seat_handle *seat_handle = + struct wlr_seat_client *seat = wl_resource_get_user_data(seat_resource); if (!surface->configured) { @@ -576,7 +576,7 @@ static void xdg_toplevel_protocol_show_window_menu(struct wl_client *client, event->client = client; event->surface = surface; - event->seat_handle = seat_handle; + event->seat = seat; event->serial = serial; event->x = x; event->y = y; @@ -590,7 +590,7 @@ static void xdg_toplevel_protocol_move(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial) { struct wlr_xdg_surface_v6 *surface = wl_resource_get_user_data(resource); - struct wlr_seat_handle *seat_handle = + struct wlr_seat_client *seat = wl_resource_get_user_data(seat_resource); if (!surface->configured) { @@ -609,7 +609,7 @@ static void xdg_toplevel_protocol_move(struct wl_client *client, event->client = client; event->surface = surface; - event->seat_handle = seat_handle; + event->seat = seat; event->serial = serial; wl_signal_emit(&surface->events.request_move, event); @@ -621,7 +621,7 @@ static void xdg_toplevel_protocol_resize(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial, uint32_t edges) { struct wlr_xdg_surface_v6 *surface = wl_resource_get_user_data(resource); - struct wlr_seat_handle *seat_handle = + struct wlr_seat_client *seat = wl_resource_get_user_data(seat_resource); if (!surface->configured) { @@ -640,7 +640,7 @@ static void xdg_toplevel_protocol_resize(struct wl_client *client, event->client = client; event->surface = surface; - event->seat_handle = seat_handle; + event->seat = seat; event->serial = serial; event->edges = edges; -- cgit v1.2.3 From 84d5e6bbb445c601d85653264f91d4faf333145d Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 5 Nov 2017 17:09:00 +0100 Subject: Send current keyboard state when entering a surface --- include/wlr/types/wlr_keyboard.h | 3 +++ types/wlr_keyboard.c | 25 +++++++++++++++++++++++++ types/wlr_seat.c | 17 +++++++++++++++-- 3 files changed, 43 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/wlr/types/wlr_keyboard.h b/include/wlr/types/wlr_keyboard.h index af837ff5..e2d50b03 100644 --- a/include/wlr/types/wlr_keyboard.h +++ b/include/wlr/types/wlr_keyboard.h @@ -28,6 +28,8 @@ enum wlr_keyboard_modifier { WLR_MODIFIER_MOD5 = 128, }; +#define WLR_KEYBOARD_KEYS_CAP 32 + struct wlr_keyboard_impl; struct wlr_keyboard { @@ -41,6 +43,7 @@ struct wlr_keyboard { xkb_led_index_t led_indexes[WLR_LED_COUNT]; xkb_mod_index_t mod_indexes[WLR_MODIFIER_COUNT]; + uint32_t keycodes[WLR_KEYBOARD_KEYS_CAP]; struct { xkb_mod_mask_t depressed; xkb_mod_mask_t latched; diff --git a/types/wlr_keyboard.c b/types/wlr_keyboard.c index c27264ef..98ebeed5 100644 --- a/types/wlr_keyboard.c +++ b/types/wlr_keyboard.c @@ -45,6 +45,30 @@ static void keyboard_modifier_update(struct wlr_keyboard *keyboard) { wl_signal_emit(&keyboard->events.modifiers, keyboard); } +static void keyboard_key_update(struct wlr_keyboard *keyboard, + struct wlr_event_keyboard_key *event) { + bool found = false; + size_t i = 0; + for (; i < WLR_KEYBOARD_KEYS_CAP; ++i) { + if (keyboard->keycodes[i] == event->keycode) { + found = true; + break; + } + } + + if (event->state == WLR_KEY_PRESSED && !found) { + for (size_t i = 0; i < WLR_KEYBOARD_KEYS_CAP; ++i) { + if (keyboard->keycodes[i] == 0) { + keyboard->keycodes[i] = event->keycode; + break; + } + } + } + if (event->state == WLR_KEY_RELEASED && found) { + keyboard->keycodes[i] = 0; + } +} + void wlr_keyboard_notify_modifiers(struct wlr_keyboard *keyboard, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) { @@ -68,6 +92,7 @@ void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard, } keyboard_led_update(keyboard); keyboard_modifier_update(keyboard); + keyboard_key_update(keyboard, event); wl_signal_emit(&keyboard->events.key, event); } diff --git a/types/wlr_seat.c b/types/wlr_seat.c index 76b34d31..ae991383 100644 --- a/types/wlr_seat.c +++ b/types/wlr_seat.c @@ -751,13 +751,26 @@ void wlr_seat_keyboard_enter(struct wlr_seat *wlr_seat, // enter the current surface if (client && client->keyboard) { - // TODO: read the currently pressed keys out of the active keyboard and - // put them in this array + struct wlr_keyboard *keyboard = wlr_seat->keyboard_state.keyboard; + struct wl_array keys; wl_array_init(&keys); + size_t n = 0; + for (size_t i = 0; i < WLR_KEYBOARD_KEYS_CAP; ++i) { + if (keyboard->keycodes[i] != 0) { + wl_array_add(&keys, sizeof(uint32_t)); + ((uint32_t *)keys.data)[n] = keyboard->keycodes[i]; + n++; + } + } uint32_t serial = wl_display_next_serial(wlr_seat->display); wl_keyboard_send_enter(client->keyboard, serial, surface->resource, &keys); + wl_array_release(&keys); + + wlr_seat_keyboard_send_modifiers(wlr_seat, + keyboard->modifiers.depressed, keyboard->modifiers.latched, + keyboard->modifiers.locked, keyboard->modifiers.group); wlr_seat_client_send_selection(client); } -- cgit v1.2.3 From a00b7f1e9bb992734f2498e597a86f1ca29b1d59 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 8 Nov 2017 09:04:33 -0500 Subject: rootston: remove devices from seat --- include/rootston/keyboard.h | 5 +---- rootston/keyboard.c | 3 +-- rootston/seat.c | 42 ++++++++++++++++++++++++++++++++++++------ 3 files changed, 38 insertions(+), 12 deletions(-) (limited to 'include') diff --git a/include/rootston/keyboard.h b/include/rootston/keyboard.h index e3caf8fb..4dd70a65 100644 --- a/include/rootston/keyboard.h +++ b/include/rootston/keyboard.h @@ -11,8 +11,6 @@ struct roots_keyboard { struct roots_seat *seat; struct wlr_input_device *device; struct keyboard_config *config; - struct wl_list seat_link; - // XXX temporary struct wl_list link; struct wl_listener keyboard_key; @@ -24,8 +22,7 @@ struct roots_keyboard { struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, struct roots_input *input); -void roots_keyboard_destroy(struct wlr_input_device *device, - struct roots_input *input); +void roots_keyboard_destroy(struct roots_keyboard *keyboard); void roots_keyboard_handle_key(struct roots_keyboard *keyboard, struct wlr_event_keyboard_key *event); diff --git a/rootston/keyboard.c b/rootston/keyboard.c index ef5eb8ab..a770f00f 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -225,8 +225,7 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, return keyboard; } -void roots_keyboard_destroy(struct wlr_input_device *device, struct roots_input *input) { - struct roots_keyboard *keyboard = device->data; +void roots_keyboard_destroy(struct roots_keyboard *keyboard) { wl_list_remove(&keyboard->link); free(keyboard->config); free(keyboard); diff --git a/rootston/seat.c b/rootston/seat.c index 7fcffc29..e860c093 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -271,7 +271,7 @@ static void seat_add_keyboard(struct roots_seat *seat, struct wlr_input_device * struct roots_keyboard *keyboard = roots_keyboard_create(device, seat->input); keyboard->seat = seat; - wl_list_insert(&seat->keyboards, &keyboard->seat_link); + wl_list_insert(&seat->keyboards, &keyboard->link); keyboard->keyboard_key.notify = handle_keyboard_key; wl_signal_add(&keyboard->device->keyboard->events.key, @@ -354,17 +354,39 @@ void roots_seat_add_device(struct roots_seat *seat, static void seat_remove_keyboard(struct roots_seat *seat, struct wlr_input_device *device) { - // TODO + struct roots_keyboard *keyboard; + wl_list_for_each(keyboard, &seat->keyboards, link) { + if (keyboard->device == device) { + roots_keyboard_destroy(keyboard); + return; + } + } } static void seat_remove_pointer(struct roots_seat *seat, struct wlr_input_device *device) { - // TODO + struct roots_pointer *pointer; + wl_list_for_each(pointer, &seat->pointers, link) { + if (pointer->device == device) { + wl_list_remove(&pointer->link); + wlr_cursor_detach_input_device(seat->cursor->cursor, device); + free(pointer); + return; + } + } } static void seat_remove_touch(struct roots_seat *seat, struct wlr_input_device *device) { - // TODO + struct roots_touch *touch; + wl_list_for_each(touch, &seat->touch, link) { + if (touch->device == device) { + wl_list_remove(&touch->link); + wlr_cursor_detach_input_device(seat->cursor->cursor, device); + free(touch); + return; + } + } } static void seat_remove_tablet_pad(struct roots_seat *seat, @@ -374,7 +396,15 @@ static void seat_remove_tablet_pad(struct roots_seat *seat, static void seat_remove_tablet_tool(struct roots_seat *seat, struct wlr_input_device *device) { - // TODO + struct roots_tablet_tool *tablet_tool; + wl_list_for_each(tablet_tool, &seat->tablet_tools, link) { + if (tablet_tool->device == device) { + wl_list_remove(&tablet_tool->link); + wlr_cursor_detach_input_device(seat->cursor->cursor, device); + free(tablet_tool); + return; + } + } } void roots_seat_remove_device(struct roots_seat *seat, @@ -410,7 +440,7 @@ void roots_seat_configure_xcursor(struct roots_seat *seat) { bool roots_seat_has_meta_pressed(struct roots_seat *seat) { struct roots_keyboard *keyboard; - wl_list_for_each(keyboard, &seat->keyboards, seat_link) { + wl_list_for_each(keyboard, &seat->keyboards, link) { if (!keyboard->config->meta_key) { continue; } -- cgit v1.2.3 From 882e6206393f1931fea3de8fd2b87b91314ed6d0 Mon Sep 17 00:00:00 2001 From: emersion Date: Wed, 8 Nov 2017 19:02:56 +0100 Subject: Always read state from wlr_keyboard in the seat --- include/wlr/types/wlr_seat.h | 12 ++----- rootston/desktop.c | 1 - rootston/keyboard.c | 23 +++++-------- types/wlr_data_device.c | 5 ++- types/wlr_seat.c | 78 ++++++++++++++++++++------------------------ types/wlr_xdg_shell_v6.c | 7 ++-- 6 files changed, 52 insertions(+), 74 deletions(-) (limited to 'include') diff --git a/include/wlr/types/wlr_seat.h b/include/wlr/types/wlr_seat.h index b8b467d2..09d3e282 100644 --- a/include/wlr/types/wlr_seat.h +++ b/include/wlr/types/wlr_seat.h @@ -45,9 +45,7 @@ struct wlr_keyboard_grab_interface { struct wlr_surface *surface); void (*key)(struct wlr_seat_keyboard_grab *grab, uint32_t time, uint32_t key, uint32_t state); - void (*modifiers)(struct wlr_seat_keyboard_grab *grab, - uint32_t mods_depressed, uint32_t mods_latched, - uint32_t mods_locked, uint32_t group); + void (*modifiers)(struct wlr_seat_keyboard_grab *grab); void (*cancel)(struct wlr_seat_keyboard_grab *grab); }; @@ -296,17 +294,13 @@ void wlr_seat_keyboard_notify_key(struct wlr_seat *seat, uint32_t time, * Send the modifier state to focused keyboard resources. Compositors should use * `wlr_seat_keyboard_notify_modifiers()` to respect any keyboard grabs. */ -void wlr_seat_keyboard_send_modifiers(struct wlr_seat *seat, - uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, - uint32_t group); +void wlr_seat_keyboard_send_modifiers(struct wlr_seat *seat); /** * Notify the seat that the modifiers for the keyboard have changed. Defers to * any keyboard grabs. */ -void wlr_seat_keyboard_notify_modifiers(struct wlr_seat *seat, - uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, - uint32_t group); +void wlr_seat_keyboard_notify_modifiers(struct wlr_seat *seat); /** * Notify the seat that the keyboard focus has changed and request it to be the diff --git a/rootston/desktop.c b/rootston/desktop.c index 29f78ac7..b36a6932 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -133,7 +133,6 @@ void view_teardown(struct roots_view *view) { struct roots_view *prev_view = views->items[views->length-2]; struct roots_input *input = prev_view->desktop->server->input; set_view_focus(input, prev_view->desktop, prev_view); - wlr_seat_keyboard_notify_enter(input->wl_seat, prev_view->wlr_surface); } struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly, diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 6c419df8..bde912aa 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -135,8 +135,8 @@ static bool keyboard_keysyms_simple(struct roots_keyboard *keyboard, const xkb_keysym_t *syms; xkb_layout_index_t layout_index = xkb_state_key_get_layout( keyboard->device->keyboard->xkb_state, keycode); - int syms_len = xkb_keymap_key_get_syms_by_level(keyboard->device->keyboard->keymap, - keycode, layout_index, 0, &syms); + int syms_len = xkb_keymap_key_get_syms_by_level( + keyboard->device->keyboard->keymap, keycode, layout_index, 0, &syms); bool handled = false; for (int i = 0; i < syms_len; i++) { @@ -195,7 +195,8 @@ static void keyboard_key_notify(struct wl_listener *listener, void *data) { bool handled = keyboard_keysyms_xkb(keyboard, keycode, event->state); if (!handled) { - bool key_handled = keyboard_keysyms_simple(keyboard, keycode, event->state); + bool key_handled = keyboard_keysyms_simple(keyboard, keycode, + event->state); handled = handled || key_handled; } @@ -207,17 +208,11 @@ static void keyboard_key_notify(struct wl_listener *listener, void *data) { } static void keyboard_modifiers_notify(struct wl_listener *listener, void *data) { - struct roots_keyboard *r_keyboard = - wl_container_of(listener, r_keyboard, modifiers); - struct wlr_seat *seat = r_keyboard->input->wl_seat; - struct wlr_keyboard *keyboard = r_keyboard->device->keyboard; - wlr_seat_set_keyboard(seat, r_keyboard->device); - wlr_seat_keyboard_notify_modifiers(seat, - keyboard->modifiers.depressed, - keyboard->modifiers.latched, - keyboard->modifiers.locked, - keyboard->modifiers.group); - + struct roots_keyboard *keyboard = + wl_container_of(listener, keyboard, modifiers); + struct wlr_seat *seat = keyboard->input->wl_seat; + wlr_seat_set_keyboard(seat, keyboard->device); + wlr_seat_keyboard_notify_modifiers(seat); } static void keyboard_config_merge(struct keyboard_config *config, diff --git a/types/wlr_data_device.c b/types/wlr_data_device.c index ee83260e..ea28ef50 100644 --- a/types/wlr_data_device.c +++ b/types/wlr_data_device.c @@ -531,9 +531,8 @@ static void keyboard_drag_key(struct wlr_seat_keyboard_grab *grab, // no keyboard input during drags } -static void keyboard_drag_modifiers(struct wlr_seat_keyboard_grab *grab, - uint32_t mods_depressed, uint32_t mods_latched, - uint32_t mods_locked, uint32_t group) { +static void keyboard_drag_modifiers(struct wlr_seat_keyboard_grab *grab) { + //struct wlr_keyboard *keyboard = grab->seat->keyboard_state.keyboard; // TODO change the dnd action based on what modifier is pressed on the // keyboard } diff --git a/types/wlr_seat.c b/types/wlr_seat.c index ae991383..9de1b3a0 100644 --- a/types/wlr_seat.c +++ b/types/wlr_seat.c @@ -284,11 +284,8 @@ static void default_keyboard_key(struct wlr_seat_keyboard_grab *grab, wlr_seat_keyboard_send_key(grab->seat, time, key, state); } -static void default_keyboard_modifiers(struct wlr_seat_keyboard_grab *grab, - uint32_t mods_depressed, uint32_t mods_latched, - uint32_t mods_locked, uint32_t group) { - wlr_seat_keyboard_send_modifiers(grab->seat, mods_depressed, - mods_latched, mods_locked, group); +static void default_keyboard_modifiers(struct wlr_seat_keyboard_grab *grab) { + wlr_seat_keyboard_send_modifiers(grab->seat); } static void default_keyboard_cancel(struct wlr_seat_keyboard_grab *grab) { @@ -708,24 +705,26 @@ static void keyboard_resource_destroy_notify(struct wl_listener *listener, wlr_seat_keyboard_clear_focus(state->seat); } -void wlr_seat_keyboard_send_modifiers(struct wlr_seat *seat, - uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, - uint32_t group) { +void wlr_seat_keyboard_send_modifiers(struct wlr_seat *seat) { struct wlr_seat_client *client = seat->keyboard_state.focused_client; if (!client || !client->keyboard) { return; } - uint32_t serial = wl_display_next_serial(seat->display); + struct wlr_keyboard *keyboard = seat->keyboard_state.keyboard; + if (!keyboard) { + return; + } + uint32_t serial = wl_display_next_serial(seat->display); wl_keyboard_send_modifiers(client->keyboard, serial, - mods_depressed, mods_latched, - mods_locked, group); + keyboard->modifiers.depressed, keyboard->modifiers.latched, + keyboard->modifiers.locked, keyboard->modifiers.group); } -void wlr_seat_keyboard_enter(struct wlr_seat *wlr_seat, +void wlr_seat_keyboard_enter(struct wlr_seat *seat, struct wlr_surface *surface) { - if (wlr_seat->keyboard_state.focused_surface == surface) { + if (seat->keyboard_state.focused_surface == surface) { // this surface already got an enter notify return; } @@ -734,24 +733,24 @@ void wlr_seat_keyboard_enter(struct wlr_seat *wlr_seat, if (surface) { struct wl_client *wl_client = wl_resource_get_client(surface->resource); - client = wlr_seat_client_for_wl_client(wlr_seat, wl_client); + client = wlr_seat_client_for_wl_client(seat, wl_client); } struct wlr_seat_client *focused_client = - wlr_seat->keyboard_state.focused_client; + seat->keyboard_state.focused_client; struct wlr_surface *focused_surface = - wlr_seat->keyboard_state.focused_surface; + seat->keyboard_state.focused_surface; // leave the previously entered surface if (focused_client && focused_client->keyboard && focused_surface) { - uint32_t serial = wl_display_next_serial(wlr_seat->display); + uint32_t serial = wl_display_next_serial(seat->display); wl_keyboard_send_leave(focused_client->keyboard, serial, focused_surface->resource); } // enter the current surface - if (client && client->keyboard) { - struct wlr_keyboard *keyboard = wlr_seat->keyboard_state.keyboard; + if (client && client->keyboard && seat->keyboard_state.keyboard) { + struct wlr_keyboard *keyboard = seat->keyboard_state.keyboard; struct wl_array keys; wl_array_init(&keys); @@ -763,55 +762,50 @@ void wlr_seat_keyboard_enter(struct wlr_seat *wlr_seat, n++; } } - uint32_t serial = wl_display_next_serial(wlr_seat->display); + uint32_t serial = wl_display_next_serial(seat->display); wl_keyboard_send_enter(client->keyboard, serial, surface->resource, &keys); wl_array_release(&keys); - wlr_seat_keyboard_send_modifiers(wlr_seat, - keyboard->modifiers.depressed, keyboard->modifiers.latched, - keyboard->modifiers.locked, keyboard->modifiers.group); + wlr_seat_keyboard_send_modifiers(seat); wlr_seat_client_send_selection(client); } // reinitialize the focus destroy events - wl_list_remove(&wlr_seat->keyboard_state.surface_destroy.link); - wl_list_init(&wlr_seat->keyboard_state.surface_destroy.link); - wl_list_remove(&wlr_seat->keyboard_state.resource_destroy.link); - wl_list_init(&wlr_seat->keyboard_state.resource_destroy.link); + wl_list_remove(&seat->keyboard_state.surface_destroy.link); + wl_list_init(&seat->keyboard_state.surface_destroy.link); + wl_list_remove(&seat->keyboard_state.resource_destroy.link); + wl_list_init(&seat->keyboard_state.resource_destroy.link); if (surface) { wl_signal_add(&surface->events.destroy, - &wlr_seat->keyboard_state.surface_destroy); + &seat->keyboard_state.surface_destroy); wl_resource_add_destroy_listener(surface->resource, - &wlr_seat->keyboard_state.resource_destroy); - wlr_seat->keyboard_state.resource_destroy.notify = + &seat->keyboard_state.resource_destroy); + seat->keyboard_state.resource_destroy.notify = keyboard_resource_destroy_notify; - wlr_seat->keyboard_state.surface_destroy.notify = + seat->keyboard_state.surface_destroy.notify = keyboard_surface_destroy_notify; } - wlr_seat->keyboard_state.focused_client = client; - wlr_seat->keyboard_state.focused_surface = surface; + seat->keyboard_state.focused_client = client; + seat->keyboard_state.focused_surface = surface; } -void wlr_seat_keyboard_notify_enter(struct wlr_seat *wlr_seat, struct +void wlr_seat_keyboard_notify_enter(struct wlr_seat *seat, struct wlr_surface *surface) { - struct wlr_seat_keyboard_grab *grab = wlr_seat->keyboard_state.grab; + struct wlr_seat_keyboard_grab *grab = seat->keyboard_state.grab; grab->interface->enter(grab, surface); } -void wlr_seat_keyboard_clear_focus(struct wlr_seat *wlr_seat) { +void wlr_seat_keyboard_clear_focus(struct wlr_seat *seat) { struct wl_array keys; wl_array_init(&keys); - wlr_seat_keyboard_enter(wlr_seat, NULL); + wlr_seat_keyboard_enter(seat, NULL); } -void wlr_seat_keyboard_notify_modifiers(struct wlr_seat *seat, - uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, - uint32_t group) { +void wlr_seat_keyboard_notify_modifiers(struct wlr_seat *seat) { struct wlr_seat_keyboard_grab *grab = seat->keyboard_state.grab; - grab->interface->modifiers(grab, - mods_depressed, mods_latched, mods_locked, group); + grab->interface->modifiers(grab); } void wlr_seat_keyboard_notify_key(struct wlr_seat *seat, uint32_t time, diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index fc45bc17..ef4ae42e 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -111,11 +111,8 @@ static void xdg_keyboard_grab_key(struct wlr_seat_keyboard_grab *grab, uint32_t wlr_seat_keyboard_send_key(grab->seat, time, key, state); } -static void xdg_keyboard_grab_modifiers(struct wlr_seat_keyboard_grab *grab, - uint32_t mods_depressed, uint32_t mods_latched, - uint32_t mods_locked, uint32_t group) { - wlr_seat_keyboard_send_modifiers(grab->seat, mods_depressed, mods_latched, - mods_locked, group); +static void xdg_keyboard_grab_modifiers(struct wlr_seat_keyboard_grab *grab) { + wlr_seat_keyboard_send_modifiers(grab->seat); } static void xdg_keyboard_grab_cancel(struct wlr_seat_keyboard_grab *grab) { -- cgit v1.2.3 From 992f931ae9319999f338298d8e0538f13ee388d7 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 8 Nov 2017 14:53:08 -0500 Subject: rootston: cleanup for multiseat --- include/rootston/input.h | 42 +----------------------------------------- include/rootston/xcursor.h | 15 +++++++++++++++ rootston/roots_cursor.c | 5 +---- rootston/seat.c | 1 + rootston/xcursor.c | 16 ++++++++-------- 5 files changed, 26 insertions(+), 53 deletions(-) create mode 100644 include/rootston/xcursor.h (limited to 'include') diff --git a/include/rootston/input.h b/include/rootston/input.h index 7463ba3a..e073a59d 100644 --- a/include/rootston/input.h +++ b/include/rootston/input.h @@ -4,7 +4,6 @@ #include #include #include -#include #include "rootston/cursor.h" #include "rootston/config.h" #include "rootston/view.h" @@ -14,30 +13,12 @@ struct roots_input { struct roots_config *config; struct roots_server *server; - struct wl_list keyboards; - struct wl_list pointers; - struct wl_list touch; - struct wl_list tablet_tools; - struct wl_list seats; - struct wl_listener input_add; struct wl_listener input_remove; - struct wl_listener cursor_motion; - struct wl_listener cursor_motion_absolute; - struct wl_listener cursor_button; - struct wl_listener cursor_axis; - - struct wl_listener cursor_touch_down; - struct wl_listener cursor_touch_up; - struct wl_listener cursor_touch_motion; - - struct wl_listener cursor_tool_axis; - struct wl_listener cursor_tool_tip; + struct wl_list seats; struct wl_listener pointer_grab_begin; - struct wl_list touch_points; - struct wl_listener pointer_grab_end; struct wl_listener request_set_cursor; @@ -47,27 +28,6 @@ struct roots_input *input_create(struct roots_server *server, struct roots_config *config); void input_destroy(struct roots_input *input); -void cursor_initialize(struct roots_input *input); -void cursor_load_config(struct roots_config *config, - struct wlr_cursor *cursor, - struct roots_input *input, - struct roots_desktop *desktop); -const struct roots_input_event *get_input_event(struct roots_input *input, - uint32_t serial); -void view_begin_move(struct roots_input *input, struct wlr_cursor *cursor, - struct roots_view *view); -void view_begin_resize(struct roots_input *input, struct wlr_cursor *cursor, - struct roots_view *view, uint32_t edges); - -struct wlr_xcursor *get_default_xcursor(struct wlr_xcursor_theme *theme); -struct wlr_xcursor *get_move_xcursor(struct wlr_xcursor_theme *theme); -struct wlr_xcursor *get_resize_xcursor(struct wlr_xcursor_theme *theme, - uint32_t edges); -struct wlr_xcursor *get_rotate_xcursor(struct wlr_xcursor_theme *theme); - -void set_view_focus(struct roots_input *input, struct roots_desktop *desktop, - struct roots_view *view); - struct roots_seat *input_seat_from_wlr_seat(struct roots_input *input, struct wlr_seat *seat); diff --git a/include/rootston/xcursor.h b/include/rootston/xcursor.h new file mode 100644 index 00000000..c96e50ef --- /dev/null +++ b/include/rootston/xcursor.h @@ -0,0 +1,15 @@ +#ifndef _ROOTSTON_XCURSOR_H +#define _ROOTSTON_XCURSOR_H + +#include + +struct wlr_xcursor *get_default_xcursor(struct wlr_xcursor_theme *theme); + +struct wlr_xcursor *get_move_xcursor(struct wlr_xcursor_theme *theme); + +struct wlr_xcursor *get_resize_xcursor(struct wlr_xcursor_theme *theme, + uint32_t edges); + +struct wlr_xcursor *get_rotate_xcursor(struct wlr_xcursor_theme *theme); + +#endif diff --git a/rootston/roots_cursor.c b/rootston/roots_cursor.c index 92c0cc9e..833551d1 100644 --- a/rootston/roots_cursor.c +++ b/rootston/roots_cursor.c @@ -7,6 +7,7 @@ #include #endif #include +#include "rootston/xcursor.h" #include "rootston/cursor.h" struct roots_cursor *roots_cursor_create(struct roots_seat *seat) { @@ -141,13 +142,11 @@ static void roots_cursor_press_button(struct roots_cursor *cursor, cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy); if (state == WLR_BUTTON_PRESSED && view && roots_seat_has_meta_pressed(seat)) { - // TODO roots_seat_focus_view(seat, view); uint32_t edges; switch (button) { case BTN_LEFT: - // TODO roots_seat_begin_move(seat, view); break; case BTN_RIGHT: @@ -171,7 +170,6 @@ static void roots_cursor_press_button(struct roots_cursor *cursor, return; } - // TODO uint32_t serial = wlr_seat_pointer_notify_button(seat->seat, time, button, state); @@ -182,7 +180,6 @@ static void roots_cursor_press_button(struct roots_cursor *cursor, roots_cursor_update_position(cursor, time); break; case WLR_BUTTON_PRESSED: - // TODO i = cursor->input_events_idx; cursor->input_events[i].serial = serial; cursor->input_events[i].cursor = cursor->cursor; diff --git a/rootston/seat.c b/rootston/seat.c index e860c093..b4d7887e 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -5,6 +5,7 @@ #include +#include "rootston/xcursor.h" #include "rootston/input.h" #include "rootston/seat.h" #include "rootston/keyboard.h" diff --git a/rootston/xcursor.c b/rootston/xcursor.c index 43cbfc51..8697cdc3 100644 --- a/rootston/xcursor.c +++ b/rootston/xcursor.c @@ -1,14 +1,6 @@ #include #include "rootston/input.h" -struct wlr_xcursor *get_default_xcursor(struct wlr_xcursor_theme *theme) { - return wlr_xcursor_theme_get_cursor(theme, "left_ptr"); -} - -struct wlr_xcursor *get_move_xcursor(struct wlr_xcursor_theme *theme) { - return wlr_xcursor_theme_get_cursor(theme, "grabbing"); -} - static const char *get_resize_xcursor_name(uint32_t edges) { if (edges & ROOTS_CURSOR_RESIZE_EDGE_TOP) { if (edges & ROOTS_CURSOR_RESIZE_EDGE_RIGHT) { @@ -32,6 +24,14 @@ static const char *get_resize_xcursor_name(uint32_t edges) { return "se-resize"; // fallback } +struct wlr_xcursor *get_default_xcursor(struct wlr_xcursor_theme *theme) { + return wlr_xcursor_theme_get_cursor(theme, "left_ptr"); +} + +struct wlr_xcursor *get_move_xcursor(struct wlr_xcursor_theme *theme) { + return wlr_xcursor_theme_get_cursor(theme, "grabbing"); +} + struct wlr_xcursor *get_resize_xcursor(struct wlr_xcursor_theme *theme, uint32_t edges) { return wlr_xcursor_theme_get_cursor(theme, get_resize_xcursor_name(edges)); -- cgit v1.2.3 From 428bf18ec70a29d6e3d778ab3baf175a3cead0af Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 8 Nov 2017 15:23:56 -0500 Subject: rootston: request set cursor --- include/rootston/cursor.h | 8 ++++++++ include/rootston/input.h | 5 ----- rootston/roots_cursor.c | 21 +++++++++++++++++++++ rootston/seat.c | 23 ++++++++++++++++++----- 4 files changed, 47 insertions(+), 10 deletions(-) (limited to 'include') diff --git a/include/rootston/cursor.h b/include/rootston/cursor.h index 18d5f720..3bc8c08b 100644 --- a/include/rootston/cursor.h +++ b/include/rootston/cursor.h @@ -53,6 +53,11 @@ struct roots_cursor { struct wl_listener tool_axis; struct wl_listener tool_tip; + + struct wl_listener pointer_grab_begin; + struct wl_listener pointer_grab_end; + + struct wl_listener request_set_cursor; }; struct roots_cursor *roots_cursor_create(struct roots_seat *seat); @@ -86,4 +91,7 @@ void roots_cursor_handle_tool_axis(struct roots_cursor *cursor, void roots_cursor_handle_tool_tip(struct roots_cursor *cursor, struct wlr_event_tablet_tool_tip *event); +void roots_cursor_handle_request_set_cursor(struct roots_cursor *cursor, + struct wlr_seat_pointer_request_set_cursor_event *event); + #endif diff --git a/include/rootston/input.h b/include/rootston/input.h index e073a59d..ea0bbeb6 100644 --- a/include/rootston/input.h +++ b/include/rootston/input.h @@ -17,11 +17,6 @@ struct roots_input { struct wl_listener input_remove; struct wl_list seats; - - struct wl_listener pointer_grab_begin; - struct wl_listener pointer_grab_end; - - struct wl_listener request_set_cursor; }; struct roots_input *input_create(struct roots_server *server, diff --git a/rootston/roots_cursor.c b/rootston/roots_cursor.c index 833551d1..c44b0e7f 100644 --- a/rootston/roots_cursor.c +++ b/rootston/roots_cursor.c @@ -281,3 +281,24 @@ void roots_cursor_handle_tool_tip(struct roots_cursor *cursor, roots_cursor_press_button(cursor, event->device, event->time_msec, BTN_LEFT, event->state); } + +void roots_cursor_handle_request_set_cursor(struct roots_cursor *cursor, + struct wlr_seat_pointer_request_set_cursor_event *event) { + struct wlr_surface *focused_surface = + event->seat_client->seat->pointer_state.focused_surface; + bool has_focused = focused_surface != NULL && focused_surface->resource != NULL; + struct wl_client *focused_client = NULL; + if (has_focused) { + focused_client = wl_resource_get_client(focused_surface->resource); + } + if (event->seat_client->client != focused_client || + cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { + wlr_log(L_DEBUG, "Denying request to set cursor from unfocused client"); + return; + } + + wlr_log(L_DEBUG, "Setting client cursor"); + wlr_cursor_set_surface(cursor->cursor, event->surface, event->hotspot_x, + event->hotspot_y); + cursor->cursor_client = event->seat_client->client; +} diff --git a/rootston/seat.c b/rootston/seat.c index b4d7887e..12f12a69 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -89,6 +89,14 @@ static void handle_tool_tip(struct wl_listener *listener, void *data) { roots_cursor_handle_tool_tip(cursor, event); } +static void handle_request_set_cursor(struct wl_listener *listener, + void *data) { + struct roots_cursor *cursor = + wl_container_of(listener, cursor, request_set_cursor); + struct wlr_seat_pointer_request_set_cursor_event *event = data; + roots_cursor_handle_request_set_cursor(cursor, event); +} + static void seat_reset_device_mappings(struct roots_seat *seat, struct wlr_input_device *device) { struct wlr_cursor *cursor = seat->cursor->cursor; struct roots_config *config = seat->input->config; @@ -224,6 +232,10 @@ static void roots_seat_init_cursor(struct roots_seat *seat) { wl_signal_add(&wlr_cursor->events.tablet_tool_tip, &seat->cursor->tool_tip); seat->cursor->tool_tip.notify = handle_tool_tip; + + wl_signal_add(&seat->seat->events.request_set_cursor, + &seat->cursor->request_set_cursor); + seat->cursor->request_set_cursor.notify = handle_request_set_cursor; } struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { @@ -240,16 +252,17 @@ struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { seat->input = input; - roots_seat_init_cursor(seat); - if (!seat->cursor) { + seat->seat = wlr_seat_create(input->server->wl_display, name); + if (!seat->seat) { free(seat); + roots_cursor_destroy(seat->cursor); return NULL; } - seat->seat = wlr_seat_create(input->server->wl_display, name); - if (!seat->seat) { + roots_seat_init_cursor(seat); + if (!seat->cursor) { + wlr_seat_destroy(seat->seat); free(seat); - roots_cursor_destroy(seat->cursor); return NULL; } -- cgit v1.2.3 From 06642859f1d6c1e88056a606dac7376fb59e9205 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 8 Nov 2017 15:35:47 -0500 Subject: rootston: drag icons --- include/rootston/cursor.h | 6 +++++ rootston/roots_cursor.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++ rootston/seat.c | 24 ++++++++++++++++++ 3 files changed, 92 insertions(+) (limited to 'include') diff --git a/include/rootston/cursor.h b/include/rootston/cursor.h index 3bc8c08b..c0dbc010 100644 --- a/include/rootston/cursor.h +++ b/include/rootston/cursor.h @@ -94,4 +94,10 @@ void roots_cursor_handle_tool_tip(struct roots_cursor *cursor, void roots_cursor_handle_request_set_cursor(struct roots_cursor *cursor, struct wlr_seat_pointer_request_set_cursor_event *event); +void roots_cursor_handle_pointer_grab_begin(struct roots_cursor *cursor, + struct wlr_seat_pointer_grab *grab); + +void roots_cursor_handle_pointer_grab_end(struct roots_cursor *cursor, + struct wlr_seat_pointer_grab *grab); + #endif diff --git a/rootston/roots_cursor.c b/rootston/roots_cursor.c index c44b0e7f..c8abe098 100644 --- a/rootston/roots_cursor.c +++ b/rootston/roots_cursor.c @@ -302,3 +302,65 @@ void roots_cursor_handle_request_set_cursor(struct roots_cursor *cursor, event->hotspot_y); cursor->cursor_client = event->seat_client->client; } + +static void handle_drag_icon_commit(struct wl_listener *listener, void *data) { + struct roots_drag_icon *drag_icon = + wl_container_of(listener, drag_icon, surface_commit); + drag_icon->sx += drag_icon->surface->current->sx; + drag_icon->sy += drag_icon->surface->current->sy; +} + +static void handle_drag_icon_destroy(struct wl_listener *listener, void *data) { + struct roots_drag_icon *drag_icon = + wl_container_of(listener, drag_icon, surface_destroy); + wl_list_remove(&drag_icon->link); + wl_list_remove(&drag_icon->surface_destroy.link); + wl_list_remove(&drag_icon->surface_commit.link); + free(drag_icon); +} + +void roots_cursor_handle_pointer_grab_begin(struct roots_cursor *cursor, + struct wlr_seat_pointer_grab *grab) { + struct roots_seat *seat = cursor->seat; + if (grab->interface == &wlr_data_device_pointer_drag_interface) { + struct wlr_drag *drag = grab->data; + if (drag->icon) { + struct roots_drag_icon *iter_icon; + wl_list_for_each(iter_icon, &seat->drag_icons, link) { + if (iter_icon->surface == drag->icon) { + // already in the list + return; + } + } + + struct roots_drag_icon *drag_icon = + calloc(1, sizeof(struct roots_drag_icon)); + drag_icon->mapped = true; + drag_icon->surface = drag->icon; + wl_list_insert(&seat->drag_icons, &drag_icon->link); + + wl_signal_add(&drag->icon->events.destroy, + &drag_icon->surface_destroy); + drag_icon->surface_destroy.notify = handle_drag_icon_destroy; + + wl_signal_add(&drag->icon->events.commit, + &drag_icon->surface_commit); + drag_icon->surface_commit.notify = handle_drag_icon_commit; + } + } +} + +void roots_cursor_handle_pointer_grab_end(struct roots_cursor *cursor, + struct wlr_seat_pointer_grab *grab) { + if (grab->interface == &wlr_data_device_pointer_drag_interface) { + struct wlr_drag *drag = grab->data; + struct roots_drag_icon *icon; + wl_list_for_each(icon, &cursor->seat->drag_icons, link) { + if (icon->surface == drag->icon) { + icon->mapped = false; + } + } + } + + roots_cursor_update_position(cursor, 0); +} diff --git a/rootston/seat.c b/rootston/seat.c index 12f12a69..ce8ad10b 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -97,6 +97,22 @@ static void handle_request_set_cursor(struct wl_listener *listener, roots_cursor_handle_request_set_cursor(cursor, event); } +static void handle_pointer_grab_begin(struct wl_listener *listener, + void *data) { + struct roots_cursor *cursor = + wl_container_of(listener, cursor, pointer_grab_begin); + struct wlr_seat_pointer_grab *grab = data; + roots_cursor_handle_pointer_grab_begin(cursor, grab); +} + +static void handle_pointer_grab_end(struct wl_listener *listener, + void *data) { + struct roots_cursor *cursor = + wl_container_of(listener, cursor, pointer_grab_end); + struct wlr_seat_pointer_grab *grab = data; + roots_cursor_handle_pointer_grab_end(cursor, grab); +} + static void seat_reset_device_mappings(struct roots_seat *seat, struct wlr_input_device *device) { struct wlr_cursor *cursor = seat->cursor->cursor; struct roots_config *config = seat->input->config; @@ -236,6 +252,14 @@ static void roots_seat_init_cursor(struct roots_seat *seat) { wl_signal_add(&seat->seat->events.request_set_cursor, &seat->cursor->request_set_cursor); seat->cursor->request_set_cursor.notify = handle_request_set_cursor; + + wl_signal_add(&seat->seat->events.pointer_grab_begin, + &seat->cursor->pointer_grab_begin); + seat->cursor->pointer_grab_begin.notify = handle_pointer_grab_begin; + + wl_signal_add(&seat->seat->events.pointer_grab_end, + &seat->cursor->pointer_grab_end); + seat->cursor->pointer_grab_end.notify = handle_pointer_grab_end; } struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { -- cgit v1.2.3 From 2118c691b13c20d7100abfa02f9e274667501aef Mon Sep 17 00:00:00 2001 From: emersion Date: Wed, 8 Nov 2017 23:03:07 +0100 Subject: Add maximize support for xwayland in rootston --- include/rootston/view.h | 1 + rootston/xwayland.c | 31 +++++++++++++++++++++++++------ 2 files changed, 26 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/rootston/view.h b/include/rootston/view.h index 67643b94..f6ac0d23 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -36,6 +36,7 @@ struct roots_xwayland_surface { struct wl_listener request_configure; struct wl_listener request_move; struct wl_listener request_resize; + struct wl_listener request_maximize; struct wl_listener map_notify; struct wl_listener unmap_notify; }; diff --git a/rootston/xwayland.c b/rootston/xwayland.c index e3fc1c84..431586ba 100644 --- a/rootston/xwayland.c +++ b/rootston/xwayland.c @@ -85,6 +85,13 @@ static void close(struct roots_view *view) { wlr_xwayland_surface_close(view->desktop->xwayland, view->xwayland_surface); } +static void maximize(struct roots_view *view, bool maximized) { + assert(view->type == ROOTS_XWAYLAND_VIEW); + + wlr_xwayland_surface_set_maximized(view->desktop->xwayland, + view->xwayland_surface, maximized); +} + static void handle_destroy(struct wl_listener *listener, void *data) { struct roots_xwayland_surface *roots_surface = wl_container_of(listener, roots_surface, destroy); @@ -161,6 +168,17 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { view_begin_resize(input, cursor, view, e->edges); } +static void handle_request_maximize(struct wl_listener *listener, void *data) { + struct roots_xwayland_surface *roots_surface = + wl_container_of(listener, roots_surface, request_resize); + struct roots_view *view = roots_surface->view; + struct wlr_xwayland_surface *xwayland_surface = view->xwayland_surface; + + bool maximized = xwayland_surface->maximized_vert && + xwayland_surface->maximized_horz; + view_maximize(view, maximized); +} + static void handle_map_notify(struct wl_listener *listener, void *data) { struct roots_xwayland_surface *roots_surface = wl_container_of(listener, roots_surface, map_notify); @@ -202,24 +220,24 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { if (roots_surface == NULL) { return; } + roots_surface->destroy.notify = handle_destroy; wl_signal_add(&surface->events.destroy, &roots_surface->destroy); - roots_surface->request_configure.notify = handle_request_configure; wl_signal_add(&surface->events.request_configure, &roots_surface->request_configure); - roots_surface->map_notify.notify = handle_map_notify; wl_signal_add(&surface->events.map_notify, &roots_surface->map_notify); - roots_surface->unmap_notify.notify = handle_unmap_notify; wl_signal_add(&surface->events.unmap_notify, &roots_surface->unmap_notify); - roots_surface->request_move.notify = handle_request_move; wl_signal_add(&surface->events.request_move, &roots_surface->request_move); - roots_surface->request_resize.notify = handle_request_resize; - wl_signal_add(&surface->events.request_resize, &roots_surface->request_resize); + wl_signal_add(&surface->events.request_resize, + &roots_surface->request_resize); + roots_surface->request_maximize.notify = handle_request_maximize; + wl_signal_add(&surface->events.request_maximize, + &roots_surface->request_maximize); struct roots_view *view = calloc(1, sizeof(struct roots_view)); if (view == NULL) { @@ -237,6 +255,7 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { view->resize = resize; view->move = move; view->move_resize = move_resize; + view->maximize = maximize; view->close = close; roots_surface->view = view; wlr_list_add(desktop->views, view); -- cgit v1.2.3 From 26dadacb7199d28af672cca3f91713e173a41258 Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 9 Nov 2017 20:06:05 +0100 Subject: Add wl_shell support for maximized views --- include/rootston/view.h | 3 ++- include/wlr/types/wlr_wl_shell.h | 2 ++ rootston/wl_shell.c | 28 ++++++++++++++++++++++++++++ types/wlr_wl_shell.c | 11 ++++------- xwayland/xwm.c | 2 -- 5 files changed, 36 insertions(+), 10 deletions(-) (limited to 'include') diff --git a/include/rootston/view.h b/include/rootston/view.h index f6ac0d23..1b0fb831 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -11,9 +11,10 @@ struct roots_wl_shell_surface { // TODO: Maybe destroy listener should go in roots_view struct wl_listener destroy; - struct wl_listener ping_timeout; struct wl_listener request_move; struct wl_listener request_resize; + struct wl_listener request_set_maximized; + struct wl_listener set_state; struct wl_listener surface_commit; }; diff --git a/include/wlr/types/wlr_wl_shell.h b/include/wlr/types/wlr_wl_shell.h index 4e814817..1f0630f2 100644 --- a/include/wlr/types/wlr_wl_shell.h +++ b/include/wlr/types/wlr_wl_shell.h @@ -42,6 +42,8 @@ struct wlr_wl_shell_popup_grab { enum wlr_wl_shell_surface_state { WLR_WL_SHELL_SURFACE_STATE_NONE, WLR_WL_SHELL_SURFACE_STATE_TOPLEVEL, + WLR_WL_SHELL_SURFACE_STATE_MAXIMIZED, + WLR_WL_SHELL_SURFACE_STATE_FULLSCREEN, WLR_WL_SHELL_SURFACE_STATE_TRANSIENT, WLR_WL_SHELL_SURFACE_STATE_POPUP, }; diff --git a/rootston/wl_shell.c b/rootston/wl_shell.c index e38eb697..3ac8fe61 100644 --- a/rootston/wl_shell.c +++ b/rootston/wl_shell.c @@ -49,6 +49,26 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { view_begin_resize(input, event->cursor, view, e->edges); } +static void handle_request_set_maximized(struct wl_listener *listener, + void *data) { + struct roots_wl_shell_surface *roots_surface = + wl_container_of(listener, roots_surface, request_set_maximized); + struct roots_view *view = roots_surface->view; + //struct wlr_wl_shell_surface_set_maximized_event *e = data; + view_maximize(view, true); +} + +static void handle_set_state(struct wl_listener *listener, void *data) { + struct roots_wl_shell_surface *roots_surface = + wl_container_of(listener, roots_surface, set_state); + struct roots_view *view = roots_surface->view; + struct wlr_wl_shell_surface *surface = view->wl_shell_surface; + if (view->maximized && + surface->state != WLR_WL_SHELL_SURFACE_STATE_MAXIMIZED) { + view_maximize(view, false); + } +} + static void handle_surface_commit(struct wl_listener *listener, void *data) { // TODO do we need to do anything here? } @@ -60,6 +80,9 @@ static void handle_destroy(struct wl_listener *listener, void *data) { wl_list_remove(&roots_surface->destroy.link); wl_list_remove(&roots_surface->request_move.link); wl_list_remove(&roots_surface->request_resize.link); + wl_list_remove(&roots_surface->request_set_maximized.link); + wl_list_remove(&roots_surface->set_state.link); + wl_list_remove(&roots_surface->surface_commit.link); view_destroy(roots_surface->view); free(roots_surface); } @@ -93,6 +116,11 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) { roots_surface->request_resize.notify = handle_request_resize; wl_signal_add(&surface->events.request_resize, &roots_surface->request_resize); + roots_surface->request_set_maximized.notify = handle_request_set_maximized; + wl_signal_add(&surface->events.request_set_maximized, + &roots_surface->request_set_maximized); + roots_surface->set_state.notify = handle_set_state; + wl_signal_add(&surface->events.set_state, &roots_surface->set_state); roots_surface->surface_commit.notify = handle_surface_commit; wl_signal_add(&surface->surface->events.commit, &roots_surface->surface_commit); diff --git a/types/wlr_wl_shell.c b/types/wlr_wl_shell.c index fe61075e..f0287ba9 100644 --- a/types/wlr_wl_shell.c +++ b/types/wlr_wl_shell.c @@ -171,7 +171,6 @@ static void shell_surface_destroy_popup_state( } } - static void shell_surface_protocol_resize(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial, enum wl_shell_surface_resize edges) { @@ -287,9 +286,8 @@ static void shell_surface_protocol_set_fullscreen(struct wl_client *client, output = wl_resource_get_user_data(output_resource); } - if (surface->state == WLR_WL_SHELL_SURFACE_STATE_TOPLEVEL) { - return; - } + shell_surface_set_state(surface, WLR_WL_SHELL_SURFACE_STATE_FULLSCREEN, + NULL, NULL); struct wlr_wl_shell_surface_set_fullscreen_event *event = calloc(1, sizeof(struct wlr_wl_shell_surface_set_fullscreen_event)); @@ -377,9 +375,8 @@ static void shell_surface_protocol_set_maximized(struct wl_client *client, output = wl_resource_get_user_data(output_resource); } - if (surface->state == WLR_WL_SHELL_SURFACE_STATE_TOPLEVEL) { - return; - } + shell_surface_set_state(surface, WLR_WL_SHELL_SURFACE_STATE_MAXIMIZED, + NULL, NULL); struct wlr_wl_shell_surface_set_maximized_event *event = calloc(1, sizeof(struct wlr_wl_shell_surface_set_maximized_event)); diff --git a/xwayland/xwm.c b/xwayland/xwm.c index e5806d5b..dff9fac2 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -839,11 +839,9 @@ static void xwm_handle_net_wm_state_message(struct wlr_xwm *xwm, xsurface_set_net_wm_state(xsurface); } else if (property == xwm->atoms[_NET_WM_STATE_MAXIMIZED_VERT] && update_state(action, &xsurface->maximized_vert)) { - wlr_log(L_DEBUG, "cc sava"); xsurface_set_net_wm_state(xsurface); } else if (property == xwm->atoms[_NET_WM_STATE_MAXIMIZED_HORZ] && update_state(action, &xsurface->maximized_horz)) { - wlr_log(L_DEBUG, "mwa sava"); xsurface_set_net_wm_state(xsurface); } } -- cgit v1.2.3 From bf1b12a72500fb8cb41cbc60d29e602c25c97fc2 Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 9 Nov 2017 21:41:11 +0100 Subject: Fix maximize delay in xdg-shell --- include/rootston/view.h | 1 + include/wlr/types/wlr_xdg_shell_v6.h | 2 ++ rootston/xdg_shell_v6.c | 19 ++++++++++++++----- types/wlr_xdg_shell_v6.c | 6 ++++++ 4 files changed, 23 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/rootston/view.h b/include/rootston/view.h index 1b0fb831..956ba1d3 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -27,6 +27,7 @@ struct roots_xdg_surface_v6 { struct wl_listener destroy; struct wl_listener request_move; struct wl_listener request_resize; + struct wl_listener request_maximize; }; struct roots_xwayland_surface { diff --git a/include/wlr/types/wlr_xdg_shell_v6.h b/include/wlr/types/wlr_xdg_shell_v6.h index b0de41e2..bc78428b 100644 --- a/include/wlr/types/wlr_xdg_shell_v6.h +++ b/include/wlr/types/wlr_xdg_shell_v6.h @@ -126,6 +126,8 @@ struct wlr_xdg_surface_v6 { struct wl_signal ack_configure; struct wl_signal ping_timeout; + struct wl_signal request_maximize; + struct wl_signal request_fullscreen; struct wl_signal request_minimize; struct wl_signal request_move; struct wl_signal request_resize; diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 45691d16..a86899be 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -128,9 +128,9 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { view_begin_resize(input, event->cursor, view, e->edges); } -static void handle_commit(struct wl_listener *listener, void *data) { +static void handle_request_maximize(struct wl_listener *listener, void *data) { struct roots_xdg_surface_v6 *roots_xdg_surface = - wl_container_of(listener, roots_xdg_surface, commit); + wl_container_of(listener, roots_xdg_surface, request_maximize); struct roots_view *view = roots_xdg_surface->view; struct wlr_xdg_surface_v6 *surface = view->xdg_surface_v6; @@ -138,9 +138,15 @@ static void handle_commit(struct wl_listener *listener, void *data) { return; } - if (view->maximized != surface->toplevel_state->current.maximized) { - view_maximize(view, surface->toplevel_state->current.maximized); - } + view_maximize(view, surface->toplevel_state->next.maximized); +} + +static void handle_commit(struct wl_listener *listener, void *data) { + //struct roots_xdg_surface_v6 *roots_xdg_surface = + // wl_container_of(listener, roots_xdg_surface, commit); + //struct roots_view *view = roots_xdg_surface->view; + //struct wlr_xdg_surface_v6 *surface = view->xdg_surface_v6; + // TODO } static void handle_destroy(struct wl_listener *listener, void *data) { @@ -185,6 +191,9 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { roots_surface->request_resize.notify = handle_request_resize; wl_signal_add(&surface->events.request_resize, &roots_surface->request_resize); + roots_surface->request_maximize.notify = handle_request_maximize; + wl_signal_add(&surface->events.request_maximize, + &roots_surface->request_maximize); struct roots_view *view = calloc(1, sizeof(struct roots_view)); if (!view) { diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index fc45bc17..c260fd5e 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -667,24 +667,28 @@ static void xdg_toplevel_protocol_set_maximized(struct wl_client *client, struct wl_resource *resource) { struct wlr_xdg_surface_v6 *surface = wl_resource_get_user_data(resource); surface->toplevel_state->next.maximized = true; + wl_signal_emit(&surface->events.request_maximize, surface); } static void xdg_toplevel_protocol_unset_maximized(struct wl_client *client, struct wl_resource *resource) { struct wlr_xdg_surface_v6 *surface = wl_resource_get_user_data(resource); surface->toplevel_state->next.maximized = false; + wl_signal_emit(&surface->events.request_maximize, surface); } static void xdg_toplevel_protocol_set_fullscreen(struct wl_client *client, struct wl_resource *resource, struct wl_resource *output_resource) { struct wlr_xdg_surface_v6 *surface = wl_resource_get_user_data(resource); surface->toplevel_state->next.fullscreen = true; + wl_signal_emit(&surface->events.request_fullscreen, surface); } static void xdg_toplevel_protocol_unset_fullscreen(struct wl_client *client, struct wl_resource *resource) { struct wlr_xdg_surface_v6 *surface = wl_resource_get_user_data(resource); surface->toplevel_state->next.fullscreen = false; + wl_signal_emit(&surface->events.request_fullscreen, surface); } static void xdg_toplevel_protocol_set_minimized(struct wl_client *client, @@ -1146,6 +1150,8 @@ static void xdg_shell_get_xdg_surface(struct wl_client *wl_client, wl_list_init(&surface->configure_list); wl_list_init(&surface->popups); + wl_signal_init(&surface->events.request_maximize); + wl_signal_init(&surface->events.request_fullscreen); wl_signal_init(&surface->events.request_minimize); wl_signal_init(&surface->events.request_move); wl_signal_init(&surface->events.request_resize); -- cgit v1.2.3 From 739361aa70d61cbc9e062d6a90df09f258a1bbcb Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Thu, 9 Nov 2017 17:29:28 -0500 Subject: wlr-keyboard: take out modifiers event struct (for now) --- backend/libinput/keyboard.c | 1 - backend/wayland/wl_seat.c | 12 ++---------- backend/x11/backend.c | 1 - include/rootston/keyboard.h | 3 +-- include/wlr/interfaces/wlr_keyboard.h | 3 ++- include/wlr/types/wlr_keyboard.h | 11 ----------- rootston/keyboard.c | 3 +-- rootston/seat.c | 3 +-- types/wlr_keyboard.c | 11 ++++++----- 9 files changed, 13 insertions(+), 35 deletions(-) (limited to 'include') diff --git a/backend/libinput/keyboard.c b/backend/libinput/keyboard.c index 9a24c791..065d8ead 100644 --- a/backend/libinput/keyboard.c +++ b/backend/libinput/keyboard.c @@ -54,7 +54,6 @@ void handle_keyboard_key(struct libinput_event *event, struct libinput_event_keyboard *kbevent = libinput_event_get_keyboard_event(event); struct wlr_event_keyboard_key wlr_event = { 0 }; - wlr_event.device = wlr_dev; wlr_event.time_msec = usec_to_msec(libinput_event_keyboard_get_time_usec(kbevent)); wlr_event.keycode = libinput_event_keyboard_get_key(kbevent); diff --git a/backend/wayland/wl_seat.c b/backend/wayland/wl_seat.c index 74eaf9bd..a2da8df5 100644 --- a/backend/wayland/wl_seat.c +++ b/backend/wayland/wl_seat.c @@ -151,7 +151,6 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard, assert(dev && dev->keyboard); struct wlr_event_keyboard_key wlr_event; - wlr_event.device = dev; wlr_event.keycode = key; wlr_event.state = state; wlr_event.time_msec = time; @@ -163,15 +162,8 @@ static void keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboar uint32_t mods_locked, uint32_t group) { struct wlr_input_device *dev = data; assert(dev && dev->keyboard); - struct wlr_event_keyboard_modifiers wlr_event; - wlr_event.device = dev; - wlr_event.keyboard = dev->keyboard; - wlr_event.mods_depressed = mods_depressed; - wlr_event.mods_latched = mods_latched; - wlr_event.mods_locked = mods_locked; - wlr_event.group = group; - - wlr_keyboard_notify_modifiers(dev->keyboard, &wlr_event); + wlr_keyboard_notify_modifiers(dev->keyboard, mods_depressed, mods_latched, + mods_locked, group); } static void keyboard_handle_repeat_info(void *data, struct wl_keyboard *wl_keyboard, diff --git a/backend/x11/backend.c b/backend/x11/backend.c index f76b314e..97b0dd8c 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -50,7 +50,6 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e case XCB_KEY_RELEASE: { xcb_key_press_event_t *ev = (xcb_key_press_event_t *)event; struct wlr_event_keyboard_key key = { - .device = &x11->keyboard_dev, .time_msec = ev->time, .keycode = ev->detail - 8, .state = event->response_type == XCB_KEY_PRESS ? diff --git a/include/rootston/keyboard.h b/include/rootston/keyboard.h index 4dd70a65..51977f08 100644 --- a/include/rootston/keyboard.h +++ b/include/rootston/keyboard.h @@ -27,7 +27,6 @@ void roots_keyboard_destroy(struct roots_keyboard *keyboard); void roots_keyboard_handle_key(struct roots_keyboard *keyboard, struct wlr_event_keyboard_key *event); -void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard, - struct wlr_event_keyboard_modifiers *event); +void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard); #endif diff --git a/include/wlr/interfaces/wlr_keyboard.h b/include/wlr/interfaces/wlr_keyboard.h index 5848416d..570f5721 100644 --- a/include/wlr/interfaces/wlr_keyboard.h +++ b/include/wlr/interfaces/wlr_keyboard.h @@ -14,6 +14,7 @@ void wlr_keyboard_destroy(struct wlr_keyboard *keyboard); void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard, struct wlr_event_keyboard_key *event); void wlr_keyboard_notify_modifiers(struct wlr_keyboard *keyboard, - struct wlr_event_keyboard_modifiers *event); + uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, + uint32_t group); #endif diff --git a/include/wlr/types/wlr_keyboard.h b/include/wlr/types/wlr_keyboard.h index 4bd5b9b6..e2d50b03 100644 --- a/include/wlr/types/wlr_keyboard.h +++ b/include/wlr/types/wlr_keyboard.h @@ -66,23 +66,12 @@ enum wlr_key_state { }; struct wlr_event_keyboard_key { - struct wlr_input_device *device; - struct wlr_keyboard *keyboard; uint32_t time_msec; uint32_t keycode; bool update_state; enum wlr_key_state state; }; -struct wlr_event_keyboard_modifiers { - struct wlr_input_device *device; - struct wlr_keyboard *keyboard; - uint32_t mods_depressed; - uint32_t mods_latched; - uint32_t mods_locked; - uint32_t group; -}; - void wlr_keyboard_set_keymap(struct wlr_keyboard *kb, struct xkb_keymap *keymap); void wlr_keyboard_led_update(struct wlr_keyboard *keyboard, uint32_t leds); diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 9692ea7d..da75b44f 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -204,8 +204,7 @@ void roots_keyboard_handle_key(struct roots_keyboard *keyboard, } } -void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard, - struct wlr_event_keyboard_modifiers *event) { +void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard) { struct wlr_seat *seat = r_keyboard->seat->seat; wlr_seat_set_keyboard(seat, r_keyboard->device); wlr_seat_keyboard_notify_modifiers(seat); diff --git a/rootston/seat.c b/rootston/seat.c index ce8ad10b..97d5c7e4 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -22,8 +22,7 @@ static void handle_keyboard_modifiers(struct wl_listener *listener, void *data) { struct roots_keyboard *keyboard = wl_container_of(listener, keyboard, keyboard_modifiers); - struct wlr_event_keyboard_modifiers *event = data; - roots_keyboard_handle_modifiers(keyboard, event); + roots_keyboard_handle_modifiers(keyboard); } static void handle_cursor_motion(struct wl_listener *listener, void *data) { diff --git a/types/wlr_keyboard.c b/types/wlr_keyboard.c index a301c6e0..98ebeed5 100644 --- a/types/wlr_keyboard.c +++ b/types/wlr_keyboard.c @@ -41,6 +41,8 @@ static void keyboard_modifier_update(struct wlr_keyboard *keyboard) { keyboard->modifiers.latched = latched; keyboard->modifiers.locked = locked; keyboard->modifiers.group = group; + + wl_signal_emit(&keyboard->events.modifiers, keyboard); } static void keyboard_key_update(struct wlr_keyboard *keyboard, @@ -68,15 +70,14 @@ static void keyboard_key_update(struct wlr_keyboard *keyboard, } void wlr_keyboard_notify_modifiers(struct wlr_keyboard *keyboard, - struct wlr_event_keyboard_modifiers *event) { + uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, + uint32_t group) { if (!keyboard->xkb_state) { return; } - xkb_state_update_mask(keyboard->xkb_state, event->mods_depressed, - event->mods_latched, event->mods_locked, 0, 0, event->group); + xkb_state_update_mask(keyboard->xkb_state, mods_depressed, mods_latched, + mods_locked, 0, 0, group); keyboard_modifier_update(keyboard); - - wl_signal_emit(&keyboard->events.modifiers, event); } void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard, -- cgit v1.2.3 From 80bf3cfff05d3ddabf75b2e53ed040aff0bbae62 Mon Sep 17 00:00:00 2001 From: Timidger Date: Thu, 9 Nov 2017 18:38:13 -0800 Subject: Fixes #399 Adds wlr_data_device_manager destructor Fixed issues --- include/wlr/types/wlr_data_device.h | 5 +++++ types/wlr_data_device.c | 8 ++++++++ 2 files changed, 13 insertions(+) (limited to 'include') diff --git a/include/wlr/types/wlr_data_device.h b/include/wlr/types/wlr_data_device.h index 691e2df8..f45c15a2 100644 --- a/include/wlr/types/wlr_data_device.h +++ b/include/wlr/types/wlr_data_device.h @@ -74,6 +74,11 @@ struct wlr_drag { struct wlr_data_device_manager *wlr_data_device_manager_create( struct wl_display *display); +/** + * Destroys a wlr_data_device_manager and removes its wl_data_device_manager global. + */ +void wlr_data_device_manager_destroy(struct wlr_data_device_manager *manager); + /** * Creates a new wl_data_offer if there is a wl_data_source currently set as * the seat selection and sends it to the seat client, followed by the diff --git a/types/wlr_data_device.c b/types/wlr_data_device.c index ea28ef50..df18317b 100644 --- a/types/wlr_data_device.c +++ b/types/wlr_data_device.c @@ -815,3 +815,11 @@ struct wlr_data_device_manager *wlr_data_device_manager_create( return manager; } + +void wlr_data_device_manager_destroy(struct wlr_data_device_manager *manager) { + if (!manager) { + return; + } + wl_global_destroy(manager->global); + free(manager); +} -- cgit v1.2.3 From 27a3a810ab372ca699bb9da1ce506816432b39f6 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Fri, 10 Nov 2017 08:27:45 -0500 Subject: rootston: fix multiseat focus --- include/rootston/input.h | 2 ++ rootston/input.c | 14 ++++++++++++++ rootston/seat.c | 35 ++++++++++------------------------- 3 files changed, 26 insertions(+), 25 deletions(-) (limited to 'include') diff --git a/include/rootston/input.h b/include/rootston/input.h index ea0bbeb6..0af48577 100644 --- a/include/rootston/input.h +++ b/include/rootston/input.h @@ -26,4 +26,6 @@ void input_destroy(struct roots_input *input); struct roots_seat *input_seat_from_wlr_seat(struct roots_input *input, struct wlr_seat *seat); +bool input_view_has_focus(struct roots_input *input, struct roots_view *view); + #endif diff --git a/rootston/input.c b/rootston/input.c index 92148b65..e96565e0 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -108,3 +108,17 @@ struct roots_seat *input_seat_from_wlr_seat(struct roots_input *input, } return seat; } + +bool input_view_has_focus(struct roots_input *input, struct roots_view *view) { + if (!view) { + return false; + } + struct roots_seat *seat; + wl_list_for_each(seat, &input->seats, link) { + if (seat->focus == view) { + return true; + } + } + + return false; +} diff --git a/rootston/seat.c b/rootston/seat.c index 72e94aec..3dcd7f2f 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -503,36 +503,21 @@ void roots_seat_focus_view(struct roots_seat *seat, struct roots_view *view) { return; } - // unfocus the old view if it is not focused by some other seat - // TODO probably should be an input function - if (seat->focus) { - bool has_other_focus = false; - struct roots_seat *iter_seat; - wl_list_for_each(iter_seat, &seat->input->seats, link) { - if (iter_seat == seat) { - continue; - } - if (iter_seat->focus == seat->focus) { - has_other_focus = true; - break; - } - } - - if (!has_other_focus) { - view_activate(seat->focus, false); - } - } - - if (!view) { - seat->focus = NULL; - seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH; + if (view && view->type == ROOTS_XWAYLAND_VIEW && + view->xwayland_surface->override_redirect) { return; } + struct roots_view *prev_focus = seat->focus; seat->focus = view; - if (view->type == ROOTS_XWAYLAND_VIEW && - view->xwayland_surface->override_redirect) { + // unfocus the old view if it is not focused by some other seat + if (prev_focus && !input_view_has_focus(seat->input, prev_focus)) { + view_activate(prev_focus, false); + } + + if (!seat->focus) { + seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH; return; } -- cgit v1.2.3 From 5be11a5c95457c6d4f6cd9720162f962286c2258 Mon Sep 17 00:00:00 2001 From: Eric Molitor Date: Fri, 10 Nov 2017 15:12:00 +0000 Subject: Remove VLA from session.h VLAs are optional C11 features and not supported by C++. --- backend/session/session.c | 2 +- include/wlr/backend/session.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/backend/session/session.c b/backend/session/session.c index b14ca4d0..760830c3 100644 --- a/backend/session/session.c +++ b/backend/session/session.c @@ -257,7 +257,7 @@ static size_t explicit_find_gpus(struct wlr_session *session, * If it's not found, it returns the first valid GPU it finds. */ size_t wlr_session_find_gpus(struct wlr_session *session, - size_t ret_len, int ret[static ret_len]) { + size_t ret_len, int *ret) { const char *explicit = getenv("WLR_DRM_DEVICES"); if (explicit) { return explicit_find_gpus(session, ret_len, ret, explicit); diff --git a/include/wlr/backend/session.h b/include/wlr/backend/session.h index 94002bc5..5c822ea9 100644 --- a/include/wlr/backend/session.h +++ b/include/wlr/backend/session.h @@ -79,6 +79,6 @@ void wlr_session_signal_add(struct wlr_session *session, int fd, bool wlr_session_change_vt(struct wlr_session *session, unsigned vt); size_t wlr_session_find_gpus(struct wlr_session *session, - size_t ret_len, int ret[static ret_len]); + size_t ret_len, int *ret); #endif -- cgit v1.2.3 From eb89f1dcd2dd820bc86ae0350774aff4d81408e8 Mon Sep 17 00:00:00 2001 From: emersion Date: Sat, 11 Nov 2017 15:39:15 +0100 Subject: Fix resize issues with some xdg-shell apps. Also renames view_get_size to view_get_box to be more consistent with wlroots API and make it more obvious that x,y are set (while in roots_view.get_size this isn't the case). Fixes #407 --- include/rootston/view.h | 2 +- rootston/cursor.c | 8 ++++---- rootston/desktop.c | 18 +++++++++--------- rootston/xdg_shell_v6.c | 10 ++++++++-- 4 files changed, 22 insertions(+), 16 deletions(-) (limited to 'include') diff --git a/include/rootston/view.h b/include/rootston/view.h index f0d102cd..99b4ed78 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -94,7 +94,7 @@ struct roots_view { void (*close)(struct roots_view *view); }; -void view_get_size(const struct roots_view *view, struct wlr_box *box); +void view_get_box(const struct roots_view *view, struct wlr_box *box); void view_activate(struct roots_view *view, bool active); void view_move(struct roots_view *view, double x, double y); void view_resize(struct roots_view *view, uint32_t width, uint32_t height); diff --git a/rootston/cursor.c b/rootston/cursor.c index cbd03af1..81841b6c 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -72,10 +72,10 @@ void view_begin_resize(struct roots_input *input, struct wlr_cursor *cursor, } else { input->view_x = view->x; input->view_y = view->y; - struct wlr_box size; - view_get_size(view, &size); - input->view_width = size.width; - input->view_height = size.height; + struct wlr_box box; + view_get_box(view, &box); + input->view_width = box.width; + input->view_height = box.height; } input->resize_edges = edges; diff --git a/rootston/desktop.c b/rootston/desktop.c index 469a503b..0f5f5fdd 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -35,15 +35,15 @@ void view_destroy(struct roots_view *view) { free(view); } -void view_get_size(const struct roots_view *view, struct wlr_box *box) { +void view_get_box(const struct roots_view *view, struct wlr_box *box) { + box->x = view->x; + box->y = view->y; if (view->get_size) { view->get_size(view, box); } else { box->width = view->wlr_surface->current->width; box->height = view->wlr_surface->current->height; } - box->x = view->x; - box->y = view->y; } static void view_update_output(const struct roots_view *view, @@ -51,7 +51,7 @@ static void view_update_output(const struct roots_view *view, struct roots_desktop *desktop = view->desktop; struct roots_output *output; struct wlr_box box; - view_get_size(view, &box); + view_get_box(view, &box); wl_list_for_each(output, &desktop->outputs, link) { bool intersected = before->x != -1 && wlr_output_layout_intersects( desktop->layout, output->wlr_output, @@ -71,7 +71,7 @@ static void view_update_output(const struct roots_view *view, void view_move(struct roots_view *view, double x, double y) { struct wlr_box before; - view_get_size(view, &before); + view_get_box(view, &before); if (view->move) { view->move(view, x, y); } else { @@ -88,7 +88,7 @@ void view_activate(struct roots_view *view, bool activate) { void view_resize(struct roots_view *view, uint32_t width, uint32_t height) { struct wlr_box before; - view_get_size(view, &before); + view_get_box(view, &before); if (view->resize) { view->resize(view, width, height); } @@ -117,7 +117,7 @@ void view_maximize(struct roots_view *view, bool maximized) { if (!view->maximized && maximized) { struct wlr_box view_box; - view_get_size(view, &view_box); + view_get_box(view, &view_box); view->maximized = true; view->saved.x = view->x; @@ -158,7 +158,7 @@ void view_close(struct roots_view *view) { bool view_center(struct roots_view *view) { struct wlr_box box; - view_get_size(view, &box); + view_get_box(view, &box); struct roots_desktop *desktop = view->desktop; struct wlr_cursor *cursor = desktop->server->input->cursor; @@ -193,7 +193,7 @@ void view_setup(struct roots_view *view) { view_center(view); set_view_focus(input, view->desktop, view); struct wlr_box before; - view_get_size(view, &before); + view_get_box(view, &before); view_update_output(view, &before); } diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 2a0660a6..5e76e5d4 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -13,8 +13,14 @@ static void get_size(const struct roots_view *view, struct wlr_box *box) { assert(view->type == ROOTS_XDG_SHELL_V6_VIEW); struct wlr_xdg_surface_v6 *surf = view->xdg_surface_v6; - // TODO: surf->geometry can be NULL - memcpy(box, surf->geometry, sizeof(struct wlr_box)); + + if (surf->geometry->width > 0 && surf->geometry->height > 0) { + box->width = surf->geometry->width; + box->height = surf->geometry->height; + } else { + box->width = view->wlr_surface->current->width; + box->height = view->wlr_surface->current->height; + } } static void activate(struct roots_view *view, bool active) { -- cgit v1.2.3 From 6e00140e8a0326ce1d78c1c3efd8b0a373298af0 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sat, 11 Nov 2017 10:41:18 -0500 Subject: rootston: remove unused import and old todo from config header --- include/rootston/config.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include') diff --git a/include/rootston/config.h b/include/rootston/config.h index 872dc7b6..8ef58100 100644 --- a/include/rootston/config.h +++ b/include/rootston/config.h @@ -2,7 +2,6 @@ #define _ROOTSTON_CONFIG_H #include #include -#include struct output_config { char *name; @@ -45,7 +44,7 @@ struct keyboard_config { struct roots_config { bool xwayland; - // TODO: Multiple cursors, multiseat + struct { char *mapped_output; struct wlr_box *mapped_box; -- cgit v1.2.3 From 18079e234a9fb8ee3ee8686cf3e28d5920326a4a Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sat, 11 Nov 2017 10:44:29 -0500 Subject: rootston: documentation for config.h functions --- include/rootston/config.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include') diff --git a/include/rootston/config.h b/include/rootston/config.h index 8ef58100..d2a25b5b 100644 --- a/include/rootston/config.h +++ b/include/rootston/config.h @@ -58,8 +58,16 @@ struct roots_config { char *startup_cmd; }; +/** + * Create a roots config from the given command line arguments. Command line + * arguments can specify the location of the config file. If it is not + * specified, the default location will be used. + */ struct roots_config *parse_args(int argc, char *argv[]); +/** + * Destroy the config and free its resources. + */ void roots_config_destroy(struct roots_config *config); /** -- cgit v1.2.3 From 1db3b5512821b1d6f936897f598e0f4d12233e8e Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sat, 11 Nov 2017 10:59:04 -0500 Subject: rootston: prefix config structs and functions --- include/rootston/config.h | 18 +++++++++--------- include/rootston/keyboard.h | 2 +- rootston/config.c | 42 ++++++++++++++++++++++-------------------- rootston/input.c | 3 ++- rootston/keyboard.c | 15 ++++++++------- rootston/main.c | 2 +- rootston/output.c | 6 ++++-- rootston/seat.c | 8 ++++---- 8 files changed, 51 insertions(+), 45 deletions(-) (limited to 'include') diff --git a/include/rootston/config.h b/include/rootston/config.h index d2a25b5b..71ee61c7 100644 --- a/include/rootston/config.h +++ b/include/rootston/config.h @@ -3,7 +3,7 @@ #include #include -struct output_config { +struct roots_output_config { char *name; enum wl_output_transform transform; int x, y; @@ -15,7 +15,7 @@ struct output_config { } mode; }; -struct device_config { +struct roots_device_config { char *name; char *mapped_output; struct wlr_box *mapped_box; @@ -23,7 +23,7 @@ struct device_config { struct wl_list link; }; -struct binding_config { +struct roots_binding_config { uint32_t modifiers; xkb_keysym_t *keysyms; size_t keysyms_len; @@ -31,7 +31,7 @@ struct binding_config { struct wl_list link; }; -struct keyboard_config { +struct roots_keyboard_config { char *name; uint32_t meta_key; char *rules; @@ -63,7 +63,7 @@ struct roots_config { * arguments can specify the location of the config file. If it is not * specified, the default location will be used. */ -struct roots_config *parse_args(int argc, char *argv[]); +struct roots_config *roots_config_create_from_args(int argc, char *argv[]); /** * Destroy the config and free its resources. @@ -74,21 +74,21 @@ void roots_config_destroy(struct roots_config *config); * Get configuration for the output. If the output is not configured, returns * NULL. */ -struct output_config *config_get_output(struct roots_config *config, +struct roots_output_config *roots_config_get_output(struct roots_config *config, struct wlr_output *output); /** * Get configuration for the device. If the device is not configured, returns * NULL. */ -struct device_config *config_get_device(struct roots_config *config, +struct roots_device_config *roots_config_get_device(struct roots_config *config, struct wlr_input_device *device); /** * Get configuration for the keyboard. If the keyboard is not configured, * returns NULL. A NULL device returns the default config for keyboards. */ -struct keyboard_config *config_get_keyboard(struct roots_config *config, - struct wlr_input_device *device); +struct roots_keyboard_config *roots_config_get_keyboard( + struct roots_config *config, struct wlr_input_device *device); #endif diff --git a/include/rootston/keyboard.h b/include/rootston/keyboard.h index 51977f08..15e7c9c4 100644 --- a/include/rootston/keyboard.h +++ b/include/rootston/keyboard.h @@ -10,7 +10,7 @@ struct roots_keyboard { struct roots_input *input; struct roots_seat *seat; struct wlr_input_device *device; - struct keyboard_config *config; + struct roots_keyboard_config *config; struct wl_list link; struct wl_listener keyboard_key; diff --git a/rootston/config.c b/rootston/config.c index 73bb6eb0..9530ba37 100644 --- a/rootston/config.c +++ b/rootston/config.c @@ -115,7 +115,8 @@ static uint32_t parse_modifier(const char *symname) { void add_binding_config(struct wl_list *bindings, const char* combination, const char* command) { - struct binding_config *bc = calloc(1, sizeof(struct binding_config)); + struct roots_binding_config *bc = + calloc(1, sizeof(struct roots_binding_config)); xkb_keysym_t keysyms[ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP]; char *symnames = strdup(combination); @@ -151,7 +152,7 @@ void add_binding_config(struct wl_list *bindings, const char* combination, static void config_handle_keyboard(struct roots_config *config, const char *device_name, const char *name, const char *value) { - struct keyboard_config *kc; + struct roots_keyboard_config *kc; bool found = false; wl_list_for_each(kc, &config->keyboards, link) { if (strcmp(kc->name, device_name) == 0) { @@ -161,7 +162,7 @@ static void config_handle_keyboard(struct roots_config *config, } if (!found) { - kc = calloc(1, sizeof(struct keyboard_config)); + kc = calloc(1, sizeof(struct roots_keyboard_config)); kc->name = strdup(device_name); wl_list_insert(&config->keyboards, &kc->link); } @@ -207,7 +208,7 @@ static int config_ini_handler(void *user, const char *section, const char *name, } } else if (strncmp(output_prefix, section, strlen(output_prefix)) == 0) { const char *output_name = section + strlen(output_prefix); - struct output_config *oc; + struct roots_output_config *oc; bool found = false; wl_list_for_each(oc, &config->outputs, link) { @@ -218,7 +219,7 @@ static int config_ini_handler(void *user, const char *section, const char *name, } if (!found) { - oc = calloc(1, sizeof(struct output_config)); + oc = calloc(1, sizeof(struct roots_output_config)); oc->name = strdup(output_name); oc->transform = WL_OUTPUT_TRANSFORM_NORMAL; oc->scale = 1; @@ -281,7 +282,7 @@ static int config_ini_handler(void *user, const char *section, const char *name, } else if (strncmp(device_prefix, section, strlen(device_prefix)) == 0) { const char *device_name = section + strlen(device_prefix); - struct device_config *dc; + struct roots_device_config *dc; bool found = false; wl_list_for_each(dc, &config->devices, link) { if (strcmp(dc->name, device_name) == 0) { @@ -291,7 +292,7 @@ static int config_ini_handler(void *user, const char *section, const char *name, } if (!found) { - dc = calloc(1, sizeof(struct device_config)); + dc = calloc(1, sizeof(struct roots_device_config)); dc->name = strdup(device_name); dc->seat = strdup("seat0"); wl_list_insert(&config->devices, &dc->link); @@ -323,7 +324,7 @@ static int config_ini_handler(void *user, const char *section, const char *name, return 1; } -struct roots_config *parse_args(int argc, char *argv[]) { +struct roots_config *roots_config_create_from_args(int argc, char *argv[]) { struct roots_config *config = calloc(1, sizeof(struct roots_config)); if (config == NULL) { return NULL; @@ -370,7 +371,8 @@ struct roots_config *parse_args(int argc, char *argv[]) { add_binding_config(&config->bindings, "Logo+Shift+E", "exit"); add_binding_config(&config->bindings, "Ctrl+q", "close"); add_binding_config(&config->bindings, "Alt+Tab", "next_window"); - struct keyboard_config *kc = calloc(1, sizeof(struct keyboard_config)); + struct roots_keyboard_config *kc = + calloc(1, sizeof(struct roots_keyboard_config)); kc->meta_key = WLR_MODIFIER_LOGO; kc->name = strdup(""); wl_list_insert(&config->keyboards, &kc->link); @@ -386,13 +388,13 @@ struct roots_config *parse_args(int argc, char *argv[]) { } void roots_config_destroy(struct roots_config *config) { - struct output_config *oc, *otmp = NULL; + struct roots_output_config *oc, *otmp = NULL; wl_list_for_each_safe(oc, otmp, &config->outputs, link) { free(oc->name); free(oc); } - struct device_config *dc, *dtmp = NULL; + struct roots_device_config *dc, *dtmp = NULL; wl_list_for_each_safe(dc, dtmp, &config->devices, link) { free(dc->name); free(dc->seat); @@ -401,7 +403,7 @@ void roots_config_destroy(struct roots_config *config) { free(dc); } - struct keyboard_config *kc, *ktmp = NULL; + struct roots_keyboard_config *kc, *ktmp = NULL; wl_list_for_each_safe(kc, ktmp, &config->bindings, link) { free(kc->name); free(kc->rules); @@ -412,7 +414,7 @@ void roots_config_destroy(struct roots_config *config) { free(kc); } - struct binding_config *bc, *btmp = NULL; + struct roots_binding_config *bc, *btmp = NULL; wl_list_for_each_safe(bc, btmp, &config->bindings, link) { free(bc->keysyms); free(bc->command); @@ -425,9 +427,9 @@ void roots_config_destroy(struct roots_config *config) { free(config); } -struct output_config *config_get_output(struct roots_config *config, +struct roots_output_config *roots_config_get_output(struct roots_config *config, struct wlr_output *output) { - struct output_config *o_config; + struct roots_output_config *o_config; wl_list_for_each(o_config, &config->outputs, link) { if (strcmp(o_config->name, output->name) == 0) { return o_config; @@ -437,9 +439,9 @@ struct output_config *config_get_output(struct roots_config *config, return NULL; } -struct device_config *config_get_device(struct roots_config *config, +struct roots_device_config *roots_config_get_device(struct roots_config *config, struct wlr_input_device *device) { - struct device_config *d_config; + struct roots_device_config *d_config; wl_list_for_each(d_config, &config->devices, link) { if (strcmp(d_config->name, device->name) == 0) { return d_config; @@ -449,9 +451,9 @@ struct device_config *config_get_device(struct roots_config *config, return NULL; } -struct keyboard_config *config_get_keyboard(struct roots_config *config, - struct wlr_input_device *device) { - struct keyboard_config *kc; +struct roots_keyboard_config *roots_config_get_keyboard( + struct roots_config *config, struct wlr_input_device *device) { + struct roots_keyboard_config *kc; wl_list_for_each(kc, &config->keyboards, link) { if ((device != NULL && strcmp(kc->name, device->name) == 0) || (device == NULL && strcmp(kc->name, "") == 0)) { diff --git a/rootston/input.c b/rootston/input.c index e96565e0..35a5af97 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -44,7 +44,8 @@ static void input_add_notify(struct wl_listener *listener, void *data) { struct roots_input *input = wl_container_of(listener, input, input_add); char *seat_name = "seat0"; - struct device_config *dc = config_get_device(input->config, device); + struct roots_device_config *dc = + roots_config_get_device(input->config, device); if (dc) { seat_name = dc->seat; } diff --git a/rootston/keyboard.c b/rootston/keyboard.c index bb748550..c118e55c 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -92,7 +92,7 @@ static bool keyboard_keysym_press(struct roots_keyboard *keyboard, uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); struct wl_list *bindings = &keyboard->input->server->config->bindings; - struct binding_config *bc; + struct roots_binding_config *bc; wl_list_for_each(bc, bindings, link) { if (modifiers ^ bc->modifiers) { continue; @@ -210,8 +210,8 @@ void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard) { wlr_seat_keyboard_notify_modifiers(seat); } -static void keyboard_config_merge(struct keyboard_config *config, - struct keyboard_config *fallback) { +static void keyboard_config_merge(struct roots_keyboard_config *config, + struct roots_keyboard_config *fallback) { if (fallback == NULL) { return; } @@ -248,15 +248,16 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, keyboard->device = device; keyboard->input = input; - struct keyboard_config *config = calloc(1, sizeof(struct keyboard_config)); + struct roots_keyboard_config *config = + calloc(1, sizeof(struct roots_keyboard_config)); if (config == NULL) { free(keyboard); return NULL; } - keyboard_config_merge(config, config_get_keyboard(input->config, device)); - keyboard_config_merge(config, config_get_keyboard(input->config, NULL)); + keyboard_config_merge(config, roots_config_get_keyboard(input->config, device)); + keyboard_config_merge(config, roots_config_get_keyboard(input->config, NULL)); - struct keyboard_config env_config = { + struct roots_keyboard_config env_config = { .rules = getenv("XKB_DEFAULT_RULES"), .model = getenv("XKB_DEFAULT_MODEL"), .layout = getenv("XKB_DEFAULT_LAYOUT"), diff --git a/rootston/main.c b/rootston/main.c index 2a054e6c..d55bc682 100644 --- a/rootston/main.c +++ b/rootston/main.c @@ -13,7 +13,7 @@ struct roots_server server = { 0 }; int main(int argc, char **argv) { - assert(server.config = parse_args(argc, argv)); + assert(server.config = roots_config_create_from_args(argc, argv)); assert(server.wl_display = wl_display_create()); assert(server.wl_event_loop = wl_display_get_event_loop(server.wl_display)); diff --git a/rootston/output.c b/rootston/output.c index f192cb48..d853c45f 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -181,7 +181,8 @@ static void output_frame_notify(struct wl_listener *listener, void *data) { output->last_frame = desktop->last_frame = now; } -static void set_mode(struct wlr_output *output, struct output_config *oc) { +static void set_mode(struct wlr_output *output, + struct roots_output_config *oc) { struct wlr_output_mode *mode, *best = NULL; int mhz = (int)(oc->mode.refresh_rate * 1000); wl_list_for_each(mode, &output->modes, link) { @@ -225,7 +226,8 @@ void output_add_notify(struct wl_listener *listener, void *data) { wl_signal_add(&wlr_output->events.frame, &output->frame); wl_list_insert(&desktop->outputs, &output->link); - struct output_config *output_config = config_get_output(config, wlr_output); + struct roots_output_config *output_config = + roots_config_get_output(config, wlr_output); if (output_config) { if (output_config->mode.width) { set_mode(wlr_output, output_config); diff --git a/rootston/seat.c b/rootston/seat.c index 3530fb75..4602aad5 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -117,8 +117,8 @@ static void seat_reset_device_mappings(struct roots_seat *seat, struct wlr_input struct roots_config *config = seat->input->config; wlr_cursor_map_input_to_output(cursor, device, NULL); - struct device_config *dconfig; - if ((dconfig = config_get_device(config, device))) { + struct roots_device_config *dconfig; + if ((dconfig = roots_config_get_device(config, device))) { wlr_cursor_map_input_to_region(cursor, device, dconfig->mapped_box); } } @@ -127,8 +127,8 @@ static void seat_set_device_output_mappings(struct roots_seat *seat, struct wlr_input_device *device, struct wlr_output *output) { struct wlr_cursor *cursor = seat->cursor->cursor; struct roots_config *config = seat->input->config; - struct device_config *dconfig; - dconfig = config_get_device(config, device); + struct roots_device_config *dconfig; + dconfig = roots_config_get_device(config, device); if (dconfig && dconfig->mapped_output && strcmp(dconfig->mapped_output, output->name) == 0) { wlr_cursor_map_input_to_output(cursor, device, output); -- cgit v1.2.3 From ac1573b0e7b0b08413e115bb88682ebedbfbf39a Mon Sep 17 00:00:00 2001 From: emersion Date: Sat, 11 Nov 2017 17:27:44 +0100 Subject: Add scale parameter to wlr_cursor_set_image --- examples/multi-pointer.c | 4 ++-- examples/pointer.c | 4 ++-- include/wlr/types/wlr_cursor.h | 15 ++++++++++++++- rootston/cursor.c | 2 +- rootston/seat.c | 21 ++++++++++----------- types/wlr_cursor.c | 7 ++++++- 6 files changed, 35 insertions(+), 18 deletions(-) (limited to 'include') diff --git a/examples/multi-pointer.c b/examples/multi-pointer.c index e29a69db..f1bcebc7 100644 --- a/examples/multi-pointer.c +++ b/examples/multi-pointer.c @@ -86,7 +86,7 @@ static void handle_output_add(struct output_state *ostate) { struct wlr_xcursor_image *image = sample->xcursor->images[0]; wlr_cursor_set_image(cursor->cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y); + image->width, image->height, image->hotspot_x, image->hotspot_y, 0); wlr_cursor_warp(cursor->cursor, NULL, cursor->cursor->x, cursor->cursor->y); @@ -150,7 +150,7 @@ static void handle_input_add(struct compositor_state *state, struct wlr_xcursor_image *image = sample->xcursor->images[0]; wlr_cursor_set_image(cursor->cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y); + image->width, image->height, image->hotspot_x, image->hotspot_y, 0); wl_list_insert(&sample->cursors, &cursor->link); } diff --git a/examples/pointer.c b/examples/pointer.c index 1bcd7349..476cc617 100644 --- a/examples/pointer.c +++ b/examples/pointer.c @@ -110,7 +110,7 @@ static void handle_output_add(struct output_state *ostate) { struct wlr_xcursor_image *image = sample->xcursor->images[0]; wlr_cursor_set_image(sample->cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y); + image->width, image->height, image->hotspot_x, image->hotspot_y, 0); wlr_cursor_warp(sample->cursor, NULL, sample->cursor->x, sample->cursor->y); } @@ -321,7 +321,7 @@ int main(int argc, char *argv[]) { struct wlr_xcursor_image *image = state.xcursor->images[0]; wlr_cursor_set_image(state.cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y); + image->width, image->height, image->hotspot_x, image->hotspot_y, 0); compositor_init(&compositor); if (!wlr_backend_start(compositor.backend)) { diff --git a/include/wlr/types/wlr_cursor.h b/include/wlr/types/wlr_cursor.h index 1aac2b94..3df74d28 100644 --- a/include/wlr/types/wlr_cursor.h +++ b/include/wlr/types/wlr_cursor.h @@ -60,9 +60,22 @@ void wlr_cursor_warp_absolute(struct wlr_cursor *cur, void wlr_cursor_move(struct wlr_cursor *cur, struct wlr_input_device *dev, double delta_x, double delta_y); +/** + * Set the cursor image. stride is given in bytes. If pixels is NULL, hides the + * cursor. + * + * 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, int32_t stride, uint32_t width, uint32_t height, int32_t hotspot_x, - int32_t hotspot_y); + int32_t hotspot_y, uint32_t scale); + +/** + * Set the cursor surface. The surface can be committed to update the cursor + * image. The surface position is substracted from the hotspot. A NULL surface + * commit hides the cursor. + */ void wlr_cursor_set_surface(struct wlr_cursor *cur, struct wlr_surface *surface, int32_t hotspot_x, int32_t hotspot_y); diff --git a/rootston/cursor.c b/rootston/cursor.c index cba9e782..c3982e0e 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -30,7 +30,7 @@ void roots_cursor_destroy(struct roots_cursor *cursor) { static void cursor_set_xcursor_image(struct roots_cursor *cursor, struct wlr_xcursor_image *image) { wlr_cursor_set_image(cursor->cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y); + image->width, image->height, image->hotspot_x, image->hotspot_y, 0); } static void roots_cursor_update_position(struct roots_cursor *cursor, uint32_t time) { diff --git a/rootston/seat.c b/rootston/seat.c index 4602aad5..280443ac 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -176,6 +176,12 @@ void roots_seat_configure_cursor(struct roots_seat *seat) { } } +static void seat_set_xcursor_image(struct roots_seat *seat, struct + wlr_xcursor_image *image) { + wlr_cursor_set_image(seat->cursor->cursor, image->buffer, image->width, + image->width, image->height, image->hotspot_x, image->hotspot_y, 0); +} + static void roots_seat_init_cursor(struct roots_seat *seat) { seat->cursor = roots_cursor_create(seat); if (!seat->cursor) { @@ -204,8 +210,7 @@ static void roots_seat_init_cursor(struct roots_seat *seat) { } struct wlr_xcursor_image *image = xcursor->images[0]; - wlr_cursor_set_image(seat->cursor->cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y); + seat_set_xcursor_image(seat, image); // XXX: xwayland will always have the theme of the last created seat if (seat->input->server->desktop->xwayland != NULL) { @@ -471,10 +476,10 @@ void roots_seat_remove_device(struct roots_seat *seat, } void roots_seat_configure_xcursor(struct roots_seat *seat) { - struct wlr_xcursor *xcursor = get_default_xcursor(seat->cursor->xcursor_theme); + struct wlr_xcursor *xcursor = + get_default_xcursor(seat->cursor->xcursor_theme); struct wlr_xcursor_image *image = xcursor->images[0]; - wlr_cursor_set_image(seat->cursor->cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y); + seat_set_xcursor_image(seat, image); wlr_cursor_warp(seat->cursor->cursor, NULL, seat->cursor->cursor->x, seat->cursor->cursor->y); @@ -537,12 +542,6 @@ void roots_seat_focus_view(struct roots_seat *seat, struct roots_view *view) { wlr_seat_keyboard_notify_enter(seat->seat, view->wlr_surface); } -static void seat_set_xcursor_image(struct roots_seat *seat, struct - wlr_xcursor_image *image) { - wlr_cursor_set_image(seat->cursor->cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y); -} - void roots_seat_begin_move(struct roots_seat *seat, struct roots_view *view) { struct roots_cursor *cursor = seat->cursor; cursor->mode = ROOTS_CURSOR_MOVE; diff --git a/types/wlr_cursor.c b/types/wlr_cursor.c index dfaccb53..e8965b68 100644 --- a/types/wlr_cursor.c +++ b/types/wlr_cursor.c @@ -299,9 +299,14 @@ void wlr_cursor_move(struct wlr_cursor *cur, struct wlr_input_device *dev, void wlr_cursor_set_image(struct wlr_cursor *cur, const uint8_t *pixels, int32_t stride, uint32_t width, uint32_t height, int32_t hotspot_x, - int32_t hotspot_y) { + int32_t hotspot_y, uint32_t scale) { struct wlr_cursor_output_cursor *output_cursor; wl_list_for_each(output_cursor, &cur->state->output_cursors, link) { + if (scale != 0 && + output_cursor->output_cursor->output->scale != scale) { + continue; + } + wlr_output_cursor_set_image(output_cursor->output_cursor, pixels, stride, width, height, hotspot_x, hotspot_y); } -- cgit v1.2.3 From aaf069188319f42bc214f4317c37d533aea64518 Mon Sep 17 00:00:00 2001 From: emersion Date: Sat, 11 Nov 2017 18:42:14 +0100 Subject: rootston: add roots_xcursor_theme roots_xcursor_theme loads multiple wlr_xcursor_theme at different scales. --- include/rootston/cursor.h | 1 - include/rootston/desktop.h | 2 + include/rootston/xcursor.h | 39 ++++++++++++++-- rootston/cursor.c | 10 +--- rootston/desktop.c | 14 ++++++ rootston/output.c | 6 +++ rootston/seat.c | 61 ++++-------------------- rootston/xcursor.c | 114 ++++++++++++++++++++++++++++++++++++++++----- 8 files changed, 170 insertions(+), 77 deletions(-) (limited to 'include') diff --git a/include/rootston/cursor.h b/include/rootston/cursor.h index c0dbc010..fc71e31d 100644 --- a/include/rootston/cursor.h +++ b/include/rootston/cursor.h @@ -30,7 +30,6 @@ struct roots_cursor { enum roots_cursor_mode mode; // state from input (review if this is necessary) - struct wlr_xcursor_theme *xcursor_theme; struct wlr_seat *wl_seat; struct wl_client *cursor_client; int offs_x, offs_y; diff --git a/include/rootston/desktop.h b/include/rootston/desktop.h index 376412fb..b12fff70 100644 --- a/include/rootston/desktop.h +++ b/include/rootston/desktop.h @@ -12,6 +12,7 @@ #include #include "rootston/view.h" #include "rootston/config.h" +#include "rootston/xcursor.h" struct roots_output { struct roots_desktop *desktop; @@ -29,6 +30,7 @@ struct roots_desktop { struct roots_server *server; struct roots_config *config; + struct roots_xcursor_theme *xcursor_theme; struct wlr_output_layout *layout; diff --git a/include/rootston/xcursor.h b/include/rootston/xcursor.h index c96e50ef..45fac481 100644 --- a/include/rootston/xcursor.h +++ b/include/rootston/xcursor.h @@ -1,15 +1,44 @@ #ifndef _ROOTSTON_XCURSOR_H #define _ROOTSTON_XCURSOR_H +#include #include +#include +#include -struct wlr_xcursor *get_default_xcursor(struct wlr_xcursor_theme *theme); +#define ROOTS_XCURSOR_SIZE 16 -struct wlr_xcursor *get_move_xcursor(struct wlr_xcursor_theme *theme); +struct roots_xcursor_scaled_theme { + uint32_t scale; + struct wlr_xcursor_theme *theme; + struct wl_list link; +}; -struct wlr_xcursor *get_resize_xcursor(struct wlr_xcursor_theme *theme, - uint32_t edges); +struct roots_xcursor_theme { + char *name; + struct wl_list scaled_themes; // roots_xcursor_scaled_theme::link +}; -struct wlr_xcursor *get_rotate_xcursor(struct wlr_xcursor_theme *theme); +struct roots_xcursor_theme *roots_xcursor_theme_create(const char *name); + +void roots_xcursor_theme_destroy(struct roots_xcursor_theme *theme); + +int roots_xcursor_theme_load(struct roots_xcursor_theme *theme, + uint32_t scale); + +void roots_xcursor_theme_set_default(struct roots_xcursor_theme *theme, + struct wlr_cursor *cursor); + +void roots_xcursor_theme_set_move(struct roots_xcursor_theme *theme, + struct wlr_cursor *cursor); + +void roots_xcursor_theme_set_resize(struct roots_xcursor_theme *theme, + struct wlr_cursor *cursor, uint32_t edges); + +void roots_xcursor_theme_set_rotate(struct roots_xcursor_theme *theme, + struct wlr_cursor *cursor); + +void roots_xcursor_theme_xwayland_set_default(struct roots_xcursor_theme *theme, + struct wlr_xwayland *xwayland); #endif diff --git a/rootston/cursor.c b/rootston/cursor.c index c3982e0e..46f4caea 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -27,12 +27,6 @@ void roots_cursor_destroy(struct roots_cursor *cursor) { // TODO } -static void cursor_set_xcursor_image(struct roots_cursor *cursor, - struct wlr_xcursor_image *image) { - wlr_cursor_set_image(cursor->cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y, 0); -} - static void roots_cursor_update_position(struct roots_cursor *cursor, uint32_t time) { struct roots_desktop *desktop = cursor->seat->input->server->desktop; struct roots_seat *seat = cursor->seat; @@ -50,8 +44,8 @@ static void roots_cursor_update_position(struct roots_cursor *cursor, uint32_t t set_compositor_cursor = view_client != cursor->cursor_client; } if (set_compositor_cursor) { - struct wlr_xcursor *xcursor = get_default_xcursor(cursor->xcursor_theme); - cursor_set_xcursor_image(cursor, xcursor->images[0]); + roots_xcursor_theme_set_default(desktop->xcursor_theme, + cursor->cursor); cursor->cursor_client = NULL; } if (view) { diff --git a/rootston/desktop.c b/rootston/desktop.c index 448171ec..e20fceab 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -323,6 +323,14 @@ struct roots_desktop *desktop_create(struct roots_server *server, desktop->server = server; desktop->config = config; + + desktop->xcursor_theme = roots_xcursor_theme_create("default"); + if (desktop->xcursor_theme == NULL) { + wlr_list_free(desktop->views); + free(desktop); + return NULL; + } + desktop->layout = wlr_output_layout_create(); desktop->compositor = wlr_compositor_create(server->wl_display, server->renderer); @@ -344,6 +352,12 @@ struct roots_desktop *desktop_create(struct roots_server *server, wl_signal_add(&desktop->xwayland->events.new_surface, &desktop->xwayland_surface); desktop->xwayland_surface.notify = handle_xwayland_surface; + + if (roots_xcursor_theme_load(desktop->xcursor_theme, 1)) { + wlr_log(L_ERROR, "Cannot load xwayland xcursor theme"); + } + roots_xcursor_theme_xwayland_set_default(desktop->xcursor_theme, + desktop->xwayland); } #endif diff --git a/rootston/output.c b/rootston/output.c index d853c45f..943e14c0 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -11,6 +11,7 @@ #include "rootston/server.h" #include "rootston/desktop.h" #include "rootston/config.h" +#include "rootston/xcursor.h" static inline int64_t timespec_to_msec(const struct timespec *a) { return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000; @@ -240,6 +241,11 @@ void output_add_notify(struct wl_listener *listener, void *data) { wlr_output_layout_add_auto(desktop->layout, wlr_output); } + if (roots_xcursor_theme_load(desktop->xcursor_theme, wlr_output->scale)) { + wlr_log(L_ERROR, "Cannot load xcursor theme with scale %d", + wlr_output->scale); + } + struct roots_seat *seat; wl_list_for_each(seat, &input->seats, link) { roots_seat_configure_cursor(seat); diff --git a/rootston/seat.c b/rootston/seat.c index 280443ac..376da67f 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -176,12 +176,6 @@ void roots_seat_configure_cursor(struct roots_seat *seat) { } } -static void seat_set_xcursor_image(struct roots_seat *seat, struct - wlr_xcursor_image *image) { - wlr_cursor_set_image(seat->cursor->cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y, 0); -} - static void roots_seat_init_cursor(struct roots_seat *seat) { seat->cursor = roots_cursor_create(seat); if (!seat->cursor) { @@ -192,33 +186,7 @@ static void roots_seat_init_cursor(struct roots_seat *seat) { struct roots_desktop *desktop = seat->input->server->desktop; wlr_cursor_attach_output_layout(wlr_cursor, desktop->layout); - seat->cursor->xcursor_theme = wlr_xcursor_theme_load("default", 16); - if (seat->cursor->xcursor_theme == NULL) { - wlr_log(L_ERROR, "Cannot load xcursor theme"); - roots_cursor_destroy(seat->cursor); - seat->cursor = NULL; - return; - } - - struct wlr_xcursor *xcursor = get_default_xcursor(seat->cursor->xcursor_theme); - if (xcursor == NULL) { - wlr_log(L_ERROR, "Cannot load xcursor from theme"); - wlr_xcursor_theme_destroy(seat->cursor->xcursor_theme); - roots_cursor_destroy(seat->cursor); - seat->cursor = NULL; - return; - } - - struct wlr_xcursor_image *image = xcursor->images[0]; - seat_set_xcursor_image(seat, image); - - // XXX: xwayland will always have the theme of the last created seat - if (seat->input->server->desktop->xwayland != NULL) { - wlr_xwayland_set_cursor(seat->input->server->desktop->xwayland, - image->buffer, image->width, image->width, - image->height, image->hotspot_x, - image->hotspot_y); - } + roots_xcursor_theme_set_default(desktop->xcursor_theme, wlr_cursor); wl_list_init(&seat->cursor->touch_points); @@ -476,11 +444,8 @@ void roots_seat_remove_device(struct roots_seat *seat, } void roots_seat_configure_xcursor(struct roots_seat *seat) { - struct wlr_xcursor *xcursor = - get_default_xcursor(seat->cursor->xcursor_theme); - struct wlr_xcursor_image *image = xcursor->images[0]; - seat_set_xcursor_image(seat, image); - + roots_xcursor_theme_set_default(seat->input->server->desktop->xcursor_theme, + seat->cursor->cursor); wlr_cursor_warp(seat->cursor->cursor, NULL, seat->cursor->cursor->x, seat->cursor->cursor->y); } @@ -557,11 +522,8 @@ void roots_seat_begin_move(struct roots_seat *seat, struct roots_view *view) { view_maximize(view, false); wlr_seat_pointer_clear_focus(seat->seat); - struct wlr_xcursor *xcursor = get_move_xcursor(seat->cursor->xcursor_theme); - if (xcursor != NULL) { - struct wlr_xcursor_image *image = xcursor->images[0]; - seat_set_xcursor_image(seat, image); - } + roots_xcursor_theme_set_move(seat->input->server->desktop->xcursor_theme, + seat->cursor->cursor); } void roots_seat_begin_resize(struct roots_seat *seat, struct roots_view *view, @@ -587,11 +549,8 @@ void roots_seat_begin_resize(struct roots_seat *seat, struct roots_view *view, view_maximize(view, false); wlr_seat_pointer_clear_focus(seat->seat); - struct wlr_xcursor *xcursor = get_resize_xcursor(cursor->xcursor_theme, edges); - if (xcursor != NULL) { - seat_set_xcursor_image(seat, xcursor->images[0]); - } - + roots_xcursor_theme_set_resize(seat->input->server->desktop->xcursor_theme, + seat->cursor->cursor, edges); } void roots_seat_begin_rotate(struct roots_seat *seat, struct roots_view *view) { @@ -603,8 +562,6 @@ void roots_seat_begin_rotate(struct roots_seat *seat, struct roots_view *view) { view_maximize(view, false); wlr_seat_pointer_clear_focus(seat->seat); - struct wlr_xcursor *xcursor = get_rotate_xcursor(cursor->xcursor_theme); - if (xcursor != NULL) { - seat_set_xcursor_image(seat, xcursor->images[0]); - } + roots_xcursor_theme_set_rotate(seat->input->server->desktop->xcursor_theme, + seat->cursor->cursor); } diff --git a/rootston/xcursor.c b/rootston/xcursor.c index 8697cdc3..6aa74bc4 100644 --- a/rootston/xcursor.c +++ b/rootston/xcursor.c @@ -1,6 +1,85 @@ -#include +#define _POSIX_C_SOURCE 200809L +#include +#include +#include "rootston/xcursor.h" #include "rootston/input.h" +struct roots_xcursor_theme *roots_xcursor_theme_create(const char *name) { + struct roots_xcursor_theme *theme = + calloc(1, sizeof(struct roots_xcursor_theme)); + if (theme == NULL) { + return NULL; + } + theme->name = strdup(name); + wl_list_init(&theme->scaled_themes); + return theme; +} + +void roots_xcursor_theme_destroy(struct roots_xcursor_theme *theme) { + if (theme == NULL) { + return; + } + struct roots_xcursor_scaled_theme *scaled_theme, *tmp; + wl_list_for_each_safe(scaled_theme, tmp, &theme->scaled_themes, link) { + wl_list_remove(&scaled_theme->link); + wlr_xcursor_theme_destroy(scaled_theme->theme); + free(scaled_theme); + } + free(theme->name); + free(theme); +} + +int roots_xcursor_theme_load(struct roots_xcursor_theme *theme, + uint32_t scale) { + struct roots_xcursor_scaled_theme *scaled_theme; + wl_list_for_each(scaled_theme, &theme->scaled_themes, link) { + if (scaled_theme->scale == scale) { + return 0; + } + } + + scaled_theme = calloc(1, sizeof(struct roots_xcursor_scaled_theme)); + if (scaled_theme == NULL) { + return 1; + } + scaled_theme->scale = scale; + scaled_theme->theme = wlr_xcursor_theme_load(NULL, + ROOTS_XCURSOR_SIZE * scale); + if (scaled_theme->theme == NULL) { + free(scaled_theme); + return 1; + } + wl_list_insert(&theme->scaled_themes, &scaled_theme->link); + return 0; +} + +static void roots_xcursor_theme_set(struct roots_xcursor_theme *theme, + struct wlr_cursor *cursor, const char *name) { + struct roots_xcursor_scaled_theme *scaled_theme; + wl_list_for_each(scaled_theme, &theme->scaled_themes, link) { + struct wlr_xcursor *xcursor = + wlr_xcursor_theme_get_cursor(scaled_theme->theme, name); + if (xcursor == NULL) { + continue; + } + + struct wlr_xcursor_image *image = xcursor->images[0]; + wlr_cursor_set_image(cursor, image->buffer, image->width, + image->width, image->height, image->hotspot_x, image->hotspot_y, + scaled_theme->scale); + } +} + +void roots_xcursor_theme_set_default(struct roots_xcursor_theme *theme, + struct wlr_cursor *cursor) { + roots_xcursor_theme_set(theme, cursor, "left_ptr"); +} + +void roots_xcursor_theme_set_move(struct roots_xcursor_theme *theme, + struct wlr_cursor *cursor) { + roots_xcursor_theme_set(theme, cursor, "grabbing"); +} + static const char *get_resize_xcursor_name(uint32_t edges) { if (edges & ROOTS_CURSOR_RESIZE_EDGE_TOP) { if (edges & ROOTS_CURSOR_RESIZE_EDGE_RIGHT) { @@ -24,19 +103,32 @@ static const char *get_resize_xcursor_name(uint32_t edges) { return "se-resize"; // fallback } -struct wlr_xcursor *get_default_xcursor(struct wlr_xcursor_theme *theme) { - return wlr_xcursor_theme_get_cursor(theme, "left_ptr"); +void roots_xcursor_theme_set_resize(struct roots_xcursor_theme *theme, + struct wlr_cursor *cursor, uint32_t edges) { + roots_xcursor_theme_set(theme, cursor, get_resize_xcursor_name(edges)); } -struct wlr_xcursor *get_move_xcursor(struct wlr_xcursor_theme *theme) { - return wlr_xcursor_theme_get_cursor(theme, "grabbing"); +void roots_xcursor_theme_set_rotate(struct roots_xcursor_theme *theme, + struct wlr_cursor *cursor) { + roots_xcursor_theme_set(theme, cursor, "grabbing"); } -struct wlr_xcursor *get_resize_xcursor(struct wlr_xcursor_theme *theme, - uint32_t edges) { - return wlr_xcursor_theme_get_cursor(theme, get_resize_xcursor_name(edges)); -} +void roots_xcursor_theme_xwayland_set_default(struct roots_xcursor_theme *theme, + struct wlr_xwayland *xwayland) { + struct roots_xcursor_scaled_theme *scaled_theme; + wl_list_for_each(scaled_theme, &theme->scaled_themes, link) { + if (scaled_theme->scale == 1) { + struct wlr_xcursor *xcursor = + wlr_xcursor_theme_get_cursor(scaled_theme->theme, "left_ptr"); + if (xcursor == NULL) { + continue; + } -struct wlr_xcursor *get_rotate_xcursor(struct wlr_xcursor_theme *theme) { - return wlr_xcursor_theme_get_cursor(theme, "grabbing"); + struct wlr_xcursor_image *image = xcursor->images[0]; + wlr_xwayland_set_cursor(xwayland, image->buffer, image->width, + image->width, image->height, image->hotspot_x, + image->hotspot_y); + break; + } + } } -- cgit v1.2.3 From 09279b90a63c5fdb2e28a61f2dfc936285126177 Mon Sep 17 00:00:00 2001 From: emersion Date: Sat, 11 Nov 2017 19:09:34 +0100 Subject: Add wlr_output.serial --- backend/drm/util.c | 9 ++++++++- include/wlr/types/wlr_output.h | 1 + rootston/output.c | 5 +++-- 3 files changed, 12 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/backend/drm/util.c b/backend/drm/util.c index 656c070a..c27d7b67 100644 --- a/backend/drm/util.c +++ b/backend/drm/util.c @@ -106,8 +106,15 @@ void parse_edid(struct wlr_output *restrict output, size_t len, const uint8_t *d if (nl) { *nl = '\0'; } + } else if (flag == 0 && data[i + 3] == 0xFF) { + sprintf(output->serial, "%.13s", &data[i + 5]); - break; + // Monitor serial numbers are terminated by newline if they're too + // short + char *nl = strchr(output->serial, '\n'); + if (nl) { + *nl = '\0'; + } } } } diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h index df123639..cf000019 100644 --- a/include/wlr/types/wlr_output.h +++ b/include/wlr/types/wlr_output.h @@ -43,6 +43,7 @@ struct wlr_output { char name[16]; char make[48]; char model[16]; + char serial[16]; uint32_t scale; int32_t width, height; int32_t phys_width, phys_height; // mm diff --git a/rootston/output.c b/rootston/output.c index d853c45f..a929e6be 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -210,8 +210,9 @@ void output_add_notify(struct wl_listener *listener, void *data) { struct roots_config *config = desktop->config; wlr_log(L_DEBUG, "Output '%s' added", wlr_output->name); - wlr_log(L_DEBUG, "%s %s %"PRId32"mm x %"PRId32"mm", wlr_output->make, - wlr_output->model, wlr_output->phys_width, wlr_output->phys_height); + wlr_log(L_DEBUG, "%s %s %s %"PRId32"mm x %"PRId32"mm", wlr_output->make, + wlr_output->model, wlr_output->serial, wlr_output->phys_width, + wlr_output->phys_height); if (wl_list_length(&wlr_output->modes) > 0) { struct wlr_output_mode *mode = NULL; mode = wl_container_of((&wlr_output->modes)->prev, mode, link); -- cgit v1.2.3 From 2dccb11741abd99fd71d4ccaba1ad42362d8f204 Mon Sep 17 00:00:00 2001 From: emersion Date: Sat, 11 Nov 2017 23:53:45 +0100 Subject: rootston: keep one xcursor_theme per seat --- include/rootston/cursor.h | 1 + rootston/cursor.c | 2 +- rootston/output.c | 11 ++++++----- rootston/seat.c | 12 +++++++----- 4 files changed, 15 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/include/rootston/cursor.h b/include/rootston/cursor.h index fc71e31d..575c9d0e 100644 --- a/include/rootston/cursor.h +++ b/include/rootston/cursor.h @@ -30,6 +30,7 @@ struct roots_cursor { enum roots_cursor_mode mode; // state from input (review if this is necessary) + struct roots_xcursor_theme *xcursor_theme; struct wlr_seat *wl_seat; struct wl_client *cursor_client; int offs_x, offs_y; diff --git a/rootston/cursor.c b/rootston/cursor.c index 46f4caea..0795cea6 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -44,7 +44,7 @@ static void roots_cursor_update_position(struct roots_cursor *cursor, uint32_t t set_compositor_cursor = view_client != cursor->cursor_client; } if (set_compositor_cursor) { - roots_xcursor_theme_set_default(desktop->xcursor_theme, + roots_xcursor_theme_set_default(cursor->xcursor_theme, cursor->cursor); cursor->cursor_client = NULL; } diff --git a/rootston/output.c b/rootston/output.c index 943e14c0..b35e56cd 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -241,13 +241,14 @@ void output_add_notify(struct wl_listener *listener, void *data) { wlr_output_layout_add_auto(desktop->layout, wlr_output); } - if (roots_xcursor_theme_load(desktop->xcursor_theme, wlr_output->scale)) { - wlr_log(L_ERROR, "Cannot load xcursor theme with scale %d", - wlr_output->scale); - } - struct roots_seat *seat; wl_list_for_each(seat, &input->seats, link) { + if (roots_xcursor_theme_load(seat->cursor->xcursor_theme, + wlr_output->scale)) { + wlr_log(L_ERROR, "Cannot load xcursor theme for output '%s' " + "with scale %d", wlr_output->name, wlr_output->scale); + } + roots_seat_configure_cursor(seat); roots_seat_configure_xcursor(seat); } diff --git a/rootston/seat.c b/rootston/seat.c index 376da67f..ec4e9800 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -186,7 +186,9 @@ static void roots_seat_init_cursor(struct roots_seat *seat) { struct roots_desktop *desktop = seat->input->server->desktop; wlr_cursor_attach_output_layout(wlr_cursor, desktop->layout); - roots_xcursor_theme_set_default(desktop->xcursor_theme, wlr_cursor); + // TODO: be able to configure per-seat cursor themes + seat->cursor->xcursor_theme = desktop->xcursor_theme; + roots_xcursor_theme_set_default(seat->cursor->xcursor_theme, wlr_cursor); wl_list_init(&seat->cursor->touch_points); @@ -444,7 +446,7 @@ void roots_seat_remove_device(struct roots_seat *seat, } void roots_seat_configure_xcursor(struct roots_seat *seat) { - roots_xcursor_theme_set_default(seat->input->server->desktop->xcursor_theme, + roots_xcursor_theme_set_default(seat->cursor->xcursor_theme, seat->cursor->cursor); wlr_cursor_warp(seat->cursor->cursor, NULL, seat->cursor->cursor->x, seat->cursor->cursor->y); @@ -522,7 +524,7 @@ void roots_seat_begin_move(struct roots_seat *seat, struct roots_view *view) { view_maximize(view, false); wlr_seat_pointer_clear_focus(seat->seat); - roots_xcursor_theme_set_move(seat->input->server->desktop->xcursor_theme, + roots_xcursor_theme_set_move(seat->cursor->xcursor_theme, seat->cursor->cursor); } @@ -549,7 +551,7 @@ void roots_seat_begin_resize(struct roots_seat *seat, struct roots_view *view, view_maximize(view, false); wlr_seat_pointer_clear_focus(seat->seat); - roots_xcursor_theme_set_resize(seat->input->server->desktop->xcursor_theme, + roots_xcursor_theme_set_resize(seat->cursor->xcursor_theme, seat->cursor->cursor, edges); } @@ -562,6 +564,6 @@ void roots_seat_begin_rotate(struct roots_seat *seat, struct roots_view *view) { view_maximize(view, false); wlr_seat_pointer_clear_focus(seat->seat); - roots_xcursor_theme_set_rotate(seat->input->server->desktop->xcursor_theme, + roots_xcursor_theme_set_rotate(seat->cursor->xcursor_theme, seat->cursor->cursor); } -- cgit v1.2.3 From 8605243459629f566ed5109ffd896fd57b329ceb Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 12 Nov 2017 11:10:56 +0100 Subject: Introduce wlr_xcursor_manager --- include/rootston/cursor.h | 2 +- include/rootston/desktop.h | 2 +- include/rootston/xcursor.h | 40 ++---------- include/wlr/types/wlr_cursor.h | 1 - include/wlr/types/wlr_xcursor_manager.h | 53 ++++++++++++++++ include/wlr/xcursor.h | 2 +- rootston/cursor.c | 5 +- rootston/desktop.c | 21 +++++-- rootston/output.c | 4 +- rootston/seat.c | 22 ++++--- rootston/xcursor.c | 108 +------------------------------- types/meson.build | 3 +- types/wlr_xcursor_manager.c | 84 +++++++++++++++++++++++++ 13 files changed, 180 insertions(+), 167 deletions(-) create mode 100644 include/wlr/types/wlr_xcursor_manager.h create mode 100644 types/wlr_xcursor_manager.c (limited to 'include') diff --git a/include/rootston/cursor.h b/include/rootston/cursor.h index 575c9d0e..f49b6439 100644 --- a/include/rootston/cursor.h +++ b/include/rootston/cursor.h @@ -30,7 +30,7 @@ struct roots_cursor { enum roots_cursor_mode mode; // state from input (review if this is necessary) - struct roots_xcursor_theme *xcursor_theme; + struct wlr_xcursor_manager *xcursor_manager; struct wlr_seat *wl_seat; struct wl_client *cursor_client; int offs_x, offs_y; diff --git a/include/rootston/desktop.h b/include/rootston/desktop.h index b12fff70..7371284f 100644 --- a/include/rootston/desktop.h +++ b/include/rootston/desktop.h @@ -30,9 +30,9 @@ struct roots_desktop { struct roots_server *server; struct roots_config *config; - struct roots_xcursor_theme *xcursor_theme; struct wlr_output_layout *layout; + struct wlr_xcursor_manager *xcursor_manager; struct wlr_compositor *compositor; struct wlr_wl_shell *wl_shell; diff --git a/include/rootston/xcursor.h b/include/rootston/xcursor.h index 45fac481..bc00f79c 100644 --- a/include/rootston/xcursor.h +++ b/include/rootston/xcursor.h @@ -1,44 +1,14 @@ #ifndef _ROOTSTON_XCURSOR_H #define _ROOTSTON_XCURSOR_H -#include -#include -#include -#include +#include #define ROOTS_XCURSOR_SIZE 16 -struct roots_xcursor_scaled_theme { - uint32_t scale; - struct wlr_xcursor_theme *theme; - struct wl_list link; -}; +#define ROOTS_XCURSOR_DEFAULT "left_ptr" +#define ROOTS_XCURSOR_MOVE "grabbing" +#define ROOTS_XCURSOR_ROTATE "grabbing" -struct roots_xcursor_theme { - char *name; - struct wl_list scaled_themes; // roots_xcursor_scaled_theme::link -}; - -struct roots_xcursor_theme *roots_xcursor_theme_create(const char *name); - -void roots_xcursor_theme_destroy(struct roots_xcursor_theme *theme); - -int roots_xcursor_theme_load(struct roots_xcursor_theme *theme, - uint32_t scale); - -void roots_xcursor_theme_set_default(struct roots_xcursor_theme *theme, - struct wlr_cursor *cursor); - -void roots_xcursor_theme_set_move(struct roots_xcursor_theme *theme, - struct wlr_cursor *cursor); - -void roots_xcursor_theme_set_resize(struct roots_xcursor_theme *theme, - struct wlr_cursor *cursor, uint32_t edges); - -void roots_xcursor_theme_set_rotate(struct roots_xcursor_theme *theme, - struct wlr_cursor *cursor); - -void roots_xcursor_theme_xwayland_set_default(struct roots_xcursor_theme *theme, - struct wlr_xwayland *xwayland); +const char *roots_xcursor_get_resize_name(uint32_t edges); #endif diff --git a/include/wlr/types/wlr_cursor.h b/include/wlr/types/wlr_cursor.h index 3df74d28..0db32eb2 100644 --- a/include/wlr/types/wlr_cursor.h +++ b/include/wlr/types/wlr_cursor.h @@ -6,7 +6,6 @@ #include #include #include -#include struct wlr_cursor_state; diff --git a/include/wlr/types/wlr_xcursor_manager.h b/include/wlr/types/wlr_xcursor_manager.h new file mode 100644 index 00000000..c78a6e8d --- /dev/null +++ b/include/wlr/types/wlr_xcursor_manager.h @@ -0,0 +1,53 @@ +#ifndef WLR_TYPES_WLR_XCURSOR_MANAGER_H +#define WLR_TYPES_WLR_XCURSOR_MANAGER_H + +#include +#include +#include + +/** + * A scaled XCursor theme. + */ +struct wlr_xcursor_manager_theme { + uint32_t scale; + struct wlr_xcursor_theme *theme; + struct wl_list link; +}; + +/** + * Manage multiple XCursor themes with different scales and set `wlr_cursor` + * images. + * + * This manager can be used to display cursor images on multiple outputs having + * different scale factors. + */ +struct wlr_xcursor_manager { + char *name; + uint32_t size; + struct wl_list scaled_themes; // wlr_xcursor_manager_theme::link +}; + +/** + * Create a new XCursor manager. After initialization, scaled themes need to be + * loaded with `wlr_xcursor_manager_load`. `size` is the unscaled cursor theme + * size. + */ +struct wlr_xcursor_manager *wlr_xcursor_manager_create(const char *name, + uint32_t size); + +void wlr_xcursor_manager_destroy(struct wlr_xcursor_manager *manager); + +int wlr_xcursor_manager_load(struct wlr_xcursor_manager *manager, + uint32_t scale); + +struct wlr_xcursor *wlr_xcursor_manager_get_xcursor( + struct wlr_xcursor_manager *manager, const char *name, uint32_t scale); + +/** + * Set a `wlr_cursor` image. The manager uses all currently loaded scaled + * themes. + */ +void wlr_xcursor_manager_set_cursor_image(struct wlr_xcursor_manager *manager, + const char *name, struct wlr_cursor *cursor); + +#endif diff --git a/include/wlr/xcursor.h b/include/wlr/xcursor.h index c12d5405..b6362b06 100644 --- a/include/wlr/xcursor.h +++ b/include/wlr/xcursor.h @@ -61,7 +61,7 @@ struct wlr_xcursor_theme *wlr_xcursor_theme_load(const char *name, int size); void wlr_xcursor_theme_destroy(struct wlr_xcursor_theme *theme); struct wlr_xcursor *wlr_xcursor_theme_get_cursor( - struct wlr_xcursor_theme *theme, const char *name); + struct wlr_xcursor_theme *theme, const char *name); int wlr_xcursor_frame(struct wlr_xcursor *cursor, uint32_t time); diff --git a/rootston/cursor.c b/rootston/cursor.c index 0795cea6..ecd5e9a0 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -6,6 +6,7 @@ #elif __FreeBSD__ #include #endif +#include #include #include "rootston/xcursor.h" #include "rootston/cursor.h" @@ -44,8 +45,8 @@ static void roots_cursor_update_position(struct roots_cursor *cursor, uint32_t t set_compositor_cursor = view_client != cursor->cursor_client; } if (set_compositor_cursor) { - roots_xcursor_theme_set_default(cursor->xcursor_theme, - cursor->cursor); + wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, + ROOTS_XCURSOR_DEFAULT, cursor->cursor); cursor->cursor_client = NULL; } if (view) { diff --git a/rootston/desktop.c b/rootston/desktop.c index e20fceab..bb030e74 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -324,8 +325,10 @@ struct roots_desktop *desktop_create(struct roots_server *server, desktop->server = server; desktop->config = config; - desktop->xcursor_theme = roots_xcursor_theme_create("default"); - if (desktop->xcursor_theme == NULL) { + desktop->xcursor_manager = wlr_xcursor_manager_create(NULL, + ROOTS_XCURSOR_SIZE); + if (desktop->xcursor_manager == NULL) { + wlr_log(L_ERROR, "Cannot create XCursor manager"); wlr_list_free(desktop->views); free(desktop); return NULL; @@ -353,11 +356,17 @@ struct roots_desktop *desktop_create(struct roots_server *server, &desktop->xwayland_surface); desktop->xwayland_surface.notify = handle_xwayland_surface; - if (roots_xcursor_theme_load(desktop->xcursor_theme, 1)) { - wlr_log(L_ERROR, "Cannot load xwayland xcursor theme"); + if (wlr_xcursor_manager_load(desktop->xcursor_manager, 1)) { + wlr_log(L_ERROR, "Cannot load XWayland XCursor theme"); + } + struct wlr_xcursor *xcursor = wlr_xcursor_manager_get_xcursor( + desktop->xcursor_manager, ROOTS_XCURSOR_DEFAULT, 1); + if (xcursor != NULL) { + struct wlr_xcursor_image *image = xcursor->images[0]; + wlr_xwayland_set_cursor(desktop->xwayland, image->buffer, + image->width, image->width, image->height, image->hotspot_x, + image->hotspot_y); } - roots_xcursor_theme_xwayland_set_default(desktop->xcursor_theme, - desktop->xwayland); } #endif diff --git a/rootston/output.c b/rootston/output.c index b35e56cd..cd288195 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -5,13 +5,13 @@ #include #include #include +#include #include #include #include #include "rootston/server.h" #include "rootston/desktop.h" #include "rootston/config.h" -#include "rootston/xcursor.h" static inline int64_t timespec_to_msec(const struct timespec *a) { return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000; @@ -243,7 +243,7 @@ void output_add_notify(struct wl_listener *listener, void *data) { struct roots_seat *seat; wl_list_for_each(seat, &input->seats, link) { - if (roots_xcursor_theme_load(seat->cursor->xcursor_theme, + if (wlr_xcursor_manager_load(seat->cursor->xcursor_manager, wlr_output->scale)) { wlr_log(L_ERROR, "Cannot load xcursor theme for output '%s' " "with scale %d", wlr_output->name, wlr_output->scale); diff --git a/rootston/seat.c b/rootston/seat.c index ec4e9800..8a838efe 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -3,6 +3,7 @@ #include #include +#include #include #include "rootston/xcursor.h" @@ -187,8 +188,9 @@ static void roots_seat_init_cursor(struct roots_seat *seat) { wlr_cursor_attach_output_layout(wlr_cursor, desktop->layout); // TODO: be able to configure per-seat cursor themes - seat->cursor->xcursor_theme = desktop->xcursor_theme; - roots_xcursor_theme_set_default(seat->cursor->xcursor_theme, wlr_cursor); + seat->cursor->xcursor_manager = desktop->xcursor_manager; + wlr_xcursor_manager_set_cursor_image(seat->cursor->xcursor_manager, + ROOTS_XCURSOR_DEFAULT, wlr_cursor); wl_list_init(&seat->cursor->touch_points); @@ -446,8 +448,8 @@ void roots_seat_remove_device(struct roots_seat *seat, } void roots_seat_configure_xcursor(struct roots_seat *seat) { - roots_xcursor_theme_set_default(seat->cursor->xcursor_theme, - seat->cursor->cursor); + wlr_xcursor_manager_set_cursor_image(seat->cursor->xcursor_manager, + ROOTS_XCURSOR_DEFAULT, seat->cursor->cursor); wlr_cursor_warp(seat->cursor->cursor, NULL, seat->cursor->cursor->x, seat->cursor->cursor->y); } @@ -524,8 +526,8 @@ void roots_seat_begin_move(struct roots_seat *seat, struct roots_view *view) { view_maximize(view, false); wlr_seat_pointer_clear_focus(seat->seat); - roots_xcursor_theme_set_move(seat->cursor->xcursor_theme, - seat->cursor->cursor); + wlr_xcursor_manager_set_cursor_image(seat->cursor->xcursor_manager, + ROOTS_XCURSOR_MOVE, seat->cursor->cursor); } void roots_seat_begin_resize(struct roots_seat *seat, struct roots_view *view, @@ -551,8 +553,8 @@ void roots_seat_begin_resize(struct roots_seat *seat, struct roots_view *view, view_maximize(view, false); wlr_seat_pointer_clear_focus(seat->seat); - roots_xcursor_theme_set_resize(seat->cursor->xcursor_theme, - seat->cursor->cursor, edges); + wlr_xcursor_manager_set_cursor_image(seat->cursor->xcursor_manager, + roots_xcursor_get_resize_name(edges), seat->cursor->cursor); } void roots_seat_begin_rotate(struct roots_seat *seat, struct roots_view *view) { @@ -564,6 +566,6 @@ void roots_seat_begin_rotate(struct roots_seat *seat, struct roots_view *view) { view_maximize(view, false); wlr_seat_pointer_clear_focus(seat->seat); - roots_xcursor_theme_set_rotate(seat->cursor->xcursor_theme, - seat->cursor->cursor); + wlr_xcursor_manager_set_cursor_image(seat->cursor->xcursor_manager, + ROOTS_XCURSOR_ROTATE, seat->cursor->cursor); } diff --git a/rootston/xcursor.c b/rootston/xcursor.c index 6aa74bc4..74e732c9 100644 --- a/rootston/xcursor.c +++ b/rootston/xcursor.c @@ -4,83 +4,7 @@ #include "rootston/xcursor.h" #include "rootston/input.h" -struct roots_xcursor_theme *roots_xcursor_theme_create(const char *name) { - struct roots_xcursor_theme *theme = - calloc(1, sizeof(struct roots_xcursor_theme)); - if (theme == NULL) { - return NULL; - } - theme->name = strdup(name); - wl_list_init(&theme->scaled_themes); - return theme; -} - -void roots_xcursor_theme_destroy(struct roots_xcursor_theme *theme) { - if (theme == NULL) { - return; - } - struct roots_xcursor_scaled_theme *scaled_theme, *tmp; - wl_list_for_each_safe(scaled_theme, tmp, &theme->scaled_themes, link) { - wl_list_remove(&scaled_theme->link); - wlr_xcursor_theme_destroy(scaled_theme->theme); - free(scaled_theme); - } - free(theme->name); - free(theme); -} - -int roots_xcursor_theme_load(struct roots_xcursor_theme *theme, - uint32_t scale) { - struct roots_xcursor_scaled_theme *scaled_theme; - wl_list_for_each(scaled_theme, &theme->scaled_themes, link) { - if (scaled_theme->scale == scale) { - return 0; - } - } - - scaled_theme = calloc(1, sizeof(struct roots_xcursor_scaled_theme)); - if (scaled_theme == NULL) { - return 1; - } - scaled_theme->scale = scale; - scaled_theme->theme = wlr_xcursor_theme_load(NULL, - ROOTS_XCURSOR_SIZE * scale); - if (scaled_theme->theme == NULL) { - free(scaled_theme); - return 1; - } - wl_list_insert(&theme->scaled_themes, &scaled_theme->link); - return 0; -} - -static void roots_xcursor_theme_set(struct roots_xcursor_theme *theme, - struct wlr_cursor *cursor, const char *name) { - struct roots_xcursor_scaled_theme *scaled_theme; - wl_list_for_each(scaled_theme, &theme->scaled_themes, link) { - struct wlr_xcursor *xcursor = - wlr_xcursor_theme_get_cursor(scaled_theme->theme, name); - if (xcursor == NULL) { - continue; - } - - struct wlr_xcursor_image *image = xcursor->images[0]; - wlr_cursor_set_image(cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y, - scaled_theme->scale); - } -} - -void roots_xcursor_theme_set_default(struct roots_xcursor_theme *theme, - struct wlr_cursor *cursor) { - roots_xcursor_theme_set(theme, cursor, "left_ptr"); -} - -void roots_xcursor_theme_set_move(struct roots_xcursor_theme *theme, - struct wlr_cursor *cursor) { - roots_xcursor_theme_set(theme, cursor, "grabbing"); -} - -static const char *get_resize_xcursor_name(uint32_t edges) { +const char *roots_xcursor_get_resize_name(uint32_t edges) { if (edges & ROOTS_CURSOR_RESIZE_EDGE_TOP) { if (edges & ROOTS_CURSOR_RESIZE_EDGE_RIGHT) { return "ne-resize"; @@ -102,33 +26,3 @@ static const char *get_resize_xcursor_name(uint32_t edges) { } return "se-resize"; // fallback } - -void roots_xcursor_theme_set_resize(struct roots_xcursor_theme *theme, - struct wlr_cursor *cursor, uint32_t edges) { - roots_xcursor_theme_set(theme, cursor, get_resize_xcursor_name(edges)); -} - -void roots_xcursor_theme_set_rotate(struct roots_xcursor_theme *theme, - struct wlr_cursor *cursor) { - roots_xcursor_theme_set(theme, cursor, "grabbing"); -} - -void roots_xcursor_theme_xwayland_set_default(struct roots_xcursor_theme *theme, - struct wlr_xwayland *xwayland) { - struct roots_xcursor_scaled_theme *scaled_theme; - wl_list_for_each(scaled_theme, &theme->scaled_themes, link) { - if (scaled_theme->scale == 1) { - struct wlr_xcursor *xcursor = - wlr_xcursor_theme_get_cursor(scaled_theme->theme, "left_ptr"); - if (xcursor == NULL) { - continue; - } - - struct wlr_xcursor_image *image = xcursor->images[0]; - wlr_xwayland_set_cursor(xwayland, image->buffer, image->width, - image->width, image->height, image->hotspot_x, - image->hotspot_y); - break; - } - } -} diff --git a/types/meson.build b/types/meson.build index 2603ecfd..4669165a 100644 --- a/types/meson.build +++ b/types/meson.build @@ -20,8 +20,9 @@ lib_wlr_types = static_library( 'wlr_tablet_pad.c', 'wlr_tablet_tool.c', 'wlr_touch.c', - 'wlr_xdg_shell_v6.c', 'wlr_wl_shell.c', + 'wlr_xcursor_manager.c', + 'wlr_xdg_shell_v6.c', ), include_directories: wlr_inc, dependencies: [wayland_server, pixman, wlr_protos], diff --git a/types/wlr_xcursor_manager.c b/types/wlr_xcursor_manager.c new file mode 100644 index 00000000..6c12d04b --- /dev/null +++ b/types/wlr_xcursor_manager.c @@ -0,0 +1,84 @@ +#define _POSIX_C_SOURCE 200809L +#include +#include +#include + +struct wlr_xcursor_manager *wlr_xcursor_manager_create(const char *name, + uint32_t size) { + struct wlr_xcursor_manager *manager = + calloc(1, sizeof(struct wlr_xcursor_manager)); + if (manager == NULL) { + return NULL; + } + if (name != NULL) { + manager->name = strdup(name); + } + manager->size = size; + wl_list_init(&manager->scaled_themes); + return manager; +} + +void wlr_xcursor_manager_destroy(struct wlr_xcursor_manager *manager) { + if (manager == NULL) { + return; + } + struct wlr_xcursor_manager_theme *theme, *tmp; + wl_list_for_each_safe(theme, tmp, &manager->scaled_themes, link) { + wl_list_remove(&theme->link); + wlr_xcursor_theme_destroy(theme->theme); + free(theme); + } + free(manager->name); + free(manager); +} + +int wlr_xcursor_manager_load(struct wlr_xcursor_manager *manager, + uint32_t scale) { + struct wlr_xcursor_manager_theme *theme; + wl_list_for_each(theme, &manager->scaled_themes, link) { + if (theme->scale == scale) { + return 0; + } + } + + theme = calloc(1, sizeof(struct wlr_xcursor_manager_theme)); + if (theme == NULL) { + return 1; + } + theme->scale = scale; + theme->theme = wlr_xcursor_theme_load(NULL, manager->size * scale); + if (theme->theme == NULL) { + free(theme); + return 1; + } + wl_list_insert(&manager->scaled_themes, &theme->link); + return 0; +} + +struct wlr_xcursor *wlr_xcursor_manager_get_xcursor( + struct wlr_xcursor_manager *manager, const char *name, uint32_t scale) { + struct wlr_xcursor_manager_theme *theme; + wl_list_for_each(theme, &manager->scaled_themes, link) { + if (theme->scale == scale) { + return wlr_xcursor_theme_get_cursor(theme->theme, name); + } + } + return NULL; +} + +void wlr_xcursor_manager_set_cursor_image(struct wlr_xcursor_manager *manager, + const char *name, struct wlr_cursor *cursor) { + struct wlr_xcursor_manager_theme *theme; + wl_list_for_each(theme, &manager->scaled_themes, link) { + struct wlr_xcursor *xcursor = + wlr_xcursor_theme_get_cursor(theme->theme, name); + if (xcursor == NULL) { + continue; + } + + struct wlr_xcursor_image *image = xcursor->images[0]; + wlr_cursor_set_image(cursor, image->buffer, image->width, + image->width, image->height, image->hotspot_x, image->hotspot_y, + theme->scale); + } +} -- cgit v1.2.3 From 5d986f1e874f93f8235fbcc333af63c5c9c99596 Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 12 Nov 2017 15:49:27 +0100 Subject: Remove unnecessary include --- include/rootston/desktop.h | 2 +- rootston/desktop.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/rootston/desktop.h b/include/rootston/desktop.h index 7371284f..b809db43 100644 --- a/include/rootston/desktop.h +++ b/include/rootston/desktop.h @@ -7,12 +7,12 @@ #include #include #include +#include #include #include #include #include "rootston/view.h" #include "rootston/config.h" -#include "rootston/xcursor.h" struct roots_output { struct roots_desktop *desktop; diff --git a/rootston/desktop.c b/rootston/desktop.c index bb030e74..51bb0e2a 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -16,6 +16,7 @@ #include #include "rootston/server.h" #include "rootston/seat.h" +#include "rootston/xcursor.h" // TODO replace me with a signal void view_destroy(struct roots_view *view) { -- cgit v1.2.3 From 1e0e73efaa5584b49405e119bf4ce3810785654e Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sun, 12 Nov 2017 09:55:28 -0500 Subject: Spawn views on last active output --- include/rootston/seat.h | 2 -- include/wlr/types/wlr_seat.h | 3 ++- rootston/desktop.c | 15 ++++++++++++++- rootston/seat.c | 6 ++---- types/wlr_seat.c | 6 ++++++ 5 files changed, 24 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/include/rootston/seat.h b/include/rootston/seat.h index b5593651..bef515a4 100644 --- a/include/rootston/seat.h +++ b/include/rootston/seat.h @@ -1,8 +1,6 @@ #ifndef _ROOTSTON_SEAT_H #define _ROOTSTON_SEAT_H - #include - #include "rootston/input.h" #include "rootston/keyboard.h" diff --git a/include/wlr/types/wlr_seat.h b/include/wlr/types/wlr_seat.h index 09d3e282..a5f00402 100644 --- a/include/wlr/types/wlr_seat.h +++ b/include/wlr/types/wlr_seat.h @@ -1,6 +1,6 @@ #ifndef WLR_TYPES_WLR_SEAT_H #define WLR_TYPES_WLR_SEAT_H - +#include #include #include #include @@ -109,6 +109,7 @@ struct wlr_seat { struct wl_list clients; char *name; uint32_t capabilities; + struct timespec last_event; struct wlr_data_device *data_device; // TODO needed? struct wlr_data_source *selection_source; diff --git a/rootston/desktop.c b/rootston/desktop.c index 448171ec..75526bcb 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -165,9 +165,22 @@ bool view_center(struct roots_view *view) { view_get_box(view, &box); struct roots_desktop *desktop = view->desktop; + struct roots_input *input = desktop->server->input; + struct roots_seat *seat = NULL, *_seat; + wl_list_for_each(_seat, &input->seats, link) { + if (!seat || (seat->seat->last_event.tv_sec > _seat->seat->last_event.tv_sec && + seat->seat->last_event.tv_nsec > _seat->seat->last_event.tv_nsec)) { + seat = _seat; + } + } + if (!seat) { + return false; + } struct wlr_output *output = - wlr_output_layout_get_center_output(desktop->layout); + wlr_output_layout_output_at(desktop->layout, + seat->cursor->cursor->x, + seat->cursor->cursor->y); if (!output) { // empty layout return false; diff --git a/rootston/seat.c b/rootston/seat.c index 4602aad5..b0688156 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -1,10 +1,8 @@ -#include +#include #include #include -#include - +#include #include - #include "rootston/xcursor.h" #include "rootston/input.h" #include "rootston/seat.h" diff --git a/types/wlr_seat.c b/types/wlr_seat.c index 9de1b3a0..dad88354 100644 --- a/types/wlr_seat.c +++ b/types/wlr_seat.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -574,12 +575,14 @@ void wlr_seat_pointer_notify_enter(struct wlr_seat *wlr_seat, void wlr_seat_pointer_notify_motion(struct wlr_seat *wlr_seat, uint32_t time, double sx, double sy) { + clock_gettime(CLOCK_MONOTONIC, &wlr_seat->last_event); struct wlr_seat_pointer_grab *grab = wlr_seat->pointer_state.grab; grab->interface->motion(grab, time, sx, sy); } uint32_t wlr_seat_pointer_notify_button(struct wlr_seat *wlr_seat, uint32_t time, uint32_t button, uint32_t state) { + clock_gettime(CLOCK_MONOTONIC, &wlr_seat->last_event); if (state == WL_POINTER_BUTTON_STATE_PRESSED) { if (wlr_seat->pointer_state.button_count == 0) { wlr_seat->pointer_state.grab_button = button; @@ -602,6 +605,7 @@ uint32_t wlr_seat_pointer_notify_button(struct wlr_seat *wlr_seat, void wlr_seat_pointer_notify_axis(struct wlr_seat *wlr_seat, uint32_t time, enum wlr_axis_orientation orientation, double value) { + clock_gettime(CLOCK_MONOTONIC, &wlr_seat->last_event); struct wlr_seat_pointer_grab *grab = wlr_seat->pointer_state.grab; grab->interface->axis(grab, time, orientation, value); } @@ -804,12 +808,14 @@ void wlr_seat_keyboard_clear_focus(struct wlr_seat *seat) { } void wlr_seat_keyboard_notify_modifiers(struct wlr_seat *seat) { + clock_gettime(CLOCK_MONOTONIC, &seat->last_event); struct wlr_seat_keyboard_grab *grab = seat->keyboard_state.grab; grab->interface->modifiers(grab); } void wlr_seat_keyboard_notify_key(struct wlr_seat *seat, uint32_t time, uint32_t key, uint32_t state) { + clock_gettime(CLOCK_MONOTONIC, &seat->last_event); struct wlr_seat_keyboard_grab *grab = seat->keyboard_state.grab; grab->interface->key(grab, time, key, state); } -- cgit v1.2.3 From a317ecdab8ef8deb184b72db208794daa4c4a3a0 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sun, 12 Nov 2017 16:01:31 -0500 Subject: Run startup command after xwayland is ready --- include/wlr/xwayland.h | 1 + rootston/main.c | 29 ++++++++++++++++++----------- xwayland/xwayland.c | 3 +++ 3 files changed, 22 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/include/wlr/xwayland.h b/include/wlr/xwayland.h index bea97394..6518b703 100644 --- a/include/wlr/xwayland.h +++ b/include/wlr/xwayland.h @@ -29,6 +29,7 @@ struct wlr_xwayland { struct wlr_xwayland_cursor *cursor; struct { + struct wl_signal ready; struct wl_signal new_surface; } events; diff --git a/rootston/main.c b/rootston/main.c index d55bc682..365ff6e0 100644 --- a/rootston/main.c +++ b/rootston/main.c @@ -12,6 +12,18 @@ struct roots_server server = { 0 }; +static void ready(struct wl_listener *listener, void *data) { + if (server.config->startup_cmd != NULL) { + const char *cmd = server.config->startup_cmd; + pid_t pid = fork(); + if (pid < 0) { + wlr_log(L_ERROR, "cannot execute binding command: fork() failed"); + } else if (pid == 0) { + execl("/bin/sh", "/bin/sh", "-c", cmd, (void *)NULL); + } + } +} + int main(int argc, char **argv) { assert(server.config = roots_config_create_from_args(argc, argv)); assert(server.wl_display = wl_display_create()); @@ -43,17 +55,12 @@ int main(int argc, char **argv) { } setenv("WAYLAND_DISPLAY", socket, true); - - if (server.config->startup_cmd != NULL) { - const char *cmd = server.config->startup_cmd; - pid_t pid = fork(); - if (pid < 0) { - wlr_log(L_ERROR, "cannot execute binding command: fork() failed"); - return 1; - } else if (pid == 0) { - execl("/bin/sh", "/bin/sh", "-c", cmd, (void *)NULL); - } - } +#ifndef HAS_XWAYLAND + ready(NULL, NULL); +#else + struct wl_listener xwayland_ready = { .notify = ready }; + wl_signal_add(&server.desktop->xwayland->events.ready, &xwayland_ready); +#endif wl_display_run(server.wl_display); wlr_backend_destroy(server.backend); diff --git a/xwayland/xwayland.c b/xwayland/xwayland.c index 0452f04c..ecec785c 100644 --- a/xwayland/xwayland.c +++ b/xwayland/xwayland.c @@ -211,6 +211,8 @@ static int xserver_handle_ready(int signal_number, void *data) { snprintf(display_name, sizeof(display_name), ":%d", wlr_xwayland->display); setenv("DISPLAY", display_name, true); + wl_signal_emit(&wlr_xwayland->events.ready, wlr_xwayland); + return 1; /* wayland event loop dispatcher's count */ } @@ -223,6 +225,7 @@ static bool wlr_xwayland_init(struct wlr_xwayland *wlr_xwayland, wlr_xwayland->wl_fd[0] = wlr_xwayland->wl_fd[1] = -1; wlr_xwayland->wm_fd[0] = wlr_xwayland->wm_fd[1] = -1; wl_signal_init(&wlr_xwayland->events.new_surface); + wl_signal_init(&wlr_xwayland->events.ready); wlr_xwayland->display = open_display_sockets(wlr_xwayland->x_fd); if (wlr_xwayland->display < 0) { -- cgit v1.2.3 From 3f6cf517b9b8d5efa0c6001db5ed0871e5d8d2b4 Mon Sep 17 00:00:00 2001 From: emersion Date: Wed, 15 Nov 2017 14:03:13 +0100 Subject: Add wlr_xdg_surface_v6_popup_get_position --- include/wlr/types/wlr_xdg_shell_v6.h | 6 ++++++ rootston/output.c | 14 ++++++-------- types/wlr_xdg_shell_v6.c | 10 ++++++++++ 3 files changed, 22 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/include/wlr/types/wlr_xdg_shell_v6.h b/include/wlr/types/wlr_xdg_shell_v6.h index 07911ffa..e3982003 100644 --- a/include/wlr/types/wlr_xdg_shell_v6.h +++ b/include/wlr/types/wlr_xdg_shell_v6.h @@ -209,6 +209,12 @@ void wlr_xdg_toplevel_v6_set_resizing(struct wlr_xdg_surface_v6 *surface, */ void wlr_xdg_toplevel_v6_send_close(struct wlr_xdg_surface_v6 *surface); +/** + * Compute the popup position in surface-local coordinates. + */ +void wlr_xdg_surface_v6_popup_get_position(struct wlr_xdg_surface_v6 *surface, + double *popup_sx, double *popup_sy); + /** * Find a popup within this surface at the surface-local coordinates. Returns * the popup and coordinates in the topmost surface coordinate system or NULL if diff --git a/rootston/output.c b/rootston/output.c index cfab3756..28312c2c 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -115,17 +115,15 @@ static void render_xdg_v6_popups(struct wlr_xdg_surface_v6 *surface, double popup_width = popup->surface->current->width; double popup_height = popup->surface->current->height; - double popup_x = surface->geometry->x + popup->popup_state->geometry.x - - popup->geometry->x; - double popup_y = surface->geometry->y + popup->popup_state->geometry.y - - popup->geometry->y; - rotate_child_position(&popup_x, &popup_y, popup_width, popup_height, + double popup_sx, popup_sy; + wlr_xdg_surface_v6_popup_get_position(popup, &popup_sx, &popup_sy); + rotate_child_position(&popup_sx, &popup_sy, popup_width, popup_height, width, height, rotation); render_surface(popup->surface, desktop, wlr_output, when, - base_x + popup_x, base_y + popup_y, rotation); - render_xdg_v6_popups(popup, desktop, wlr_output, when, base_x + popup_x, - base_y + popup_y, rotation); + base_x + popup_sx, base_y + popup_sy, rotation); + render_xdg_v6_popups(popup, desktop, wlr_output, when, + base_x + popup_sx, base_y + popup_sy, rotation); } } diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index 05ca2b76..429baa70 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -1350,6 +1350,16 @@ void wlr_xdg_toplevel_v6_send_close(struct wlr_xdg_surface_v6 *surface) { zxdg_toplevel_v6_send_close(surface->toplevel_state->resource); } +void wlr_xdg_surface_v6_popup_get_position(struct wlr_xdg_surface_v6 *surface, + double *popup_sx, double *popup_sy) { + assert(surface->role == WLR_XDG_SURFACE_V6_ROLE_POPUP); + struct wlr_xdg_surface_v6 *parent = surface->popup_state->parent; + *popup_sx = parent->geometry->x + surface->popup_state->geometry.x - + surface->geometry->x; + *popup_sy = parent->geometry->y + surface->popup_state->geometry.y - + surface->geometry->y; +} + struct wlr_xdg_surface_v6 *wlr_xdg_surface_v6_popup_at( struct wlr_xdg_surface_v6 *surface, double sx, double sy, double *popup_sx, double *popup_sy) { -- cgit v1.2.3 From 53d4cb47ffae0f8632ba7aea1687fdf75dd7deb8 Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 16 Nov 2017 16:13:23 +0100 Subject: Refactor rootston keyboard --- include/rootston/keyboard.h | 3 +- rootston/keyboard.c | 159 ++++++++++++++++++++++++-------------------- 2 files changed, 90 insertions(+), 72 deletions(-) (limited to 'include') diff --git a/include/rootston/keyboard.h b/include/rootston/keyboard.h index 15e7c9c4..39650d7c 100644 --- a/include/rootston/keyboard.h +++ b/include/rootston/keyboard.h @@ -16,7 +16,8 @@ struct roots_keyboard { struct wl_listener keyboard_key; struct wl_listener keyboard_modifiers; - xkb_keysym_t pressed_keysyms[ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP]; + xkb_keysym_t pressed_keysyms_translated[ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP]; + xkb_keysym_t pressed_keysyms_raw[ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP]; }; struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, diff --git a/rootston/keyboard.c b/rootston/keyboard.c index fb648ae5..566a1d7e 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -13,16 +13,35 @@ #include "rootston/seat.h" #include "rootston/keyboard.h" -static ssize_t keyboard_pressed_keysym_index(struct roots_keyboard *keyboard, +static ssize_t pressed_keysyms_index(xkb_keysym_t *pressed_keysyms, xkb_keysym_t keysym) { - for (size_t i = 0; i < ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP; i++) { - if (keyboard->pressed_keysyms[i] == keysym) { + for (size_t i = 0; i < ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP; ++i) { + if (pressed_keysyms[i] == keysym) { return i; } } return -1; } +static void pressed_keysyms_add(xkb_keysym_t *pressed_keysyms, + xkb_keysym_t keysym) { + ssize_t i = pressed_keysyms_index(pressed_keysyms, keysym); + if (i < 0) { + i = pressed_keysyms_index(pressed_keysyms, XKB_KEY_NoSymbol); + if (i >= 0) { + pressed_keysyms[i] = keysym; + } + } +} + +static void pressed_keysyms_remove(xkb_keysym_t *pressed_keysyms, + xkb_keysym_t keysym) { + ssize_t i = pressed_keysyms_index(pressed_keysyms, keysym); + if (i >= 0) { + pressed_keysyms[i] = XKB_KEY_NoSymbol; + } +} + static const char *exec_prefix = "exec "; static void keyboard_binding_execute(struct roots_keyboard *keyboard, @@ -56,21 +75,13 @@ static void keyboard_binding_execute(struct roots_keyboard *keyboard, } /** - * Process a keypress from the keyboard. + * Execute a built-in, hardcoded compositor action when a keysym is pressed. * * Returns true if the keysym was handled by a binding and false if the event * should be propagated to clients. */ -static bool keyboard_keysym_press(struct roots_keyboard *keyboard, +static bool keyboard_press_keysym(struct roots_keyboard *keyboard, xkb_keysym_t keysym) { - ssize_t i = keyboard_pressed_keysym_index(keyboard, keysym); - if (i < 0) { - i = keyboard_pressed_keysym_index(keyboard, XKB_KEY_NoSymbol); - if (i >= 0) { - keyboard->pressed_keysyms[i] = keysym; - } - } - if (keysym >= XKB_KEY_XF86Switch_VT_1 && keysym <= XKB_KEY_XF86Switch_VT_12) { struct roots_server *server = keyboard->input->server; @@ -90,7 +101,35 @@ static bool keyboard_keysym_press(struct roots_keyboard *keyboard, wlr_seat_keyboard_end_grab(keyboard->seat->seat); } - uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); + return false; +} + +/** + * Press or release keysyms. + * + * Returns true if the keysym was handled by a binding and false if the event + * should be propagated to clients. + */ +static bool keyboard_handle_keysyms(struct roots_keyboard *keyboard, + xkb_keysym_t *pressed_keysyms, uint32_t modifiers, + const xkb_keysym_t *keysyms, size_t keysyms_len, + enum wlr_key_state state) { + bool handled = false; + for (size_t i = 0; i < keysyms_len; ++i) { + if (state == WLR_KEY_PRESSED) { + pressed_keysyms_add(pressed_keysyms, keysyms[i]); + handled |= keyboard_press_keysym(keyboard, keysyms[i]); + } else { // WLR_KEY_RELEASED + pressed_keysyms_remove(pressed_keysyms, keysyms[i]); + } + } + if (handled) { + return true; + } + if (state != WLR_KEY_PRESSED) { + return false; + } + struct wl_list *bindings = &keyboard->input->server->config->bindings; struct roots_binding_config *bc; wl_list_for_each(bc, bindings, link) { @@ -100,7 +139,7 @@ static bool keyboard_keysym_press(struct roots_keyboard *keyboard, bool ok = true; for (size_t i = 0; i < bc->keysyms_len; i++) { - ssize_t j = keyboard_pressed_keysym_index(keyboard, bc->keysyms[i]); + ssize_t j = pressed_keysyms_index(pressed_keysyms, bc->keysyms[i]); if (j < 0) { ok = false; break; @@ -116,86 +155,64 @@ static bool keyboard_keysym_press(struct roots_keyboard *keyboard, return false; } -static void keyboard_keysym_release(struct roots_keyboard *keyboard, - xkb_keysym_t keysym) { - ssize_t i = keyboard_pressed_keysym_index(keyboard, keysym); - if (i >= 0) { - keyboard->pressed_keysyms[i] = XKB_KEY_NoSymbol; - } -} /* - * Process keypresses from the keyboard as xkb sees them. + * Get keysyms and modifiers from the keyboard as xkb sees them. * * This uses the xkb keysyms translation based on pressed modifiers and clears * the consumed modifiers from the list of modifiers passed to keybind * detection. * - * (On US layout) this will trigger: [Alt]+[at] + * On US layout, this will trigger: Alt + @ */ -static bool keyboard_keysyms_xkb(struct roots_keyboard *keyboard, - uint32_t keycode, enum wlr_key_state state) { - uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); - const xkb_keysym_t *syms; - int syms_len = xkb_state_key_get_syms(keyboard->device->keyboard->xkb_state, - keycode, &syms); - uint32_t consumed = xkb_state_key_get_consumed_mods2( +static size_t keyboard_keysyms_translated(struct roots_keyboard *keyboard, + xkb_keycode_t keycode, const xkb_keysym_t **keysyms, + uint32_t *modifiers) { + *modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); + xkb_mod_mask_t consumed = xkb_state_key_get_consumed_mods2( keyboard->device->keyboard->xkb_state, keycode, XKB_CONSUMED_MODE_XKB); + *modifiers = *modifiers & ~consumed; - // TODO: actually use this value - modifiers = modifiers & ~consumed; - - bool handled = false; - for (int i = 0; i < syms_len; i++) { - if (state) { - bool keysym_handled = - keyboard_keysym_press(keyboard, syms[i]); - handled = handled || keysym_handled; - } else { // WLR_KEY_RELEASED - keyboard_keysym_release(keyboard, syms[i]); - } - } - - return handled; + return xkb_state_key_get_syms(keyboard->device->keyboard->xkb_state, + keycode, keysyms); } + /* - * Process keypresses from the keyboard as if modifiers didn't change keysyms. + * Get keysyms and modifiers from the keyboard as if modifiers didn't change + * keysyms. * * This avoids the xkb keysym translation based on modifiers considered pressed - * in the state and uses the list of modifiers saved on the rootston side. + * in the state. * - * This will trigger the keybind: [Alt]+[Shift]+2 + * This will trigger the keybind: Alt + Shift + 2 */ -static bool keyboard_keysyms_simple(struct roots_keyboard *keyboard, - uint32_t keycode, enum wlr_key_state state) { - const xkb_keysym_t *syms; +static size_t keyboard_keysyms_raw(struct roots_keyboard *keyboard, + xkb_keycode_t keycode, const xkb_keysym_t **keysyms, + uint32_t *modifiers) { + *modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); + xkb_layout_index_t layout_index = xkb_state_key_get_layout( keyboard->device->keyboard->xkb_state, keycode); - int syms_len = xkb_keymap_key_get_syms_by_level( - keyboard->device->keyboard->keymap, keycode, layout_index, 0, &syms); - - bool handled = false; - for (int i = 0; i < syms_len; i++) { - if (state) { - bool keysym_handled = keyboard_keysym_press(keyboard, syms[i]); - handled = handled || keysym_handled; - } else { // WLR_KEY_RELEASED - keyboard_keysym_release(keyboard, syms[i]); - } - } - - return handled; + return xkb_keymap_key_get_syms_by_level(keyboard->device->keyboard->keymap, + keycode, layout_index, 0, keysyms); } void roots_keyboard_handle_key(struct roots_keyboard *keyboard, struct wlr_event_keyboard_key *event) { - uint32_t keycode = event->keycode + 8; - - bool handled = keyboard_keysyms_xkb(keyboard, keycode, event->state); + xkb_keycode_t keycode = event->keycode + 8; + uint32_t modifiers; + const xkb_keysym_t *keysyms; + size_t keysyms_len = keyboard_keysyms_translated(keyboard, keycode, + &keysyms, &modifiers); + bool handled = keyboard_handle_keysyms(keyboard, + keyboard->pressed_keysyms_translated, modifiers, keysyms, keysyms_len, + event->state); if (!handled) { - bool key_handled = keyboard_keysyms_simple(keyboard, keycode, + keysyms_len = keyboard_keysyms_raw(keyboard, keycode, &keysyms, + &modifiers); + handled = keyboard_handle_keysyms(keyboard, + keyboard->pressed_keysyms_raw, modifiers, keysyms, keysyms_len, event->state); - handled = handled || key_handled; } if (!handled) { -- cgit v1.2.3