From b5f405590408032c672e4fa34b1ae7812de1bc7b Mon Sep 17 00:00:00 2001 From: Keith Bowes Date: Sat, 30 Dec 2023 15:30:52 -0500 Subject: [PATCH] Implemented idle-inhibit Now all the protocols in ./protocol are actually being used --- include/waybox/output.h | 3 ++- include/waybox/server.h | 4 ++++ include/waybox/xdg_shell.h | 3 +++ waybox/idle.c | 28 ++++++++++++++++++++++++++++ waybox/idle.h | 4 ++++ waybox/meson.build | 1 + waybox/output.c | 26 ++++++++++++++++++++++++++ waybox/server.c | 8 +++----- waybox/xdg_shell.c | 8 ++++++-- 9 files changed, 77 insertions(+), 8 deletions(-) create mode 100644 waybox/idle.c create mode 100644 waybox/idle.h diff --git a/include/waybox/output.h b/include/waybox/output.h index 4658025..6b49b68 100644 --- a/include/waybox/output.h +++ b/include/waybox/output.h @@ -4,6 +4,7 @@ #include #include "waybox/server.h" +#include struct wb_output { struct wlr_output *wlr_output; @@ -34,6 +35,6 @@ struct wb_output { void handle_gamma_control_set_gamma(struct wl_listener *listener, void *data); void output_frame_notify(struct wl_listener *listener, void *data); void output_destroy_notify(struct wl_listener *listener, void *data); -void new_output_notify(struct wl_listener *listener, void *data); +void init_output(struct wb_server *server); #endif /* output.h */ diff --git a/include/waybox/server.h b/include/waybox/server.h index c154445..9abcfda 100644 --- a/include/waybox/server.h +++ b/include/waybox/server.h @@ -46,6 +46,7 @@ struct wb_server { struct wlr_backend *backend; struct wlr_compositor *compositor; struct wlr_gamma_control_manager_v1 *gamma_control_manager; + struct wlr_idle_inhibit_manager_v1 *idle_inhibitor; struct wlr_idle_notifier_v1 *idle_notifier; struct wlr_output_layout *output_layout; struct wlr_xdg_output_manager_v1 *output_manager; @@ -69,6 +70,8 @@ struct wb_server { struct wlr_layer_shell_v1 *layer_shell; struct wlr_xdg_shell *xdg_shell; + struct wlr_output_manager_v1 *wlr_output_manager; + struct wl_listener gamma_control_set_gamma; struct wl_listener new_layer_surface; struct wl_listener new_xdg_decoration; @@ -81,6 +84,7 @@ struct wb_server { struct wl_listener new_input; struct wl_listener new_output; + struct wl_listener output_configuration_applied; struct wl_list outputs; /* wb_output::link */ }; diff --git a/include/waybox/xdg_shell.h b/include/waybox/xdg_shell.h index 4855d26..b7568de 100644 --- a/include/waybox/xdg_shell.h +++ b/include/waybox/xdg_shell.h @@ -20,9 +20,12 @@ struct wb_toplevel { struct wl_listener request_minimize; struct wl_listener request_move; struct wl_listener request_resize; + struct wl_listener new_inhibitor; + struct wl_listener destroy_inhibitor; struct wlr_box geometry; struct wlr_box previous_geometry; + bool inhibited; }; void init_xdg_shell(struct wb_server *server); diff --git a/waybox/idle.c b/waybox/idle.c new file mode 100644 index 0000000..3bfac1c --- /dev/null +++ b/waybox/idle.c @@ -0,0 +1,28 @@ +#include + +#include "idle.h" + +void idle_inhibitor_new(struct wl_listener *listener, void *data) { + struct wb_toplevel *toplevel = wl_container_of(listener, toplevel, new_inhibitor); + toplevel->inhibited = true; +} + +void idle_inhibitor_destroy(struct wl_listener *listener, void *data) { + struct wb_toplevel *toplevel = wl_container_of(listener, toplevel, new_inhibitor); + toplevel->inhibited = false; +} + +bool create_idle_manager(struct wb_server *server) { + server->idle_notifier = wlr_idle_notifier_v1_create(server->wl_display); + server->idle_inhibitor = wlr_idle_inhibit_v1_create(server->wl_display); + return true; +} + +bool install_inhibitor(struct wb_toplevel *toplevel) { + + toplevel->new_inhibitor.notify = idle_inhibitor_new; + wl_signal_add(&toplevel->server->idle_inhibitor->events.new_inhibitor, &toplevel->new_inhibitor); + toplevel->destroy_inhibitor.notify = idle_inhibitor_destroy; + wl_signal_add(&toplevel->server->idle_inhibitor->events.destroy, &toplevel->destroy_inhibitor); + return true; +} diff --git a/waybox/idle.h b/waybox/idle.h new file mode 100644 index 0000000..2e5c689 --- /dev/null +++ b/waybox/idle.h @@ -0,0 +1,4 @@ +#include "waybox/server.h" + +bool create_idle_manager(struct wb_server *server); +bool install_inhibitor(struct wb_toplevel *toplevel); diff --git a/waybox/meson.build b/waybox/meson.build index 8ce249b..0e5039c 100644 --- a/waybox/meson.build +++ b/waybox/meson.build @@ -2,6 +2,7 @@ wb_src = files( 'config.c', 'cursor.c', 'decoration.c', + 'idle.c', 'layer_shell.c', 'main.c', 'output.c', diff --git a/waybox/output.c b/waybox/output.c index 17b2f96..7696f8e 100644 --- a/waybox/output.c +++ b/waybox/output.c @@ -41,9 +41,19 @@ void output_frame_notify(struct wl_listener *listener, void *data) { wlr_scene_output_send_frame_done(scene_output, &now); } +void output_configuration_applied(struct wl_listener *listener, void *data) { + struct wb_server *server = wl_container_of(listener, server, wlr_output_manager); + struct wlr_output_configuration_v1 *configuration = data; + wlr_output_configuration_v1_send_succeeded(configuration); +} + void output_request_state_notify(struct wl_listener *listener, void *data) { struct wb_output *output = wl_container_of(listener, output, request_state); const struct wlr_output_event_request_state *event = data; + + struct wlr_output_configuration_v1 *configuration = wlr_output_configuration_v1_create(); + wlr_output_manager_v1_set_configuration(output->server->wlr_output_manager, configuration); + wlr_output_commit_state(output->wlr_output, event->state); } @@ -140,6 +150,22 @@ void new_output_notify(struct wl_listener *listener, void *data) { return; } + struct wlr_output_configuration_v1 *configuration = wlr_output_configuration_v1_create(); + wlr_output_configuration_head_v1_create(configuration, wlr_output); + wlr_output_manager_v1_set_configuration(server->wlr_output_manager, configuration); + struct wlr_scene_output *scene_output = wlr_scene_output_create(server->scene, wlr_output); wlr_scene_output_layout_add_output(server->scene_layout, l_output, scene_output); } + +void init_output(struct wb_server *server) { + wl_list_init(&server->outputs); + + server->new_output.notify = new_output_notify; + wl_signal_add(&server->backend->events.new_output, &server->new_output); + + server->wlr_output_manager = wlr_output_manager_v1_create(server->wl_display); + server->output_configuration_applied.notify = output_configuration_applied; + wl_signal_add(&server->wlr_output_manager->events.apply, &server->output_configuration_applied); + wl_signal_add(&server->wlr_output_manager->events.test, &server->output_configuration_applied); +} diff --git a/waybox/server.c b/waybox/server.c index 0f74026..487e44a 100644 --- a/waybox/server.c +++ b/waybox/server.c @@ -1,3 +1,4 @@ +#include "idle.h" #include "waybox/server.h" #include "waybox/xdg_shell.h" @@ -61,10 +62,7 @@ bool wb_create_backend(struct wb_server* server) { bool wb_start_server(struct wb_server* server) { init_config(server); - wl_list_init(&server->outputs); - - server->new_output.notify = new_output_notify; - wl_signal_add(&server->backend->events.new_output, &server->new_output); + init_output(server); /* Create a scene graph. This is a wlroots abstraction that handles all * rendering and damage tracking. All the compositor author needs to do @@ -100,7 +98,7 @@ bool wb_start_server(struct wb_server* server) { wl_signal_add(&server->gamma_control_manager->events.set_gamma, &server->gamma_control_set_gamma); wlr_screencopy_manager_v1_create(server->wl_display); - server->idle_notifier = wlr_idle_notifier_v1_create(server->wl_display); + create_idle_manager(server); wl_list_init(&server->toplevels); init_xdg_decoration(server); diff --git a/waybox/xdg_shell.c b/waybox/xdg_shell.c index 8d6ea6f..de5c6fe 100644 --- a/waybox/xdg_shell.c +++ b/waybox/xdg_shell.c @@ -1,3 +1,4 @@ +#include "idle.h" #include "waybox/xdg_shell.h" struct wb_toplevel *get_toplevel_at( @@ -35,7 +36,7 @@ void focus_toplevel(struct wb_toplevel *toplevel, struct wlr_surface *surface) { } struct wlr_xdg_surface *xdg_surface = wlr_xdg_surface_try_from_wlr_surface(surface); - if (xdg_surface) + if (xdg_surface != NULL) wlr_log(WLR_INFO, "%s: %s", _("Keyboard focus is now on surface"), xdg_surface->toplevel->app_id); @@ -46,7 +47,7 @@ void focus_toplevel(struct wb_toplevel *toplevel, struct wlr_surface *surface) { /* Don't re-focus an already focused surface. */ return; } - if (prev_surface) { + if (prev_surface != NULL) { /* * Deactivate the previously focused surface. This lets the client know * it no longer has focus and the client will repaint accordingly, e.g. @@ -72,6 +73,7 @@ void focus_toplevel(struct wb_toplevel *toplevel, struct wlr_surface *surface) { * clients without additional work on your part. */ seat_focus_surface(server->seat, toplevel->xdg_toplevel->base->surface); + wlr_idle_notifier_v1_set_inhibited(server->idle_notifier, toplevel->inhibited); } struct wlr_output *get_active_output(struct wb_toplevel *toplevel) { @@ -355,6 +357,8 @@ static void handle_new_xdg_toplevel(struct wl_listener *listener, void *data) { toplevel->new_popup.notify = handle_new_popup; wl_signal_add(&xdg_toplevel->base->events.new_popup, &toplevel->new_popup); + install_inhibitor(toplevel); + toplevel->scene_tree = wlr_scene_xdg_surface_create( &toplevel->server->scene->tree, xdg_toplevel->base); toplevel->scene_tree->node.data = toplevel;