diff --git a/include/waybox/server.h b/include/waybox/server.h index 9abcfda..06e8857 100644 --- a/include/waybox/server.h +++ b/include/waybox/server.h @@ -46,7 +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_inhibit_manager_v1 *idle_inhibit_manager; struct wlr_idle_notifier_v1 *idle_notifier; struct wlr_output_layout *output_layout; struct wlr_xdg_output_manager_v1 *output_manager; @@ -54,6 +54,7 @@ struct wb_server { struct wlr_scene *scene; struct wlr_scene_output_layout *scene_layout; struct wlr_subcompositor *subcompositor; + struct wlr_output_manager_v1 *wlr_output_manager; struct wb_config *config; char *config_file; @@ -70,8 +71,6 @@ 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; @@ -82,6 +81,11 @@ struct wb_server { struct wl_listener new_xdg_surface; #endif + struct wl_listener destroy_inhibit_manager; + struct wl_listener destroy_inhibitor; + struct wl_listener new_inhibitor; + struct wl_list inhibitors; + struct wl_listener new_input; struct wl_listener new_output; struct wl_listener output_configuration_applied; diff --git a/include/waybox/xdg_shell.h b/include/waybox/xdg_shell.h index b7568de..4855d26 100644 --- a/include/waybox/xdg_shell.h +++ b/include/waybox/xdg_shell.h @@ -20,12 +20,9 @@ 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 index 3bfac1c..fe3caf7 100644 --- a/waybox/idle.c +++ b/waybox/idle.c @@ -2,27 +2,38 @@ #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; +static void idle_inhibit_manager_destroy(struct wl_listener *listener, void *data) { + struct wb_server *server = wl_container_of(listener, server, destroy_inhibit_manager); + wl_list_remove(&server->inhibitors); } -void idle_inhibitor_destroy(struct wl_listener *listener, void *data) { - struct wb_toplevel *toplevel = wl_container_of(listener, toplevel, new_inhibitor); - toplevel->inhibited = false; +static void idle_inhibitor_destroy(struct wl_listener *listener, void *data) { + struct wb_server *server = wl_container_of(listener, server, destroy_inhibitor); + /* wlroots will destroy the inhibitor after this callback, so this number will be 1 if the + * last inhibitor is being destroyed. */ + wlr_idle_notifier_v1_set_inhibited(server->idle_notifier, + wl_list_length(&server->inhibitors) > 1); +} + +static void idle_inhibitor_new(struct wl_listener *listener, void *data) { + struct wb_server *server = wl_container_of(listener, server, new_inhibitor); + struct wlr_idle_inhibitor_v1 *inhibitor = data; + + server->destroy_inhibitor.notify = idle_inhibitor_destroy; + wl_signal_add(&inhibitor->events.destroy, &server->destroy_inhibitor); + wl_list_remove(&inhibitor->link); + wl_list_insert(&server->inhibitors, &inhibitor->link); + wlr_idle_notifier_v1_set_inhibited(server->idle_notifier, true); } 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); + server->idle_inhibit_manager = wlr_idle_inhibit_v1_create(server->wl_display); + + wl_list_init(&server->inhibitors); + server->new_inhibitor.notify = idle_inhibitor_new; + wl_signal_add(&server->idle_inhibit_manager->events.new_inhibitor, &server->new_inhibitor); + server->destroy_inhibit_manager.notify = idle_inhibit_manager_destroy; + wl_signal_add(&server->idle_inhibit_manager->events.destroy, &server->destroy_inhibit_manager); return true; } diff --git a/waybox/idle.h b/waybox/idle.h index 2e5c689..0adfa79 100644 --- a/waybox/idle.h +++ b/waybox/idle.h @@ -1,4 +1,3 @@ #include "waybox/server.h" bool create_idle_manager(struct wb_server *server); -bool install_inhibitor(struct wb_toplevel *toplevel); diff --git a/waybox/xdg_shell.c b/waybox/xdg_shell.c index 9f8a855..8f37e55 100644 --- a/waybox/xdg_shell.c +++ b/waybox/xdg_shell.c @@ -75,7 +75,6 @@ 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) { @@ -368,8 +367,6 @@ 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;