summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDrew DeVault <sir@cmpwn.com>2019-08-20 18:30:09 +0900
committerSimon Ser <contact@emersion.fr>2020-06-23 22:26:00 +0200
commit8d5e627bc98f376f84e7f5b0a7caed791351c577 (patch)
tree7d90c18521bfbcc59155a418efbd9b489617086e
parenteeb90a7963cf2a846b6c9ce32f4796ac28a8629f (diff)
Implement wlr-foreign-toplevel-management-v1
-rw-r--r--include/sway/server.h2
-rw-r--r--include/sway/tree/view.h4
-rw-r--r--sway/server.c2
-rw-r--r--sway/tree/container.c8
-rw-r--r--sway/tree/view.c50
5 files changed, 66 insertions, 0 deletions
diff --git a/include/sway/server.h b/include/sway/server.h
index 3c972bc56..0f5e3ab20 100644
--- a/include/sway/server.h
+++ b/include/sway/server.h
@@ -8,6 +8,7 @@
#include <wlr/types/wlr_compositor.h>
#include <wlr/types/wlr_data_device.h>
#include <wlr/types/wlr_input_method_v2.h>
+#include <wlr/types/wlr_foreign_toplevel_management_v1.h>
#include <wlr/types/wlr_layer_shell_v1.h>
#include <wlr/types/wlr_output_management_v1.h>
#include <wlr/types/wlr_output_power_management_v1.h>
@@ -82,6 +83,7 @@ struct sway_server {
struct wl_listener output_power_manager_set_mode;
struct wlr_input_method_manager_v2 *input_method;
struct wlr_text_input_manager_v3 *text_input;
+ struct wlr_foreign_toplevel_manager_v1 *foreign_toplevel_manager;
size_t txn_timeout_ms;
list_t *transactions;
diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h
index 6007ec49f..b495fdf93 100644
--- a/include/sway/tree/view.h
+++ b/include/sway/tree/view.h
@@ -96,6 +96,10 @@ struct sway_view {
// when a transaction is applied.
struct wlr_box saved_geometry;
+ struct wlr_foreign_toplevel_handle_v1 *foreign_toplevel;
+ struct wl_listener foreign_activate_request;
+ struct wl_listener foreign_close_request;
+
bool destroying;
list_t *executed_criteria; // struct criteria *
diff --git a/sway/server.c b/sway/server.c
index 724a0e25f..c036396f3 100644
--- a/sway/server.c
+++ b/sway/server.c
@@ -142,6 +142,8 @@ bool server_init(struct sway_server *server) {
&server->output_power_manager_set_mode);
server->input_method = wlr_input_method_manager_v2_create(server->wl_display);
server->text_input = wlr_text_input_manager_v3_create(server->wl_display);
+ server->foreign_toplevel_manager =
+ wlr_foreign_toplevel_manager_v1_create(server->wl_display);
wlr_export_dmabuf_manager_v1_create(server->wl_display);
wlr_screencopy_manager_v1_create(server->wl_display);
diff --git a/sway/tree/container.c b/sway/tree/container.c
index 2fbd0d384..4cc42747d 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -1168,6 +1168,10 @@ void container_discover_outputs(struct sway_container *con) {
if (con->view) {
view_for_each_surface(con->view,
surface_send_enter_iterator, output->wlr_output);
+ if (con->view->foreign_toplevel) {
+ wlr_foreign_toplevel_handle_v1_output_enter(
+ con->view->foreign_toplevel, output->wlr_output);
+ }
}
list_add(con->outputs, output);
} else if (!intersects && index != -1) {
@@ -1176,6 +1180,10 @@ void container_discover_outputs(struct sway_container *con) {
if (con->view) {
view_for_each_surface(con->view,
surface_send_leave_iterator, output->wlr_output);
+ if (con->view->foreign_toplevel) {
+ wlr_foreign_toplevel_handle_v1_output_leave(
+ con->view->foreign_toplevel, output->wlr_output);
+ }
}
list_del(con->outputs, index);
}
diff --git a/sway/tree/view.c b/sway/tree/view.c
index e5d3948ce..6dccaa2e6 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -22,6 +22,7 @@
#include "sway/ipc-server.h"
#include "sway/output.h"
#include "sway/input/seat.h"
+#include "sway/server.h"
#include "sway/tree/arrange.h"
#include "sway/tree/container.h"
#include "sway/tree/view.h"
@@ -329,6 +330,10 @@ void view_set_activated(struct sway_view *view, bool activated) {
if (view->impl->set_activated) {
view->impl->set_activated(view, activated);
}
+ if (view->foreign_toplevel) {
+ wlr_foreign_toplevel_handle_v1_set_activated(
+ view->foreign_toplevel, activated);
+ }
}
void view_request_activate(struct sway_view *view) {
@@ -589,6 +594,27 @@ static bool should_focus(struct sway_view *view) {
return len == 0;
}
+static void handle_foreign_activate_request(
+ struct wl_listener *listener, void *data) {
+ struct sway_view *view = wl_container_of(
+ listener, view, foreign_activate_request);
+ struct wlr_foreign_toplevel_handle_v1_activated_event *event = data;
+ struct sway_seat *seat;
+ wl_list_for_each(seat, &server.input->seats, link) {
+ if (seat->wlr_seat == event->seat) {
+ seat_set_focus_container(seat, view->container);
+ break;
+ }
+ }
+}
+
+static void handle_foreign_close_request(
+ struct wl_listener *listener, void *data) {
+ struct sway_view *view = wl_container_of(
+ listener, view, foreign_close_request);
+ view_close(view);
+}
+
void view_map(struct sway_view *view, struct wlr_surface *wlr_surface,
bool fullscreen, struct wlr_output *fullscreen_output,
bool decoration) {
@@ -617,6 +643,15 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface,
struct sway_container *target_sibling = node->type == N_CONTAINER ?
node->sway_container : NULL;
+ view->foreign_toplevel =
+ wlr_foreign_toplevel_handle_v1_create(server.foreign_toplevel_manager);
+ view->foreign_activate_request.notify = handle_foreign_activate_request;
+ wl_signal_add(&view->foreign_toplevel->events.request_activate,
+ &view->foreign_activate_request);
+ view->foreign_close_request.notify = handle_foreign_close_request;
+ wl_signal_add(&view->foreign_toplevel->events.request_close,
+ &view->foreign_close_request);
+
// If we're about to launch the view into the floating container, then
// launch it as a tiled view in the root of the workspace instead.
if (target_sibling && container_is_floating(target_sibling)) {
@@ -679,6 +714,12 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface,
if (should_focus(view)) {
input_manager_set_focus(&view->container->node);
}
+
+ const char *app_id = view_get_app_id(view);
+ if (app_id != NULL) {
+ wlr_foreign_toplevel_handle_v1_set_app_id(
+ view->foreign_toplevel, app_id);
+ }
}
void view_unmap(struct sway_view *view) {
@@ -691,6 +732,11 @@ void view_unmap(struct sway_view *view) {
view->urgent_timer = NULL;
}
+ if (view->foreign_toplevel) {
+ wlr_foreign_toplevel_handle_v1_destroy(view->foreign_toplevel);
+ view->foreign_toplevel = NULL;
+ }
+
struct sway_container *parent = view->container->parent;
struct sway_workspace *ws = view->container->workspace;
container_begin_destroy(view->container);
@@ -1097,6 +1143,10 @@ void view_update_title(struct sway_view *view, bool force) {
container_update_title_textures(view->container);
ipc_event_window(view->container, "title");
+
+ if (view->foreign_toplevel) {
+ wlr_foreign_toplevel_handle_v1_set_title(view->foreign_toplevel, title);
+ }
}
bool view_is_visible(struct sway_view *view) {