mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	Factor out binding command execution to separate file
This commit is contained in:
		
							parent
							
								
									2a3c62b4d2
								
							
						
					
					
						commit
						2a7edfa24c
					
				
					 4 changed files with 121 additions and 101 deletions
				
			
		
							
								
								
									
										9
									
								
								include/rootston/bindings.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								include/rootston/bindings.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,9 @@
 | 
				
			||||||
 | 
					#ifndef ROOTSTON_BINDINGS_H
 | 
				
			||||||
 | 
					#define ROOTSTON_BINDINGS_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "rootston/seat.h"
 | 
				
			||||||
 | 
					#include "rootston/input.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void execute_binding_command (struct roots_seat *seat, struct roots_input *input, const char *command);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif //ROOTSTON_BINDINGS_H
 | 
				
			||||||
							
								
								
									
										109
									
								
								rootston/bindings.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								rootston/bindings.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,109 @@
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					#include <sys/wait.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <wlr/util/log.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#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);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -2,8 +2,6 @@
 | 
				
			||||||
#include <stdbool.h>
 | 
					#include <stdbool.h>
 | 
				
			||||||
#include <stdint.h>
 | 
					#include <stdint.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <sys/wait.h>
 | 
					 | 
				
			||||||
#include <unistd.h>
 | 
					 | 
				
			||||||
#include <wayland-server.h>
 | 
					#include <wayland-server.h>
 | 
				
			||||||
#include <wlr/backend/session.h>
 | 
					#include <wlr/backend/session.h>
 | 
				
			||||||
#include <wlr/types/wlr_input_device.h>
 | 
					#include <wlr/types/wlr_input_device.h>
 | 
				
			||||||
| 
						 | 
					@ -11,6 +9,7 @@
 | 
				
			||||||
#include <wlr/types/wlr_pointer.h>
 | 
					#include <wlr/types/wlr_pointer.h>
 | 
				
			||||||
#include <wlr/util/log.h>
 | 
					#include <wlr/util/log.h>
 | 
				
			||||||
#include <xkbcommon/xkbcommon.h>
 | 
					#include <xkbcommon/xkbcommon.h>
 | 
				
			||||||
 | 
					#include "rootston/bindings.h"
 | 
				
			||||||
#include "rootston/input.h"
 | 
					#include "rootston/input.h"
 | 
				
			||||||
#include "rootston/keyboard.h"
 | 
					#include "rootston/keyboard.h"
 | 
				
			||||||
#include "rootston/seat.h"
 | 
					#include "rootston/seat.h"
 | 
				
			||||||
| 
						 | 
					@ -85,107 +84,9 @@ static void pressed_keysyms_update(xkb_keysym_t *pressed_keysyms,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const char *exec_prefix = "exec ";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static bool outputs_enabled = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void keyboard_binding_execute(struct roots_keyboard *keyboard,
 | 
					static void keyboard_binding_execute(struct roots_keyboard *keyboard,
 | 
				
			||||||
		const char *command) {
 | 
							const char *command) {
 | 
				
			||||||
	struct roots_seat *seat = keyboard->seat;
 | 
						execute_binding_command(keyboard->seat, keyboard->input, command);
 | 
				
			||||||
	if (strcmp(command, "exit") == 0) {
 | 
					 | 
				
			||||||
		wl_display_terminate(keyboard->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, &keyboard->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 =
 | 
					 | 
				
			||||||
			&keyboard->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);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,5 @@
 | 
				
			||||||
sources = [
 | 
					sources = [
 | 
				
			||||||
 | 
						'bindings.c',
 | 
				
			||||||
	'config.c',
 | 
						'config.c',
 | 
				
			||||||
	'cursor.c',
 | 
						'cursor.c',
 | 
				
			||||||
	'desktop.c',
 | 
						'desktop.c',
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue