diff options
-rw-r--r-- | .builds/alpine.yml | 22 | ||||
-rw-r--r-- | backend/drm/drm.c | 18 | ||||
-rw-r--r-- | include/rootston/desktop.h | 4 | ||||
-rw-r--r-- | include/rootston/view.h | 3 | ||||
-rw-r--r-- | include/types/wlr_xdg_shell.h | 1 | ||||
-rw-r--r-- | rootston/cursor.c | 26 | ||||
-rw-r--r-- | rootston/desktop.c | 58 | ||||
-rw-r--r-- | rootston/output.c | 12 | ||||
-rw-r--r-- | rootston/seat.c | 8 | ||||
-rw-r--r-- | rootston/wl_shell.c | 12 | ||||
-rw-r--r-- | rootston/xdg_shell.c | 20 | ||||
-rw-r--r-- | rootston/xdg_shell_v6.c | 20 | ||||
-rw-r--r-- | rootston/xwayland.c | 20 | ||||
-rw-r--r-- | types/tablet_v2/wlr_tablet_v2.c | 7 | ||||
-rw-r--r-- | types/xdg_shell/wlr_xdg_popup.c | 32 | ||||
-rw-r--r-- | types/xdg_shell/wlr_xdg_surface.c | 49 | ||||
-rw-r--r-- | types/xdg_shell/wlr_xdg_toplevel.c | 53 |
17 files changed, 200 insertions, 165 deletions
diff --git a/.builds/alpine.yml b/.builds/alpine.yml new file mode 100644 index 00000000..9751dc8a --- /dev/null +++ b/.builds/alpine.yml @@ -0,0 +1,22 @@ +image: alpine/edge +packages: + - eudev-dev + - ffmpeg-dev + - libcap-dev + - libinput-dev + - libxkbcommon-dev + - mesa-dev + - meson + - pixman-dev + - wayland-dev + - wayland-protocols + - xcb-util-image-dev +sources: + - https://github.com/swaywm/wlroots +tasks: + - setup: | + cd wlroots + meson build + - build: | + cd wlroots + ninja -C build diff --git a/backend/drm/drm.c b/backend/drm/drm.c index c2186932..97028dc7 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -428,6 +428,19 @@ bool enable_drm_connector(struct wlr_output *output, bool enable) { return true; } +static ssize_t connector_index_from_crtc(struct wlr_drm_backend *drm, + struct wlr_drm_crtc *crtc) { + size_t i = 0; + struct wlr_drm_connector *conn; + wl_list_for_each(conn, &drm->outputs, link) { + if (conn->crtc == crtc) { + return i; + } + ++i; + } + return -1; +} + static void realloc_planes(struct wlr_drm_backend *drm, const uint32_t *crtc_in, bool *changed_outputs) { wlr_log(WLR_DEBUG, "Reallocating planes"); @@ -477,7 +490,10 @@ static void realloc_planes(struct wlr_drm_backend *drm, const uint32_t *crtc_in, type, c->id); - changed_outputs[crtc_res[i]] = true; + ssize_t conn_idx = connector_index_from_crtc(drm, c); + if (conn_idx >= 0) { + changed_outputs[conn_idx] = true; + } if (*old) { finish_drm_surface(&(*old)->surf); } diff --git a/include/rootston/desktop.h b/include/rootston/desktop.h index 31338acf..cd85e794 100644 --- a/include/rootston/desktop.h +++ b/include/rootston/desktop.h @@ -99,8 +99,8 @@ void view_destroy(struct roots_view *view); void view_activate(struct roots_view *view, bool activate); void view_apply_damage(struct roots_view *view); void view_damage_whole(struct roots_view *view); -void view_update_position(struct roots_view *view, double x, double y); -void view_update_size(struct roots_view *view, uint32_t width, uint32_t height); +void view_update_position(struct roots_view *view, int x, int y); +void view_update_size(struct roots_view *view, int width, int height); void view_update_decorated(struct roots_view *view, bool decorated); void view_initial_focus(struct roots_view *view); void view_map(struct roots_view *view, struct wlr_surface *surface); diff --git a/include/rootston/view.h b/include/rootston/view.h index 0c75737b..e67aaf36 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -88,8 +88,7 @@ struct roots_view { struct roots_desktop *desktop; struct wl_list link; // roots_desktop::views - double x, y; - uint32_t width, height; + struct wlr_box box; float rotation; float alpha; diff --git a/include/types/wlr_xdg_shell.h b/include/types/wlr_xdg_shell.h index 93fdc670..08a691bd 100644 --- a/include/types/wlr_xdg_shell.h +++ b/include/types/wlr_xdg_shell.h @@ -18,6 +18,7 @@ struct wlr_xdg_surface *create_xdg_surface( struct wlr_xdg_client *client, struct wlr_surface *surface, uint32_t id); void unmap_xdg_surface(struct wlr_xdg_surface *surface); +void reset_xdg_surface(struct wlr_xdg_surface *xdg_surface); void destroy_xdg_surface(struct wlr_xdg_surface *surface); void handle_xdg_surface_commit(struct wlr_surface *wlr_surface); void handle_xdg_surface_precommit(struct wlr_surface *wlr_surface); diff --git a/rootston/cursor.c b/rootston/cursor.c index 9a163c63..b9ded30e 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -190,8 +190,8 @@ void roots_cursor_update_position(struct roots_cursor *cursor, if (view != NULL) { double dx = cursor->cursor->x - cursor->offs_x; double dy = cursor->cursor->y - cursor->offs_y; - double x = view->x; - double y = view->y; + double x = view->box.x; + double y = view->box.y; int width = cursor->view_width; int height = cursor->view_height; if (cursor->resize_edges & WLR_EDGE_TOP) { @@ -220,8 +220,8 @@ void roots_cursor_update_position(struct roots_cursor *cursor, case ROOTS_CURSOR_ROTATE: view = roots_seat_get_focus(seat); if (view != NULL) { - int ox = view->x + view->wlr_surface->current.width/2, - oy = view->y + view->wlr_surface->current.height/2; + int ox = view->box.x + view->wlr_surface->current.width/2, + oy = view->box.y + view->wlr_surface->current.height/2; int ux = cursor->offs_x - ox, uy = cursor->offs_y - oy; int vx = cursor->cursor->x - ox, @@ -322,11 +322,11 @@ void roots_cursor_handle_motion(struct roots_cursor *cursor, double lx2 = lx1 + dx; double ly2 = ly1 + dy; - double sx1 = lx1 - view->x; - double sy1 = ly1 - view->y; + double sx1 = lx1 - view->box.x; + double sy1 = ly1 - view->box.y; - double sx2 = lx2 - view->x; - double sy2 = ly2 - view->y; + double sx2 = lx2 - view->box.x; + double sy2 = ly2 - view->box.y; double sx2_confined, sy2_confined; if (!wlr_region_confine(&cursor->confine, sx1, sy1, sx2, sy2, @@ -354,7 +354,7 @@ void roots_cursor_handle_motion_absolute(struct roots_cursor *cursor, if (cursor->active_constraint && !pixman_region32_contains_point(&cursor->confine, - floor(lx - view->x), floor(ly - view->y), NULL)) { + floor(lx - view->box.x), floor(ly - view->box.y), NULL)) { return; } } @@ -474,7 +474,7 @@ void roots_cursor_handle_tool_axis(struct roots_cursor *cursor, if (cursor->active_constraint && !pixman_region32_contains_point(&cursor->confine, - floor(lx - view->x), floor(ly - view->y), NULL)) { + floor(lx - view->box.x), floor(ly - view->box.y), NULL)) { return; } } @@ -598,11 +598,11 @@ void roots_cursor_constrain(struct roots_cursor *cursor, double sx = (boxes[0].x1 + boxes[0].x2) / 2.; double sy = (boxes[0].y1 + boxes[0].y2) / 2.; - rotate_child_position(&sx, &sy, 0, 0, view->width, view->height, + rotate_child_position(&sx, &sy, 0, 0, view->box.width, view->box.height, view->rotation); - double lx = view->x + sx; - double ly = view->y + sy; + double lx = view->box.x + sx; + double ly = view->box.y + sy; wlr_cursor_warp_closest(cursor->cursor, NULL, lx, ly); } diff --git a/rootston/desktop.c b/rootston/desktop.c index 9b5291a3..69f025e1 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -48,10 +48,10 @@ struct roots_view *view_create(struct roots_desktop *desktop) { } void view_get_box(const struct roots_view *view, struct wlr_box *box) { - box->x = view->x; - box->y = view->y; - box->width = view->width; - box->height = view->height; + box->x = view->box.x; + box->y = view->box.y; + box->width = view->box.width; + box->height = view->box.height; } void view_get_deco_box(const struct roots_view *view, struct wlr_box *box) { @@ -131,7 +131,7 @@ static void view_update_output(const struct roots_view *view, } void view_move(struct roots_view *view, double x, double y) { - if (view->x == x && view->y == y) { + if (view->box.x == x && view->box.y == y) { return; } @@ -162,8 +162,8 @@ void view_resize(struct roots_view *view, uint32_t width, uint32_t height) { void view_move_resize(struct roots_view *view, double x, double y, uint32_t width, uint32_t height) { - bool update_x = x != view->x; - bool update_y = y != view->y; + bool update_x = x != view->box.x; + bool update_y = y != view->box.y; if (!update_x && !update_y) { view_resize(view, width, height); return; @@ -190,8 +190,8 @@ static struct wlr_output *view_get_output(struct roots_view *view) { double output_x, output_y; wlr_output_layout_closest_point(view->desktop->layout, NULL, - view->x + (double)view_box.width/2, - view->y + (double)view_box.height/2, + view->box.x + (double)view_box.width/2, + view->box.y + (double)view_box.height/2, &output_x, &output_y); return wlr_output_layout_output_at(view->desktop->layout, output_x, output_y); @@ -227,11 +227,11 @@ void view_maximize(struct roots_view *view, bool maximized) { if (!view->maximized && maximized) { view->maximized = true; - view->saved.x = view->x; - view->saved.y = view->y; + view->saved.x = view->box.x; + view->saved.y = view->box.y; view->saved.rotation = view->rotation; - view->saved.width = view->width; - view->saved.height = view->height; + view->saved.width = view->box.width; + view->saved.height = view->box.height; view_arrange_maximized(view); } @@ -272,8 +272,8 @@ void view_set_fullscreen(struct roots_view *view, bool fullscreen, struct wlr_box view_box; view_get_box(view, &view_box); - view->saved.x = view->x; - view->saved.y = view->y; + view->saved.x = view->box.x; + view->saved.y = view->box.y; view->saved.rotation = view->rotation; view->saved.width = view_box.width; view->saved.height = view_box.height; @@ -500,7 +500,7 @@ void view_unmap(struct roots_view *view) { } view->wlr_surface = NULL; - view->width = view->height = 0; + view->box.width = view->box.height = 0; } void view_initial_focus(struct roots_view *view) { @@ -536,25 +536,25 @@ void view_damage_whole(struct roots_view *view) { } } -void view_update_position(struct roots_view *view, double x, double y) { - if (view->x == x && view->y == y) { +void view_update_position(struct roots_view *view, int x, int y) { + if (view->box.x == x && view->box.y == y) { return; } view_damage_whole(view); - view->x = x; - view->y = y; + view->box.x = x; + view->box.y = y; view_damage_whole(view); } -void view_update_size(struct roots_view *view, uint32_t width, uint32_t height) { - if (view->width == width && view->height == height) { +void view_update_size(struct roots_view *view, int width, int height) { + if (view->box.width == width && view->box.height == height) { return; } view_damage_whole(view); - view->width = width; - view->height = height; + view->box.width = width; + view->box.height = height; view_damage_whole(view); } @@ -585,8 +585,8 @@ static bool view_at(struct roots_view *view, double lx, double ly, return false; } - double view_sx = lx - view->x; - double view_sy = ly - view->y; + double view_sx = lx - view->box.x; + double view_sy = ly - view->box.y; struct wlr_surface_state *state = &view->wlr_surface->current; struct wlr_box box = { @@ -806,10 +806,10 @@ static void handle_constraint_destroy(struct wl_listener *listener, double sy = wlr_constraint->current.cursor_hint.y; struct roots_view *view = seat->cursor->pointer_view->view; - rotate_child_position(&sx, &sy, 0, 0, view->width, view->height, + rotate_child_position(&sx, &sy, 0, 0, view->box.width, view->box.height, view->rotation); - double lx = view->x + sx; - double ly = view->y + sy; + double lx = view->box.x + sx; + double ly = view->box.y + sy; wlr_cursor_warp(seat->cursor->cursor, NULL, lx, ly); } diff --git a/rootston/output.c b/rootston/output.c index 7017bd1f..5819833b 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -67,8 +67,8 @@ static void surface_for_each_surface(struct wlr_surface *surface, static void view_for_each_surface(struct roots_view *view, struct layout_data *layout_data, wlr_surface_iterator_func_t iterator, void *user_data) { - layout_data->x = view->x; - layout_data->y = view->y; + layout_data->x = view->box.x; + layout_data->y = view->box.y; layout_data->width = view->wlr_surface->current.width; layout_data->height = view->wlr_surface->current.height; layout_data->rotation = view->rotation; @@ -304,13 +304,13 @@ static void get_decoration_box(struct roots_view *view, struct wlr_box deco_box; view_get_deco_box(view, &deco_box); - double sx = deco_box.x - view->x; - double sy = deco_box.y - view->y; + double sx = deco_box.x - view->box.x; + double sy = deco_box.y - view->box.y; rotate_child_position(&sx, &sy, deco_box.width, deco_box.height, view->wlr_surface->current.width, view->wlr_surface->current.height, view->rotation); - double x = sx + view->x; - double y = sy + view->y; + double x = sx + view->box.x; + double y = sy + view->box.y; wlr_output_layout_output_coords(output->desktop->layout, wlr_output, &x, &y); diff --git a/rootston/seat.c b/rootston/seat.c index 95e7d6c9..e91278c5 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -1341,8 +1341,8 @@ void roots_seat_begin_move(struct roots_seat *seat, struct roots_view *view) { cursor->view_x = view->saved.x; cursor->view_y = view->saved.y; } else { - cursor->view_x = view->x; - cursor->view_y = view->y; + cursor->view_x = view->box.x; + cursor->view_y = view->box.y; } view_maximize(view, false); wlr_seat_pointer_clear_focus(seat->seat); @@ -1363,8 +1363,8 @@ void roots_seat_begin_resize(struct roots_seat *seat, struct roots_view *view, cursor->view_width = view->saved.width; cursor->view_height = view->saved.height; } else { - cursor->view_x = view->x; - cursor->view_y = view->y; + cursor->view_x = view->box.x; + cursor->view_y = view->box.y; struct wlr_box box; view_get_box(view, &box); cursor->view_width = box.width; diff --git a/rootston/wl_shell.c b/rootston/wl_shell.c index 07ac9f58..0f7228bb 100644 --- a/rootston/wl_shell.c +++ b/rootston/wl_shell.c @@ -162,8 +162,8 @@ static void handle_surface_commit(struct wl_listener *listener, void *data) { int height = wlr_surface->current.height; view_update_size(view, width, height); - double x = view->x; - double y = view->y; + double x = view->box.x; + double y = view->box.y; if (view->pending_move_resize.update_x) { x = view->pending_move_resize.x + view->pending_move_resize.width - width; @@ -236,8 +236,8 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) { return; } view->type = ROOTS_WL_SHELL_VIEW; - view->width = surface->surface->current.width; - view->height = surface->surface->current.height; + view->box.width = surface->surface->current.width; + view->box.height = surface->surface->current.height; view->wl_shell_surface = surface; view->roots_wl_shell_surface = roots_surface; @@ -262,8 +262,8 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) { } if (found) { view_move(view, - parent->x + surface->transient_state->x, - parent->y + surface->transient_state->y); + parent->box.x + surface->transient_state->x, + parent->box.y + surface->transient_state->y); } } } diff --git a/rootston/xdg_shell.c b/rootston/xdg_shell.c index 2cf2081e..d3fc5372 100644 --- a/rootston/xdg_shell.c +++ b/rootston/xdg_shell.c @@ -72,8 +72,8 @@ static void popup_unconstrain(struct roots_xdg_popup *popup) { int popup_lx, popup_ly; wlr_xdg_popup_get_toplevel_coords(wlr_popup, wlr_popup->geometry.x, wlr_popup->geometry.y, &popup_lx, &popup_ly); - popup_lx += view->x; - popup_ly += view->y; + popup_lx += view->box.x; + popup_ly += view->box.y; anchor_lx += popup_lx; anchor_ly += popup_ly; @@ -95,8 +95,8 @@ static void popup_unconstrain(struct roots_xdg_popup *popup) { // the output box expressed in the coordinate system of the toplevel parent // of the popup struct wlr_box output_toplevel_sx_box = { - .x = output->lx - view->x, - .y = output->ly - view->y, + .x = output->lx - view->box.x, + .y = output->ly - view->box.y, .width = width, .height = height }; @@ -193,8 +193,8 @@ static void move_resize(struct roots_view *view, double x, double y, return; } - bool update_x = x != view->x; - bool update_y = y != view->y; + bool update_x = x != view->box.x; + bool update_y = y != view->box.y; uint32_t constrained_width, constrained_height; apply_size_constraints(surface, width, height, &constrained_width, @@ -345,8 +345,8 @@ static void handle_surface_commit(struct wl_listener *listener, void *data) { uint32_t pending_serial = roots_surface->pending_move_resize_configure_serial; if (pending_serial > 0 && pending_serial >= surface->configure_serial) { - double x = view->x; - double y = view->y; + double x = view->box.x; + double y = view->box.y; if (view->pending_move_resize.update_x) { x = view->pending_move_resize.x + view->pending_move_resize.width - size.width; @@ -377,8 +377,8 @@ static void handle_map(struct wl_listener *listener, void *data) { struct wlr_box box; get_size(view, &box); - view->width = box.width; - view->height = box.height; + view->box.width = box.width; + view->box.height = box.height; view_map(view, view->xdg_surface->surface); view_setup(view); diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 1201ba68..6bdf749f 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -73,8 +73,8 @@ static void popup_unconstrain(struct roots_xdg_popup_v6 *popup) { int popup_lx, popup_ly; wlr_xdg_popup_v6_get_toplevel_coords(wlr_popup, wlr_popup->geometry.x, wlr_popup->geometry.y, &popup_lx, &popup_ly); - popup_lx += view->x; - popup_ly += view->y; + popup_lx += view->box.x; + popup_ly += view->box.y; anchor_lx += popup_lx; anchor_ly += popup_ly; @@ -96,8 +96,8 @@ static void popup_unconstrain(struct roots_xdg_popup_v6 *popup) { // the output box expressed in the coordinate system of the toplevel parent // of the popup struct wlr_box output_toplevel_sx_box = { - .x = output->lx - view->x, - .y = output->ly - view->y, + .x = output->lx - view->box.x, + .y = output->ly - view->box.y, .width = width, .height = height }; @@ -193,8 +193,8 @@ static void move_resize(struct roots_view *view, double x, double y, return; } - bool update_x = x != view->x; - bool update_y = y != view->y; + bool update_x = x != view->box.x; + bool update_y = y != view->box.y; uint32_t constrained_width, constrained_height; apply_size_constraints(surface, width, height, &constrained_width, @@ -344,8 +344,8 @@ static void handle_surface_commit(struct wl_listener *listener, void *data) { uint32_t pending_serial = roots_surface->pending_move_resize_configure_serial; if (pending_serial > 0 && pending_serial >= surface->configure_serial) { - double x = view->x; - double y = view->y; + double x = view->box.x; + double y = view->box.y; if (view->pending_move_resize.update_x) { x = view->pending_move_resize.x + view->pending_move_resize.width - size.width; @@ -376,8 +376,8 @@ static void handle_map(struct wl_listener *listener, void *data) { struct wlr_box box; get_size(view, &box); - view->width = box.width; - view->height = box.height; + view->box.width = box.width; + view->box.height = box.height; view_map(view, view->xdg_surface_v6->surface); view_setup(view); diff --git a/rootston/xwayland.c b/rootston/xwayland.c index 66ccce69..d98f808b 100644 --- a/rootston/xwayland.c +++ b/rootston/xwayland.c @@ -64,8 +64,8 @@ static void move_resize(struct roots_view *view, double x, double y, assert(view->type == ROOTS_XWAYLAND_VIEW); struct wlr_xwayland_surface *xwayland_surface = view->xwayland_surface; - bool update_x = x != view->x; - bool update_y = y != view->y; + bool update_x = x != view->box.x; + bool update_y = y != view->box.y; uint32_t constrained_width, constrained_height; apply_size_constraints(xwayland_surface, width, height, &constrained_width, @@ -210,8 +210,8 @@ static void handle_surface_commit(struct wl_listener *listener, void *data) { int height = wlr_surface->current.height; view_update_size(view, width, height); - double x = view->x; - double y = view->y; + double x = view->box.x; + double y = view->box.y; if (view->pending_move_resize.update_x) { x = view->pending_move_resize.x + view->pending_move_resize.width - width; @@ -231,10 +231,10 @@ static void handle_map(struct wl_listener *listener, void *data) { struct wlr_xwayland_surface *surface = data; struct roots_view *view = roots_surface->view; - view->x = surface->x; - view->y = surface->y; - view->width = surface->surface->current.width; - view->height = surface->surface->current.height; + view->box.x = surface->x; + view->box.y = surface->y; + view->box.width = surface->surface->current.width; + view->box.height = surface->surface->current.height; roots_surface->surface_commit.notify = handle_surface_commit; wl_signal_add(&surface->surface->events.commit, @@ -307,8 +307,8 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { return; } view->type = ROOTS_XWAYLAND_VIEW; - view->x = (double)surface->x; - view->y = (double)surface->y; + view->box.x = surface->x; + view->box.y = surface->y; view->xwayland_surface = surface; view->roots_xwayland_surface = roots_surface; diff --git a/types/tablet_v2/wlr_tablet_v2.c b/types/tablet_v2/wlr_tablet_v2.c index a1cace93..d0bc799d 100644 --- a/types/tablet_v2/wlr_tablet_v2.c +++ b/types/tablet_v2/wlr_tablet_v2.c @@ -28,13 +28,14 @@ struct wlr_tablet_manager_client_v2 { }; static void tablet_seat_destroy(struct wlr_tablet_seat_v2 *seat) { - wl_list_remove(&seat->link); - wl_list_remove(&seat->seat_destroy.link); - struct wlr_tablet_seat_client_v2 *client, *client_tmp; wl_list_for_each_safe(client, client_tmp, &seat->clients, seat_link) { tablet_seat_client_v2_destroy(client->resource); } + + wl_list_remove(&seat->link); + wl_list_remove(&seat->seat_destroy.link); + free(seat); } static void handle_wlr_seat_destroy(struct wl_listener *listener, void *data) { diff --git a/types/xdg_shell/wlr_xdg_popup.c b/types/xdg_shell/wlr_xdg_popup.c index d23d7dac..874329f9 100644 --- a/types/xdg_shell/wlr_xdg_popup.c +++ b/types/xdg_shell/wlr_xdg_popup.c @@ -207,9 +207,7 @@ static const struct xdg_popup_interface xdg_popup_implementation = { static void xdg_popup_handle_resource_destroy(struct wl_resource *resource) { struct wlr_xdg_surface *surface = wlr_xdg_surface_from_popup_resource(resource); - if (surface != NULL) { - destroy_xdg_popup(surface); - } + destroy_xdg_popup(surface); } const struct wlr_surface_role xdg_popup_surface_role = { @@ -241,14 +239,13 @@ void create_xdg_popup(struct wlr_xdg_surface *xdg_surface, return; } - if (xdg_surface->popup == NULL) { - xdg_surface->popup = calloc(1, sizeof(struct wlr_xdg_popup)); - if (!xdg_surface->popup) { - wl_resource_post_no_memory(xdg_surface->resource); - return; - } - xdg_surface->popup->base = xdg_surface; + assert(xdg_surface->popup == NULL); + xdg_surface->popup = calloc(1, sizeof(struct wlr_xdg_popup)); + if (!xdg_surface->popup) { + wl_resource_post_no_memory(xdg_surface->resource); + return; } + xdg_surface->popup->base = xdg_surface; xdg_surface->popup->resource = wl_resource_create( xdg_surface->client->client, &xdg_popup_interface, @@ -280,18 +277,11 @@ void create_xdg_popup(struct wlr_xdg_surface *xdg_surface, } void destroy_xdg_popup(struct wlr_xdg_surface *xdg_surface) { + if (xdg_surface == NULL) { + return; + } assert(xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP); - unmap_xdg_surface(xdg_surface); - - // Don't destroy the popup state yet, the compositor might have some - // listeners set up. Anyway the client can only re-create another xdg-popup - // with this xdg-surface because of role restrictions. - wl_resource_set_user_data(xdg_surface->popup->resource, NULL); - xdg_surface->toplevel->resource = NULL; - - wl_list_remove(&xdg_surface->popup->link); - - xdg_surface->role = WLR_XDG_SURFACE_ROLE_NONE; + reset_xdg_surface(xdg_surface); } void wlr_xdg_popup_get_anchor_point(struct wlr_xdg_popup *popup, diff --git a/types/xdg_shell/wlr_xdg_surface.c b/types/xdg_shell/wlr_xdg_surface.c index 0b1d599f..7046d5f0 100644 --- a/types/xdg_shell/wlr_xdg_surface.c +++ b/types/xdg_shell/wlr_xdg_surface.c @@ -439,39 +439,53 @@ struct wlr_xdg_surface *create_xdg_surface( return xdg_surface; } -void destroy_xdg_surface(struct wlr_xdg_surface *surface) { - if (surface->role != WLR_XDG_SURFACE_ROLE_NONE) { - unmap_xdg_surface(surface); +void reset_xdg_surface(struct wlr_xdg_surface *xdg_surface) { + if (xdg_surface->role != WLR_XDG_SURFACE_ROLE_NONE) { + unmap_xdg_surface(xdg_surface); } - wlr_signal_emit_safe(&surface->events.destroy, surface); - - struct wlr_xdg_popup *popup_state, *next; - wl_list_for_each_safe(popup_state, next, &surface->popups, link) { - xdg_popup_send_popup_done(popup_state->resource); - destroy_xdg_popup(popup_state->base); + if (xdg_surface->added) { + wlr_signal_emit_safe(&xdg_surface->events.destroy, xdg_surface); + xdg_surface->added = false; } - switch (surface->role) { + switch (xdg_surface->role) { case WLR_XDG_SURFACE_ROLE_TOPLEVEL: - destroy_xdg_toplevel(surface); + wl_resource_set_user_data(xdg_surface->toplevel->resource, NULL); + xdg_surface->toplevel->resource = NULL; + + free(xdg_surface->toplevel); + xdg_surface->toplevel = NULL; break; case WLR_XDG_SURFACE_ROLE_POPUP: - destroy_xdg_popup(surface); + wl_resource_set_user_data(xdg_surface->popup->resource, NULL); + xdg_surface->toplevel->resource = NULL; + + wl_list_remove(&xdg_surface->popup->link); + + free(xdg_surface->popup); + xdg_surface->popup = NULL; break; case WLR_XDG_SURFACE_ROLE_NONE: // This space is intentionally left blank break; } - if (surface->surface->role == &xdg_toplevel_surface_role) { - free(surface->toplevel); - } else if (surface->surface->role == &xdg_popup_surface_role) { - free(surface->popup); + xdg_surface->role = WLR_XDG_SURFACE_ROLE_NONE; +} + +void destroy_xdg_surface(struct wlr_xdg_surface *surface) { + reset_xdg_surface(surface); + + struct wlr_xdg_popup *popup_state, *next; + wl_list_for_each_safe(popup_state, next, &surface->popups, link) { + xdg_popup_send_popup_done(popup_state->resource); + destroy_xdg_popup(popup_state->base); } wl_resource_set_user_data(surface->resource, NULL); surface->surface->role_data = NULL; + wl_list_remove(&surface->link); wl_list_remove(&surface->surface_destroy.link); wl_list_remove(&surface->surface_commit.link); @@ -625,7 +639,8 @@ void wlr_xdg_surface_for_each_popup(struct wlr_xdg_surface *surface, xdg_surface_for_each_popup(surface, 0, 0, iterator, user_data); } -void wlr_xdg_surface_get_geometry(struct wlr_xdg_surface *surface, struct wlr_box *box) { +void wlr_xdg_surface_get_geometry(struct wlr_xdg_surface *surface, + struct wlr_box *box) { wlr_surface_get_extends(surface->surface, box); /* The client never set the geometry */ if (!surface->geometry.width) { diff --git a/types/xdg_shell/wlr_xdg_toplevel.c b/types/xdg_shell/wlr_xdg_toplevel.c index d3220994..d3ee0cb7 100644 --- a/types/xdg_shell/wlr_xdg_toplevel.c +++ b/types/xdg_shell/wlr_xdg_toplevel.c @@ -444,9 +444,7 @@ static const struct xdg_toplevel_interface xdg_toplevel_implementation = { static void xdg_toplevel_handle_resource_destroy(struct wl_resource *resource) { struct wlr_xdg_surface *surface = wlr_xdg_surface_from_toplevel_resource(resource); - if (surface != NULL) { - destroy_xdg_toplevel(surface); - } + destroy_xdg_toplevel(surface); } const struct wlr_surface_role xdg_toplevel_surface_role = { @@ -469,28 +467,24 @@ void create_xdg_toplevel(struct wlr_xdg_surface *xdg_surface, return; } + assert(xdg_surface->toplevel == NULL); + xdg_surface->toplevel = calloc(1, sizeof(struct wlr_xdg_toplevel)); if (xdg_surface->toplevel == NULL) { - xdg_surface->toplevel = calloc(1, sizeof(struct wlr_xdg_toplevel)); - if (xdg_surface->toplevel == NULL) { - wl_resource_post_no_memory(xdg_surface->resource); - return; - } - wl_signal_init(&xdg_surface->toplevel->events.request_maximize); - wl_signal_init(&xdg_surface->toplevel->events.request_fullscreen); - wl_signal_init(&xdg_surface->toplevel->events.request_minimize); - wl_signal_init(&xdg_surface->toplevel->events.request_move); - wl_signal_init(&xdg_surface->toplevel->events.request_resize); - wl_signal_init(&xdg_surface->toplevel->events.request_show_window_menu); - wl_signal_init(&xdg_surface->toplevel->events.set_parent); - wl_signal_init(&xdg_surface->toplevel->events.set_title); - wl_signal_init(&xdg_surface->toplevel->events.set_app_id); - - xdg_surface->toplevel->base = xdg_surface; + wl_resource_post_no_memory(xdg_surface->resource); + return; } + xdg_surface->toplevel->base = xdg_surface; + + wl_signal_init(&xdg_surface->toplevel->events.request_maximize); + wl_signal_init(&xdg_surface->toplevel->events.request_fullscreen); + wl_signal_init(&xdg_surface->toplevel->events.request_minimize); + wl_signal_init(&xdg_surface->toplevel->events.request_move); + wl_signal_init(&xdg_surface->toplevel->events.request_resize); + wl_signal_init(&xdg_surface->toplevel->events.request_show_window_menu); + wl_signal_init(&xdg_surface->toplevel->events.set_parent); + wl_signal_init(&xdg_surface->toplevel->events.set_title); + wl_signal_init(&xdg_surface->toplevel->events.set_app_id); - xdg_surface->role = WLR_XDG_SURFACE_ROLE_TOPLEVEL; - - assert(xdg_surface->toplevel->resource == NULL); xdg_surface->toplevel->resource = wl_resource_create( xdg_surface->client->client, &xdg_toplevel_interface, wl_resource_get_version(xdg_surface->resource), id); @@ -502,19 +496,16 @@ void create_xdg_toplevel(struct wlr_xdg_surface *xdg_surface, wl_resource_set_implementation(xdg_surface->toplevel->resource, &xdg_toplevel_implementation, xdg_surface, xdg_toplevel_handle_resource_destroy); + + xdg_surface->role = WLR_XDG_SURFACE_ROLE_TOPLEVEL; } void destroy_xdg_toplevel(struct wlr_xdg_surface *xdg_surface) { + if (xdg_surface == NULL) { + return; + } assert(xdg_surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL); - unmap_xdg_surface(xdg_surface); - - // Don't destroy the toplevel state yet, the compositor might have some - // listeners set up. Anyway the client can only re-create another - // xdg-toplevel with this xdg-surface because of role restrictions. - wl_resource_set_user_data(xdg_surface->toplevel->resource, NULL); - xdg_surface->toplevel->resource = NULL; - - xdg_surface->role = WLR_XDG_SURFACE_ROLE_NONE; + reset_xdg_surface(xdg_surface); } uint32_t wlr_xdg_toplevel_set_size(struct wlr_xdg_surface *surface, |