6 | 6 |
|
7 | 7 |
static bool outputs_enabled = true;
|
8 | 8 |
|
9 | |
static const char *exec_prefix = "exec ";
|
|
9 |
static const char exec_prefix[] = "exec ";
|
10 | 10 |
|
11 | 11 |
static void double_fork_shell_cmd(const char *shell_cmd) {
|
12 | |
pid_t pid = fork();
|
13 | |
if (pid < 0) {
|
14 | |
wlr_log(WLR_ERROR, "cannot execute binding command: fork() failed");
|
15 | |
return;
|
16 | |
}
|
|
12 |
pid_t pid = fork();
|
|
13 |
if (pid < 0) {
|
|
14 |
wlr_log(WLR_ERROR, "cannot execute binding command: fork() failed");
|
|
15 |
return;
|
|
16 |
}
|
17 | 17 |
|
18 | |
if (pid == 0) {
|
19 | |
pid = fork();
|
20 | |
if (pid == 0) {
|
21 | |
execl("/bin/sh", "/bin/sh", "-c", shell_cmd, NULL);
|
22 | |
_exit(EXIT_FAILURE);
|
23 | |
} else {
|
24 | |
_exit(pid == -1);
|
25 | |
}
|
26 | |
}
|
|
18 |
if (pid == 0) {
|
|
19 |
pid = fork();
|
|
20 |
if (pid == 0) {
|
|
21 |
execl("/bin/sh", "/bin/sh", "-c", shell_cmd, NULL);
|
|
22 |
_exit(EXIT_FAILURE);
|
|
23 |
} else {
|
|
24 |
_exit(pid == -1);
|
|
25 |
}
|
|
26 |
}
|
27 | 27 |
|
28 | |
int status;
|
29 | |
while (waitpid(pid, &status, 0) < 0) {
|
30 | |
if (errno == EINTR) {
|
31 | |
continue;
|
32 | |
}
|
33 | |
wlr_log_errno(WLR_ERROR, "waitpid() on first child failed");
|
34 | |
return;
|
35 | |
}
|
|
28 |
int status;
|
|
29 |
while (waitpid(pid, &status, 0) < 0) {
|
|
30 |
if (errno == EINTR) {
|
|
31 |
continue;
|
|
32 |
}
|
|
33 |
wlr_log_errno(WLR_ERROR, "waitpid() on first child failed");
|
|
34 |
return;
|
|
35 |
}
|
36 | 36 |
|
37 | |
if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
|
38 | |
return;
|
39 | |
}
|
|
37 |
if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
|
|
38 |
return;
|
|
39 |
}
|
40 | 40 |
|
41 | |
wlr_log(WLR_ERROR, "first child failed to fork command");
|
|
41 |
wlr_log(WLR_ERROR, "first child failed to fork command");
|
42 | 42 |
}
|
43 | 43 |
|
44 | |
void execute_binding_command(struct roots_seat *seat,
|
45 | |
struct roots_input *input, const char *command) {
|
46 | |
if (strcmp(command, "exit") == 0) {
|
47 | |
wl_display_terminate(input->server->wl_display);
|
48 | |
} else if (strcmp(command, "close") == 0) {
|
49 | |
struct roots_view *focus = roots_seat_get_focus(seat);
|
50 | |
if (focus != NULL) {
|
51 | |
view_close(focus);
|
52 | |
}
|
53 | |
} else if (strcmp(command, "fullscreen") == 0) {
|
54 | |
struct roots_view *focus = roots_seat_get_focus(seat);
|
55 | |
if (focus != NULL) {
|
56 | |
bool is_fullscreen = focus->fullscreen_output != NULL;
|
57 | |
view_set_fullscreen(focus, !is_fullscreen, NULL);
|
58 | |
}
|
59 | |
} else if (strcmp(command, "next_window") == 0) {
|
60 | |
roots_seat_cycle_focus(seat);
|
61 | |
} else if (strcmp(command, "alpha") == 0) {
|
62 | |
struct roots_view *focus = roots_seat_get_focus(seat);
|
63 | |
if (focus != NULL) {
|
64 | |
view_cycle_alpha(focus);
|
65 | |
}
|
66 | |
} else if (strncmp(exec_prefix, command, strlen(exec_prefix)) == 0) {
|
67 | |
const char *shell_cmd = command + strlen(exec_prefix);
|
68 | |
double_fork_shell_cmd(shell_cmd);
|
69 | |
} else if (strcmp(command, "maximize") == 0) {
|
70 | |
struct roots_view *focus = roots_seat_get_focus(seat);
|
71 | |
if (focus != NULL) {
|
72 | |
view_maximize(focus, !focus->maximized);
|
73 | |
}
|
74 | |
} else if (strcmp(command, "nop") == 0) {
|
75 | |
wlr_log(WLR_DEBUG, "nop command");
|
76 | |
} else if (strcmp(command, "toggle_outputs") == 0) {
|
77 | |
outputs_enabled = !outputs_enabled;
|
78 | |
struct roots_output *output;
|
79 | |
wl_list_for_each(output, &input->server->desktop->outputs, link) {
|
80 | |
wlr_output_enable(output->wlr_output, outputs_enabled);
|
81 | |
}
|
82 | |
} else if (strcmp(command, "toggle_decoration_mode") == 0) {
|
83 | |
struct roots_view *focus = roots_seat_get_focus(seat);
|
84 | |
if (focus != NULL && focus->type == ROOTS_XDG_SHELL_VIEW) {
|
85 | |
struct roots_xdg_toplevel_decoration *decoration =
|
86 | |
focus->roots_xdg_surface->xdg_toplevel_decoration;
|
87 | |
if (decoration != NULL) {
|
88 | |
enum wlr_xdg_toplevel_decoration_v1_mode mode =
|
89 | |
decoration->wlr_decoration->current_mode;
|
90 | |
mode = mode == WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE
|
91 | |
? WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE
|
92 | |
: WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE;
|
93 | |
wlr_xdg_toplevel_decoration_v1_set_mode(
|
94 | |
decoration->wlr_decoration, mode);
|
95 | |
}
|
96 | |
}
|
97 | |
} else if (strcmp(command, "break_pointer_constraint") == 0) {
|
98 | |
struct wl_list *list = &input->seats;
|
99 | |
struct roots_seat *seat;
|
100 | |
wl_list_for_each(seat, list, link) {
|
101 | |
roots_cursor_constrain(seat->cursor, NULL, NAN, NAN);
|
102 | |
}
|
103 | |
} else {
|
104 | |
wlr_log(WLR_ERROR, "unknown binding command: %s", command);
|
105 | |
}
|
|
44 |
void execute_binding_command(struct roots_seat *seat,
|
|
45 |
struct roots_input *input, const char *command) {
|
|
46 |
if (strcmp(command, "exit") == 0) {
|
|
47 |
wl_display_terminate(input->server->wl_display);
|
|
48 |
} else if (strcmp(command, "close") == 0) {
|
|
49 |
struct roots_view *focus = roots_seat_get_focus(seat);
|
|
50 |
if (focus != NULL) {
|
|
51 |
view_close(focus);
|
|
52 |
}
|
|
53 |
} else if (strcmp(command, "fullscreen") == 0) {
|
|
54 |
struct roots_view *focus = roots_seat_get_focus(seat);
|
|
55 |
if (focus != NULL) {
|
|
56 |
bool is_fullscreen = focus->fullscreen_output != NULL;
|
|
57 |
view_set_fullscreen(focus, !is_fullscreen, NULL);
|
|
58 |
}
|
|
59 |
} else if (strcmp(command, "next_window") == 0) {
|
|
60 |
roots_seat_cycle_focus(seat);
|
|
61 |
} else if (strcmp(command, "alpha") == 0) {
|
|
62 |
struct roots_view *focus = roots_seat_get_focus(seat);
|
|
63 |
if (focus != NULL) {
|
|
64 |
view_cycle_alpha(focus);
|
|
65 |
}
|
|
66 |
} else if (strncmp(exec_prefix, command, strlen(exec_prefix)) == 0) {
|
|
67 |
const char *shell_cmd = command + strlen(exec_prefix);
|
|
68 |
double_fork_shell_cmd(shell_cmd);
|
|
69 |
} else if (strcmp(command, "maximize") == 0) {
|
|
70 |
struct roots_view *focus = roots_seat_get_focus(seat);
|
|
71 |
if (focus != NULL) {
|
|
72 |
view_maximize(focus, !focus->maximized);
|
|
73 |
}
|
|
74 |
} else if (strcmp(command, "nop") == 0) {
|
|
75 |
wlr_log(WLR_DEBUG, "nop command");
|
|
76 |
} else if (strcmp(command, "toggle_outputs") == 0) {
|
|
77 |
outputs_enabled = !outputs_enabled;
|
|
78 |
struct roots_output *output;
|
|
79 |
wl_list_for_each(output, &input->server->desktop->outputs, link) {
|
|
80 |
wlr_output_enable(output->wlr_output, outputs_enabled);
|
|
81 |
}
|
|
82 |
} else if (strcmp(command, "toggle_decoration_mode") == 0) {
|
|
83 |
struct roots_view *focus = roots_seat_get_focus(seat);
|
|
84 |
if (focus != NULL && focus->type == ROOTS_XDG_SHELL_VIEW) {
|
|
85 |
struct roots_xdg_toplevel_decoration *decoration =
|
|
86 |
focus->roots_xdg_surface->xdg_toplevel_decoration;
|
|
87 |
if (decoration != NULL) {
|
|
88 |
enum wlr_xdg_toplevel_decoration_v1_mode mode =
|
|
89 |
decoration->wlr_decoration->current_mode;
|
|
90 |
mode = mode == WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE
|
|
91 |
? WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE
|
|
92 |
: WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE;
|
|
93 |
wlr_xdg_toplevel_decoration_v1_set_mode(
|
|
94 |
decoration->wlr_decoration, mode);
|
|
95 |
}
|
|
96 |
}
|
|
97 |
} else if (strcmp(command, "break_pointer_constraint") == 0) {
|
|
98 |
struct wl_list *list = &input->seats;
|
|
99 |
struct roots_seat *seat;
|
|
100 |
wl_list_for_each(seat, list, link) {
|
|
101 |
roots_cursor_constrain(seat->cursor, NULL, NAN, NAN);
|
|
102 |
}
|
|
103 |
} else {
|
|
104 |
wlr_log(WLR_ERROR, "unknown binding command: %s", command);
|
|
105 |
}
|
106 | 106 |
}
|