mirror of
https://github.com/labwc/labwc.git
synced 2026-04-10 08:21:07 -04:00
[fixup] support popups
This commit is contained in:
parent
ed4edd77a4
commit
93aff4e0d3
1 changed files with 80 additions and 0 deletions
|
|
@ -15,12 +15,89 @@ struct xdg_unmanaged {
|
||||||
struct wlr_scene_node *node;
|
struct wlr_scene_node *node;
|
||||||
|
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
|
struct wl_listener new_popup;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct popup {
|
||||||
|
struct wlr_xdg_popup *wlr_popup;
|
||||||
|
struct wlr_scene_tree *scene_tree;
|
||||||
|
struct wlr_box output_toplevel_sx_box;
|
||||||
|
|
||||||
|
struct wl_listener destroy;
|
||||||
|
struct wl_listener new_popup;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
popup_handle_destroy(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct popup *popup = wl_container_of(listener, popup, destroy);
|
||||||
|
wl_list_remove(&popup->destroy.link);
|
||||||
|
wl_list_remove(&popup->new_popup.link);
|
||||||
|
free(popup);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void popup_handle_new_popup(struct wl_listener *listener, void *data);
|
||||||
|
|
||||||
|
static struct popup *
|
||||||
|
create_popup(struct wlr_xdg_popup *wlr_popup, struct wlr_scene_tree *parent,
|
||||||
|
struct wlr_box *output_toplevel_sx_box)
|
||||||
|
{
|
||||||
|
struct popup *popup = znew(*popup);
|
||||||
|
popup->wlr_popup = wlr_popup;
|
||||||
|
popup->scene_tree = wlr_scene_xdg_surface_create(parent, wlr_popup->base);
|
||||||
|
if (!popup->scene_tree) {
|
||||||
|
free(popup);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
node_descriptor_create(&popup->scene_tree->node,
|
||||||
|
LAB_NODE_DESC_LAYER_POPUP, popup);
|
||||||
|
|
||||||
|
popup->destroy.notify = popup_handle_destroy;
|
||||||
|
wl_signal_add(&wlr_popup->base->events.destroy, &popup->destroy);
|
||||||
|
popup->new_popup.notify = popup_handle_new_popup;
|
||||||
|
wl_signal_add(&wlr_popup->base->events.new_popup, &popup->new_popup);
|
||||||
|
|
||||||
|
wlr_xdg_popup_unconstrain_from_box(wlr_popup, output_toplevel_sx_box);
|
||||||
|
return popup;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
popup_handle_new_popup(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct popup *popup = wl_container_of(listener, popup, new_popup);
|
||||||
|
struct wlr_xdg_popup *wlr_popup = data;
|
||||||
|
struct popup *new_popup = create_popup(wlr_popup, popup->scene_tree,
|
||||||
|
&popup->output_toplevel_sx_box);
|
||||||
|
new_popup->output_toplevel_sx_box = popup->output_toplevel_sx_box;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_new_popup(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct xdg_unmanaged *unmanaged = wl_container_of(listener, unmanaged, new_popup);
|
||||||
|
struct wlr_xdg_popup *wlr_popup = data;
|
||||||
|
|
||||||
|
int lx, ly;
|
||||||
|
wlr_scene_node_coords(unmanaged->node, &lx, &ly);
|
||||||
|
|
||||||
|
struct wlr_box output_box = { 0 };
|
||||||
|
|
||||||
|
struct wlr_box output_toplevel_sx_box = {
|
||||||
|
.x = output_box.x - lx,
|
||||||
|
.y = output_box.y - ly,
|
||||||
|
.width = output_box.width,
|
||||||
|
.height = output_box.height,
|
||||||
|
};
|
||||||
|
struct popup *popup = create_popup(wlr_popup,
|
||||||
|
unmanaged->tree, &output_toplevel_sx_box);
|
||||||
|
popup->output_toplevel_sx_box = output_toplevel_sx_box;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
unmanaged_handle_destroy(struct wl_listener *listener, void *data)
|
unmanaged_handle_destroy(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct xdg_unmanaged *unmanaged = wl_container_of(listener, unmanaged, destroy);
|
struct xdg_unmanaged *unmanaged = wl_container_of(listener, unmanaged, destroy);
|
||||||
|
wl_list_remove(&unmanaged->new_popup.link);
|
||||||
wl_list_remove(&unmanaged->destroy.link);
|
wl_list_remove(&unmanaged->destroy.link);
|
||||||
free(unmanaged);
|
free(unmanaged);
|
||||||
}
|
}
|
||||||
|
|
@ -35,6 +112,9 @@ xdg_unmanaged_create(struct server *server, struct wlr_xdg_surface *wlr_xdg_surf
|
||||||
unmanaged->destroy.notify = unmanaged_handle_destroy;
|
unmanaged->destroy.notify = unmanaged_handle_destroy;
|
||||||
wl_signal_add(&wlr_xdg_surface->events.destroy, &unmanaged->destroy);
|
wl_signal_add(&wlr_xdg_surface->events.destroy, &unmanaged->destroy);
|
||||||
|
|
||||||
|
unmanaged->new_popup.notify = handle_new_popup;
|
||||||
|
wl_signal_add(&wlr_xdg_surface->events.new_popup, &unmanaged->new_popup);
|
||||||
|
|
||||||
unmanaged->tree = server->view_tree_always_on_top;
|
unmanaged->tree = server->view_tree_always_on_top;
|
||||||
unmanaged->node = &wlr_scene_surface_create(unmanaged->tree,
|
unmanaged->node = &wlr_scene_surface_create(unmanaged->tree,
|
||||||
wlr_xdg_surface->surface)->buffer->node;
|
wlr_xdg_surface->surface)->buffer->node;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue