From 2a7edfa24c973d3797aaa22e1a593cb1356eda94 Mon Sep 17 00:00:00 2001 From: Ryan Walklin Date: Sun, 25 Nov 2018 14:39:53 +0100 Subject: Factor out binding command execution to separate file --- rootston/bindings.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 rootston/bindings.c (limited to 'rootston/bindings.c') diff --git a/rootston/bindings.c b/rootston/bindings.c new file mode 100644 index 00000000..d9813cbc --- /dev/null +++ b/rootston/bindings.c @@ -0,0 +1,109 @@ +#include +#include +#include +#include + +#include + +#include "rootston/bindings.h" + +static bool outputs_enabled = true; + +static const char *exec_prefix = "exec "; + +static void double_fork_shell_cmd(const char *shell_cmd) { + pid_t pid = fork(); + if (pid < 0) { + wlr_log(WLR_ERROR, "cannot execute binding command: fork() failed"); + return; + } + + if (pid == 0) { + pid = fork(); + if (pid == 0) { + execl("/bin/sh", "/bin/sh", "-c", shell_cmd, NULL); + _exit(EXIT_FAILURE); + } else { + _exit(pid == -1); + } + } + + int status; + while (waitpid(pid, &status, 0) < 0) { + if (errno == EINTR) { + continue; + } + wlr_log_errno(WLR_ERROR, "waitpid() on first child failed"); + return; + } + + if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { + return; + } + + wlr_log(WLR_ERROR, "first child failed to fork command"); +} + +void execute_binding_command (struct roots_seat *seat, struct roots_input *input, const char *command) { + if (strcmp(command, "exit") == 0) { + wl_display_terminate(input->server->wl_display); + } else if (strcmp(command, "close") == 0) { + struct roots_view *focus = roots_seat_get_focus(seat); + if (focus != NULL) { + view_close(focus); + } + } else if (strcmp(command, "fullscreen") == 0) { + struct roots_view *focus = roots_seat_get_focus(seat); + if (focus != NULL) { + bool is_fullscreen = focus->fullscreen_output != NULL; + view_set_fullscreen(focus, !is_fullscreen, NULL); + } + } else if (strcmp(command, "next_window") == 0) { + roots_seat_cycle_focus(seat); + } else if (strcmp(command, "alpha") == 0) { + struct roots_view *focus = roots_seat_get_focus(seat); + if (focus != NULL) { + view_cycle_alpha(focus); + } + } else if (strncmp(exec_prefix, command, strlen(exec_prefix)) == 0) { + const char *shell_cmd = command + strlen(exec_prefix); + double_fork_shell_cmd(shell_cmd); + } else if (strcmp(command, "maximize") == 0) { + struct roots_view *focus = roots_seat_get_focus(seat); + if (focus != NULL) { + view_maximize(focus, !focus->maximized); + } + } else if (strcmp(command, "nop") == 0) { + wlr_log(WLR_DEBUG, "nop command"); + } else if (strcmp(command, "toggle_outputs") == 0) { + outputs_enabled = !outputs_enabled; + struct roots_output *output; + wl_list_for_each(output, &input->server->desktop->outputs, link) { + wlr_output_enable(output->wlr_output, outputs_enabled); + } + } else if (strcmp(command, "toggle_decoration_mode") == 0) { + struct roots_view *focus = roots_seat_get_focus(seat); + if (focus != NULL && focus->type == ROOTS_XDG_SHELL_VIEW) { + struct roots_xdg_toplevel_decoration *decoration = + focus->roots_xdg_surface->xdg_toplevel_decoration; + if (decoration != NULL) { + enum wlr_xdg_toplevel_decoration_v1_mode mode = + decoration->wlr_decoration->current_mode; + mode = mode == WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE + ? WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE + : WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE; + wlr_xdg_toplevel_decoration_v1_set_mode( + decoration->wlr_decoration, mode); + } + } + } else if (strcmp(command, "break_pointer_constraint") == 0) { + struct wl_list *list = + &input->seats; + struct roots_seat *seat; + wl_list_for_each(seat, list, link) { + roots_cursor_constrain(seat->cursor, NULL, NAN, NAN); + } + } else { + wlr_log(WLR_ERROR, "unknown binding command: %s", command); + } +} -- cgit v1.2.3 From 8f5ec5e2bb6ca0574dc9c6a292b9fac55d189d87 Mon Sep 17 00:00:00 2001 From: Ryan Walklin Date: Sat, 15 Dec 2018 14:57:12 +1100 Subject: Fix style nits --- include/rootston/bindings.h | 2 +- rootston/bindings.c | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'rootston/bindings.c') diff --git a/include/rootston/bindings.h b/include/rootston/bindings.h index 8ca23a9f..db38130b 100644 --- a/include/rootston/bindings.h +++ b/include/rootston/bindings.h @@ -4,6 +4,6 @@ #include "rootston/seat.h" #include "rootston/input.h" -void execute_binding_command (struct roots_seat *seat, struct roots_input *input, const char *command); +void execute_binding_command(struct roots_seat *seat, struct roots_input *input, const char *command); #endif //ROOTSTON_BINDINGS_H diff --git a/rootston/bindings.c b/rootston/bindings.c index d9813cbc..9fdbb33b 100644 --- a/rootston/bindings.c +++ b/rootston/bindings.c @@ -2,9 +2,7 @@ #include #include #include - #include - #include "rootston/bindings.h" static bool outputs_enabled = true; @@ -44,7 +42,8 @@ static void double_fork_shell_cmd(const char *shell_cmd) { wlr_log(WLR_ERROR, "first child failed to fork command"); } -void execute_binding_command (struct roots_seat *seat, struct roots_input *input, const char *command) { +void execute_binding_command(struct roots_seat *seat, + struct roots_input *input, const char *command) { if (strcmp(command, "exit") == 0) { wl_display_terminate(input->server->wl_display); } else if (strcmp(command, "close") == 0) { @@ -97,8 +96,7 @@ void execute_binding_command (struct roots_seat *seat, struct roots_input *input } } } else if (strcmp(command, "break_pointer_constraint") == 0) { - struct wl_list *list = - &input->seats; + struct wl_list *list = &input->seats; struct roots_seat *seat; wl_list_for_each(seat, list, link) { roots_cursor_constrain(seat->cursor, NULL, NAN, NAN); -- cgit v1.2.3