improve: better support foreign protocol
This commit is contained in:
parent
dced6db8b2
commit
68a0b669ef
2
diyac.h
2
diyac.h
@ -205,6 +205,8 @@ struct diyac_view
|
|||||||
|
|
||||||
struct wl_listener set_app_id; // only useful when using SSD
|
struct wl_listener set_app_id; // only useful when using SSD
|
||||||
struct wl_listener new_popup;
|
struct wl_listener new_popup;
|
||||||
|
struct wl_listener set_title;
|
||||||
|
|
||||||
struct foreign_toplevel toplevel;
|
struct foreign_toplevel toplevel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
21
foreign.c
21
foreign.c
@ -9,7 +9,6 @@ static void handle_request_minimize(struct wl_listener *listener, void *data)
|
|||||||
// view_minimize(view, event->minimized);
|
// view_minimize(view, event->minimized);
|
||||||
diyac_view_set_mimimize(view, event->minimized);
|
diyac_view_set_mimimize(view, event->minimized);
|
||||||
wlr_log(WLR_INFO, "foreign: request minimize");
|
wlr_log(WLR_INFO, "foreign: request minimize");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_request_maximize(struct wl_listener *listener, void *data)
|
static void handle_request_maximize(struct wl_listener *listener, void *data)
|
||||||
@ -37,7 +36,7 @@ static void handle_request_activate(struct wl_listener *listener, void *data)
|
|||||||
// struct wlr_foreign_toplevel_handle_v1_activated_event *event = data;
|
// struct wlr_foreign_toplevel_handle_v1_activated_event *event = data;
|
||||||
/* In a multi-seat world we would select seat based on event->seat here. */
|
/* In a multi-seat world we would select seat based on event->seat here. */
|
||||||
// desktop_focus_view(view, /*raise*/ true);
|
// desktop_focus_view(view, /*raise*/ true);
|
||||||
diyac_focus_view(view,true);
|
diyac_focus_view(view, true);
|
||||||
wlr_log(WLR_INFO, "foreign: request activate");
|
wlr_log(WLR_INFO, "foreign: request activate");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,7 +44,7 @@ static void
|
|||||||
handle_request_close(struct wl_listener *listener, void *data)
|
handle_request_close(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct diyac_view *view = wl_container_of(listener, view, toplevel.close);
|
struct diyac_view *view = wl_container_of(listener, view, toplevel.close);
|
||||||
//view_close(view);
|
wlr_xdg_toplevel_send_close(view->xdg_toplevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -94,4 +93,20 @@ void diyac_init_foreign_toplevel(struct diyac_view *view)
|
|||||||
|
|
||||||
toplevel->destroy.notify = handle_destroy;
|
toplevel->destroy.notify = handle_destroy;
|
||||||
wl_signal_add(&toplevel->handle->events.destroy, &toplevel->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
31
view.c
@ -349,4 +349,35 @@ void diyac_view_set_mimimize(struct diyac_view * view, bool activated)
|
|||||||
// view->requested.minimized = activated;
|
// view->requested.minimized = activated;
|
||||||
//TODO implement minimize
|
//TODO implement minimize
|
||||||
wlr_xdg_surface_schedule_configure(view->xdg_toplevel->base);
|
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
2
view.h
@ -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_maximize(struct diyac_view * view, bool activated);
|
||||||
void diyac_view_set_fullscreen(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_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
|
#endif
|
61
xdg.c
61
xdg.c
@ -56,10 +56,10 @@ static void begin_interactive(struct diyac_view *toplevel,
|
|||||||
|
|
||||||
static void xdg_toplevel_map(struct wl_listener *listener, void *data)
|
static void xdg_toplevel_map(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Called when the surface is mapped, or ready to display on-screen. */
|
/* Called when the surface is mapped, or ready to display on-screen. */
|
||||||
struct diyac_view *toplevel = wl_container_of(listener, toplevel, map);
|
struct diyac_view *toplevel = wl_container_of(listener, toplevel, map);
|
||||||
if(toplevel->mapped)
|
if (toplevel->mapped)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -67,13 +67,14 @@ static void xdg_toplevel_map(struct wl_listener *listener, void *data)
|
|||||||
wlr_xdg_toplevel_set_wm_capabilities(toplevel->xdg_toplevel,
|
wlr_xdg_toplevel_set_wm_capabilities(toplevel->xdg_toplevel,
|
||||||
WLR_XDG_TOPLEVEL_WM_CAPABILITIES_MAXIMIZE |
|
WLR_XDG_TOPLEVEL_WM_CAPABILITIES_MAXIMIZE |
|
||||||
WLR_XDG_TOPLEVEL_WM_CAPABILITIES_MINIMIZE);
|
WLR_XDG_TOPLEVEL_WM_CAPABILITIES_MINIMIZE);
|
||||||
//WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN
|
//WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN
|
||||||
*/
|
*/
|
||||||
wlr_xdg_surface_get_geometry(toplevel->xdg_toplevel->base, &toplevel->original);
|
wlr_xdg_surface_get_geometry(toplevel->xdg_toplevel->base, &toplevel->original);
|
||||||
wlr_scene_node_set_enabled(&toplevel->scene_tree->node, true);
|
wlr_scene_node_set_enabled(&toplevel->scene_tree->node, true);
|
||||||
toplevel->mapped = true;
|
toplevel->mapped = true;
|
||||||
diyac_init_foreign_toplevel(toplevel);
|
|
||||||
wl_list_insert(&toplevel->server->views, &toplevel->link);
|
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.x = (toplevel->output->usable_area.width - toplevel->original.width) / 2;
|
||||||
toplevel->original.y = (toplevel->output->usable_area.height - toplevel->original.height) / 2;
|
toplevel->original.y = (toplevel->output->usable_area.height - toplevel->original.height) / 2;
|
||||||
if (toplevel->original.width > toplevel->output->usable_area.width)
|
if (toplevel->original.width > toplevel->output->usable_area.width)
|
||||||
@ -98,15 +99,15 @@ static void xdg_toplevel_unmap(struct wl_listener *listener, void *data)
|
|||||||
{
|
{
|
||||||
diyac_reset_cursor_mode(toplevel->server);
|
diyac_reset_cursor_mode(toplevel->server);
|
||||||
}
|
}
|
||||||
if(toplevel->state.fullscreen)
|
if (toplevel->state.fullscreen)
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* When a client exit during fullscreen mode, the top layer shall
|
* When a client exit during fullscreen mode, the top layer shall
|
||||||
* be restored as it is currently disabled
|
* be restored as it is currently disabled
|
||||||
*/
|
*/
|
||||||
wlr_scene_node_set_enabled(&toplevel->output->scenes.top->node, true);
|
wlr_scene_node_set_enabled(&toplevel->output->scenes.top->node, true);
|
||||||
}
|
}
|
||||||
if(toplevel->server->active_view == toplevel)
|
if (toplevel->server->active_view == toplevel)
|
||||||
{
|
{
|
||||||
toplevel->server->active_view = NULL;
|
toplevel->server->active_view = NULL;
|
||||||
}
|
}
|
||||||
@ -114,11 +115,11 @@ static void xdg_toplevel_unmap(struct wl_listener *listener, void *data)
|
|||||||
if (root && root->mapped)
|
if (root && root->mapped)
|
||||||
{
|
{
|
||||||
diyac_focus_view(root, true);
|
diyac_focus_view(root, true);
|
||||||
//wlr_log(WLR_INFO, "focus root");
|
// wlr_log(WLR_INFO, "focus root");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//wlr_log(WLR_INFO, "focus topmost");
|
// wlr_log(WLR_INFO, "focus topmost");
|
||||||
diyac_focus_topmost_view(toplevel->server, true);
|
diyac_focus_topmost_view(toplevel->server, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,7 +170,7 @@ static void xdg_toplevel_request_fullscreen(struct wl_listener *listener, void *
|
|||||||
{
|
{
|
||||||
struct diyac_view *toplevel =
|
struct diyac_view *toplevel =
|
||||||
wl_container_of(listener, toplevel, request_fullscreen);
|
wl_container_of(listener, toplevel, request_fullscreen);
|
||||||
diyac_view_set_fullscreen(toplevel,toplevel->xdg_toplevel->requested.fullscreen);
|
diyac_view_set_fullscreen(toplevel, toplevel->xdg_toplevel->requested.fullscreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xdg_toplevel_request_minimize(struct wl_listener *listener, void *data)
|
static void xdg_toplevel_request_minimize(struct wl_listener *listener, void *data)
|
||||||
@ -183,7 +184,10 @@ static void xdg_toplevel_destroy(struct wl_listener *listener, void *data)
|
|||||||
{
|
{
|
||||||
/* Called when the xdg_toplevel is destroyed. */
|
/* Called when the xdg_toplevel is destroyed. */
|
||||||
struct diyac_view *toplevel = wl_container_of(listener, toplevel, destroy);
|
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->map.link);
|
||||||
wl_list_remove(&toplevel->unmap.link);
|
wl_list_remove(&toplevel->unmap.link);
|
||||||
wl_list_remove(&toplevel->destroy.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_resize.link);
|
||||||
wl_list_remove(&toplevel->request_maximize.link);
|
wl_list_remove(&toplevel->request_maximize.link);
|
||||||
wl_list_remove(&toplevel->request_fullscreen.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);
|
free(toplevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,13 +224,12 @@ static void popup_unconstrain(struct diyac_popup *popup)
|
|||||||
struct wlr_output_layout *output_layout = server->output_layout;
|
struct wlr_output_layout *output_layout = server->output_layout;
|
||||||
struct wlr_output *wlr_output = view->output->wlr_output;
|
struct wlr_output *wlr_output = view->output->wlr_output;
|
||||||
struct wlr_box usable = {
|
struct wlr_box usable = {
|
||||||
.x = 0,
|
.x = 0,
|
||||||
.y = 0,
|
.y = 0,
|
||||||
.width = view->output->wlr_output->width,
|
.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);
|
struct diyac_view *root = diyac_get_root_view(view);
|
||||||
if(!root || ! root->state.fullscreen)
|
if (!root || !root->state.fullscreen)
|
||||||
{
|
{
|
||||||
usable = view->output->usable_area;
|
usable = view->output->usable_area;
|
||||||
}
|
}
|
||||||
@ -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)
|
static void xdg_set_appid_notify(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct diyac_view *xdg_toplevel_view =
|
struct diyac_view *view = wl_container_of(listener, view, set_app_id);
|
||||||
wl_container_of(listener, xdg_toplevel_view, set_app_id);
|
diyac_view_update_app_id(view);
|
||||||
wlr_log(WLR_INFO, "set application id");
|
}
|
||||||
|
|
||||||
|
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)
|
static void xdg_new_popup_notify(struct wl_listener *listener, void *data)
|
||||||
@ -358,7 +371,7 @@ void diyac_new_xdg_surface(struct wl_listener *listener, void *data)
|
|||||||
wlr_log(WLR_INFO, "diyac_new_xdg_surface: Creating new application windows");
|
wlr_log(WLR_INFO, "diyac_new_xdg_surface: Creating new application windows");
|
||||||
wlr_xdg_surface_ping(xdg_surface);
|
wlr_xdg_surface_ping(xdg_surface);
|
||||||
/* Allocate a diyac_view for this surface */
|
/* Allocate a diyac_view for this surface */
|
||||||
struct diyac_view *toplevel = calloc(1, sizeof(*toplevel));
|
struct diyac_view *toplevel = calloc(1, sizeof(*toplevel));
|
||||||
memset(&toplevel->state, 0, sizeof(toplevel->state));
|
memset(&toplevel->state, 0, sizeof(toplevel->state));
|
||||||
memset(&toplevel->requested, 0, sizeof(toplevel->requested));
|
memset(&toplevel->requested, 0, sizeof(toplevel->requested));
|
||||||
toplevel->server = server;
|
toplevel->server = server;
|
||||||
@ -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);
|
wlr_scene_node_set_enabled(&toplevel->scene_tree->node, false);
|
||||||
diyac_node_descriptor_create(&toplevel->scene_tree->node,
|
diyac_node_descriptor_create(&toplevel->scene_tree->node,
|
||||||
DIYAC_NODE_VIEW, toplevel);
|
DIYAC_NODE_VIEW, toplevel);
|
||||||
|
diyac_init_foreign_toplevel(toplevel);
|
||||||
|
|
||||||
/* Listen to the various events it can emit */
|
/* Listen to the various events it can emit */
|
||||||
toplevel->map.notify = xdg_toplevel_map;
|
toplevel->map.notify = xdg_toplevel_map;
|
||||||
wl_signal_add(&xdg_surface->surface->events.map, &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->request_fullscreen);
|
||||||
toplevel->new_popup.notify = xdg_new_popup_notify;
|
toplevel->new_popup.notify = xdg_new_popup_notify;
|
||||||
wl_signal_add(&xdg_surface->events.new_popup, &toplevel->new_popup);
|
wl_signal_add(&xdg_surface->events.new_popup, &toplevel->new_popup);
|
||||||
|
|
||||||
toplevel->set_app_id.notify = xdg_set_appid_notify;
|
toplevel->set_app_id.notify = xdg_set_appid_notify;
|
||||||
wl_signal_add(&xdg_toplevel->events.set_app_id, &toplevel->set_app_id);
|
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);
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user