diff options
Diffstat (limited to 'rootston')
-rw-r--r-- | rootston/desktop.c | 86 | ||||
-rw-r--r-- | rootston/wl_shell.c | 26 | ||||
-rw-r--r-- | rootston/xdg_shell.c | 28 | ||||
-rw-r--r-- | rootston/xdg_shell_v6.c | 28 | ||||
-rw-r--r-- | rootston/xwayland.c | 29 |
5 files changed, 196 insertions, 1 deletions
diff --git a/rootston/desktop.c b/rootston/desktop.c index 69f025e1..b41a3079 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -123,9 +123,17 @@ static void view_update_output(const struct roots_view *view, output->wlr_output, &box); if (intersected && !intersects) { wlr_surface_send_leave(view->wlr_surface, output->wlr_output); + if (view->toplevel_handle) { + wlr_foreign_toplevel_handle_v1_output_leave( + view->toplevel_handle, output->wlr_output); + } } if (!intersected && intersects) { wlr_surface_send_enter(view->wlr_surface, output->wlr_output); + if (view->toplevel_handle) { + wlr_foreign_toplevel_handle_v1_output_enter( + view->toplevel_handle, output->wlr_output); + } } } } @@ -149,6 +157,11 @@ void view_activate(struct roots_view *view, bool activate) { if (view->activate) { view->activate(view, activate); } + + if (view->toplevel_handle) { + wlr_foreign_toplevel_handle_v1_set_activated(view->toplevel_handle, + activate); + } } void view_resize(struct roots_view *view, uint32_t width, uint32_t height) { @@ -225,6 +238,11 @@ void view_maximize(struct roots_view *view, bool maximized) { view->maximize(view, maximized); } + if (view->toplevel_handle) { + wlr_foreign_toplevel_handle_v1_set_maximized(view->toplevel_handle, + maximized); + } + if (!view->maximized && maximized) { view->maximized = true; view->saved.x = view->box.x; @@ -501,6 +519,11 @@ void view_unmap(struct roots_view *view) { view->wlr_surface = NULL; view->box.width = view->box.height = 0; + + if (view->toplevel_handle) { + wlr_foreign_toplevel_handle_v1_destroy(view->toplevel_handle); + view->toplevel_handle = NULL; + } } void view_initial_focus(struct roots_view *view) { @@ -520,6 +543,7 @@ void view_setup(struct roots_view *view) { } view_update_output(view, NULL); + view_create_foreign_toplevel_handle(view); } void view_apply_damage(struct roots_view *view) { @@ -575,6 +599,66 @@ void view_update_decorated(struct roots_view *view, bool decorated) { view_damage_whole(view); } +void view_set_title(struct roots_view *view, const char *title) { + if (view->toplevel_handle) { + wlr_foreign_toplevel_handle_v1_set_title(view->toplevel_handle, title); + } +} + +void view_set_app_id(struct roots_view *view, const char *app_id) { + if (view->toplevel_handle) { + wlr_foreign_toplevel_handle_v1_set_app_id(view->toplevel_handle, app_id); + } +} + +static void handle_toplevel_handle_request_maximize(struct wl_listener *listener, + void *data) { + struct roots_view *view = wl_container_of(listener, view, + toplevel_handle_request_maximize); + struct wlr_foreign_toplevel_handle_v1_maximized_event *event = data; + view_maximize(view, event->maximized); +} + +static void handle_toplevel_handle_request_activate(struct wl_listener *listener, + void *data) { + struct roots_view *view = + wl_container_of(listener, view, toplevel_handle_request_activate); + struct wlr_foreign_toplevel_handle_v1_activated_event *event = data; + + struct roots_seat *seat; + wl_list_for_each(seat, &view->desktop->server->input->seats, link) { + if (event->seat == seat->seat) { + roots_seat_set_focus(seat, view); + } + } +} + +static void handle_toplevel_handle_request_close(struct wl_listener *listener, + void *data) { + struct roots_view *view = + wl_container_of(listener, view, toplevel_handle_request_close); + view_close(view); +} + +void view_create_foreign_toplevel_handle(struct roots_view *view) { + view->toplevel_handle = + wlr_foreign_toplevel_handle_v1_create( + view->desktop->foreign_toplevel_manager_v1); + + view->toplevel_handle_request_maximize.notify = + handle_toplevel_handle_request_maximize; + wl_signal_add(&view->toplevel_handle->events.request_maximize, + &view->toplevel_handle_request_maximize); + view->toplevel_handle_request_activate.notify = + handle_toplevel_handle_request_activate; + wl_signal_add(&view->toplevel_handle->events.request_activate, + &view->toplevel_handle_request_activate); + view->toplevel_handle_request_close.notify = + handle_toplevel_handle_request_close; + wl_signal_add(&view->toplevel_handle->events.request_close, + &view->toplevel_handle_request_close); +} + static bool view_at(struct roots_view *view, double lx, double ly, struct wlr_surface **surface, double *sx, double *sy) { if (view->type == ROOTS_WL_SHELL_VIEW && @@ -995,6 +1079,8 @@ struct roots_desktop *desktop_create(struct roots_server *server, desktop->presentation = wlr_presentation_create(server->wl_display, server->backend); + desktop->foreign_toplevel_manager_v1 = + wlr_foreign_toplevel_manager_v1_create(server->wl_display); return desktop; } diff --git a/rootston/wl_shell.c b/rootston/wl_shell.c index 0f7228bb..2bf4f4c2 100644 --- a/rootston/wl_shell.c +++ b/rootston/wl_shell.c @@ -87,6 +87,8 @@ static void destroy(struct roots_view *view) { wl_list_remove(&roots_surface->request_maximize.link); wl_list_remove(&roots_surface->request_fullscreen.link); wl_list_remove(&roots_surface->set_state.link); + wl_list_remove(&roots_surface->set_title.link); + wl_list_remove(&roots_surface->set_class.link); wl_list_remove(&roots_surface->surface_commit.link); free(roots_surface); } @@ -150,6 +152,20 @@ static void handle_set_state(struct wl_listener *listener, void *data) { } } +static void handle_set_title(struct wl_listener *listener, void *data) { + struct roots_wl_shell_surface *roots_surface = + wl_container_of(listener, roots_surface, set_state); + view_set_title(roots_surface->view, + roots_surface->view->wl_shell_surface->title); +} + +static void handle_set_class(struct wl_listener *listener, void *data) { + struct roots_wl_shell_surface *roots_surface = + wl_container_of(listener, roots_surface, set_state); + view_set_app_id(roots_surface->view, + roots_surface->view->wl_shell_surface->class); +} + static void handle_surface_commit(struct wl_listener *listener, void *data) { struct roots_wl_shell_surface *roots_surface = wl_container_of(listener, roots_surface, surface_commit); @@ -225,8 +241,13 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) { handle_request_fullscreen; wl_signal_add(&surface->events.request_fullscreen, &roots_surface->request_fullscreen); + roots_surface->set_state.notify = handle_set_state; wl_signal_add(&surface->events.set_state, &roots_surface->set_state); + roots_surface->set_title.notify = handle_set_title; + wl_signal_add(&surface->events.set_title, &roots_surface->set_title); + roots_surface->set_class.notify = handle_set_class; + wl_signal_add(&surface->events.set_class, &roots_surface->set_class); roots_surface->surface_commit.notify = handle_surface_commit; wl_signal_add(&surface->surface->events.commit, &roots_surface->surface_commit); @@ -249,6 +270,11 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) { view_map(view, surface->surface); view_setup(view); + wlr_foreign_toplevel_handle_v1_set_title(view->toplevel_handle, + view->wl_shell_surface->title ?: "none"); + wlr_foreign_toplevel_handle_v1_set_app_id(view->toplevel_handle, + view->wl_shell_surface->class ?: "none"); + if (surface->state == WLR_WL_SHELL_SURFACE_STATE_TRANSIENT) { // We need to map it relative to the parent bool found = false; diff --git a/rootston/xdg_shell.c b/rootston/xdg_shell.c index d3fc5372..da8909ba 100644 --- a/rootston/xdg_shell.c +++ b/rootston/xdg_shell.c @@ -265,6 +265,8 @@ static void destroy(struct roots_view *view) { wl_list_remove(&roots_xdg_surface->request_resize.link); wl_list_remove(&roots_xdg_surface->request_maximize.link); wl_list_remove(&roots_xdg_surface->request_fullscreen.link); + wl_list_remove(&roots_xdg_surface->set_title.link); + wl_list_remove(&roots_xdg_surface->set_app_id.link); roots_xdg_surface->view->xdg_surface->data = NULL; free(roots_xdg_surface); } @@ -326,6 +328,22 @@ static void handle_request_fullscreen(struct wl_listener *listener, view_set_fullscreen(view, e->fullscreen, e->output); } +static void handle_set_title(struct wl_listener *listener, void *data) { + struct roots_xdg_surface *roots_xdg_surface = + wl_container_of(listener, roots_xdg_surface, set_title); + + view_set_title(roots_xdg_surface->view, + roots_xdg_surface->view->xdg_surface->toplevel->title); +} + +static void handle_set_app_id(struct wl_listener *listener, void *data) { + struct roots_xdg_surface *roots_xdg_surface = + wl_container_of(listener, roots_xdg_surface, set_app_id); + + view_set_app_id(roots_xdg_surface->view, + roots_xdg_surface->view->xdg_surface->toplevel->app_id); +} + static void handle_surface_commit(struct wl_listener *listener, void *data) { struct roots_xdg_surface *roots_surface = wl_container_of(listener, roots_surface, surface_commit); @@ -382,6 +400,11 @@ static void handle_map(struct wl_listener *listener, void *data) { view_map(view, view->xdg_surface->surface); view_setup(view); + + wlr_foreign_toplevel_handle_v1_set_title(view->toplevel_handle, + view->xdg_surface->toplevel->title ?: "none"); + wlr_foreign_toplevel_handle_v1_set_app_id(view->toplevel_handle, + view->xdg_surface->toplevel->app_id ?: "none"); } static void handle_unmap(struct wl_listener *listener, void *data) { @@ -438,6 +461,11 @@ void handle_xdg_shell_surface(struct wl_listener *listener, void *data) { roots_surface->request_fullscreen.notify = handle_request_fullscreen; wl_signal_add(&surface->toplevel->events.request_fullscreen, &roots_surface->request_fullscreen); + roots_surface->set_title.notify = handle_set_title; + wl_signal_add(&surface->toplevel->events.set_title, &roots_surface->set_title); + roots_surface->set_app_id.notify = handle_set_app_id; + wl_signal_add(&surface->toplevel->events.set_app_id, + &roots_surface->set_app_id); roots_surface->new_popup.notify = handle_new_popup; wl_signal_add(&surface->events.new_popup, &roots_surface->new_popup); surface->data = roots_surface; diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 6bdf749f..8d989aef 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -265,6 +265,8 @@ static void destroy(struct roots_view *view) { wl_list_remove(&roots_xdg_surface->request_resize.link); wl_list_remove(&roots_xdg_surface->request_maximize.link); wl_list_remove(&roots_xdg_surface->request_fullscreen.link); + wl_list_remove(&roots_xdg_surface->set_title.link); + wl_list_remove(&roots_xdg_surface->set_app_id.link); free(roots_xdg_surface); } @@ -325,6 +327,22 @@ static void handle_request_fullscreen(struct wl_listener *listener, view_set_fullscreen(view, e->fullscreen, e->output); } +static void handle_set_title(struct wl_listener *listener, void *data) { + struct roots_xdg_surface_v6 *roots_xdg_surface = + wl_container_of(listener, roots_xdg_surface, set_title); + + view_set_title(roots_xdg_surface->view, + roots_xdg_surface->view->xdg_surface_v6->toplevel->title); +} + +static void handle_set_app_id(struct wl_listener *listener, void *data) { + struct roots_xdg_surface_v6 *roots_xdg_surface = + wl_container_of(listener, roots_xdg_surface, set_app_id); + + view_set_app_id(roots_xdg_surface->view, + roots_xdg_surface->view->xdg_surface_v6->toplevel->app_id); +} + static void handle_surface_commit(struct wl_listener *listener, void *data) { struct roots_xdg_surface_v6 *roots_surface = wl_container_of(listener, roots_surface, surface_commit); @@ -381,6 +399,11 @@ static void handle_map(struct wl_listener *listener, void *data) { view_map(view, view->xdg_surface_v6->surface); view_setup(view); + + wlr_foreign_toplevel_handle_v1_set_title(view->toplevel_handle, + view->xdg_surface_v6->toplevel->title ?: "none"); + wlr_foreign_toplevel_handle_v1_set_app_id(view->toplevel_handle, + view->xdg_surface_v6->toplevel->app_id ?: "none"); } static void handle_unmap(struct wl_listener *listener, void *data) { @@ -437,6 +460,11 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { roots_surface->request_fullscreen.notify = handle_request_fullscreen; wl_signal_add(&surface->toplevel->events.request_fullscreen, &roots_surface->request_fullscreen); + roots_surface->set_title.notify = handle_set_title; + wl_signal_add(&surface->toplevel->events.set_title, &roots_surface->set_title); + roots_surface->set_app_id.notify = handle_set_app_id; + wl_signal_add(&surface->toplevel->events.set_app_id, + &roots_surface->set_app_id); roots_surface->new_popup.notify = handle_new_popup; wl_signal_add(&surface->events.new_popup, &roots_surface->new_popup); diff --git a/rootston/xwayland.c b/rootston/xwayland.c index d98f808b..f3f962e8 100644 --- a/rootston/xwayland.c +++ b/rootston/xwayland.c @@ -114,6 +114,8 @@ static void destroy(struct roots_view *view) { wl_list_remove(&roots_surface->request_move.link); wl_list_remove(&roots_surface->request_resize.link); wl_list_remove(&roots_surface->request_maximize.link); + wl_list_remove(&roots_surface->set_title.link); + wl_list_remove(&roots_surface->set_class.link); wl_list_remove(&roots_surface->map.link); wl_list_remove(&roots_surface->unmap.link); free(roots_surface); @@ -198,6 +200,22 @@ static void handle_request_fullscreen(struct wl_listener *listener, view_set_fullscreen(view, xwayland_surface->fullscreen, NULL); } +static void handle_set_title(struct wl_listener *listener, void *data) { + struct roots_xwayland_surface *roots_surface = + wl_container_of(listener, roots_surface, set_title); + + view_set_title(roots_surface->view, + roots_surface->view->xwayland_surface->title); +} + +static void handle_set_class(struct wl_listener *listener, void *data) { + struct roots_xwayland_surface *roots_surface = + wl_container_of(listener, roots_surface, set_class); + + view_set_app_id(roots_surface->view, + roots_surface->view->xwayland_surface->class); +} + static void handle_surface_commit(struct wl_listener *listener, void *data) { struct roots_xwayland_surface *roots_surface = wl_container_of(listener, roots_surface, surface_commit); @@ -250,6 +268,11 @@ static void handle_map(struct wl_listener *listener, void *data) { } view_setup(view); + + wlr_foreign_toplevel_handle_v1_set_title(view->toplevel_handle, + view->xwayland_surface->title ?: "none"); + wlr_foreign_toplevel_handle_v1_set_app_id(view->toplevel_handle, + view->xwayland_surface->class ?: "none"); } else { view_initial_focus(view); } @@ -261,7 +284,6 @@ static void handle_unmap(struct wl_listener *listener, void *data) { struct roots_view *view = roots_surface->view; wl_list_remove(&roots_surface->surface_commit.link); - view_unmap(view); } @@ -300,6 +322,11 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { roots_surface->request_fullscreen.notify = handle_request_fullscreen; wl_signal_add(&surface->events.request_fullscreen, &roots_surface->request_fullscreen); + roots_surface->set_title.notify = handle_set_title; + wl_signal_add(&surface->events.set_title, &roots_surface->set_title); + roots_surface->set_class.notify = handle_set_class; + wl_signal_add(&surface->events.set_class, + &roots_surface->set_class); struct roots_view *view = view_create(desktop); if (view == NULL) { |