render override redirect

This commit is contained in:
Tony Crisci 2018-01-14 13:19:21 -05:00
parent 2ce1d8d6cd
commit 83ddd2d9db
7 changed files with 97 additions and 12 deletions

View file

@ -9,6 +9,8 @@ struct sway_root {
struct wlr_output_layout *output_layout;
struct wl_listener output_layout_change;
struct wl_list unmanaged_views; // sway_view::unmanaged_view_link
};
void init_layout(void);

View file

@ -28,6 +28,8 @@ struct sway_xwayland_surface {
struct wl_listener request_resize;
struct wl_listener request_maximize;
struct wl_listener request_configure;
struct wl_listener unmap_notify;
struct wl_listener map_notify;
struct wl_listener destroy;
int pending_width, pending_height;
@ -91,6 +93,9 @@ struct sway_view {
double ox, double oy);
void (*set_activated)(struct sway_view *view, bool activated);
} iface;
// only used for unmanaged views (shell specific)
struct wl_list unmanaged_view_link; // sway_root::unmanaged views
};
#endif

View file

@ -218,6 +218,19 @@ static void output_frame_notify(struct wl_listener *listener, void *data) {
swayc_descendants_of_type(
&root_container, C_VIEW, output_frame_view, soutput);
// render unmanaged views on top
struct sway_view *view;
wl_list_for_each(view, &root_container.sway_root->unmanaged_views,
unmanaged_view_link) {
if (view->type == SWAY_XWAYLAND_VIEW) {
// the only kind of unamanged view right now is xwayland override redirect
int view_x = view->wlr_xwayland_surface->x;
int view_y = view->wlr_xwayland_surface->y;
render_surface(view->surface, wlr_output, &soutput->last_frame,
view_x, view_y, 0);
}
}
wlr_renderer_end(server->renderer);
wlr_output_swap_buffers(wlr_output);

View file

@ -93,13 +93,43 @@ static void handle_commit(struct wl_listener *listener, void *data) {
static void handle_destroy(struct wl_listener *listener, void *data) {
struct sway_xwayland_surface *sway_surface =
wl_container_of(listener, sway_surface, destroy);
struct wlr_xwayland_surface *xsurface = data;
wl_list_remove(&sway_surface->commit.link);
wl_list_remove(&sway_surface->destroy.link);
wl_list_remove(&sway_surface->request_configure.link);
swayc_t *parent = destroy_view(sway_surface->view->swayc);
if (xsurface->override_redirect) {
if (xsurface->mapped) {
wl_list_remove(&sway_surface->view->unmanaged_view_link);
}
} else {
swayc_t *parent = destroy_view(sway_surface->view->swayc);
arrange_windows(parent, -1, -1);
}
free(sway_surface->view);
free(sway_surface);
arrange_windows(parent, -1, -1);
}
static void handle_unmap_notify(struct wl_listener *listener, void *data) {
// TODO take the view out of the tree
struct sway_xwayland_surface *sway_surface =
wl_container_of(listener, sway_surface, unmap_notify);
struct wlr_xwayland_surface *xsurface = data;
if (xsurface->override_redirect) {
wl_list_remove(&sway_surface->view->unmanaged_view_link);
}
sway_surface->view->surface = NULL;
}
static void handle_map_notify(struct wl_listener *listener, void *data) {
// TODO put the view back into the tree
struct sway_xwayland_surface *sway_surface =
wl_container_of(listener, sway_surface, map_notify);
struct wlr_xwayland_surface *xsurface = data;
if (xsurface->override_redirect) {
wl_list_insert(&root_container.sway_root->unmanaged_views,
&sway_surface->view->unmanaged_view_link);
}
sway_surface->view->surface = xsurface->surface;
}
static void handle_configure_request(struct wl_listener *listener, void *data) {
@ -119,11 +149,6 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) {
listener, server, xwayland_surface);
struct wlr_xwayland_surface *xsurface = data;
if (xsurface->override_redirect) {
// TODO: floating popups
return;
}
wlr_log(L_DEBUG, "New xwayland surface title='%s' class='%s'",
xsurface->title, xsurface->class);
@ -155,15 +180,29 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) {
// - Set new view to maximized so it behaves nicely
// - Criteria
sway_surface->commit.notify = handle_commit;
wl_signal_add(&xsurface->surface->events.commit, &sway_surface->commit);
sway_surface->destroy.notify = handle_destroy;
sway_surface->commit.notify = handle_commit;
wl_signal_add(&xsurface->events.destroy, &sway_surface->destroy);
sway_surface->request_configure.notify = handle_configure_request;
sway_surface->destroy.notify = handle_destroy;
wl_signal_add(&xsurface->events.request_configure,
&sway_surface->request_configure);
sway_surface->request_configure.notify = handle_configure_request;
wl_signal_add(&xsurface->events.unmap_notify, &sway_surface->unmap_notify);
sway_surface->unmap_notify.notify = handle_unmap_notify;
wl_signal_add(&xsurface->events.map_notify, &sway_surface->map_notify);
sway_surface->map_notify.notify = handle_map_notify;
if (xsurface->override_redirect) {
// these don't get a container in the tree
wl_list_insert(&root_container.sway_root->unmanaged_views,
&sway_view->unmanaged_view_link);
return;
}
// TODO: actual focus semantics
swayc_t *parent = root_container.children->items[0];
parent = parent->children->items[0]; // workspace

View file

@ -24,6 +24,31 @@ static void cursor_send_pointer_motion(struct sway_cursor *cursor,
struct wlr_seat *seat = cursor->seat->wlr_seat;
struct wlr_surface *surface = NULL;
double sx, sy;
// check for unmanaged views first
struct sway_view *view;
wl_list_for_each_reverse(view, &root_container.sway_root->unmanaged_views,
unmanaged_view_link) {
if (view->type == SWAY_XWAYLAND_VIEW) {
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
struct wlr_box box = {
.x = xsurface->x,
.y = xsurface->y,
.width = xsurface->width,
.height = xsurface->height,
};
if (wlr_box_contains_point(&box, cursor->x, cursor->y)) {
surface = xsurface->surface;
sx = cursor->x - box.x;
sy = cursor->y - box.y;
wlr_seat_pointer_notify_enter(seat, surface, sx, sy);
wlr_seat_pointer_notify_motion(seat, time, sx, sy);
return;
}
}
}
swayc_t *swayc =
swayc_at(&root_container, cursor->x, cursor->y, &surface, &sx, &sy);
if (swayc) {

View file

@ -207,7 +207,7 @@ swayc_t *destroy_output(swayc_t *output) {
}
swayc_t *destroy_view(swayc_t *view) {
if (!sway_assert(view, "null view passed to destroy_view")) {
if (!view) {
return NULL;
}
wlr_log(L_DEBUG, "Destroying view '%s'", view->name);

View file

@ -51,6 +51,7 @@ void init_layout(void) {
root_container.sway_root = calloc(1, sizeof(*root_container.sway_root));
root_container.sway_root->output_layout = wlr_output_layout_create();
wl_list_init(&root_container.sway_root->unmanaged_views);
root_container.sway_root->output_layout_change.notify =
output_layout_change_notify;