diff --git a/include/view.h b/include/view.h index 5ba62a5b..30fa6a16 100644 --- a/include/view.h +++ b/include/view.h @@ -40,6 +40,7 @@ struct view; struct view_impl { void (*configure)(struct view *view, struct wlr_box geo); void (*close)(struct view *view); + void (*close_popups)(struct view *view); const char *(*get_string_prop)(struct view *view, const char *prop); void (*map)(struct view *view); void (*set_activated)(struct view *view, bool activated); @@ -166,6 +167,7 @@ void view_toggle_keybinds(struct view *view); void view_set_activated(struct view *view); void view_set_output(struct view *view, struct output *output); void view_close(struct view *view); +void view_close_popups(struct view *view); /** * view_move_resize - resize and move view diff --git a/src/cursor.c b/src/cursor.c index 38323a02..cd30d3d9 100644 --- a/src/cursor.c +++ b/src/cursor.c @@ -879,6 +879,9 @@ handle_press_mousebinding(struct server *server, struct cursor_context *ctx, continue; } consumed_by_frame_context |= mousebind->context == LAB_SSD_FRAME; + if (ctx->view) { + view_close_popups(ctx->view); + } actions_run(ctx->view, server, &mousebind->actions, resize_edges); } } diff --git a/src/desktop.c b/src/desktop.c index 7c6e944e..f5201e92 100644 --- a/src/desktop.c +++ b/src/desktop.c @@ -34,10 +34,20 @@ desktop_arrange_all_views(struct server *server) } } +static void +close_all_popups(struct server *server) +{ + struct view *view; + wl_list_for_each(view, &server->views, link) { + view_close_popups(view); + } +} + void desktop_focus_and_activate_view(struct seat *seat, struct view *view) { if (!view) { + close_all_popups(seat->server); seat_focus_surface(seat, NULL); return; } @@ -77,6 +87,7 @@ desktop_focus_and_activate_view(struct seat *seat, struct view *view) return; } + view_close_popups(view); view_set_activated(view); seat_focus_surface(seat, view->surface); } @@ -168,6 +179,9 @@ desktop_cycle_view(struct server *server, struct view *start_view, return start_view; /* may be NULL */ } } + + view_close_popups(start_view); + struct view *view = start_view; struct wlr_scene_node *node = &view->scene_tree->node; diff --git a/src/interactive.c b/src/interactive.c index 9a009d93..018206fd 100644 --- a/src/interactive.c +++ b/src/interactive.c @@ -96,6 +96,7 @@ interactive_begin(struct view *view, enum input_mode mode, uint32_t edges) server->grab_y = seat->cursor->y; server->grab_box = geometry; server->resize_edges = edges; + view_close_popups(view); } /* Returns true if view was snapped to any edge */ diff --git a/src/view.c b/src/view.c index 729cedb2..de6e0bfa 100644 --- a/src/view.c +++ b/src/view.c @@ -152,6 +152,14 @@ view_close(struct view *view) } } +void +view_close_popups(struct view *view) +{ + if (view->impl->close_popups) { + view->impl->close_popups(view); + } +} + void view_move(struct view *view, int x, int y) { diff --git a/src/xdg.c b/src/xdg.c index 20b87b6a..0a0c0553 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -308,6 +308,16 @@ xdg_toplevel_view_close(struct view *view) wlr_xdg_toplevel_send_close(xdg_toplevel_from_view(view)); } +static void +xdg_toplevel_view_close_popups(struct view *view) +{ + struct wlr_xdg_toplevel *toplevel = xdg_toplevel_from_view(view); + struct wlr_xdg_popup *popup, *next; + wl_list_for_each_safe(popup, next, &toplevel->base->popups, link) { + wlr_xdg_popup_destroy(popup); + } +} + static void xdg_toplevel_view_maximize(struct view *view, bool maximized) { @@ -549,6 +559,7 @@ xdg_toplevel_view_unmap(struct view *view, bool client_request) static const struct view_impl xdg_toplevel_view_impl = { .configure = xdg_toplevel_view_configure, .close = xdg_toplevel_view_close, + .close_popups = xdg_toplevel_view_close_popups, .get_string_prop = xdg_toplevel_view_get_string_prop, .map = xdg_toplevel_view_map, .set_activated = xdg_toplevel_view_set_activated,