diff options
Diffstat (limited to 'rootston')
-rw-r--r-- | rootston/cursor.c | 40 | ||||
-rw-r--r-- | rootston/desktop.c | 153 | ||||
-rw-r--r-- | rootston/keyboard.c | 15 | ||||
-rw-r--r-- | rootston/output.c | 27 | ||||
-rw-r--r-- | rootston/rootston.ini.example | 5 | ||||
-rw-r--r-- | rootston/wl_shell.c | 29 | ||||
-rw-r--r-- | rootston/xdg_shell_v6.c | 39 | ||||
-rw-r--r-- | rootston/xwayland.c | 21 |
8 files changed, 274 insertions, 55 deletions
diff --git a/rootston/cursor.c b/rootston/cursor.c index eec8eb5d..605920cc 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -68,8 +68,8 @@ void cursor_update_position(struct roots_input *input, uint32_t time) { view = view_at(desktop, input->cursor->x, input->cursor->y, &surface, &sx, &sy); if (view) { - wlr_seat_pointer_enter(input->wl_seat, surface, sx, sy); - wlr_seat_pointer_send_motion(input->wl_seat, time, sx, sy); + wlr_seat_pointer_notify_enter(input->wl_seat, surface, sx, sy); + wlr_seat_pointer_notify_motion(input->wl_seat, time, sx, sy); } else { wlr_seat_pointer_clear_focus(input->wl_seat); } @@ -123,8 +123,8 @@ void cursor_update_position(struct roots_input *input, uint32_t time) { } } -static void set_view_focus(struct roots_input *input, - struct roots_desktop *desktop, struct roots_view *view) { +void set_view_focus(struct roots_input *input, struct roots_desktop *desktop, + struct roots_view *view) { if (input->active_view == view) { return; } @@ -133,15 +133,18 @@ static void set_view_focus(struct roots_input *input, if (!view) { return; } + input->last_active_view = view; size_t index = 0; for (size_t i = 0; i < desktop->views->length; ++i) { struct roots_view *_view = desktop->views->items[i]; - view_activate(_view, _view == view); - if (view == _view) { + if (_view != view) { + view_activate(_view, false); + } else { index = i; } } + view_activate(view, true); // TODO: list_swap list_del(desktop->views, index); list_add(desktop->views, view); @@ -152,7 +155,7 @@ static void handle_cursor_motion(struct wl_listener *listener, void *data) { struct wlr_event_pointer_motion *event = data; wlr_cursor_move(input->cursor, event->device, event->delta_x, event->delta_y); - cursor_update_position(input, (uint32_t)event->time_usec); + cursor_update_position(input, (uint32_t)(event->time_usec / 1000)); } static void handle_cursor_motion_absolute(struct wl_listener *listener, @@ -162,14 +165,14 @@ static void handle_cursor_motion_absolute(struct wl_listener *listener, struct wlr_event_pointer_motion_absolute *event = data; wlr_cursor_warp_absolute(input->cursor, event->device, event->x_mm / event->width_mm, event->y_mm / event->height_mm); - cursor_update_position(input, (uint32_t)event->time_usec); + cursor_update_position(input, (uint32_t)(event->time_usec / 1000)); } static void handle_cursor_axis(struct wl_listener *listener, void *data) { struct roots_input *input = wl_container_of(listener, input, cursor_axis); struct wlr_event_pointer_axis *event = data; - wlr_seat_pointer_send_axis(input->wl_seat, event->time_sec, + wlr_seat_pointer_notify_axis(input->wl_seat, event->time_sec, event->orientation, event->delta); } @@ -217,7 +220,7 @@ static void do_cursor_button_press(struct roots_input *input, return; } - uint32_t serial = wlr_seat_pointer_send_button(input->wl_seat, time, button, + uint32_t serial = wlr_seat_pointer_notify_button(input->wl_seat, time, button, state); int i; @@ -234,7 +237,7 @@ static void do_cursor_button_press(struct roots_input *input, % (sizeof(input->input_events) / sizeof(input->input_events[0])); set_view_focus(input, desktop, view); if (view) { - wlr_seat_keyboard_enter(input->wl_seat, surface); + wlr_seat_keyboard_notify_enter(input->wl_seat, surface); } break; } @@ -244,7 +247,7 @@ static void handle_cursor_button(struct wl_listener *listener, void *data) { struct roots_input *input = wl_container_of(listener, input, cursor_button); struct wlr_event_pointer_button *event = data; do_cursor_button_press(input, input->cursor, event->device, - (uint32_t)event->time_usec, event->button, event->state); + (uint32_t)(event->time_usec / 1000), event->button, event->state); } static void handle_tool_axis(struct wl_listener *listener, void *data) { @@ -254,7 +257,7 @@ static void handle_tool_axis(struct wl_listener *listener, void *data) { (event->updated_axes & WLR_TABLET_TOOL_AXIS_Y)) { wlr_cursor_warp_absolute(input->cursor, event->device, event->x_mm / event->width_mm, event->y_mm / event->height_mm); - cursor_update_position(input, (uint32_t)event->time_usec); + cursor_update_position(input, (uint32_t)(event->time_usec / 1000)); } } @@ -262,7 +265,13 @@ static void handle_tool_tip(struct wl_listener *listener, void *data) { struct roots_input *input = wl_container_of(listener, input, cursor_tool_tip); struct wlr_event_tablet_tool_tip *event = data; do_cursor_button_press(input, input->cursor, event->device, - (uint32_t)event->time_usec, BTN_LEFT, event->state); + (uint32_t)(event->time_usec / 1000), BTN_LEFT, event->state); +} + +static void handle_pointer_grab_end(struct wl_listener *listener, void *data) { + struct roots_input *input = + wl_container_of(listener, input, pointer_grab_end); + cursor_update_position(input, 0); } void cursor_initialize(struct roots_input *input) { @@ -292,6 +301,9 @@ void cursor_initialize(struct roots_input *input) { wl_list_init(&input->cursor_tool_tip.link); wl_signal_add(&cursor->events.tablet_tool_tip, &input->cursor_tool_tip); input->cursor_tool_tip.notify = handle_tool_tip; + + wl_signal_add(&input->wl_seat->events.pointer_grab_end, &input->pointer_grab_end); + input->pointer_grab_end.notify = handle_pointer_grab_end; } static void reset_device_mappings(struct roots_config *config, diff --git a/rootston/desktop.c b/rootston/desktop.c index f0f8320d..001cefe0 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -16,6 +16,16 @@ void view_destroy(struct roots_view *view) { struct roots_desktop *desktop = view->desktop; + + struct roots_input *input = desktop->server->input; + if (input->active_view == view) { + input->active_view = NULL; + input->mode = ROOTS_CURSOR_PASSTHROUGH; + } + if (input->last_active_view == view) { + input->last_active_view = NULL; + } + for (size_t i = 0; i < desktop->views->length; ++i) { struct roots_view *_view = desktop->views->items[i]; if (view == _view) { @@ -36,16 +46,6 @@ void view_get_size(struct roots_view *view, struct wlr_box *box) { box->height = view->wlr_surface->current->height; } -void view_get_input_bounds(struct roots_view *view, struct wlr_box *box) { - if (view->get_input_bounds) { - view->get_input_bounds(view, box); - return; - } - box->x = box->y = 0; - box->width = view->wlr_surface->current->width; - box->height = view->wlr_surface->current->height; -} - void view_activate(struct roots_view *view, bool activate) { if (view->activate) { view->activate(view, activate); @@ -58,6 +58,46 @@ void view_resize(struct roots_view *view, uint32_t width, uint32_t height) { } } +void view_close(struct roots_view *view) { + if (view->close) { + view->close(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); + if (!output) { + return false; + } + + view->x = (double)(output->width - size.width) / 2 + + output_layout->x; + view->y = (double)(output->height - size.height) / 2 + + output_layout->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; +} + static struct wlr_subsurface *subsurface_at(struct wlr_surface *surface, double sx, double sy, double *sub_x, double *sub_y) { struct wlr_subsurface *subsurface; @@ -68,17 +108,59 @@ static struct wlr_subsurface *subsurface_at(struct wlr_surface *surface, subsurface_at(subsurface->surface, _sub_x + sx, _sub_y + sy, sub_x, sub_y); if (sub) { - // TODO: convert sub_x and sub_y to the parent coordinate system + // TODO: This won't work for nested subsurfaces. Convert sub_x and + // sub_y to the parent coordinate system return sub; } int sub_width = subsurface->surface->current->buffer_width; int sub_height = subsurface->surface->current->buffer_height; if ((sx > _sub_x && sx < _sub_x + sub_width) && - (sy > _sub_y && sub_y < sub_y + sub_height)) { - *sub_x = _sub_x; - *sub_y = _sub_y; - return subsurface; + (sy > _sub_y && sy < _sub_y + sub_height)) { + if (pixman_region32_contains_point( + &subsurface->surface->current->input, + sx - _sub_x, sy - _sub_y, NULL)) { + *sub_x = _sub_x; + *sub_y = _sub_y; + return subsurface; + } + } + } + + return NULL; +} + +static struct wlr_xdg_surface_v6 *xdg_v6_popup_at( + struct wlr_xdg_surface_v6 *surface, double sx, double sy, + double *popup_sx, double *popup_sy) { + // XXX: I think this is so complicated because we're mixing geometry + // coordinates with surface coordinates. Input handling should only deal + // with surface coordinates. + struct wlr_xdg_surface_v6 *popup; + wl_list_for_each(popup, &surface->popups, popup_link) { + double _popup_sx = surface->geometry->x + popup->popup_state->geometry.x; + double _popup_sy = surface->geometry->y + popup->popup_state->geometry.y; + int popup_width = popup->popup_state->geometry.width; + int popup_height = popup->popup_state->geometry.height; + + struct wlr_xdg_surface_v6 *_popup = + xdg_v6_popup_at(popup, sx - _popup_sx + popup->geometry->x, + sy - _popup_sy + popup->geometry->y, popup_sx, popup_sy); + if (_popup) { + *popup_sx = *popup_sx + _popup_sx - popup->geometry->x; + *popup_sy = *popup_sy + _popup_sy - popup->geometry->y; + return _popup; + } + + if ((sx > _popup_sx && sx < _popup_sx + popup_width) && + (sy > _popup_sy && sy < _popup_sy + popup_height)) { + if (pixman_region32_contains_point(&popup->surface->current->input, + sx - _popup_sx + popup->geometry->x, + sy - _popup_sy + popup->geometry->y, NULL)) { + *popup_sx = _popup_sx - popup->geometry->x; + *popup_sy = _popup_sy - popup->geometry->y; + return popup; + } } } @@ -93,8 +175,12 @@ struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly, double view_sx = lx - view->x; double view_sy = ly - view->y; - struct wlr_box box; - view_get_input_bounds(view, &box); + struct wlr_box box = { + .x = 0, + .y = 0, + .width = view->wlr_surface->current->buffer_width, + .height = view->wlr_surface->current->buffer_height, + }; if (view->rotation != 0.0) { // Coordinates relative to the center of the view double ox = view_sx - (double)box.width/2, @@ -106,6 +192,21 @@ struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly, view_sy = ry + (double)box.height/2; } + if (view->type == ROOTS_XDG_SHELL_V6_VIEW) { + // TODO: test if this works with rotated views + double popup_sx, popup_sy; + struct wlr_xdg_surface_v6 *popup = + xdg_v6_popup_at(view->xdg_surface_v6, view_sx, view_sy, + &popup_sx, &popup_sy); + + if (popup) { + *sx = view_sx - popup_sx; + *sy = view_sy - popup_sy; + *surface = popup->surface; + return view; + } + } + double sub_x, sub_y; struct wlr_subsurface *subsurface = subsurface_at(view->wlr_surface, view_sx, view_sy, &sub_x, &sub_y); @@ -116,7 +217,10 @@ struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly, return view; } - if (wlr_box_contains_point(&box, view_sx, view_sy)) { + if (wlr_box_contains_point(&box, view_sx, view_sy) && + pixman_region32_contains_point( + &view->wlr_surface->current->input, + view_sx, view_sy, NULL)) { *sx = view_sx; *sy = view_sy; *surface = view->wlr_surface; @@ -138,16 +242,15 @@ struct roots_desktop *desktop_create(struct roots_server *server, wl_list_init(&desktop->output_remove.link); desktop->output_remove.notify = output_remove_notify; - wl_signal_add(&server->backend->events.output_add, - &desktop->output_add); + wl_signal_add(&server->backend->events.output_add, &desktop->output_add); wl_signal_add(&server->backend->events.output_remove, - &desktop->output_remove); + &desktop->output_remove); desktop->server = server; desktop->config = config; desktop->layout = wlr_output_layout_create(); - desktop->compositor = wlr_compositor_create( - server->wl_display, server->renderer); + desktop->compositor = wlr_compositor_create(server->wl_display, + server->renderer); desktop->xdg_shell_v6 = wlr_xdg_shell_v6_create(server->wl_display); wl_signal_add(&desktop->xdg_shell_v6->events.new_surface, @@ -170,7 +273,9 @@ struct roots_desktop *desktop_create(struct roots_server *server, #endif desktop->gamma_control_manager = wlr_gamma_control_manager_create( - server->wl_display); + server->wl_display); + desktop->screenshooter = wlr_screenshooter_create(server->wl_display, + server->renderer); return desktop; } diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 6f6fa0e8..6f4334af 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -21,19 +21,28 @@ static ssize_t keyboard_pressed_keysym_index(struct roots_keyboard *keyboard, return -1; } +static const char *exec_prefix = "exec "; + static void keyboard_binding_execute(struct roots_keyboard *keyboard, - char *command) { + const char *command) { struct roots_server *server = keyboard->input->server; if (strcmp(command, "exit") == 0) { wl_display_terminate(server->wl_display); - } else { + } else if (strcmp(command, "close") == 0) { + if (keyboard->input->last_active_view != NULL) { + view_close(keyboard->input->last_active_view); + } + } else if (strncmp(exec_prefix, command, strlen(exec_prefix)) == 0) { + const char *shell_cmd = command + strlen(exec_prefix); pid_t pid = fork(); if (pid < 0) { wlr_log(L_ERROR, "cannot execute binding command: fork() failed"); return; } else if (pid == 0) { - execl("/bin/sh", "/bin/sh", "-c", command, (void *)NULL); + execl("/bin/sh", "/bin/sh", "-c", shell_cmd, (void *)NULL); } + } else { + wlr_log(L_ERROR, "unknown binding command: %s", command); } } diff --git a/rootston/output.c b/rootston/output.c index d7aade3d..6c7fbf51 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -78,10 +78,34 @@ static void render_surface(struct wlr_surface *surface, } } +static void render_xdg_v6_popups(struct wlr_xdg_surface_v6 *surface, + struct roots_desktop *desktop, struct wlr_output *wlr_output, + struct timespec *when, double base_x, double base_y, float rotation) { + // TODO: make sure this works with view rotation + struct wlr_xdg_surface_v6 *popup; + wl_list_for_each(popup, &surface->popups, popup_link) { + if (!popup->configured) { + continue; + } + + double popup_x = base_x + surface->geometry->x + + popup->popup_state->geometry.x - popup->geometry->x; + double popup_y = base_y + surface->geometry->y + + popup->popup_state->geometry.y - popup->geometry->y; + render_surface(popup->surface, desktop, wlr_output, when, popup_x, + popup_y, rotation); + render_xdg_v6_popups(popup, desktop, wlr_output, when, popup_x, popup_y, rotation); + } +} + static void render_view(struct roots_view *view, struct roots_desktop *desktop, struct wlr_output *wlr_output, struct timespec *when) { render_surface(view->wlr_surface, desktop, wlr_output, when, view->x, view->y, view->rotation); + if (view->type == ROOTS_XDG_SHELL_V6_VIEW) { + render_xdg_v6_popups(view->xdg_surface_v6, desktop, wlr_output, + when, view->x, view->y, view->rotation); + } } static void output_frame_notify(struct wl_listener *listener, void *data) { @@ -145,7 +169,8 @@ void output_add_notify(struct wl_listener *listener, void *data) { // TODO the cursor must be set depending on which surface it is displayed // over which should happen in the compositor. if (!wlr_output_set_cursor(wlr_output, image->buffer, - image->width, image->width, image->height)) { + image->width, image->width, image->height, + image->hotspot_x, image->hotspot_y)) { wlr_log(L_DEBUG, "Failed to set hardware cursor"); return; } diff --git a/rootston/rootston.ini.example b/rootston/rootston.ini.example index cc7d8baa..460efa13 100644 --- a/rootston/rootston.ini.example +++ b/rootston/rootston.ini.example @@ -34,6 +34,7 @@ meta-key = Logo # Keybindings # Maps key combinations with commands to execute -# The special command "exit" stops the compositor +# Use the prefix "exec" to execute a shell command [bindings] -Logo+q = exit +Logo+Shift+e = exit # Stop the compositor +Logo+q = close # Close the current view diff --git a/rootston/wl_shell.c b/rootston/wl_shell.c index 1991d332..009a8c06 100644 --- a/rootston/wl_shell.c +++ b/rootston/wl_shell.c @@ -17,6 +17,12 @@ static void resize(struct roots_view *view, uint32_t width, uint32_t height) { height); } +static void close(struct roots_view *view) { + assert(view->type == ROOTS_WL_SHELL_VIEW); + struct wlr_wl_shell_surface *surf = view->wl_shell_surface; + wl_client_destroy(surf->client); +} + static void handle_request_move(struct wl_listener *listener, void *data) { struct roots_wl_shell_surface *roots_surface = wl_container_of(listener, roots_surface, request_move); @@ -43,6 +49,17 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { view_begin_resize(input, event->cursor, view, e->edges); } +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); + } +} + static void handle_destroy(struct wl_listener *listener, void *data) { struct roots_wl_shell_surface *roots_surface = wl_container_of(listener, roots_surface, destroy); @@ -67,7 +84,9 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) { struct roots_wl_shell_surface *roots_surface = calloc(1, sizeof(struct roots_wl_shell_surface)); - // TODO: all of the trimmings + if (!roots_surface) { + return; + } wl_list_init(&roots_surface->destroy.link); roots_surface->destroy.notify = handle_destroy; wl_signal_add(&surface->events.destroy, &roots_surface->destroy); @@ -77,9 +96,14 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) { wl_signal_add(&surface->events.request_move, &roots_surface->request_move); wl_list_init(&roots_surface->request_resize.link); roots_surface->request_resize.notify = handle_request_resize; - wl_signal_add(&surface->events.request_resize, &roots_surface->request_resize); + wl_signal_add(&surface->events.request_resize, + &roots_surface->request_resize); wl_list_init(&roots_surface->request_set_fullscreen.link); wl_list_init(&roots_surface->request_set_maximized.link); + wl_list_init(&roots_surface->surface_commit.link); + roots_surface->surface_commit.notify = handle_surface_commit; + wl_signal_add(&surface->surface->events.commit, + &roots_surface->surface_commit); struct roots_view *view = calloc(1, sizeof(struct roots_view)); view->type = ROOTS_WL_SHELL_VIEW; @@ -88,6 +112,7 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) { view->roots_wl_shell_surface = roots_surface; view->wlr_surface = surface->surface; view->resize = resize; + view->close = close; view->desktop = desktop; roots_surface->view = view; list_add(desktop->views, view); diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index ab34f52a..9b8d8882 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -33,6 +33,14 @@ static void resize(struct roots_view *view, uint32_t width, uint32_t height) { } } +static void close(struct roots_view *view) { + assert(view->type == ROOTS_XDG_SHELL_V6_VIEW); + struct wlr_xdg_surface_v6 *surf = view->xdg_surface_v6; + if (surf->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL) { + wlr_xdg_toplevel_v6_send_close(surf); + } +} + static void handle_request_move(struct wl_listener *listener, void *data) { struct roots_xdg_surface_v6 *roots_xdg_surface = wl_container_of(listener, roots_xdg_surface, request_move); @@ -59,6 +67,17 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { view_begin_resize(input, event->cursor, view, e->edges); } +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); + } +} + static void handle_destroy(struct wl_listener *listener, void *data) { struct roots_xdg_surface_v6 *roots_xdg_surface = wl_container_of(listener, roots_xdg_surface, destroy); @@ -73,17 +92,29 @@ static void handle_destroy(struct wl_listener *listener, void *data) { } void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { + struct wlr_xdg_surface_v6 *surface = data; + assert(surface->role != WLR_XDG_SURFACE_V6_ROLE_NONE); + + if (surface->role == WLR_XDG_SURFACE_V6_ROLE_POPUP) { + wlr_log(L_DEBUG, "new xdg popup"); + return; + } + struct roots_desktop *desktop = wl_container_of(listener, desktop, xdg_shell_v6_surface); - struct wlr_xdg_surface_v6 *surface = data; - wlr_log(L_DEBUG, "new xdg surface: title=%s, app_id=%s", + wlr_log(L_DEBUG, "new xdg toplevel: title=%s, app_id=%s", surface->title, surface->app_id); wlr_xdg_surface_v6_ping(surface); struct roots_xdg_surface_v6 *roots_surface = calloc(1, sizeof(struct roots_xdg_surface_v6)); - // TODO: all of the trimmings + if (!roots_surface) { + return; + } + wl_list_init(&roots_surface->commit.link); + roots_surface->commit.notify = handle_commit; + wl_signal_add(&surface->events.commit, &roots_surface->commit); wl_list_init(&roots_surface->destroy.link); roots_surface->destroy.notify = handle_destroy; wl_signal_add(&surface->events.destroy, &roots_surface->destroy); @@ -100,13 +131,13 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { struct roots_view *view = calloc(1, sizeof(struct roots_view)); view->type = ROOTS_XDG_SHELL_V6_VIEW; - view->x = view->y = 200; view->xdg_surface_v6 = surface; view->roots_xdg_surface_v6 = roots_surface; view->wlr_surface = surface->surface; view->get_size = get_size; view->activate = activate; view->resize = resize; + view->close = close; view->desktop = desktop; roots_surface->view = view; list_add(desktop->views, view); diff --git a/rootston/xwayland.c b/rootston/xwayland.c index 7ecc4d4f..c32ee15b 100644 --- a/rootston/xwayland.c +++ b/rootston/xwayland.c @@ -9,6 +9,16 @@ #include "rootston/desktop.h" #include "rootston/server.h" +static void activate(struct roots_view *view, bool active) { + assert(view->type == ROOTS_XWAYLAND_VIEW); + if (active) { + wlr_xwayland_surface_activate(view->desktop->xwayland, + view->xwayland_surface); + } else { + wlr_xwayland_surface_activate(view->desktop->xwayland, NULL); + } +} + static void resize(struct roots_view *view, uint32_t width, uint32_t height) { assert(view->type == ROOTS_XWAYLAND_VIEW); struct wlr_xwayland_surface *xwayland_surface = view->xwayland_surface; @@ -16,6 +26,11 @@ static void resize(struct roots_view *view, uint32_t width, uint32_t height) { xwayland_surface->x, xwayland_surface->y, width, height); } +static void close(struct roots_view *view) { + assert(view->type == ROOTS_XWAYLAND_VIEW); + wlr_xwayland_surface_close(view->desktop->xwayland, view->xwayland_surface); +} + static void handle_destroy(struct wl_listener *listener, void *data) { struct roots_xwayland_surface *roots_surface = wl_container_of(listener, roots_surface, destroy); @@ -38,11 +53,6 @@ static void handle_request_configure(struct wl_listener *listener, void *data) { xwayland_surface, event->x, event->y, event->width, event->height); } -static void activate(struct roots_view *view, bool active) { - wlr_xwayland_surface_activate(view->desktop->xwayland, - view->xwayland_surface); -} - void handle_xwayland_surface(struct wl_listener *listener, void *data) { struct roots_desktop *desktop = wl_container_of(listener, desktop, xwayland_surface); @@ -78,6 +88,7 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { view->desktop = desktop; view->activate = activate; view->resize = resize; + view->close = close; roots_surface->view = view; list_add(desktop->views, view); } |