diff options
33 files changed, 424 insertions, 116 deletions
diff --git a/.editorconfig b/.editorconfig index 4b8b3e12..64f18915 100644 --- a/.editorconfig +++ b/.editorconfig @@ -7,3 +7,7 @@ charset = utf-8 indent_style = tab indent_size = 4 trim_trailing_whitespace = true + +[*.xml] +indent_style = space +indent_size = 2 @@ -31,3 +31,5 @@ Run these commands: meson build ninja -C build + +(On FreeBSD, you need to pass an extra flag to prevent a linking error: `meson build -D b_lundef=false`) diff --git a/backend/libinput/pointer.c b/backend/libinput/pointer.c index 005c9516..ad9b8f02 100644 --- a/backend/libinput/pointer.c +++ b/backend/libinput/pointer.c @@ -128,7 +128,7 @@ void handle_pointer_axis(struct libinput_event *event, } wlr_event.delta = libinput_event_pointer_get_axis_value( pevent, axies[i]); + wl_signal_emit(&wlr_dev->pointer->events.axis, &wlr_event); } - wl_signal_emit(&wlr_dev->pointer->events.axis, &wlr_event); } } diff --git a/backend/meson.build b/backend/meson.build index cf62a56f..5ed7b227 100644 --- a/backend/meson.build +++ b/backend/meson.build @@ -1,7 +1,6 @@ backend_files = files( 'backend.c', 'session/direct-ipc.c', - 'session/direct.c', 'session/session.c', 'drm/atomic.c', 'drm/backend.c', @@ -26,6 +25,12 @@ backend_files = files( 'x11/backend.c', ) +if host_machine.system().startswith('freebsd') + backend_files += files('session/direct-freebsd.c') +else + backend_files += files('session/direct.c') +endif + if systemd.found() backend_files += files('session/logind.c') endif diff --git a/backend/session/direct-freebsd.c b/backend/session/direct-freebsd.c new file mode 100644 index 00000000..fc4bab04 --- /dev/null +++ b/backend/session/direct-freebsd.c @@ -0,0 +1,217 @@ +#include <errno.h> +#include <stdlib.h> +#include <stdio.h> +#include <stdbool.h> +#include <unistd.h> +#include <signal.h> +#include <sys/ioctl.h> +#include <sys/stat.h> +#include <termios.h> +#include <fcntl.h> +#include <sys/types.h> +#include <dev/evdev/input.h> +#include <sys/kbio.h> +#include <sys/consio.h> +#include <wayland-server.h> +#include <wlr/backend/session/interface.h> +#include <wlr/util/log.h> +#include "backend/session/direct-ipc.h" + +const struct session_impl session_direct; + +struct direct_session { + struct wlr_session base; + int tty_fd; + int old_kbmode; + int sock; + pid_t child; + + struct wl_event_source *vt_source; +}; + +static int direct_session_open(struct wlr_session *base, const char *path) { + struct direct_session *session = wl_container_of(base, session, base); + + int fd = direct_ipc_open(session->sock, path); + if (fd < 0) { + wlr_log(L_ERROR, "Failed to open %s: %s%s", path, strerror(-fd), + fd == -EINVAL ? "; is another display server running?" : ""); + return fd; + } + + struct stat st; + if (fstat(fd, &st) < 0) { + close(fd); + return -errno; + } + + return fd; +} + +static void direct_session_close(struct wlr_session *base, int fd) { + struct direct_session *session = wl_container_of(base, session, base); + + struct stat st; + if (fstat(fd, &st) < 0) { + wlr_log_errno(L_ERROR, "Stat failed"); + close(fd); + return; + } + + close(fd); +} + +static bool direct_change_vt(struct wlr_session *base, unsigned vt) { + struct direct_session *session = wl_container_of(base, session, base); + return ioctl(session->tty_fd, VT_ACTIVATE, (int)vt) == 0; +} + +static void direct_session_destroy(struct wlr_session *base) { + struct direct_session *session = wl_container_of(base, session, base); + struct vt_mode mode = { + .mode = VT_AUTO, + }; + + errno = 0; + + ioctl(session->tty_fd, KDSKBMODE, session->old_kbmode); + ioctl(session->tty_fd, KDSETMODE, KD_TEXT); + ioctl(session->tty_fd, VT_SETMODE, &mode); + + if (errno) { + wlr_log(L_ERROR, "Failed to restore tty"); + } + + direct_ipc_finish(session->sock, session->child); + close(session->sock); + + wl_event_source_remove(session->vt_source); + close(session->tty_fd); + free(session); +} + +static int vt_handler(int signo, void *data) { + struct direct_session *session = data; + + if (session->base.active) { + session->base.active = false; + wl_signal_emit(&session->base.session_signal, session); + ioctl(session->tty_fd, VT_RELDISP, 1); + } else { + ioctl(session->tty_fd, VT_RELDISP, VT_ACKACQ); + session->base.active = true; + wl_signal_emit(&session->base.session_signal, session); + } + + return 1; +} + +static bool setup_tty(struct direct_session *session, struct wl_display *display) { + int fd = -1, tty = -1, tty0_fd = -1; + if ((tty0_fd = open("/dev/ttyv0", O_RDWR | O_CLOEXEC)) < 0) { + wlr_log_errno(L_ERROR, "Could not open /dev/ttyv0 to find a free vt"); + goto error; + } + if (ioctl(tty0_fd, VT_OPENQRY, &tty) != 0) { + wlr_log_errno(L_ERROR, "Could not find a free vt"); + goto error; + } + close(tty0_fd); + char tty_path[64]; + snprintf(tty_path, sizeof(tty_path), "/dev/ttyv%d", tty - 1); + wlr_log(L_INFO, "Using tty %s", tty_path); + fd = open(tty_path, O_RDWR | O_NOCTTY | O_CLOEXEC); + + if (fd == -1) { + wlr_log_errno(L_ERROR, "Cannot open tty"); + return false; + } + + ioctl(fd, VT_ACTIVATE, tty); + ioctl(fd, VT_WAITACTIVE, tty); + + int old_kbmode; + if (ioctl(fd, KDGKBMODE, &old_kbmode)) { + wlr_log_errno(L_ERROR, "Failed to read tty %d keyboard mode", tty); + goto error; + } + + if (ioctl(fd, KDSKBMODE, K_CODE)) { + wlr_log_errno(L_ERROR, "Failed to set keyboard mode K_CODE on tty %d", tty); + goto error; + } + + if (ioctl(fd, KDSETMODE, KD_GRAPHICS)) { + wlr_log_errno(L_ERROR, "Failed to set graphics mode on tty %d", tty); + goto error; + } + + struct vt_mode mode = { + .mode = VT_PROCESS, + .relsig = SIGUSR1, + .acqsig = SIGUSR1, + .frsig = SIGIO, // has to be set + }; + + if (ioctl(fd, VT_SETMODE, &mode) < 0) { + wlr_log(L_ERROR, "Failed to take control of tty %d", tty); + goto error; + } + + struct wl_event_loop *loop = wl_display_get_event_loop(display); + session->vt_source = wl_event_loop_add_signal(loop, SIGUSR1, + vt_handler, session); + if (!session->vt_source) { + goto error; + } + + session->base.vtnr = tty; + session->tty_fd = fd; + session->old_kbmode = old_kbmode; + + return true; + +error: + // Drop back to tty 1, better than hanging in a useless blank console + ioctl(fd, VT_ACTIVATE, 1); + close(fd); + return false; +} + +static struct wlr_session *direct_session_create(struct wl_display *disp) { + struct direct_session *session = calloc(1, sizeof(*session)); + if (!session) { + wlr_log_errno(L_ERROR, "Allocation failed"); + return NULL; + } + + session->sock = direct_ipc_init(&session->child); + if (session->sock == -1) { + goto error_session; + } + + if (!setup_tty(session, disp)) { + goto error_ipc; + } + + wlr_log(L_INFO, "Successfully loaded direct session"); + + snprintf(session->base.seat, sizeof(session->base.seat), "seat0"); + session->base.impl = &session_direct; + return &session->base; + +error_ipc: + direct_ipc_finish(session->sock, session->child); + close(session->sock); +error_session: + free(session); + return NULL; +} + +const struct session_impl session_direct = { + .create = direct_session_create, + .destroy = direct_session_destroy, + .open = direct_session_open, + .close = direct_session_close, + .change_vt = direct_change_vt, +}; diff --git a/backend/session/direct-ipc.c b/backend/session/direct-ipc.c index 5f1494a6..0ea51e2f 100644 --- a/backend/session/direct-ipc.c +++ b/backend/session/direct-ipc.c @@ -1,4 +1,8 @@ #define _POSIX_C_SOURCE 200809L +#ifdef __FreeBSD__ +#define __BSD_VISIBLE 1 +#define INPUT_MAJOR 0 +#endif #include <errno.h> #include <stdio.h> #include <stdlib.h> @@ -8,10 +12,12 @@ #include <sys/socket.h> #include <sys/stat.h> #include <sys/types.h> -#include <sys/sysmacros.h> #include <sys/wait.h> -#include <xf86drm.h> +#ifdef __linux__ +#include <sys/sysmacros.h> #include <linux/major.h> +#endif +#include <xf86drm.h> #include <wlr/util/log.h> #include "backend/session/direct-ipc.h" @@ -35,11 +41,12 @@ static bool have_permissions(void) { } #else static bool have_permissions(void) { +#ifdef __linux__ if (geteuid() != 0) { wlr_log(L_ERROR, "Do not have root privileges; cannot become DRM master"); return false; } - +#endif return true; } #endif diff --git a/backend/session/session.c b/backend/session/session.c index b73952fd..b14ca4d0 100644 --- a/backend/session/session.c +++ b/backend/session/session.c @@ -263,6 +263,11 @@ size_t wlr_session_find_gpus(struct wlr_session *session, return explicit_find_gpus(session, ret_len, ret, explicit); } +#ifdef __FreeBSD__ + // XXX: libudev-devd does not return any GPUs (yet?) + return explicit_find_gpus(session, ret_len, ret, "/dev/drm/0"); +#else + struct udev_enumerate *en = udev_enumerate_new(session->udev); if (!en) { wlr_log(L_ERROR, "Failed to create udev enumeration"); @@ -329,4 +334,5 @@ size_t wlr_session_find_gpus(struct wlr_session *session, udev_enumerate_unref(en); return i; +#endif } diff --git a/backend/wayland/os-compatibility.c b/backend/wayland/os-compatibility.c index cd268539..14125793 100644 --- a/backend/wayland/os-compatibility.c +++ b/backend/wayland/os-compatibility.c @@ -29,7 +29,9 @@ #include <unistd.h> #include <fcntl.h> #include <errno.h> +#ifdef __linux__ #include <sys/epoll.h> +#endif #include <string.h> #include <stdlib.h> diff --git a/backend/x11/backend.c b/backend/x11/backend.c index 1eb5a952..11dd8568 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -1,4 +1,4 @@ -#define _POSIX_C_SOURCE 199309L +#define _POSIX_C_SOURCE 200112L #include <stdbool.h> #include <stdio.h> #include <stdlib.h> @@ -8,7 +8,11 @@ #include <xcb/xcb.h> #include <xcb/glx.h> #include <X11/Xlib-xcb.h> +#ifdef __linux__ #include <linux/input-event-codes.h> +#elif __FreeBSD__ +#include <dev/evdev/input-event-codes.h> +#endif #include <wlr/backend/interface.h> #include <wlr/backend/x11.h> #include <wlr/egl.h> @@ -59,8 +63,7 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e x11->time = ev->time; break; } - case XCB_BUTTON_PRESS: - case XCB_BUTTON_RELEASE: { + case XCB_BUTTON_PRESS: { xcb_button_press_event_t *ev = (xcb_button_press_event_t *)event; if (ev->detail == XCB_BUTTON_INDEX_4 || @@ -75,7 +78,16 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e .delta = delta, }; wl_signal_emit(&x11->pointer.events.axis, &axis); - } else { + x11->time = ev->time; + break; + } + } + /* fallthrough */ + case XCB_BUTTON_RELEASE: { + xcb_button_press_event_t *ev = (xcb_button_press_event_t *)event; + + if (ev->detail != XCB_BUTTON_INDEX_4 && + ev->detail != XCB_BUTTON_INDEX_5) { struct wlr_event_pointer_button button = { .device = &x11->pointer_dev, .time_sec = ev->time / 1000, diff --git a/examples/output-layout.c b/examples/output-layout.c index 560a7113..771ccd77 100644 --- a/examples/output-layout.c +++ b/examples/output-layout.c @@ -1,5 +1,5 @@ #define _POSIX_C_SOURCE 199309L -#define _XOPEN_SOURCE 500 +#define _XOPEN_SOURCE 700 #include <stdio.h> #include <stdlib.h> #include <time.h> diff --git a/include/rootston/view.h b/include/rootston/view.h index af087182..a4fb6f01 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -17,8 +17,6 @@ struct roots_wl_shell_surface { struct wl_listener request_set_maximized; struct wl_listener surface_commit; - - bool initialized; }; struct roots_xdg_surface_v6 { @@ -32,8 +30,6 @@ struct roots_xdg_surface_v6 { struct wl_listener request_move; struct wl_listener request_resize; struct wl_listener request_show_window_menu; - - bool initialized; }; struct roots_xwayland_surface { @@ -85,6 +81,6 @@ void view_activate(struct roots_view *view, bool active); void view_resize(struct roots_view *view, uint32_t width, uint32_t height); void view_close(struct roots_view *view); bool view_center(struct roots_view *view); -bool view_initialize(struct roots_view *view); +void view_initialize(struct roots_view *view); #endif diff --git a/include/wlr/types/wlr_output_layout.h b/include/wlr/types/wlr_output_layout.h index fe09106f..ea8dbcd2 100644 --- a/include/wlr/types/wlr_output_layout.h +++ b/include/wlr/types/wlr_output_layout.h @@ -84,4 +84,10 @@ struct wlr_box *wlr_output_layout_get_box( void wlr_output_layout_add_auto(struct wlr_output_layout *layout, struct wlr_output *output); +/** + * Get the output closest to the center of the layout extents. + */ +struct wlr_output *wlr_output_layout_get_center_output( + struct wlr_output_layout *layout); + #endif diff --git a/include/wlr/types/wlr_xdg_shell_v6.h b/include/wlr/types/wlr_xdg_shell_v6.h index 48da6604..b0de41e2 100644 --- a/include/wlr/types/wlr_xdg_shell_v6.h +++ b/include/wlr/types/wlr_xdg_shell_v6.h @@ -106,6 +106,7 @@ struct wlr_xdg_surface_v6 { struct wl_list popup_link; bool configured; + bool added; struct wl_event_source *configure_idle; struct wl_list configure_list; diff --git a/include/wlr/util/log.h b/include/wlr/util/log.h index 3de2cacf..b017cc96 100644 --- a/include/wlr/util/log.h +++ b/include/wlr/util/log.h @@ -16,7 +16,7 @@ typedef enum { typedef void (*log_callback_t)(log_importance_t importance, const char *fmt, va_list args); -void wlr_init_log(log_callback_t callback); +void wlr_log_init(log_callback_t callback); #ifdef __GNUC__ #define ATTRIB_PRINTF(start, end) __attribute__((format(printf, start, end))) diff --git a/meson.build b/meson.build index d885484b..3e4cab38 100644 --- a/meson.build +++ b/meson.build @@ -34,6 +34,9 @@ if cc.get_id() == 'clang' add_project_arguments('-Wno-missing-braces', language: 'c') endif +# Avoid wl_buffer deprecation warnings +add_project_arguments('-DWL_HIDE_DEPRECATED', language: 'c') + wayland_server = dependency('wayland-server') wayland_client = dependency('wayland-client') wayland_egl = dependency('wayland-egl') diff --git a/protocol/meson.build b/protocol/meson.build index 79871fea..2cbb5b6d 100644 --- a/protocol/meson.build +++ b/protocol/meson.build @@ -46,7 +46,8 @@ foreach p : client_protocols wl_protos_headers += wayland_scanner_client.process(xml) endforeach -lib_wl_protos = static_library('wl_protos', wl_protos_src + wl_protos_headers) +lib_wl_protos = static_library('wl_protos', wl_protos_src + wl_protos_headers, + dependencies: [wayland_client]) # for the include directory wlr_protos = declare_dependency( link_with: lib_wl_protos, diff --git a/rootston/config.c b/rootston/config.c index 4918c8dd..5e911e39 100644 --- a/rootston/config.c +++ b/rootston/config.c @@ -11,6 +11,7 @@ #include <wlr/util/log.h> #include <wlr/types/wlr_box.h> #include "rootston/config.h" +#include "rootston/input.h" #include "rootston/ini.h" static void usage(const char *name, int ret) { @@ -109,6 +110,42 @@ static uint32_t parse_modifier(const char *symname) { } } +void add_binding_config(struct wl_list *bindings, const char* combination, + const char* command) { + struct binding_config *bc = calloc(1, sizeof(struct binding_config)); + + xkb_keysym_t keysyms[ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP]; + char *symnames = strdup(combination); + char* symname = strtok(symnames, "+"); + while (symname) { + uint32_t modifier = parse_modifier(symname); + if (modifier != 0) { + bc->modifiers |= modifier; + } else { + xkb_keysym_t sym = xkb_keysym_from_name(symname, + XKB_KEYSYM_NO_FLAGS); + if (sym == XKB_KEY_NoSymbol) { + wlr_log(L_ERROR, "got unknown key binding symbol: %s", + symname); + free(bc); + bc = NULL; + break; + } + keysyms[bc->keysyms_len] = sym; + bc->keysyms_len++; + } + symname = strtok(NULL, "+"); + } + free(symnames); + + if (bc) { + wl_list_insert(bindings, &bc->link); + bc->command = strdup(command); + bc->keysyms = malloc(bc->keysyms_len * sizeof(xkb_keysym_t)); + memcpy(bc->keysyms, keysyms, bc->keysyms_len * sizeof(xkb_keysym_t)); + } +} + static const char *output_prefix = "output:"; static const char *device_prefix = "device:"; @@ -216,45 +253,7 @@ static int config_ini_handler(void *user, const char *section, const char *name, wlr_log(L_ERROR, "got unknown keyboard config: %s", name); } } else if (strcmp(section, "bindings") == 0) { - struct binding_config *bc = calloc(1, sizeof(struct binding_config)); - wl_list_insert(&config->bindings, &bc->link); - - bc->command = strdup(value); - - size_t keysyms_len = 1; - char *symnames = strdup(name); - for (char *c = symnames; *c != '\0'; c++) { - if (*c == '+') { - *c = '\0'; - keysyms_len++; - } - } - - // TODO: bc->keysyms is larger than needed - bc->keysyms = calloc(1, keysyms_len * sizeof(xkb_keysym_t)); - char *symname = symnames; - for (size_t i = 0; i < keysyms_len; i++) { - uint32_t modifier = parse_modifier(symname); - if (modifier != 0) { - bc->modifiers |= modifier; - } else { - xkb_keysym_t sym = xkb_keysym_from_name(symname, - XKB_KEYSYM_NO_FLAGS); - if (sym == XKB_KEY_NoSymbol) { - wlr_log(L_ERROR, "got unknown key binding symbol: %s", - symname); - wl_list_remove(&bc->link); - free(bc->keysyms); - free(bc); - break; - } - bc->keysyms[bc->keysyms_len] = sym; - bc->keysyms_len++; - } - symname += strlen(symname) + 1; - } - - free(symnames); + add_binding_config(&config->bindings, name, value); } else { wlr_log(L_ERROR, "got unknown config section: %s", section); } @@ -298,15 +297,9 @@ struct roots_config *parse_args(int argc, char *argv[]) { if (result == -1) { wlr_log(L_DEBUG, "No config file found. Using empty config."); - - struct binding_config *bc = calloc(1, sizeof(struct binding_config)); - wl_list_insert(&config->bindings, &bc->link); - bc->command = strdup("exit"); - bc->modifiers = WLR_MODIFIER_LOGO; - bc->keysyms_len = 2; - bc->keysyms = calloc(1, bc->keysyms_len * sizeof(xkb_keysym_t)); - bc->keysyms[0] = XKB_KEY_Meta_L; - bc->keysyms[1] = XKB_KEY_q; + add_binding_config(&config->bindings, "Logo+Shift+e", "exit"); + add_binding_config(&config->bindings, "Ctrl+q", "close"); + add_binding_config(&config->bindings, "Alt+Tab", "next_window"); } else if (result == -2) { wlr_log(L_ERROR, "Could not allocate memory to parse config file"); exit(1); diff --git a/rootston/cursor.c b/rootston/cursor.c index 03189587..65109534 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -1,10 +1,13 @@ -#define _XOPEN_SOURCE 500 +#define _XOPEN_SOURCE 700 #include <stdbool.h> #include <stdint.h> #include <string.h> #include <math.h> -// TODO: BSD et al +#ifdef __linux__ #include <linux/input-event-codes.h> +#elif __FreeBSD__ +#include <dev/evdev/input-event-codes.h> +#endif #include <wayland-server.h> #include <wlr/types/wlr_cursor.h> #include <wlr/util/log.h> diff --git a/rootston/desktop.c b/rootston/desktop.c index d5cac575..a7137255 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -67,35 +67,42 @@ void view_close(struct roots_view *view) { bool view_center(struct roots_view *view) { struct wlr_box size; view_get_size(view, &size); - if (size.width == 0 && size.height == 0) { - return false; - } struct roots_desktop *desktop = view->desktop; struct wlr_cursor *cursor = desktop->server->input->cursor; - struct wlr_output *output = wlr_output_layout_output_at(desktop->layout, - cursor->x, cursor->y); - const struct wlr_output_layout_output *output_layout = - wlr_output_layout_get(desktop->layout, output); + + struct wlr_output *output = + wlr_output_layout_output_at(desktop->layout, cursor->x, cursor->y); + + if (!output) { + output = wlr_output_layout_get_center_output(desktop->layout); + } + if (!output) { + // empty layout return false; } - view->x = (double)(output->width - size.width) / 2 - + output_layout->x; - view->y = (double)(output->height - size.height) / 2 - + output_layout->y; + const struct wlr_output_layout_output *l_output = + wlr_output_layout_get(desktop->layout, output); + + int width, height; + wlr_output_effective_resolution(output, &width, &height); + + view->x = (double)(width - size.width) / 2 + + l_output->x; + view->y = (double)(height - size.height) / 2 + + l_output->y; + return true; } -bool view_initialize(struct roots_view *view) { - bool centered = view_center(view); - if (centered) { - struct roots_input *input = view->desktop->server->input; - set_view_focus(input, view->desktop, view); - wlr_seat_keyboard_notify_enter(input->wl_seat, view->wlr_surface); - } - return centered; +void view_initialize(struct roots_view *view) { + view_center(view); + struct roots_input *input = view->desktop->server->input; + + set_view_focus(input, view->desktop, view); + wlr_seat_keyboard_notify_enter(input->wl_seat, view->wlr_surface); } struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly, diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 6f4334af..aee6b098 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -32,6 +32,13 @@ static void keyboard_binding_execute(struct roots_keyboard *keyboard, if (keyboard->input->last_active_view != NULL) { view_close(keyboard->input->last_active_view); } + } else if (strcmp(command, "next_window") == 0) { + if (server->desktop->views->length > 0) { + struct roots_view *view = server->desktop->views->items[0]; + set_view_focus(keyboard->input, server->desktop, view); + wlr_seat_keyboard_notify_enter(keyboard->input->wl_seat, + view->wlr_surface); + } } else if (strncmp(exec_prefix, command, strlen(exec_prefix)) == 0) { const char *shell_cmd = command + strlen(exec_prefix); pid_t pid = fork(); diff --git a/rootston/output.c b/rootston/output.c index 2c061739..39a90fe3 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -1,4 +1,4 @@ -#define _POSIX_C_SOURCE 199309L +#define _POSIX_C_SOURCE 200809L #include <time.h> #include <stdlib.h> #include <stdbool.h> diff --git a/rootston/rootston.ini.example b/rootston/rootston.ini.example index 460efa13..4774108a 100644 --- a/rootston/rootston.ini.example +++ b/rootston/rootston.ini.example @@ -38,3 +38,4 @@ meta-key = Logo [bindings] Logo+Shift+e = exit # Stop the compositor Logo+q = close # Close the current view +Alt+Tab = next_window # Cycle through windows diff --git a/rootston/wl_shell.c b/rootston/wl_shell.c index 34f53c7a..33f54a32 100644 --- a/rootston/wl_shell.c +++ b/rootston/wl_shell.c @@ -50,14 +50,7 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { } static void handle_surface_commit(struct wl_listener *listener, void *data) { - struct roots_wl_shell_surface *roots_surface = - wl_container_of(listener, roots_surface, surface_commit); - struct roots_view *view = roots_surface->view; - - if (view->wl_shell_surface->state == WLR_WL_SHELL_SURFACE_STATE_TOPLEVEL && - !roots_surface->initialized) { - roots_surface->initialized = view_initialize(view); - } + // TODO do we need to do anything here? } static void handle_destroy(struct wl_listener *listener, void *data) { @@ -137,4 +130,5 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) { view->desktop = desktop; roots_surface->view = view; list_add(desktop->views, view); + view_initialize(view); } diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 9b8d8882..1e21fa02 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -68,14 +68,7 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { } static void handle_commit(struct wl_listener *listener, void *data) { - struct roots_xdg_surface_v6 *roots_xdg_surface = - wl_container_of(listener, roots_xdg_surface, commit); - struct roots_view *view = roots_xdg_surface->view; - - if (view->xdg_surface_v6->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL && - !roots_xdg_surface->initialized) { - roots_xdg_surface->initialized = view_initialize(view); - } + // TODO is there anything we need to do here? } static void handle_destroy(struct wl_listener *listener, void *data) { @@ -141,4 +134,6 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { view->desktop = desktop; roots_surface->view = view; list_add(desktop->views, view); + + view_initialize(view); } diff --git a/types/wlr_keyboard.c b/types/wlr_keyboard.c index f37895b0..c27264ef 100644 --- a/types/wlr_keyboard.c +++ b/types/wlr_keyboard.c @@ -48,6 +48,9 @@ static void keyboard_modifier_update(struct wlr_keyboard *keyboard) { void wlr_keyboard_notify_modifiers(struct wlr_keyboard *keyboard, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) { + if (!keyboard->xkb_state) { + return; + } xkb_state_update_mask(keyboard->xkb_state, mods_depressed, mods_latched, mods_locked, 0, 0, group); keyboard_modifier_update(keyboard); @@ -55,6 +58,9 @@ void wlr_keyboard_notify_modifiers(struct wlr_keyboard *keyboard, void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard, struct wlr_event_keyboard_key *event) { + if (!keyboard->xkb_state) { + return; + } if (event->update_state) { uint32_t keycode = event->keycode + 8; xkb_state_update_key(keyboard->xkb_state, keycode, diff --git a/types/wlr_output.c b/types/wlr_output.c index d3b37d65..4c9814ef 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -1,4 +1,4 @@ -#define _POSIX_C_SOURCE 199309L +#define _POSIX_C_SOURCE 200809L #include <assert.h> #include <stdlib.h> #include <string.h> diff --git a/types/wlr_output_layout.c b/types/wlr_output_layout.c index 1890074b..8c3f1d88 100644 --- a/types/wlr_output_layout.c +++ b/types/wlr_output_layout.c @@ -343,3 +343,20 @@ void wlr_output_layout_add_auto(struct wlr_output_layout *layout, l_output->state->auto_configured = true; wlr_output_layout_reconfigure(layout); } + +struct wlr_output *wlr_output_layout_get_center_output( + struct wlr_output_layout *layout) { + if (wl_list_empty(&layout->outputs)) { + return NULL; + } + + struct wlr_box *extents = wlr_output_layout_get_box(layout, NULL); + double center_x = extents->width / 2 + extents->x; + double center_y = extents->height / 2 + extents->y; + + double dest_x = 0, dest_y = 0; + wlr_output_layout_closest_point(layout, NULL, center_x, center_y, + &dest_x, &dest_y); + + return wlr_output_layout_output_at(layout, dest_x, dest_y); +} diff --git a/types/wlr_seat.c b/types/wlr_seat.c index aea4196b..ce055520 100644 --- a/types/wlr_seat.c +++ b/types/wlr_seat.c @@ -516,6 +516,7 @@ void wlr_seat_pointer_end_grab(struct wlr_seat *wlr_seat) { struct wlr_seat_pointer_grab *grab = wlr_seat->pointer_state.grab; if (grab != wlr_seat->pointer_state.default_grab) { wlr_seat->pointer_state.grab = wlr_seat->pointer_state.default_grab; + wl_signal_emit(&wlr_seat->events.pointer_grab_end, grab); } } diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index a16d3319..c8c09dc9 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -9,6 +9,7 @@ #include <wlr/types/wlr_surface.h> #include <wlr/types/wlr_seat.h> #include <wlr/util/log.h> +#include <wlr/render/interface.h> #include "xdg-shell-unstable-v6-protocol.h" static const char *wlr_desktop_xdg_toplevel_role = "xdg_toplevel"; @@ -802,10 +803,7 @@ static void xdg_surface_ack_configure(struct wl_client *client, break; } - if (!surface->configured) { - surface->configured = true; - wl_signal_emit(&surface->client->shell->events.new_surface, surface); - } + surface->configured = true; wl_signal_emit(&surface->events.ack_configure, surface); @@ -996,7 +994,7 @@ static void wlr_xdg_surface_v6_toplevel_committed( struct wlr_xdg_surface_v6 *surface) { assert(surface->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL); - if (!surface->surface->current->buffer && !surface->toplevel_state->added) { + if (!surface->surface->texture->valid && !surface->toplevel_state->added) { // on the first commit, send a configure request to tell the client it // is added wlr_xdg_surface_v6_schedule_configure(surface, true); @@ -1004,7 +1002,7 @@ static void wlr_xdg_surface_v6_toplevel_committed( return; } - if (!surface->surface->current->buffer) { + if (!surface->surface->texture->valid) { return; } @@ -1026,7 +1024,7 @@ static void handle_wlr_surface_committed(struct wl_listener *listener, struct wlr_xdg_surface_v6 *surface = wl_container_of(listener, surface, surface_commit_listener); - if (surface->surface->current->buffer && !surface->configured) { + if (surface->surface->texture->valid && !surface->configured) { wl_resource_post_error(surface->resource, ZXDG_SURFACE_V6_ERROR_UNCONFIGURED_BUFFER, "xdg_surface has never been configured"); @@ -1055,6 +1053,11 @@ static void handle_wlr_surface_committed(struct wl_listener *listener, break; } + if (surface->configured && !surface->added) { + surface->added = true; + wl_signal_emit(&surface->client->shell->events.new_surface, surface); + } + wl_signal_emit(&surface->events.commit, surface); } @@ -1090,7 +1093,7 @@ static void xdg_shell_get_xdg_surface(struct wl_client *wl_client, &zxdg_surface_v6_interface, wl_resource_get_version(client_resource), id); - if (surface->surface->current->buffer != NULL) { + if (surface->surface->texture->valid) { wl_resource_post_error(surface->resource, ZXDG_SURFACE_V6_ERROR_UNCONFIGURED_BUFFER, "xdg_surface must not have a buffer at creation"); @@ -1147,8 +1150,7 @@ static void wlr_xdg_client_v6_destroy(struct wl_resource *resource) { struct wlr_xdg_surface_v6 *surface, *tmp = NULL; wl_list_for_each_safe(surface, tmp, &client->surfaces, link) { - wl_list_remove(&surface->link); - wl_list_init(&surface->link); + xdg_surface_destroy(surface); } if (client->ping_timer != NULL) { @@ -1,4 +1,4 @@ -#define _POSIX_C_SOURCE 1 +#define _POSIX_C_SOURCE 199506L #include <errno.h> #include <stdarg.h> #include <stdio.h> diff --git a/xcursor/meson.build b/xcursor/meson.build index e8d456cb..afaab915 100644 --- a/xcursor/meson.build +++ b/xcursor/meson.build @@ -5,4 +5,5 @@ lib_wlr_xcursor = static_library( 'wlr_xcursor.c', ), include_directories: wlr_inc, + dependencies: [egl] # header required via include/wlr/render.h ) diff --git a/xwayland/sockets.c b/xwayland/sockets.c index 48bcc822..dd732dd7 100644 --- a/xwayland/sockets.c +++ b/xwayland/sockets.c @@ -1,4 +1,8 @@ #define _XOPEN_SOURCE 700 +#ifdef __FreeBSD__ +// for SOCK_CLOEXEC +#define __BSD_VISIBLE 1 +#endif #include <stdlib.h> #include <stddef.h> #include <stdint.h> @@ -65,9 +69,12 @@ static bool open_sockets(int socks[2], int display) { mkdir(socket_dir, 0777); - // TODO: non-linux apparently want another format +#ifdef __linux__ addr.sun_path[0] = 0; path_size = snprintf(addr.sun_path + 1, sizeof(addr.sun_path) - 1, socket_fmt, display); +#else + path_size = snprintf(addr.sun_path, sizeof(addr.sun_path), socket_fmt, display); +#endif socks[0] = open_socket(&addr, path_size); if (socks[0] < 0) { return false; diff --git a/xwayland/xwayland.c b/xwayland/xwayland.c index 2bec1b63..f1599911 100644 --- a/xwayland/xwayland.c +++ b/xwayland/xwayland.c @@ -1,5 +1,9 @@ #define _XOPEN_SOURCE 700 #define _DEFAULT_SOURCE +#ifdef __FreeBSD__ +// for SOCK_CLOEXEC +#define __BSD_VISIBLE 1 +#endif #include <stdlib.h> #include <stdio.h> #include <unistd.h> @@ -17,6 +21,14 @@ #include "sockets.h" #include "xwm.h" +#ifdef __FreeBSD__ +static inline int clearenv(void) { + extern char **environ; + environ[0] = NULL; + return 0; +} +#endif + static void safe_close(int fd) { if (fd >= 0) { close(fd); |