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 <stdint.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <wayland-server.h>
 | 
			
		||||
#include <wlr/backend/session.h>
 | 
			
		||||
#include <wlr/types/wlr_input_device.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -11,6 +9,7 @@
 | 
			
		|||
#include <wlr/types/wlr_pointer.h>
 | 
			
		||||
#include <wlr/util/log.h>
 | 
			
		||||
#include <xkbcommon/xkbcommon.h>
 | 
			
		||||
#include "rootston/bindings.h"
 | 
			
		||||
#include "rootston/input.h"
 | 
			
		||||
#include "rootston/keyboard.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,
 | 
			
		||||
		const char *command) {
 | 
			
		||||
	struct roots_seat *seat = keyboard->seat;
 | 
			
		||||
	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);
 | 
			
		||||
	}
 | 
			
		||||
	execute_binding_command(keyboard->seat, keyboard->input, command);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,5 @@
 | 
			
		|||
sources = [
 | 
			
		||||
	'bindings.c',
 | 
			
		||||
	'config.c',
 | 
			
		||||
	'cursor.c',
 | 
			
		||||
	'desktop.c',
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue