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

Update to wlroots-0.18 #9

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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
3 changes: 2 additions & 1 deletion include/comp/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,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 @@ -46,7 +47,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
8 changes: 4 additions & 4 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -39,26 +39,26 @@ 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,
)

# Execute the scenefx subproject, if any
scenefx_version = '0.1'
scenefx_version = '0.2'
subproject(
'scenefx',
required: false,
version: scenefx_version,
)
scenefx = dependency('scenefx', version: scenefx_version)
scenefx = dependency('scenefx-0.2', 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 @@ -68,55 +71,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
4 changes: 3 additions & 1 deletion src/desktop/widgets/resize_edge.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <cairo.h>
#include <linux/input-event-codes.h>
#include <stdlib.h>
#include <wayland-server-protocol.h>
#include <wlr/types/wlr_cursor.h>
#include <wlr/util/log.h>
#include <xdg-shell-protocol.h>
Expand Down Expand Up @@ -56,7 +57,8 @@ static void edge_destroy(struct comp_widget *widget) {

static void edge_pointer_button(struct comp_widget *widget, double x, double y,
struct wlr_pointer_button_event *event) {
if (event->state != WLR_BUTTON_PRESSED || event->button != BTN_LEFT) {
if (event->state != WL_POINTER_BUTTON_STATE_PRESSED ||
event->button != BTN_LEFT) {
return;
}

Expand Down
34 changes: 12 additions & 22 deletions src/desktop/xdg.c
Original file line number Diff line number Diff line change
Expand Up @@ -329,32 +329,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 @@ -384,19 +372,21 @@ void xdg_new_xdg_surface(struct wl_listener *listener, void *data) {
toplevel->toplevel_scene_tree = wlr_scene_xdg_surface_create(
toplevel->object.content_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 @@ -73,6 +74,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 @@ -171,14 +171,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 @@ -228,7 +229,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 @@ -282,7 +283,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 @@ -300,9 +300,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
Loading