Skip to content

Commit

Permalink
Updated to wlroots-0.18
Browse files Browse the repository at this point in the history
  • Loading branch information
ErikReider committed Sep 16, 2024
1 parent 19016c1 commit a2c59c3
Show file tree
Hide file tree
Showing 9 changed files with 152 additions and 61 deletions.
3 changes: 2 additions & 1 deletion include/comp/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ struct comp_server {
struct wl_display *wl_display;
struct wlr_backend *headless_backend; // used for creating virtual outputs
struct wlr_backend *backend;
struct wlr_session *session;
struct wlr_renderer *renderer;
struct wlr_allocator *allocator;
struct wl_event_loop *wl_event_loop;
Expand All @@ -29,7 +30,7 @@ struct comp_server {

// XDG
struct wlr_xdg_shell *xdg_shell;
struct wl_listener new_xdg_surface;
struct wl_listener new_xdg_toplevel;
struct wl_listener new_xdg_decoration;
struct wl_list xdg_decorations;

Expand Down
2 changes: 1 addition & 1 deletion include/desktop/xdg.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ struct comp_xdg_toplevel {
struct wl_listener set_title;
};

void xdg_new_xdg_surface(struct wl_listener *listener, void *data);
void xdg_new_xdg_toplevel(struct wl_listener *listener, void *data);

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

Expand Down
6 changes: 3 additions & 3 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ add_project_arguments(

# Execute the wlroots subproject, if any
wlroots_options = [ 'examples=false' ]
wlroots_version = ['>=0.17.0', '<0.18.0']
wlroots_version = ['>=0.18.0', '<0.19.0']
subproject(
'wlroots',
default_options: wlroots_options,
required: false,
version: wlroots_version,
)
wlroots = dependency('wlroots',
wlroots = dependency('wlroots-0.18',
version: wlroots_version,
default_options: wlroots_options,
)
Expand All @@ -58,7 +58,7 @@ subproject(
required: false,
version: scenefx_version,
)
scenefx = dependency('scenefx', version: scenefx_version)
scenefx = dependency('scenefx-0.1', version: scenefx_version)

cc = meson.get_compiler('c')

Expand Down
142 changes: 117 additions & 25 deletions src/comp/server.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#include <wlr/backend.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_xcursor_manager.h>
#include <wlr/util/log.h>

Expand Down Expand Up @@ -65,55 +68,144 @@ static void server_update_monitors(struct comp_server *server) {
output_config);
}

static void
server_apply_output_config(struct comp_server *server,
struct wlr_output_configuration_v1 *output_config,
bool test) {
// TODO: Check if HEADLESS output or not
bool ok = true;
static bool
apply_resolved_output_configs(struct wlr_output_configuration_head_v1 *configs,
size_t configs_len, bool test) {
struct wlr_backend_output_state *states =
calloc(configs_len, sizeof(*states));
if (!states) {
return false;
}

wlr_log(WLR_DEBUG, "Committing %zd outputs", configs_len);
for (size_t i = 0; i < configs_len; i++) {
struct wlr_output_configuration_head_v1 *head = &configs[i];
struct wlr_backend_output_state *backend_state = &states[i];

struct wlr_output_configuration_head_v1 *head;
wl_list_for_each(head, &output_config->heads, link) {
struct wlr_output *output = head->state.output;
struct comp_output *monitor = output->data;

wlr_output_enable(output, head->state.enabled);
backend_state->output = head->state.output;
wlr_output_state_init(&backend_state->base);

struct wlr_output_state *state = &backend_state->base;

// Skip fallback
if (monitor == server.fallback_output) {
continue;
}

wlr_log(WLR_DEBUG, "Preparing config for %s", head->state.output->name);
wlr_output_state_set_enabled(state, head->state.enabled);
if (head->state.enabled) {
if (head->state.mode) {
wlr_output_set_mode(output, head->state.mode);
wlr_output_state_set_mode(state, head->state.mode);
} else {
wlr_output_set_custom_mode(output,
head->state.custom_mode.width,
head->state.custom_mode.height,
head->state.custom_mode.refresh);
wlr_output_state_set_custom_mode(
state, head->state.custom_mode.width,
head->state.custom_mode.height,
head->state.custom_mode.refresh);
}

if (monitor->geometry.x != head->state.x ||
monitor->geometry.y != head->state.y) {
wlr_output_layout_add(server->output_layout, output,
wlr_output_layout_add(server.output_layout, output,
head->state.x, head->state.y);
}
wlr_output_set_transform(output, head->state.transform);
wlr_output_set_scale(output, head->state.scale);
wlr_xcursor_manager_load(server->seat->cursor->cursor_mgr,
wlr_output_state_set_transform(state, head->state.transform);
wlr_output_state_set_scale(state, head->state.scale);
wlr_xcursor_manager_load(server.seat->cursor->cursor_mgr,
head->state.scale);
wlr_output_enable_adaptive_sync(output,
head->state.adaptive_sync_enabled);
wlr_output_state_set_adaptive_sync_enabled(
state, head->state.adaptive_sync_enabled);
}
}

struct wlr_output_swapchain_manager swapchain_mgr;
wlr_output_swapchain_manager_init(&swapchain_mgr, server.backend);
bool ok = wlr_output_swapchain_manager_prepare(&swapchain_mgr, states,
configs_len);

if (!ok || test) {
goto out;
}

for (size_t i = 0; i < configs_len; i++) {
struct wlr_output_configuration_head_v1 *head = &configs[i];
struct wlr_backend_output_state *backend_state = &states[i];

struct wlr_output *output = head->state.output;
struct comp_output *monitor = output->data;

// Skip fallback
if (monitor == server.fallback_output) {
continue;
}

if (test) {
ok &= wlr_output_test(output);
wlr_output_rollback(output);
} else {
ok &= wlr_output_commit(output);
struct wlr_scene_output_state_options opts = {
.swapchain = wlr_output_swapchain_manager_get_swapchain(
&swapchain_mgr, output),
};
struct wlr_scene_output *scene_output = monitor->scene_output;
struct wlr_output_state *state = &backend_state->base;
if (!wlr_scene_output_build_state(scene_output, state, &opts)) {
wlr_log(WLR_ERROR, "Building output state for '%s' failed",
backend_state->output->name);
goto out;
}
}

ok = wlr_backend_commit(server.backend, states, configs_len);
if (!ok) {
wlr_log(WLR_ERROR, "Backend commit failed");
goto out;
}

wlr_log(WLR_DEBUG, "Commit of %zd outputs succeeded", configs_len);

wlr_output_swapchain_manager_apply(&swapchain_mgr);

out:
wlr_output_swapchain_manager_finish(&swapchain_mgr);
for (size_t i = 0; i < configs_len; i++) {
struct wlr_backend_output_state *backend_state = &states[i];
wlr_output_state_finish(&backend_state->base);
}
free(states);

return ok;
}

static void
server_apply_output_config(struct comp_server *server,
struct wlr_output_configuration_v1 *output_config,
bool test) {
bool ok = false;

size_t configs_len = wl_list_length(&output_config->heads);
struct wlr_output_configuration_head_v1 *configs =
calloc(configs_len, sizeof(*configs));
if (!configs) {
goto done;
}

size_t i = 0;
struct wlr_output_configuration_head_v1 *head;
wl_list_for_each(head, &output_config->heads, link) {
configs[i++] = *head;
}

ok = apply_resolved_output_configs(configs, configs_len, test);

free(configs);

done:
if (ok) {
wlr_output_configuration_v1_send_succeeded(output_config);
} else {
wlr_output_configuration_v1_send_failed(output_config);
}
wlr_output_configuration_v1_destroy(output_config);

server_update_monitors(server);
}
Expand Down
34 changes: 12 additions & 22 deletions src/desktop/xdg.c
Original file line number Diff line number Diff line change
Expand Up @@ -327,32 +327,20 @@ static void xdg_toplevel_unmap(struct wl_listener *listener, void *data) {
comp_toplevel_generic_unmap(toplevel);
}

void xdg_new_xdg_surface(struct wl_listener *listener, void *data) {
void xdg_new_xdg_toplevel(struct wl_listener *listener, void *data) {
/* This event is raised when wlr_xdg_shell receives a new xdg surface from a
* client, either a toplevel (application window) or popup. */
struct comp_server *server =
wl_container_of(listener, server, new_xdg_surface);
struct wlr_xdg_surface *xdg_surface = data;

switch (xdg_surface->role) {
case WLR_XDG_SURFACE_ROLE_NONE:
// Ignore surfaces with the role none
wlr_log(WLR_ERROR, "Unknown XDG Surface Role");
return;
case WLR_XDG_SURFACE_ROLE_POPUP:
// Ignore surfaces with the role popup and listen to signal after the
// toplevel has ben mapped
return;
case WLR_XDG_SURFACE_ROLE_TOPLEVEL:
break;
}
wl_container_of(listener, server, new_xdg_toplevel);
// struct wlr_xdg_surface *xdg_surface = data;
struct wlr_xdg_toplevel *xdg_toplevel = data;

struct comp_xdg_toplevel *toplevel_xdg = calloc(1, sizeof(*toplevel_xdg));
if (!toplevel_xdg) {
wlr_log(WLR_ERROR, "Could not allocate comp XDG toplevel");
return;
}
toplevel_xdg->xdg_toplevel = xdg_surface->toplevel;
toplevel_xdg->xdg_toplevel = xdg_toplevel;
bool is_fullscreen = toplevel_xdg->xdg_toplevel->requested.fullscreen;

// Add the toplevel to the tiled/floating layer
Expand Down Expand Up @@ -383,19 +371,21 @@ void xdg_new_xdg_surface(struct wl_listener *listener, void *data) {
toplevel->toplevel_scene_tree = wlr_scene_xdg_surface_create(
toplevel->object.scene_tree, toplevel_xdg->xdg_toplevel->base);
toplevel->toplevel_scene_tree->node.data = &toplevel->object;
xdg_surface->data = toplevel->object.scene_tree;
xdg_toplevel->base->data = toplevel->object.scene_tree;

/*
* Events
*/

/* Listen to the various events it can emit */
toplevel_xdg->map.notify = xdg_toplevel_map;
wl_signal_add(&xdg_surface->surface->events.map, &toplevel_xdg->map);
wl_signal_add(&xdg_toplevel->base->surface->events.map, &toplevel_xdg->map);
toplevel_xdg->unmap.notify = xdg_toplevel_unmap;
wl_signal_add(&xdg_surface->surface->events.unmap, &toplevel_xdg->unmap);
wl_signal_add(&xdg_toplevel->base->surface->events.unmap,
&toplevel_xdg->unmap);
toplevel_xdg->commit.notify = xdg_toplevel_commit;
wl_signal_add(&xdg_surface->surface->events.commit, &toplevel_xdg->commit);
wl_signal_add(&xdg_toplevel->base->surface->events.commit,
&toplevel_xdg->commit);
toplevel_xdg->destroy.notify = xdg_toplevel_destroy;
wl_signal_add(&xdg_surface->events.destroy, &toplevel_xdg->destroy);
wl_signal_add(&xdg_toplevel->base->events.destroy, &toplevel_xdg->destroy);
}
5 changes: 5 additions & 0 deletions src/desktop/xdg_decoration.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <wayland-util.h>
#include <wlr/util/log.h>

#include "comp/object.h"
#include "comp/tiling_node.h"
Expand Down Expand Up @@ -60,6 +61,10 @@ static void xdg_decoration_handle_request_mode(struct wl_listener *listener,
/* Ensure that the XDG toplevels use our server-side decorations */
void handle_xdg_decoration(struct wl_listener *listener, void *data) {
struct wlr_xdg_toplevel_decoration_v1 *wlr_deco = data;
if (!wlr_deco->toplevel) {
wlr_log(WLR_ERROR, "Decoration Toplevel NULL");
return;
}
struct wlr_scene_tree *tree = wlr_deco->toplevel->base->data;
struct comp_object *object = tree->node.data;
if (!object || object->type != COMP_OBJECT_TYPE_TOPLEVEL) {
Expand Down
14 changes: 7 additions & 7 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,14 +149,15 @@ int main(int argc, char *argv[]) {
* backend based on the current environment, such as opening an X11 window
* if an X11 server is running. */
// TODO: Use wlr_session?
server.backend = wlr_backend_autocreate(server.wl_display, NULL);
server.backend =
wlr_backend_autocreate(server.wl_event_loop, &server.session);
if (server.backend == NULL) {
wlr_log(WLR_ERROR, "failed to create wlr_backend");
return 1;
}

// Create headless backend
server.headless_backend = wlr_headless_backend_create(server.wl_display);
server.headless_backend = wlr_headless_backend_create(server.wl_event_loop);
if (server.headless_backend == NULL) {
wlr_log(WLR_ERROR, "Failed to create headless backend");
wlr_backend_destroy(server.backend);
Expand Down Expand Up @@ -206,7 +207,7 @@ int main(int argc, char *argv[]) {

/* Creates an output layout, which a wlroots utility for working with an
* arrangement of screens in a physical layout. */
server.output_layout = wlr_output_layout_create();
server.output_layout = wlr_output_layout_create(server.wl_display);
if (server.output_layout == NULL) {
wlr_log(WLR_ERROR, "failed to create wlr_output_layout");
return 1;
Expand Down Expand Up @@ -260,7 +261,6 @@ int main(int argc, char *argv[]) {
wlr_log(WLR_ERROR, "failed to create wlr_presentation");
return 1;
}
wlr_scene_set_presentation(server.root_scene, presentation);

// Create a fallback headless output
struct wlr_output *wlr_output = wlr_headless_add_output(
Expand All @@ -278,9 +278,9 @@ int main(int argc, char *argv[]) {
* https://drewdevault.com/2018/07/29/Wayland-shells.html.
*/
server.xdg_shell = wlr_xdg_shell_create(server.wl_display, 3);
server.new_xdg_surface.notify = xdg_new_xdg_surface;
wl_signal_add(&server.xdg_shell->events.new_surface,
&server.new_xdg_surface);
server.new_xdg_toplevel.notify = xdg_new_xdg_toplevel;
wl_signal_add(&server.xdg_shell->events.new_toplevel,
&server.new_xdg_toplevel);

/*
* Layer shell
Expand Down
3 changes: 2 additions & 1 deletion src/seat/cursor.c
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,8 @@ static void comp_server_cursor_axis(struct wl_listener *listener, void *data) {
/* Notify the client with pointer focus of the axis event. */
wlr_seat_pointer_notify_axis(server->seat->wlr_seat, event->time_msec,
event->orientation, event->delta,
event->delta_discrete, event->source);
event->delta_discrete, event->source,
event->relative_direction);
}

static void comp_server_cursor_frame(struct wl_listener *listener, void *data) {
Expand Down
4 changes: 3 additions & 1 deletion src/seat/keyboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,9 @@ static void keyboard_handle_key(struct wl_listener *listener, void *data) {
}
}

if (!handled) {
// TODO: Handling for wlr_session_change_vt

if (!handled && seat->wlr_seat->keyboard_state.focused_surface) {
/* Otherwise, we pass it along to the client. */
wlr_seat_set_keyboard(wlr_seat, keyboard->wlr_keyboard);
wlr_seat_keyboard_notify_key(wlr_seat, event->time_msec, event->keycode,
Expand Down

0 comments on commit a2c59c3

Please sign in to comment.