improve: better support foreign protocol

This commit is contained in:
DanyLE 2024-04-13 00:25:39 +02:00
parent dced6db8b2
commit 68a0b669ef
5 changed files with 93 additions and 24 deletions

View File

@ -205,6 +205,8 @@ struct diyac_view
struct wl_listener set_app_id; // only useful when using SSD
struct wl_listener new_popup;
struct wl_listener set_title;
struct foreign_toplevel toplevel;
};

View File

@ -9,7 +9,6 @@ static void handle_request_minimize(struct wl_listener *listener, void *data)
// view_minimize(view, event->minimized);
diyac_view_set_mimimize(view, event->minimized);
wlr_log(WLR_INFO, "foreign: request minimize");
}
static void handle_request_maximize(struct wl_listener *listener, void *data)
@ -45,7 +44,7 @@ static void
handle_request_close(struct wl_listener *listener, void *data)
{
struct diyac_view *view = wl_container_of(listener, view, toplevel.close);
//view_close(view);
wlr_xdg_toplevel_send_close(view->xdg_toplevel);
}
static void
@ -94,4 +93,20 @@ void diyac_init_foreign_toplevel(struct diyac_view *view)
toplevel->destroy.notify = handle_destroy;
wl_signal_add(&toplevel->handle->events.destroy, &toplevel->destroy);
wlr_foreign_toplevel_handle_v1_output_enter(
view->toplevel.handle, view->output->wlr_output);
//wlr_foreign_toplevel_handle_v1_output_enter
struct wlr_xdg_toplevel *xdg_toplevel = view->xdg_toplevel;
if (!xdg_toplevel->parent)
{
return;
}
struct wlr_xdg_surface *surface = xdg_toplevel->parent->base;
struct diyac_view *parent = surface->data;
if (!parent->toplevel.handle)
{
return;
}
wlr_foreign_toplevel_handle_v1_set_parent(view->toplevel.handle, parent->toplevel.handle);
}

31
view.c
View File

@ -350,3 +350,34 @@ void diyac_view_set_mimimize(struct diyac_view * view, bool activated)
//TODO implement minimize
wlr_xdg_surface_schedule_configure(view->xdg_toplevel->base);
}
void diyac_view_update_title(struct diyac_view * view)
{
struct wlr_xdg_toplevel *xdg_toplevel = view->xdg_toplevel;
if (!xdg_toplevel)
{
return;
}
const char *title = xdg_toplevel->title;
wlr_log(WLR_INFO, "diyac_view_update_title: %s", title ? title : "");
if (!view->toplevel.handle || !title)
{
return;
}
wlr_foreign_toplevel_handle_v1_set_title(view->toplevel.handle, title);
}
void diyac_view_update_app_id(struct diyac_view * view)
{
struct wlr_xdg_toplevel *xdg_toplevel = view->xdg_toplevel;
if (!xdg_toplevel)
{
return;
}
const char *appid = xdg_toplevel->app_id;
wlr_log(WLR_INFO, "diyac_view_update_app_id: %s", appid ? appid : "");
if (!view->toplevel.handle || !appid)
{
return;
}
wlr_foreign_toplevel_handle_v1_set_app_id(view->toplevel.handle, appid);
}

2
view.h
View File

@ -18,4 +18,6 @@ struct wlr_box diyac_view_get_geometry(struct diyac_view *view);
void diyac_view_set_maximize(struct diyac_view * view, bool activated);
void diyac_view_set_fullscreen(struct diyac_view * view, bool activated);
void diyac_view_set_mimimize(struct diyac_view * view, bool activated);
void diyac_view_update_title(struct diyac_view * view);
void diyac_view_update_app_id(struct diyac_view * view);
#endif

33
xdg.c
View File

@ -72,8 +72,9 @@ static void xdg_toplevel_map(struct wl_listener *listener, void *data)
wlr_xdg_surface_get_geometry(toplevel->xdg_toplevel->base, &toplevel->original);
wlr_scene_node_set_enabled(&toplevel->scene_tree->node, true);
toplevel->mapped = true;
diyac_init_foreign_toplevel(toplevel);
wl_list_insert(&toplevel->server->views, &toplevel->link);
diyac_view_update_app_id(toplevel);
diyac_view_update_title(toplevel);
toplevel->original.x = (toplevel->output->usable_area.width - toplevel->original.width) / 2;
toplevel->original.y = (toplevel->output->usable_area.height - toplevel->original.height) / 2;
if (toplevel->original.width > toplevel->output->usable_area.width)
@ -183,7 +184,10 @@ static void xdg_toplevel_destroy(struct wl_listener *listener, void *data)
{
/* Called when the xdg_toplevel is destroyed. */
struct diyac_view *toplevel = wl_container_of(listener, toplevel, destroy);
if (toplevel->toplevel.handle)
{
wlr_foreign_toplevel_handle_v1_destroy(toplevel->toplevel.handle);
}
wl_list_remove(&toplevel->map.link);
wl_list_remove(&toplevel->unmap.link);
wl_list_remove(&toplevel->destroy.link);
@ -191,6 +195,11 @@ static void xdg_toplevel_destroy(struct wl_listener *listener, void *data)
wl_list_remove(&toplevel->request_resize.link);
wl_list_remove(&toplevel->request_maximize.link);
wl_list_remove(&toplevel->request_fullscreen.link);
wl_list_remove(&toplevel->set_app_id.link);
wl_list_remove(&toplevel->new_popup.link);
wl_list_remove(&toplevel->set_title.link);
free(toplevel);
}
@ -218,8 +227,7 @@ static void popup_unconstrain(struct diyac_popup *popup)
.x = 0,
.y = 0,
.width = view->output->wlr_output->width,
.height = view->output->wlr_output->height
};
.height = view->output->wlr_output->height};
struct diyac_view *root = diyac_get_root_view(view);
if (!root || !root->state.fullscreen)
{
@ -316,9 +324,14 @@ static void xdg_popup_create(struct diyac_view *view, struct wlr_xdg_popup *wlr_
static void xdg_set_appid_notify(struct wl_listener *listener, void *data)
{
struct diyac_view *xdg_toplevel_view =
wl_container_of(listener, xdg_toplevel_view, set_app_id);
wlr_log(WLR_INFO, "set application id");
struct diyac_view *view = wl_container_of(listener, view, set_app_id);
diyac_view_update_app_id(view);
}
static void xdg_set_title_notify(struct wl_listener *listener, void *data)
{
struct diyac_view *view = wl_container_of(listener, view, set_title);
diyac_view_update_title(view);
}
static void xdg_new_popup_notify(struct wl_listener *listener, void *data)
@ -379,6 +392,8 @@ void diyac_new_xdg_surface(struct wl_listener *listener, void *data)
wlr_scene_node_set_enabled(&toplevel->scene_tree->node, false);
diyac_node_descriptor_create(&toplevel->scene_tree->node,
DIYAC_NODE_VIEW, toplevel);
diyac_init_foreign_toplevel(toplevel);
/* Listen to the various events it can emit */
toplevel->map.notify = xdg_toplevel_map;
wl_signal_add(&xdg_surface->surface->events.map, &toplevel->map);
@ -403,6 +418,10 @@ void diyac_new_xdg_surface(struct wl_listener *listener, void *data)
&toplevel->request_fullscreen);
toplevel->new_popup.notify = xdg_new_popup_notify;
wl_signal_add(&xdg_surface->events.new_popup, &toplevel->new_popup);
toplevel->set_app_id.notify = xdg_set_appid_notify;
wl_signal_add(&xdg_toplevel->events.set_app_id, &toplevel->set_app_id);
toplevel->set_title.notify = xdg_set_title_notify;
wl_signal_add(&xdg_toplevel->events.set_title, &toplevel->set_title);
}