xwm: add surface to rootston on surface commit
This commit is contained in:
parent
c666d34d2d
commit
a3f2754668
|
@ -66,14 +66,16 @@ struct wlr_xwayland_surface_size_hints {
|
||||||
|
|
||||||
struct wlr_xwayland_surface {
|
struct wlr_xwayland_surface {
|
||||||
xcb_window_t window_id;
|
xcb_window_t window_id;
|
||||||
|
struct wlr_xwm *xwm;
|
||||||
uint32_t surface_id;
|
uint32_t surface_id;
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
|
|
||||||
struct wlr_surface *surface;
|
struct wlr_surface *surface;
|
||||||
struct wl_listener surface_destroy_listener;
|
|
||||||
int16_t x, y;
|
int16_t x, y;
|
||||||
uint16_t width, height;
|
uint16_t width, height;
|
||||||
bool override_redirect;
|
bool override_redirect;
|
||||||
|
bool mapped;
|
||||||
|
bool added;
|
||||||
|
|
||||||
char *title;
|
char *title;
|
||||||
char *class;
|
char *class;
|
||||||
|
@ -95,9 +97,7 @@ struct wlr_xwayland_surface {
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct wl_signal destroy;
|
struct wl_signal destroy;
|
||||||
|
|
||||||
struct wl_signal request_configure;
|
struct wl_signal request_configure;
|
||||||
|
|
||||||
struct wl_signal set_title;
|
struct wl_signal set_title;
|
||||||
struct wl_signal set_class;
|
struct wl_signal set_class;
|
||||||
struct wl_signal set_parent;
|
struct wl_signal set_parent;
|
||||||
|
@ -106,6 +106,9 @@ struct wlr_xwayland_surface {
|
||||||
struct wl_signal set_window_type;
|
struct wl_signal set_window_type;
|
||||||
} events;
|
} events;
|
||||||
|
|
||||||
|
struct wl_listener surface_destroy;
|
||||||
|
struct wl_listener surface_commit;
|
||||||
|
|
||||||
void *data;
|
void *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -99,10 +99,10 @@ bool view_center(struct roots_view *view) {
|
||||||
int width, height;
|
int width, height;
|
||||||
wlr_output_effective_resolution(output, &width, &height);
|
wlr_output_effective_resolution(output, &width, &height);
|
||||||
|
|
||||||
view->x = (double)(width - size.width) / 2
|
double view_x = (double)(width - size.width) / 2 + l_output->x;
|
||||||
+ l_output->x;
|
double view_y = (double)(height - size.height) / 2 + l_output->y;
|
||||||
view->y = (double)(height - size.height) / 2
|
|
||||||
+ l_output->y;
|
view_set_position(view, view_x, view_y);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,6 +67,7 @@ static struct wlr_xwayland_surface *wlr_xwayland_surface_create(
|
||||||
wlr_log(L_ERROR, "Could not allocate wlr xwayland surface");
|
wlr_log(L_ERROR, "Could not allocate wlr xwayland surface");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
surface->xwm = xwm;
|
||||||
surface->window_id = window_id;
|
surface->window_id = window_id;
|
||||||
surface->x = x;
|
surface->x = x;
|
||||||
surface->y = y;
|
surface->y = y;
|
||||||
|
@ -92,6 +93,12 @@ static void wlr_xwayland_surface_destroy(struct wlr_xwayland_surface *surface) {
|
||||||
for (size_t i = 0; i < surface->state->length; i++) {
|
for (size_t i = 0; i < surface->state->length; i++) {
|
||||||
free(surface->state->items[i]);
|
free(surface->state->items[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (surface->surface) {
|
||||||
|
wl_list_remove(&surface->surface_destroy.link);
|
||||||
|
wl_list_remove(&surface->surface_commit.link);
|
||||||
|
}
|
||||||
|
|
||||||
free(surface->title);
|
free(surface->title);
|
||||||
free(surface->class);
|
free(surface->class);
|
||||||
free(surface->instance);
|
free(surface->instance);
|
||||||
|
@ -412,11 +419,30 @@ static void read_surface_property(struct wlr_xwm *xwm,
|
||||||
free(reply);
|
free(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_surface_commit(struct wl_listener *listener, void *data) {
|
||||||
|
struct wlr_xwayland_surface *xsurface =
|
||||||
|
wl_container_of(listener, xsurface, surface_commit);
|
||||||
|
|
||||||
|
if (!xsurface->added &&
|
||||||
|
wlr_surface_has_buffer(xsurface->surface) &&
|
||||||
|
xsurface->mapped) {
|
||||||
|
wl_signal_emit(&xsurface->xwm->xwayland->events.new_surface, xsurface);
|
||||||
|
xsurface->added = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_surface_destroy(struct wl_listener *listener, void *data) {
|
||||||
|
struct wlr_xwayland_surface *xsurface =
|
||||||
|
wl_container_of(listener, xsurface, surface_destroy);
|
||||||
|
|
||||||
|
// TODO destroy xwayland surface?
|
||||||
|
}
|
||||||
|
|
||||||
static void map_shell_surface(struct wlr_xwm *xwm,
|
static void map_shell_surface(struct wlr_xwm *xwm,
|
||||||
struct wlr_xwayland_surface *xwayland_surface,
|
struct wlr_xwayland_surface *xsurface,
|
||||||
struct wlr_surface *surface) {
|
struct wlr_surface *surface) {
|
||||||
// get xcb geometry for depth = alpha channel
|
// get xcb geometry for depth = alpha channel
|
||||||
xwayland_surface->surface = surface;
|
xsurface->surface = surface;
|
||||||
|
|
||||||
// read all surface properties
|
// read all surface properties
|
||||||
const xcb_atom_t props[] = {
|
const xcb_atom_t props[] = {
|
||||||
|
@ -433,13 +459,20 @@ static void map_shell_surface(struct wlr_xwm *xwm,
|
||||||
xwm->atoms[NET_WM_PID],
|
xwm->atoms[NET_WM_PID],
|
||||||
};
|
};
|
||||||
for (size_t i = 0; i < sizeof(props)/sizeof(xcb_atom_t); i++) {
|
for (size_t i = 0; i < sizeof(props)/sizeof(xcb_atom_t); i++) {
|
||||||
read_surface_property(xwm, xwayland_surface, props[i]);
|
read_surface_property(xwm, xsurface, props[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
wl_list_remove(&xwayland_surface->link);
|
wl_list_remove(&xsurface->link);
|
||||||
wl_list_insert(&xwm->xwayland->displayable_surfaces,
|
wl_list_insert(&xwm->xwayland->displayable_surfaces,
|
||||||
&xwayland_surface->link);
|
&xsurface->link);
|
||||||
wl_signal_emit(&xwm->xwayland->events.new_surface, xwayland_surface);
|
|
||||||
|
xsurface->surface_commit.notify = handle_surface_commit;
|
||||||
|
wl_signal_add(&surface->events.commit, &xsurface->surface_commit);
|
||||||
|
|
||||||
|
xsurface->surface_destroy.notify = handle_surface_destroy;
|
||||||
|
wl_signal_add(&surface->events.destroy, &xsurface->surface_destroy);
|
||||||
|
|
||||||
|
xsurface->mapped = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* xcb event handlers */
|
/* xcb event handlers */
|
||||||
|
@ -620,10 +653,10 @@ static int x11_event_handler(int fd, uint32_t mask, void *data) {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void create_surface_handler(struct wl_listener *listener, void *data) {
|
static void handle_compositor_surface_create(struct wl_listener *listener, void *data) {
|
||||||
struct wlr_surface *surface = data;
|
struct wlr_surface *surface = data;
|
||||||
struct wlr_xwm *xwm =
|
struct wlr_xwm *xwm =
|
||||||
wl_container_of(listener, xwm, surface_create_listener);
|
wl_container_of(listener, xwm, compositor_surface_create);
|
||||||
if (wl_resource_get_client(surface->resource) != xwm->xwayland->client) {
|
if (wl_resource_get_client(surface->resource) != xwm->xwayland->client) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -757,7 +790,7 @@ void xwm_destroy(struct wlr_xwm *xwm) {
|
||||||
wl_list_for_each_safe(surface, tmp, &xwm->unpaired_surfaces, link) {
|
wl_list_for_each_safe(surface, tmp, &xwm->unpaired_surfaces, link) {
|
||||||
wlr_xwayland_surface_destroy(surface);
|
wlr_xwayland_surface_destroy(surface);
|
||||||
}
|
}
|
||||||
wl_list_remove(&xwm->surface_create_listener.link);
|
wl_list_remove(&xwm->compositor_surface_create.link);
|
||||||
xcb_disconnect(xwm->xcb_conn);
|
xcb_disconnect(xwm->xcb_conn);
|
||||||
|
|
||||||
free(xwm);
|
free(xwm);
|
||||||
|
@ -875,9 +908,9 @@ struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland) {
|
||||||
|
|
||||||
free(xfixes_reply);
|
free(xfixes_reply);
|
||||||
|
|
||||||
xwm->surface_create_listener.notify = create_surface_handler;
|
xwm->compositor_surface_create.notify = handle_compositor_surface_create;
|
||||||
wl_signal_add(&wlr_xwayland->compositor->events.create_surface,
|
wl_signal_add(&wlr_xwayland->compositor->events.create_surface,
|
||||||
&xwm->surface_create_listener);
|
&xwm->compositor_surface_create);
|
||||||
|
|
||||||
return xwm;
|
return xwm;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,6 @@ enum net_wm_state_action {
|
||||||
struct wlr_xwm {
|
struct wlr_xwm {
|
||||||
struct wlr_xwayland *xwayland;
|
struct wlr_xwayland *xwayland;
|
||||||
struct wl_event_source *event_source;
|
struct wl_event_source *event_source;
|
||||||
struct wl_listener surface_create_listener;
|
|
||||||
|
|
||||||
xcb_atom_t atoms[ATOM_LAST];
|
xcb_atom_t atoms[ATOM_LAST];
|
||||||
xcb_connection_t *xcb_conn;
|
xcb_connection_t *xcb_conn;
|
||||||
|
@ -49,6 +48,8 @@ struct wlr_xwm {
|
||||||
struct wl_list unpaired_surfaces;
|
struct wl_list unpaired_surfaces;
|
||||||
|
|
||||||
const xcb_query_extension_reply_t *xfixes;
|
const xcb_query_extension_reply_t *xfixes;
|
||||||
|
|
||||||
|
struct wl_listener compositor_surface_create;
|
||||||
};
|
};
|
||||||
|
|
||||||
void xwm_destroy(struct wlr_xwm *xwm);
|
void xwm_destroy(struct wlr_xwm *xwm);
|
||||||
|
|
Loading…
Reference in New Issue