diff options
Diffstat (limited to 'rootston')
-rw-r--r-- | rootston/config.c | 2 | ||||
-rw-r--r-- | rootston/desktop.c | 15 | ||||
-rw-r--r-- | rootston/keyboard.c | 14 | ||||
-rw-r--r-- | rootston/output.c | 180 |
4 files changed, 140 insertions, 71 deletions
diff --git a/rootston/config.c b/rootston/config.c index 5c168679..119a9e2c 100644 --- a/rootston/config.c +++ b/rootston/config.c @@ -577,7 +577,7 @@ void roots_config_destroy(struct roots_config *config) { struct roots_output_config *roots_config_get_output(struct roots_config *config, struct wlr_output *output) { - char name[83]; + char name[88]; snprintf(name, sizeof(name), "%s %s %s", output->make, output->model, output->serial); diff --git a/rootston/desktop.c b/rootston/desktop.c index 5de916dd..06b785ad 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -1,4 +1,4 @@ -#define _POSIX_C_SOURCE 199309L +#define _POSIX_C_SOURCE 200112L #include <assert.h> #include <math.h> #include <stdlib.h> @@ -881,7 +881,6 @@ struct roots_desktop *desktop_create(struct roots_server *server, desktop->tablet_v2 = wlr_tablet_v2_create(server->wl_display); -#ifdef WLR_HAS_XWAYLAND const char *cursor_theme = NULL; const char *cursor_default = ROOTS_XCURSOR_DEFAULT; struct roots_cursor_config *cc = @@ -893,6 +892,15 @@ struct roots_desktop *desktop_create(struct roots_server *server, } } + char cursor_size_fmt[16]; + snprintf(cursor_size_fmt, sizeof(cursor_size_fmt), + "%d", ROOTS_XCURSOR_SIZE); + setenv("XCURSOR_SIZE", cursor_size_fmt, 1); + if (cursor_theme != NULL) { + setenv("XCURSOR_THEME", cursor_theme, 1); + } + +#ifdef WLR_HAS_XWAYLAND desktop->xcursor_manager = wlr_xcursor_manager_create(cursor_theme, ROOTS_XCURSOR_SIZE); if (desktop->xcursor_manager == NULL) { @@ -974,6 +982,9 @@ struct roots_desktop *desktop_create(struct roots_server *server, wl_signal_add(&desktop->pointer_constraints->events.new_constraint, &desktop->pointer_constraint); + desktop->presentation = + wlr_presentation_create(server->wl_display, server->backend); + return desktop; } diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 6ba0bd6d..66c373cf 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -5,7 +5,6 @@ #include <sys/wait.h> #include <unistd.h> #include <wayland-server.h> -#include <wlr/backend/multi.h> #include <wlr/backend/session.h> #include <wlr/types/wlr_input_device.h> #include <wlr/types/wlr_pointer_constraints_v1.h> @@ -201,14 +200,13 @@ static bool keyboard_execute_compositor_binding(struct roots_keyboard *keyboard, if (keysym >= XKB_KEY_XF86Switch_VT_1 && keysym <= XKB_KEY_XF86Switch_VT_12) { struct roots_server *server = keyboard->input->server; - if (wlr_backend_is_multi(server->backend)) { - struct wlr_session *session = - wlr_multi_get_session(server->backend); - if (session) { - unsigned vt = keysym - XKB_KEY_XF86Switch_VT_1 + 1; - wlr_session_change_vt(session, vt); - } + + struct wlr_session *session = wlr_backend_get_session(server->backend); + if (session) { + unsigned vt = keysym - XKB_KEY_XF86Switch_VT_1 + 1; + wlr_session_change_vt(session, vt); } + return true; } diff --git a/rootston/output.c b/rootston/output.c index e85612fa..9d376f8e 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -5,9 +5,10 @@ #include <time.h> #include <wlr/backend/drm.h> #include <wlr/config.h> -#include <wlr/types/wlr_matrix.h> #include <wlr/types/wlr_compositor.h> +#include <wlr/types/wlr_matrix.h> #include <wlr/types/wlr_output_layout.h> +#include <wlr/types/wlr_presentation_time.h> #include <wlr/types/wlr_wl_shell.h> #include <wlr/types/wlr_xdg_shell_v6.h> #include <wlr/types/wlr_xdg_shell.h> @@ -127,6 +128,65 @@ static void drag_icons_for_each_surface(struct roots_input *input, } } +static void layer_for_each_surface(struct wl_list *layer, + const struct wlr_box *output_layout_box, + wlr_surface_iterator_func_t iterator, struct layout_data *layout_data, + void *user_data) { + struct roots_layer_surface *roots_surface; + wl_list_for_each(roots_surface, layer, link) { + struct wlr_layer_surface_v1 *layer = roots_surface->layer_surface; + + layout_data->x = roots_surface->geo.x + output_layout_box->x; + layout_data->y = roots_surface->geo.y + output_layout_box->y; + layout_data->width = roots_surface->geo.width; + layout_data->height = roots_surface->geo.height; + layout_data->rotation = 0; + wlr_layer_surface_v1_for_each_surface(layer, iterator, user_data); + } +} + +static void output_for_each_surface(struct roots_output *output, + wlr_surface_iterator_func_t iterator, struct layout_data *layout_data, + void *user_data) { + struct wlr_output *wlr_output = output->wlr_output; + struct roots_desktop *desktop = output->desktop; + struct roots_server *server = desktop->server; + + const struct wlr_box *output_box = + wlr_output_layout_get_box(desktop->layout, wlr_output); + + if (output->fullscreen_view != NULL) { + struct roots_view *view = output->fullscreen_view; + if (wlr_output->fullscreen_surface == view->wlr_surface) { + // The surface is managed by the wlr_output + return; + } + + view_for_each_surface(view, layout_data, iterator, user_data); + +#ifdef WLR_HAS_XWAYLAND + if (view->type == ROOTS_XWAYLAND_VIEW) { + xwayland_children_for_each_surface(view->xwayland_surface, + iterator, layout_data, user_data); + } +#endif + } else { + struct roots_view *view; + wl_list_for_each_reverse(view, &desktop->views, link) { + view_for_each_surface(view, layout_data, iterator, user_data); + } + + drag_icons_for_each_surface(server->input, iterator, + layout_data, user_data); + } + + size_t len = sizeof(output->layers) / sizeof(output->layers[0]); + for (size_t i = 0; i < len; ++i) { + layer_for_each_surface(&output->layers[i], output_box, + iterator, layout_data, user_data); + } +} + struct render_data { struct layout_data layout; @@ -320,6 +380,14 @@ static void render_view(struct roots_view *view, struct render_data *data) { view_for_each_surface(view, &data->layout, render_surface, data); } +static void render_layer(struct roots_output *output, + const struct wlr_box *output_layout_box, struct render_data *data, + struct wl_list *layer) { + data->alpha = 1; + layer_for_each_surface(layer, output_layout_box, render_surface, + &data->layout, data); +} + static bool has_standalone_surface(struct roots_view *view) { if (!wl_list_empty(&view->wlr_surface->subsurfaces)) { return false; @@ -358,38 +426,6 @@ static void surface_send_frame_done(struct wlr_surface *surface, int sx, int sy, wlr_surface_send_frame_done(surface, when); } -static void render_layer(struct roots_output *output, - const struct wlr_box *output_layout_box, struct render_data *data, - struct wl_list *layer) { - struct roots_layer_surface *roots_surface; - wl_list_for_each(roots_surface, layer, link) { - struct wlr_layer_surface_v1 *layer = roots_surface->layer_surface; - - surface_for_each_surface(layer->surface, - roots_surface->geo.x + output_layout_box->x, - roots_surface->geo.y + output_layout_box->y, - 0, &data->layout, render_surface, data); - - wlr_layer_surface_v1_for_each_surface(layer, render_surface, data); - } -} - -static void layers_send_done( - struct roots_output *output, struct timespec *when) { - size_t len = sizeof(output->layers) / sizeof(output->layers[0]); - for (size_t i = 0; i < len; ++i) { - struct roots_layer_surface *roots_surface; - wl_list_for_each(roots_surface, &output->layers[i], link) { - struct wlr_layer_surface_v1 *layer = roots_surface->layer_surface; - wlr_surface_send_frame_done(layer->surface, when); - struct wlr_xdg_popup *popup; - wl_list_for_each(popup, &roots_surface->layer_surface->popups, link) { - wlr_surface_send_frame_done(popup->base->surface, when); - } - } - } -} - static void render_output(struct roots_output *output) { struct wlr_output *wlr_output = output->wlr_output; struct roots_desktop *desktop = output->desktop; @@ -537,33 +573,8 @@ damage_finish: pixman_region32_fini(&damage); // Send frame done events to all surfaces - if (output->fullscreen_view != NULL) { - struct roots_view *view = output->fullscreen_view; - if (wlr_output->fullscreen_surface == view->wlr_surface) { - // The surface is managed by the wlr_output - return; - } - - view_for_each_surface(view, &data.layout, surface_send_frame_done, - &data); - -#ifdef WLR_HAS_XWAYLAND - if (view->type == ROOTS_XWAYLAND_VIEW) { - xwayland_children_for_each_surface(view->xwayland_surface, - surface_send_frame_done, &data.layout, &data); - } -#endif - } else { - struct roots_view *view; - wl_list_for_each_reverse(view, &desktop->views, link) { - view_for_each_surface(view, &data.layout, surface_send_frame_done, - &data); - } - - drag_icons_for_each_surface(server->input, surface_send_frame_done, - &data.layout, &data); - } - layers_send_done(output, data.when); + output_for_each_surface(output, surface_send_frame_done, + &data.layout, &data); } void output_damage_whole(struct roots_output *output) { @@ -774,6 +785,7 @@ static void output_destroy(struct roots_output *output) { wl_list_remove(&output->destroy.link); wl_list_remove(&output->mode.link); wl_list_remove(&output->transform.link); + wl_list_remove(&output->present.link); wl_list_remove(&output->damage_frame.link); wl_list_remove(&output->damage_destroy.link); free(output); @@ -810,6 +822,52 @@ static void output_handle_transform(struct wl_listener *listener, void *data) { arrange_layers(output); } +struct presentation_data { + struct layout_data layout; + struct roots_output *output; + struct wlr_presentation_event *event; +}; + +static void surface_send_presented(struct wlr_surface *surface, int sx, int sy, + void *_data) { + struct presentation_data *data = _data; + struct roots_output *output = data->output; + float rotation = data->layout.rotation; + + double lx, ly; + get_layout_position(&data->layout, &lx, &ly, surface, sx, sy); + + if (!surface_intersect_output(surface, output->desktop->layout, + output->wlr_output, lx, ly, rotation, NULL)) { + return; + } + + wlr_presentation_send_surface_presented(output->desktop->presentation, + surface, data->event); +} + +static void output_handle_present(struct wl_listener *listener, void *data) { + struct roots_output *output = + wl_container_of(listener, output, present); + struct wlr_output_event_present *output_event = data; + + struct wlr_presentation_event event = { + .output = output->wlr_output, + .tv_sec = (uint64_t)output_event->when->tv_sec, + .tv_nsec = (uint32_t)output_event->when->tv_nsec, + .refresh = (uint32_t)output_event->refresh, + .seq = (uint64_t)output_event->seq, + .flags = output_event->flags, + }; + + struct presentation_data presentation_data = { + .output = output, + .event = &event, + }; + output_for_each_surface(output, surface_send_presented, + &presentation_data.layout, &presentation_data); +} + void handle_new_output(struct wl_listener *listener, void *data) { struct roots_desktop *desktop = wl_container_of(listener, desktop, new_output); @@ -837,6 +895,8 @@ void handle_new_output(struct wl_listener *listener, void *data) { wl_signal_add(&wlr_output->events.mode, &output->mode); output->transform.notify = output_handle_transform; wl_signal_add(&wlr_output->events.transform, &output->transform); + output->present.notify = output_handle_present; + wl_signal_add(&wlr_output->events.present, &output->present); output->damage_frame.notify = output_damage_handle_frame; wl_signal_add(&output->damage->events.frame, &output->damage_frame); |