Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

output: use backend commits #316

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
pacman -Syu --noconfirm xcb-util-wm seatd git clang meson libinput libdrm mesa libxkbcommon wayland wayland-protocols xorg-server-xwayland scdoc

- name: Fetch wlroots as a subproject
run: git clone https://gitlab.freedesktop.org/wlroots/wlroots.git subprojects/wlroots -b 0.17
run: git clone https://gitlab.freedesktop.org/wlroots/wlroots.git subprojects/wlroots -b master

# TODO: use --fatal-meson-warnings when on wlroots 0.15.0
- name: Compile Cage (XWayland=${{ matrix.xwayland }})
Expand All @@ -51,7 +51,7 @@ jobs:
pacman-key --init
pacman -Syu --noconfirm xcb-util-wm seatd git clang meson libinput libdrm mesa libxkbcommon wayland wayland-protocols xorg-server-xwayland scdoc hwdata
- name: Fetch wlroots as a subproject
run: git clone https://gitlab.freedesktop.org/wlroots/wlroots.git subprojects/wlroots -b 0.17
run: git clone https://gitlab.freedesktop.org/wlroots/wlroots.git subprojects/wlroots -b master
- name: Check for formatting changes
run: |
meson build-clang-format -Dxwayland=enabled
Expand All @@ -70,7 +70,7 @@ jobs:
pacman-key --init
pacman -Syu --noconfirm xcb-util-wm seatd git clang meson libinput libdrm mesa libxkbcommon wayland wayland-protocols xorg-server-xwayland scdoc hwdata
- name: Fetch wlroots as a subproject
run: git clone https://gitlab.freedesktop.org/wlroots/wlroots.git subprojects/wlroots -b 0.17
run: git clone https://gitlab.freedesktop.org/wlroots/wlroots.git subprojects/wlroots -b master
- name: Run scan-build
run: |
meson build-scan-build -Dxwayland=enabled
Expand Down
11 changes: 6 additions & 5 deletions cage.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ main(int argc, char *argv[])
struct wl_event_source *sigterm_source =
wl_event_loop_add_signal(event_loop, SIGTERM, handle_signal, &server.wl_display);

server.backend = wlr_backend_autocreate(server.wl_display, &server.session);
server.backend = wlr_backend_autocreate(event_loop, &server.session);
if (!server.backend) {
wlr_log(WLR_ERROR, "Unable to create the wlroots backend");
ret = 1;
Expand Down Expand Up @@ -324,7 +324,7 @@ main(int argc, char *argv[])
wl_list_init(&server.views);
wl_list_init(&server.outputs);

server.output_layout = wlr_output_layout_create();
server.output_layout = wlr_output_layout_create(server.wl_display);
if (!server.output_layout) {
wlr_log(WLR_ERROR, "Unable to create output layout");
ret = 1;
Expand Down Expand Up @@ -397,8 +397,10 @@ main(int argc, char *argv[])
ret = 1;
goto end;
}
server.new_xdg_shell_surface.notify = handle_xdg_shell_surface_new;
wl_signal_add(&xdg_shell->events.new_surface, &server.new_xdg_shell_surface);
server.new_xdg_toplevel.notify = handle_new_xdg_toplevel;
wl_signal_add(&xdg_shell->events.new_toplevel, &server.new_xdg_toplevel);
server.new_xdg_popup.notify = handle_new_xdg_popup;
wl_signal_add(&xdg_shell->events.new_popup, &server.new_xdg_popup);

struct wlr_xdg_decoration_manager_v1 *xdg_decoration_manager =
wlr_xdg_decoration_manager_v1_create(server.wl_display);
Expand Down Expand Up @@ -433,7 +435,6 @@ main(int argc, char *argv[])
ret = 1;
goto end;
}
wlr_scene_set_presentation(server.scene, presentation);

if (!wlr_export_dmabuf_manager_v1_create(server.wl_display)) {
wlr_log(WLR_ERROR, "Unable to create the export DMABUF manager");
Expand Down
2 changes: 1 addition & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ if is_freebsd
)
endif

wlroots = dependency('wlroots', version: '>= 0.17.0', fallback: ['wlroots', 'wlroots'])
wlroots = dependency('wlroots', version: '>= 0.18.0', fallback: ['wlroots', 'wlroots'])
wayland_protos = dependency('wayland-protocols', version: '>=1.14')
wayland_server = dependency('wayland-server')
xkbcommon = dependency('xkbcommon')
Expand Down
65 changes: 36 additions & 29 deletions output.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@
#if WLR_HAS_X11_BACKEND
#include <wlr/backend/x11.h>
#endif
#include <wlr/render/swapchain.h>
#include <wlr/render/wlr_renderer.h>
#include <wlr/types/wlr_compositor.h>
#include <wlr/types/wlr_data_device.h>
#include <wlr/types/wlr_matrix.h>
#include <wlr/types/wlr_output.h>
#include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_output_management_v1.h>
#include <wlr/types/wlr_output_swapchain_manager.h>
#include <wlr/types/wlr_scene.h>
#include <wlr/types/wlr_xdg_shell.h>
#include <wlr/util/log.h>
Expand Down Expand Up @@ -131,31 +133,6 @@ output_disable(struct cg_output *output)
output_layout_remove(output);
}

static bool
output_apply_config(struct cg_output *output, struct wlr_output_configuration_head_v1 *head, bool test_only)
{
struct wlr_output_state state = {0};
wlr_output_head_v1_state_apply(&head->state, &state);

if (test_only) {
bool ret = wlr_output_test_state(output->wlr_output, &state);
return ret;
}

/* Apply output configuration */
if (!wlr_output_commit_state(output->wlr_output, &state)) {
return false;
}

if (head->state.enabled) {
output_layout_add(output, head->state.x, head->state.y);
} else {
output_layout_remove(output);
}

return true;
}

static void
handle_output_frame(struct wl_listener *listener, void *data)
{
Expand Down Expand Up @@ -356,17 +333,47 @@ output_set_window_title(struct cg_output *output, const char *title)
static bool
output_config_apply(struct cg_server *server, struct wlr_output_configuration_v1 *config, bool test_only)
{
struct wlr_output_configuration_head_v1 *head;
bool ok = false;

size_t states_len;
struct wlr_backend_output_state *states = wlr_output_configuration_v1_build_state(config, &states_len);
if (states == NULL) {
return false;
}

struct wlr_output_swapchain_manager swapchain_manager;
wlr_output_swapchain_manager_init(&swapchain_manager, server->backend);

ok = wlr_output_swapchain_manager_prepare(&swapchain_manager, states, states_len);
if (!ok || test_only) {
goto out;
}

ok = wlr_backend_commit(server->backend, states, states_len);
if (!ok) {
goto out;
}

wlr_output_swapchain_manager_apply(&swapchain_manager);

struct wlr_output_configuration_head_v1 *head;
wl_list_for_each (head, &config->heads, link) {
struct cg_output *output = head->state.output->data;

if (!output_apply_config(output, head, test_only)) {
return false;
if (head->state.enabled) {
output_layout_add(output, head->state.x, head->state.y);
} else {
output_layout_remove(output);
}
}

return true;
out:
wlr_output_swapchain_manager_finish(&swapchain_manager);
for (size_t i = 0; i < states_len; i++) {
wlr_output_state_finish(&states[i].base);
}
free(states);
return ok;
}

void
Expand Down
2 changes: 1 addition & 1 deletion seat.c
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,7 @@ handle_cursor_axis(struct wl_listener *listener, void *data)
struct wlr_pointer_axis_event *event = data;

wlr_seat_pointer_notify_axis(seat->seat, event->time_msec, event->orientation, event->delta,
event->delta_discrete, event->source);
event->delta_discrete, event->source, event->relative_direction);
wlr_idle_notifier_v1_notify_activity(seat->server->idle, seat->seat);
}

Expand Down
3 changes: 2 additions & 1 deletion server.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ struct cg_server {
struct wl_listener output_layout_change;

struct wl_listener xdg_toplevel_decoration;
struct wl_listener new_xdg_shell_surface;
struct wl_listener new_xdg_toplevel;
struct wl_listener new_xdg_popup;

struct wl_listener new_virtual_keyboard;
struct wl_listener new_virtual_pointer;
Expand Down
109 changes: 54 additions & 55 deletions xdg_shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,72 +221,71 @@ static const struct cg_view_impl xdg_shell_view_impl = {
};

void
handle_xdg_shell_surface_new(struct wl_listener *listener, void *data)
handle_new_xdg_toplevel(struct wl_listener *listener, void *data)
{
struct cg_server *server = wl_container_of(listener, server, new_xdg_shell_surface);
struct wlr_xdg_surface *xdg_surface = data;
struct cg_server *server = wl_container_of(listener, server, new_xdg_toplevel);
struct wlr_xdg_toplevel *toplevel = data;

switch (xdg_surface->role) {
case WLR_XDG_SURFACE_ROLE_TOPLEVEL:;
struct cg_xdg_shell_view *xdg_shell_view = calloc(1, sizeof(struct cg_xdg_shell_view));
if (!xdg_shell_view) {
wlr_log(WLR_ERROR, "Failed to allocate XDG Shell view");
return;
}
struct cg_xdg_shell_view *xdg_shell_view = calloc(1, sizeof(struct cg_xdg_shell_view));
if (!xdg_shell_view) {
wlr_log(WLR_ERROR, "Failed to allocate XDG Shell view");
return;
}

view_init(&xdg_shell_view->view, server, CAGE_XDG_SHELL_VIEW, &xdg_shell_view_impl);
xdg_shell_view->xdg_toplevel = xdg_surface->toplevel;
view_init(&xdg_shell_view->view, server, CAGE_XDG_SHELL_VIEW, &xdg_shell_view_impl);
xdg_shell_view->xdg_toplevel = toplevel;

xdg_shell_view->map.notify = handle_xdg_shell_surface_map;
wl_signal_add(&xdg_surface->surface->events.map, &xdg_shell_view->map);
xdg_shell_view->unmap.notify = handle_xdg_shell_surface_unmap;
wl_signal_add(&xdg_surface->surface->events.unmap, &xdg_shell_view->unmap);
xdg_shell_view->destroy.notify = handle_xdg_shell_surface_destroy;
wl_signal_add(&xdg_surface->events.destroy, &xdg_shell_view->destroy);
xdg_shell_view->request_fullscreen.notify = handle_xdg_shell_surface_request_fullscreen;
wl_signal_add(&xdg_surface->toplevel->events.request_fullscreen, &xdg_shell_view->request_fullscreen);
xdg_shell_view->map.notify = handle_xdg_shell_surface_map;
wl_signal_add(&toplevel->base->surface->events.map, &xdg_shell_view->map);
xdg_shell_view->unmap.notify = handle_xdg_shell_surface_unmap;
wl_signal_add(&toplevel->base->surface->events.unmap, &xdg_shell_view->unmap);
xdg_shell_view->destroy.notify = handle_xdg_shell_surface_destroy;
wl_signal_add(&toplevel->events.destroy, &xdg_shell_view->destroy);
xdg_shell_view->request_fullscreen.notify = handle_xdg_shell_surface_request_fullscreen;
wl_signal_add(&toplevel->events.request_fullscreen, &xdg_shell_view->request_fullscreen);

xdg_surface->data = xdg_shell_view;
break;
case WLR_XDG_SURFACE_ROLE_POPUP:;
struct wlr_xdg_popup *popup = xdg_surface->popup;
struct cg_view *view = popup_get_view(popup);
if (view == NULL) {
return;
}

struct wlr_scene_tree *parent_scene_tree = NULL;
struct wlr_xdg_surface *parent = wlr_xdg_surface_try_from_wlr_surface(popup->parent);
if (parent == NULL) {
return;
}
switch (parent->role) {
case WLR_XDG_SURFACE_ROLE_TOPLEVEL:;
parent_scene_tree = view->scene_tree;
break;
case WLR_XDG_SURFACE_ROLE_POPUP:
parent_scene_tree = parent->data;
break;
case WLR_XDG_SURFACE_ROLE_NONE:
break;
}
if (parent_scene_tree == NULL) {
return;
}
toplevel->base->data = xdg_shell_view;
}

struct wlr_scene_tree *popup_scene_tree = wlr_scene_xdg_surface_create(parent_scene_tree, xdg_surface);
if (popup_scene_tree == NULL) {
wlr_log(WLR_ERROR, "Failed to allocate scene-graph node for XDG popup");
return;
}
void
handle_new_xdg_popup(struct wl_listener *listener, void *data)
{
struct cg_server *server = wl_container_of(listener, server, new_xdg_popup);
struct wlr_xdg_popup *popup = data;

popup_unconstrain(view, popup);
struct cg_view *view = popup_get_view(popup);
if (view == NULL) {
return;
}

xdg_surface->data = popup_scene_tree;
struct wlr_scene_tree *parent_scene_tree = NULL;
struct wlr_xdg_surface *parent = wlr_xdg_surface_try_from_wlr_surface(popup->parent);
if (parent == NULL) {
return;
}
switch (parent->role) {
case WLR_XDG_SURFACE_ROLE_TOPLEVEL:;
parent_scene_tree = view->scene_tree;
break;
case WLR_XDG_SURFACE_ROLE_POPUP:
parent_scene_tree = parent->data;
break;
case WLR_XDG_SURFACE_ROLE_NONE:
assert(false); // unreachable
break;
}
if (parent_scene_tree == NULL) {
return;
}

struct wlr_scene_tree *popup_scene_tree = wlr_scene_xdg_surface_create(parent_scene_tree, popup->base);
if (popup_scene_tree == NULL) {
wlr_log(WLR_ERROR, "Failed to allocate scene-graph node for XDG popup");
return;
}

popup_unconstrain(view, popup);

popup->base->data = popup_scene_tree;
}

void
Expand Down
3 changes: 2 additions & 1 deletion xdg_shell.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ struct cg_xdg_decoration {
struct wl_listener request_mode;
};

void handle_xdg_shell_surface_new(struct wl_listener *listener, void *data);
void handle_new_xdg_toplevel(struct wl_listener *listener, void *data);
void handle_new_xdg_popup(struct wl_listener *listener, void *data);

void handle_xdg_toplevel_decoration(struct wl_listener *listener, void *data);

Expand Down
Loading