wlroots 0.15.1
Alexander Orzechowski (1): xdg-foreign: Fix crash on destroy of degenerate surface Isaac Freund (3): wlr_texture: remove wlr_texture_from_wl_drm() from header foreign-toplevel: send enter if needed on output bind tinywl: fix check whether client is focused or not Kirill Primak (3): scene/subsurface_tree: fix handling subsurface destruction compositor: damage the whole buffer on viewport src change subsurface: unlock cached state on commit if desynced Simon Ser (4): backend: error out in autocreate without libinput support scene: schedule an output frame on wl_surface.frame scene: try to import buffers as textures before rendering build: bump version to 0.15.1 Tadeo Kondrak (1): input_method_v2: improve mapping detection Thomas Hebb (1): render/gles2: don't constrain shm formats to ones that support reading nyorain (1): vulkan: Fix imported image layout -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEENP+VJs/vDpejQOLkD9574OiPXkgFAmH8RzEACgkQD9574OiP XkjPGw/+KdgxXeVJ1Typ8fp9ZfhGTW3sJVREpMpnLra/1lA4LQ1jUDFfvXEPAveI UjgGiyoBpBWcWgj0jS0GgcTE2ExnGlkd9Y6pImM0zUTQ1mQF8hPxyThQiJNDpBix 42lqWtIqYPQObJnXa19SpebNCw/TbHoF/0sHR8I/a0o2PgVT9LGIsqI1nAYH7H/e lUR5paZU5G60lQdePhTIOv7MuXNt7fgtpizw/WNMqz0Cl+1weoIAtXv2UWZM39wW hhK2e02n8GncLYQn459xqf5UfkCnie9u6BCL4PMuEm+sOsYH5sQzsUFfQjBsNCqL ztgFssPwW6v/vImvWclvD0DAOgPK0kMEg0RWlBOKfTTxBewloKp4MIY/udKX9+5S b8ALOizzS0vL/lTFc+o4XBELE/X9f0S0Sv+mtWXD4xuOMREPUaijJ5LyOmDf6gG5 K/CB5T2pdQqNC9UdTGMPlauSFVqliBO7hyQSHl3tr5/ZjQZ3tGFL+szp7b62Rb5r ChQCUC6NvDhcKzZaPwL9py005yk0LT5oEXVxRJId6ipWuGn+XBnBoWWckpy/3Zpu cnacvsxyKaQS3Uts13UlVW4ojr3wolDzBqDPQGU8xsqQcbgcbjGLxkPFDIWT++3D XzBx6bRBTKr1EJRoEROuSl0xDEaWJlZt1XUGPLP1Uxew4DSrXOg= =mFoc -----END PGP SIGNATURE----- gpgsig -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE+M9eMyy2C5F27kiEzBX8gix/YfUFAmIphlUACgkQzBX8gix/ YfVWfA/8C+GEw9/P2s+eKBdK6jIB9H0as/yjLCDQDmAX2iAIGdnJ+4ojd2C6xDMK mUDRU1UOufafXMdaFa7DXeWYGkHII62K3qxdVD737bCRApkBGLVC9h11QuWgcYYC BxeduZouZ1npRtTxINBCC5TXKDWkt0cvQDrD7pnL+AH+ny5WvOnRO1CaPXCgnc7v hqdrVAtHRdAkYBBHuu9WgMpvVzkS3KXr7NaWLpRdGa7nWpkKX9aoa0tNjCL86TPq QHDMhQnPxghxJl6xc9rhDWJYcYCUxJ4W4ABbyqkkP64wBtjnDJVh7LWRx4qnFNIO ky0E3JM6A5YZ/N0fdOIsxvJ2YOpqYYXhKS8NJa2a+Wnsw+QEHe8hnST4UWGcQERf qX0hghKhuYNxpm4vrB3rOPwbcQIdjGo2jlEH4GG3gENduekvvdGAr5qcXDH+5pol 7iwrbARI3T6kTplx/iDvHk5wYGKwj5oatXy4AKwbBt+DNDakF6Vf9RGLKOtC2cty YS607osq9kUUX47RCSP11W3zb84cAtJNw5eHmQzVPJ+hAlGsaMdDVUbUGgJiruVe pyYeSKxKyFTao3SYSizZwJB0mwYXWsDsVdf4c6mbdr3w5MBWslrliCof9vzSQSq3 KAiGawPiT+ar87kyQMaCaMl0ZLaXG7g/MXKNsRp/Ss437nhknqg= =6/3L -----END PGP SIGNATURE----- Merge tag '0.15.1' into dkondor-upstream-pr-2551 wlroots 0.15.1 Alexander Orzechowski (1): xdg-foreign: Fix crash on destroy of degenerate surface Isaac Freund (3): wlr_texture: remove wlr_texture_from_wl_drm() from header foreign-toplevel: send enter if needed on output bind tinywl: fix check whether client is focused or not Kirill Primak (3): scene/subsurface_tree: fix handling subsurface destruction compositor: damage the whole buffer on viewport src change subsurface: unlock cached state on commit if desynced Simon Ser (4): backend: error out in autocreate without libinput support scene: schedule an output frame on wl_surface.frame scene: try to import buffers as textures before rendering build: bump version to 0.15.1 Tadeo Kondrak (1): input_method_v2: improve mapping detection Thomas Hebb (1): render/gles2: don't constrain shm formats to ones that support reading nyorain (1): vulkan: Fix imported image layout
This commit is contained in:
commit
c5e3ca6249
|
@ -364,6 +364,19 @@ struct wlr_backend *wlr_backend_autocreate(struct wl_display *display) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
wlr_multi_backend_add(backend, libinput);
|
wlr_multi_backend_add(backend, libinput);
|
||||||
|
#else
|
||||||
|
const char *no_devs = getenv("WLR_LIBINPUT_NO_DEVICES");
|
||||||
|
if (no_devs && strcmp(no_devs, "1") == 0) {
|
||||||
|
wlr_log(WLR_INFO, "WLR_LIBINPUT_NO_DEVICES is set, "
|
||||||
|
"starting without libinput backend");
|
||||||
|
} else {
|
||||||
|
wlr_log(WLR_ERROR, "libinput support is not compiled in, "
|
||||||
|
"refusing to start");
|
||||||
|
wlr_log(WLR_ERROR, "Set WLR_LIBINPUT_NO_DEVICES=1 to suppress this check");
|
||||||
|
wlr_session_destroy(multi->session);
|
||||||
|
wlr_backend_destroy(backend);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if WLR_HAS_DRM_BACKEND
|
#if WLR_HAS_DRM_BACKEND
|
||||||
|
|
|
@ -33,16 +33,6 @@ struct wlr_texture *wlr_texture_from_pixels(struct wlr_renderer *renderer,
|
||||||
uint32_t fmt, uint32_t stride, uint32_t width, uint32_t height,
|
uint32_t fmt, uint32_t stride, uint32_t width, uint32_t height,
|
||||||
const void *data);
|
const void *data);
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new texture from a wl_drm resource. The returned texture is
|
|
||||||
* immutable.
|
|
||||||
*
|
|
||||||
* Should not be called in a rendering block like renderer_begin()/end() or
|
|
||||||
* between attaching a renderer to an output and committing it.
|
|
||||||
*/
|
|
||||||
struct wlr_texture *wlr_texture_from_wl_drm(struct wlr_renderer *renderer,
|
|
||||||
struct wl_resource *data);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new texture from a DMA-BUF. The returned texture is immutable.
|
* Create a new texture from a DMA-BUF. The returned texture is immutable.
|
||||||
*
|
*
|
||||||
|
|
|
@ -36,10 +36,13 @@ enum wlr_foreign_toplevel_handle_v1_state {
|
||||||
|
|
||||||
struct wlr_foreign_toplevel_handle_v1_output {
|
struct wlr_foreign_toplevel_handle_v1_output {
|
||||||
struct wl_list link; // wlr_foreign_toplevel_handle_v1::outputs
|
struct wl_list link; // wlr_foreign_toplevel_handle_v1::outputs
|
||||||
struct wl_listener output_destroy;
|
|
||||||
struct wlr_output *output;
|
struct wlr_output *output;
|
||||||
|
|
||||||
struct wlr_foreign_toplevel_handle_v1 *toplevel;
|
struct wlr_foreign_toplevel_handle_v1 *toplevel;
|
||||||
|
|
||||||
|
// private state
|
||||||
|
|
||||||
|
struct wl_listener output_bind;
|
||||||
|
struct wl_listener output_destroy;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_foreign_toplevel_handle_v1 {
|
struct wlr_foreign_toplevel_handle_v1 {
|
||||||
|
|
|
@ -68,6 +68,9 @@ struct wlr_scene {
|
||||||
// May be NULL
|
// May be NULL
|
||||||
struct wlr_presentation *presentation;
|
struct wlr_presentation *presentation;
|
||||||
struct wl_listener presentation_destroy;
|
struct wl_listener presentation_destroy;
|
||||||
|
|
||||||
|
// List of buffers which need to be imported as textures
|
||||||
|
struct wl_list pending_buffers; // wlr_scene_buffer.pending_link
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A sub-tree in the scene-graph. */
|
/** A sub-tree in the scene-graph. */
|
||||||
|
@ -114,6 +117,7 @@ struct wlr_scene_buffer {
|
||||||
struct wlr_fbox src_box;
|
struct wlr_fbox src_box;
|
||||||
int dst_width, dst_height;
|
int dst_width, dst_height;
|
||||||
enum wl_output_transform transform;
|
enum wl_output_transform transform;
|
||||||
|
struct wl_list pending_link; // wlr_scene.pending_buffers
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A viewport for an output in the scene-graph */
|
/** A viewport for an output in the scene-graph */
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
project(
|
project(
|
||||||
'wlroots',
|
'wlroots',
|
||||||
'c',
|
'c',
|
||||||
version: '0.15.0',
|
version: '0.15.1',
|
||||||
license: 'MIT',
|
license: 'MIT',
|
||||||
meson_version: '>=0.58.1',
|
meson_version: '>=0.58.1',
|
||||||
default_options: [
|
default_options: [
|
||||||
|
|
|
@ -98,6 +98,10 @@ static const struct wlr_gles2_pixel_format formats[] = {
|
||||||
|
|
||||||
// TODO: more pixel formats
|
// TODO: more pixel formats
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return true if supported for texturing, even if other operations like
|
||||||
|
* reading aren't supported.
|
||||||
|
*/
|
||||||
bool is_gles2_pixel_format_supported(const struct wlr_gles2_renderer *renderer,
|
bool is_gles2_pixel_format_supported(const struct wlr_gles2_renderer *renderer,
|
||||||
const struct wlr_gles2_pixel_format *format) {
|
const struct wlr_gles2_pixel_format *format) {
|
||||||
if (format->gl_type == GL_UNSIGNED_INT_2_10_10_10_REV_EXT
|
if (format->gl_type == GL_UNSIGNED_INT_2_10_10_10_REV_EXT
|
||||||
|
@ -108,10 +112,12 @@ bool is_gles2_pixel_format_supported(const struct wlr_gles2_renderer *renderer,
|
||||||
&& !renderer->exts.OES_texture_half_float_linear) {
|
&& !renderer->exts.OES_texture_half_float_linear) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (format->gl_format == GL_BGRA_EXT
|
/*
|
||||||
&& !renderer->exts.EXT_read_format_bgra) {
|
* Note that we don't need to check for GL_EXT_texture_format_BGRA8888
|
||||||
return false;
|
* here, since we've already checked if we have it at renderer creation
|
||||||
}
|
* time and bailed out if not. We do the check there because Wayland
|
||||||
|
* requires all compositors to support SHM buffers in that format.
|
||||||
|
*/
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -441,6 +441,12 @@ static bool gles2_read_pixels(struct wlr_renderer *wlr_renderer,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fmt->gl_format == GL_BGRA_EXT && !renderer->exts.EXT_read_format_bgra) {
|
||||||
|
wlr_log(WLR_ERROR,
|
||||||
|
"Cannot read pixels: missing GL_EXT_read_format_bgra extension");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const struct wlr_pixel_format_info *drm_fmt =
|
const struct wlr_pixel_format_info *drm_fmt =
|
||||||
drm_get_pixel_format_info(fmt->drm_format);
|
drm_get_pixel_format_info(fmt->drm_format);
|
||||||
assert(drm_fmt);
|
assert(drm_fmt);
|
||||||
|
|
|
@ -598,7 +598,7 @@ static void vulkan_end(struct wlr_renderer *wlr_renderer) {
|
||||||
wl_list_for_each_safe(texture, tmp_tex, &renderer->foreign_textures, foreign_link) {
|
wl_list_for_each_safe(texture, tmp_tex, &renderer->foreign_textures, foreign_link) {
|
||||||
VkImageLayout src_layout = VK_IMAGE_LAYOUT_GENERAL;
|
VkImageLayout src_layout = VK_IMAGE_LAYOUT_GENERAL;
|
||||||
if (!texture->transitioned) {
|
if (!texture->transitioned) {
|
||||||
src_layout = VK_IMAGE_LAYOUT_PREINITIALIZED;
|
src_layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
texture->transitioned = true;
|
texture->transitioned = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -438,7 +438,7 @@ VkImage vulkan_import_dmabuf(struct wlr_vk_renderer *renderer,
|
||||||
img_info.arrayLayers = 1;
|
img_info.arrayLayers = 1;
|
||||||
img_info.samples = VK_SAMPLE_COUNT_1_BIT;
|
img_info.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
img_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
img_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
img_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
|
img_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
img_info.extent = (VkExtent3D) { attribs->width, attribs->height, 1 };
|
img_info.extent = (VkExtent3D) { attribs->width, attribs->height, 1 };
|
||||||
img_info.usage = for_render ?
|
img_info.usage = for_render ?
|
||||||
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT :
|
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT :
|
||||||
|
|
|
@ -611,7 +611,8 @@ static void begin_interactive(struct tinywl_view *view,
|
||||||
struct tinywl_server *server = view->server;
|
struct tinywl_server *server = view->server;
|
||||||
struct wlr_surface *focused_surface =
|
struct wlr_surface *focused_surface =
|
||||||
server->seat->pointer_state.focused_surface;
|
server->seat->pointer_state.focused_surface;
|
||||||
if (view->xdg_surface->surface != focused_surface) {
|
if (view->xdg_surface->surface !=
|
||||||
|
wlr_surface_get_root_surface(focused_surface)) {
|
||||||
/* Deny move/resize requests from unfocused clients. */
|
/* Deny move/resize requests from unfocused clients. */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,15 +13,20 @@ struct wlr_scene_subsurface_tree {
|
||||||
struct wlr_surface *surface;
|
struct wlr_surface *surface;
|
||||||
struct wlr_scene_surface *scene_surface;
|
struct wlr_scene_surface *scene_surface;
|
||||||
|
|
||||||
struct wlr_scene_subsurface_tree *parent; // NULL for the top-level surface
|
|
||||||
struct wlr_addon surface_addon; // only set if there's a parent
|
|
||||||
|
|
||||||
struct wl_listener tree_destroy;
|
struct wl_listener tree_destroy;
|
||||||
struct wl_listener surface_destroy;
|
struct wl_listener surface_destroy;
|
||||||
struct wl_listener surface_commit;
|
struct wl_listener surface_commit;
|
||||||
struct wl_listener surface_map;
|
|
||||||
struct wl_listener surface_unmap;
|
|
||||||
struct wl_listener surface_new_subsurface;
|
struct wl_listener surface_new_subsurface;
|
||||||
|
|
||||||
|
struct wlr_scene_subsurface_tree *parent; // NULL for the top-level surface
|
||||||
|
|
||||||
|
// Only valid if the surface is a sub-surface
|
||||||
|
|
||||||
|
struct wlr_addon surface_addon;
|
||||||
|
|
||||||
|
struct wl_listener subsurface_destroy;
|
||||||
|
struct wl_listener subsurface_map;
|
||||||
|
struct wl_listener subsurface_unmap;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void subsurface_tree_handle_tree_destroy(struct wl_listener *listener,
|
static void subsurface_tree_handle_tree_destroy(struct wl_listener *listener,
|
||||||
|
@ -31,23 +36,17 @@ static void subsurface_tree_handle_tree_destroy(struct wl_listener *listener,
|
||||||
// tree and scene_surface will be cleaned up by scene_node_finish
|
// tree and scene_surface will be cleaned up by scene_node_finish
|
||||||
if (subsurface_tree->parent) {
|
if (subsurface_tree->parent) {
|
||||||
wlr_addon_finish(&subsurface_tree->surface_addon);
|
wlr_addon_finish(&subsurface_tree->surface_addon);
|
||||||
|
wl_list_remove(&subsurface_tree->subsurface_destroy.link);
|
||||||
|
wl_list_remove(&subsurface_tree->subsurface_map.link);
|
||||||
|
wl_list_remove(&subsurface_tree->subsurface_unmap.link);
|
||||||
}
|
}
|
||||||
wl_list_remove(&subsurface_tree->tree_destroy.link);
|
wl_list_remove(&subsurface_tree->tree_destroy.link);
|
||||||
wl_list_remove(&subsurface_tree->surface_destroy.link);
|
wl_list_remove(&subsurface_tree->surface_destroy.link);
|
||||||
wl_list_remove(&subsurface_tree->surface_commit.link);
|
wl_list_remove(&subsurface_tree->surface_commit.link);
|
||||||
wl_list_remove(&subsurface_tree->surface_map.link);
|
|
||||||
wl_list_remove(&subsurface_tree->surface_unmap.link);
|
|
||||||
wl_list_remove(&subsurface_tree->surface_new_subsurface.link);
|
wl_list_remove(&subsurface_tree->surface_new_subsurface.link);
|
||||||
free(subsurface_tree);
|
free(subsurface_tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void subsurface_tree_handle_surface_destroy(struct wl_listener *listener,
|
|
||||||
void *data) {
|
|
||||||
struct wlr_scene_subsurface_tree *subsurface_tree =
|
|
||||||
wl_container_of(listener, subsurface_tree, surface_destroy);
|
|
||||||
wlr_scene_node_destroy(&subsurface_tree->tree->node);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct wlr_addon_interface subsurface_tree_addon_impl;
|
static const struct wlr_addon_interface subsurface_tree_addon_impl;
|
||||||
|
|
||||||
static struct wlr_scene_subsurface_tree *subsurface_tree_from_subsurface(
|
static struct wlr_scene_subsurface_tree *subsurface_tree_from_subsurface(
|
||||||
|
@ -97,6 +96,13 @@ static void subsurface_tree_reconfigure(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void subsurface_tree_handle_surface_destroy(struct wl_listener *listener,
|
||||||
|
void *data) {
|
||||||
|
struct wlr_scene_subsurface_tree *subsurface_tree =
|
||||||
|
wl_container_of(listener, subsurface_tree, surface_destroy);
|
||||||
|
wlr_scene_node_destroy(&subsurface_tree->tree->node);
|
||||||
|
}
|
||||||
|
|
||||||
static void subsurface_tree_handle_surface_commit(struct wl_listener *listener,
|
static void subsurface_tree_handle_surface_commit(struct wl_listener *listener,
|
||||||
void *data) {
|
void *data) {
|
||||||
struct wlr_scene_subsurface_tree *subsurface_tree =
|
struct wlr_scene_subsurface_tree *subsurface_tree =
|
||||||
|
@ -106,18 +112,25 @@ static void subsurface_tree_handle_surface_commit(struct wl_listener *listener,
|
||||||
subsurface_tree_reconfigure(subsurface_tree);
|
subsurface_tree_reconfigure(subsurface_tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void subsurface_tree_handle_surface_map(struct wl_listener *listener,
|
static void subsurface_tree_handle_subsurface_destroy(struct wl_listener *listener,
|
||||||
void *data) {
|
void *data) {
|
||||||
struct wlr_scene_subsurface_tree *subsurface_tree =
|
struct wlr_scene_subsurface_tree *subsurface_tree =
|
||||||
wl_container_of(listener, subsurface_tree, surface_map);
|
wl_container_of(listener, subsurface_tree, subsurface_destroy);
|
||||||
|
wlr_scene_node_destroy(&subsurface_tree->tree->node);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void subsurface_tree_handle_subsurface_map(struct wl_listener *listener,
|
||||||
|
void *data) {
|
||||||
|
struct wlr_scene_subsurface_tree *subsurface_tree =
|
||||||
|
wl_container_of(listener, subsurface_tree, subsurface_map);
|
||||||
|
|
||||||
wlr_scene_node_set_enabled(&subsurface_tree->tree->node, true);
|
wlr_scene_node_set_enabled(&subsurface_tree->tree->node, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void subsurface_tree_handle_surface_unmap(struct wl_listener *listener,
|
static void subsurface_tree_handle_subsurface_unmap(struct wl_listener *listener,
|
||||||
void *data) {
|
void *data) {
|
||||||
struct wlr_scene_subsurface_tree *subsurface_tree =
|
struct wlr_scene_subsurface_tree *subsurface_tree =
|
||||||
wl_container_of(listener, subsurface_tree, surface_unmap);
|
wl_container_of(listener, subsurface_tree, subsurface_unmap);
|
||||||
|
|
||||||
wlr_scene_node_set_enabled(&subsurface_tree->tree->node, false);
|
wlr_scene_node_set_enabled(&subsurface_tree->tree->node, false);
|
||||||
}
|
}
|
||||||
|
@ -151,8 +164,14 @@ static bool subsurface_tree_create_subsurface(
|
||||||
wlr_addon_init(&child->surface_addon, &subsurface->surface->addons,
|
wlr_addon_init(&child->surface_addon, &subsurface->surface->addons,
|
||||||
parent, &subsurface_tree_addon_impl);
|
parent, &subsurface_tree_addon_impl);
|
||||||
|
|
||||||
wl_signal_add(&subsurface->events.map, &child->surface_map);
|
child->subsurface_destroy.notify = subsurface_tree_handle_subsurface_destroy;
|
||||||
wl_signal_add(&subsurface->events.unmap, &child->surface_unmap);
|
wl_signal_add(&subsurface->events.destroy, &child->subsurface_destroy);
|
||||||
|
|
||||||
|
child->subsurface_map.notify = subsurface_tree_handle_subsurface_map;
|
||||||
|
wl_signal_add(&subsurface->events.map, &child->subsurface_map);
|
||||||
|
|
||||||
|
child->subsurface_unmap.notify = subsurface_tree_handle_subsurface_unmap;
|
||||||
|
wl_signal_add(&subsurface->events.unmap, &child->subsurface_unmap);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -214,12 +233,6 @@ static struct wlr_scene_subsurface_tree *scene_surface_tree_create(
|
||||||
subsurface_tree->surface_commit.notify = subsurface_tree_handle_surface_commit;
|
subsurface_tree->surface_commit.notify = subsurface_tree_handle_surface_commit;
|
||||||
wl_signal_add(&surface->events.commit, &subsurface_tree->surface_commit);
|
wl_signal_add(&surface->events.commit, &subsurface_tree->surface_commit);
|
||||||
|
|
||||||
subsurface_tree->surface_map.notify = subsurface_tree_handle_surface_map;
|
|
||||||
wl_list_init(&subsurface_tree->surface_map.link);
|
|
||||||
|
|
||||||
subsurface_tree->surface_unmap.notify = subsurface_tree_handle_surface_unmap;
|
|
||||||
wl_list_init(&subsurface_tree->surface_unmap.link);
|
|
||||||
|
|
||||||
subsurface_tree->surface_new_subsurface.notify =
|
subsurface_tree->surface_new_subsurface.notify =
|
||||||
subsurface_tree_handle_surface_new_subsurface;
|
subsurface_tree_handle_surface_new_subsurface;
|
||||||
wl_signal_add(&surface->events.new_subsurface,
|
wl_signal_add(&surface->events.new_subsurface,
|
||||||
|
|
|
@ -130,6 +130,7 @@ void wlr_scene_node_destroy(struct wlr_scene_node *node) {
|
||||||
break;
|
break;
|
||||||
case WLR_SCENE_NODE_BUFFER:;
|
case WLR_SCENE_NODE_BUFFER:;
|
||||||
struct wlr_scene_buffer *scene_buffer = scene_buffer_from_node(node);
|
struct wlr_scene_buffer *scene_buffer = scene_buffer_from_node(node);
|
||||||
|
wl_list_remove(&scene_buffer->pending_link);
|
||||||
wlr_texture_destroy(scene_buffer->texture);
|
wlr_texture_destroy(scene_buffer->texture);
|
||||||
wlr_buffer_unlock(scene_buffer->buffer);
|
wlr_buffer_unlock(scene_buffer->buffer);
|
||||||
free(scene_buffer);
|
free(scene_buffer);
|
||||||
|
@ -145,6 +146,7 @@ struct wlr_scene *wlr_scene_create(void) {
|
||||||
scene_node_init(&scene->node, WLR_SCENE_NODE_ROOT, NULL);
|
scene_node_init(&scene->node, WLR_SCENE_NODE_ROOT, NULL);
|
||||||
wl_list_init(&scene->outputs);
|
wl_list_init(&scene->outputs);
|
||||||
wl_list_init(&scene->presentation_destroy.link);
|
wl_list_init(&scene->presentation_destroy.link);
|
||||||
|
wl_list_init(&scene->pending_buffers);
|
||||||
return scene;
|
return scene;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,10 +238,6 @@ static void scene_surface_handle_surface_commit(struct wl_listener *listener,
|
||||||
wl_container_of(listener, scene_surface, surface_commit);
|
wl_container_of(listener, scene_surface, surface_commit);
|
||||||
struct wlr_surface *surface = scene_surface->surface;
|
struct wlr_surface *surface = scene_surface->surface;
|
||||||
|
|
||||||
if (!pixman_region32_not_empty(&surface->buffer_damage)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct wlr_scene *scene = scene_node_get_root(&scene_surface->node);
|
struct wlr_scene *scene = scene_node_get_root(&scene_surface->node);
|
||||||
|
|
||||||
int lx, ly;
|
int lx, ly;
|
||||||
|
@ -256,6 +254,17 @@ static void scene_surface_handle_surface_commit(struct wl_listener *listener,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Even if the surface hasn't submitted damage, schedule a new frame if
|
||||||
|
// the client has requested a wl_surface.frame callback.
|
||||||
|
if (!wl_list_empty(&surface->current.frame_callback_list) &&
|
||||||
|
scene_surface->primary_output != NULL) {
|
||||||
|
wlr_output_schedule_frame(scene_surface->primary_output);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pixman_region32_not_empty(&surface->buffer_damage)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
struct wlr_scene_output *scene_output;
|
struct wlr_scene_output *scene_output;
|
||||||
wl_list_for_each(scene_output, &scene->outputs, link) {
|
wl_list_for_each(scene_output, &scene->outputs, link) {
|
||||||
struct wlr_output *output = scene_output->output;
|
struct wlr_output *output = scene_output->output;
|
||||||
|
@ -353,6 +362,9 @@ struct wlr_scene_buffer *wlr_scene_buffer_create(struct wlr_scene_node *parent,
|
||||||
|
|
||||||
scene_node_damage_whole(&scene_buffer->node);
|
scene_node_damage_whole(&scene_buffer->node);
|
||||||
|
|
||||||
|
struct wlr_scene *scene = scene_node_get_root(parent);
|
||||||
|
wl_list_insert(&scene->pending_buffers, &scene_buffer->pending_link);
|
||||||
|
|
||||||
return scene_buffer;
|
return scene_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1106,6 +1118,15 @@ bool wlr_scene_output_commit(struct wlr_scene_output *scene_output) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try to import new buffers as textures
|
||||||
|
struct wlr_scene_buffer *scene_buffer, *scene_buffer_tmp;
|
||||||
|
wl_list_for_each_safe(scene_buffer, scene_buffer_tmp,
|
||||||
|
&scene_output->scene->pending_buffers, pending_link) {
|
||||||
|
scene_buffer_get_texture(scene_buffer, renderer);
|
||||||
|
wl_list_remove(&scene_buffer->pending_link);
|
||||||
|
wl_list_init(&scene_buffer->pending_link);
|
||||||
|
}
|
||||||
|
|
||||||
wlr_renderer_begin(renderer, output->width, output->height);
|
wlr_renderer_begin(renderer, output->width, output->height);
|
||||||
|
|
||||||
int nrects;
|
int nrects;
|
||||||
|
|
|
@ -256,6 +256,23 @@ static void toplevel_send_output(struct wlr_foreign_toplevel_handle_v1 *toplevel
|
||||||
toplevel_update_idle_source(toplevel);
|
toplevel_update_idle_source(toplevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void toplevel_handle_output_bind(struct wl_listener *listener,
|
||||||
|
void *data) {
|
||||||
|
struct wlr_foreign_toplevel_handle_v1_output *toplevel_output =
|
||||||
|
wl_container_of(listener, toplevel_output, output_bind);
|
||||||
|
struct wlr_output_event_bind *event = data;
|
||||||
|
struct wl_client *client = wl_resource_get_client(event->resource);
|
||||||
|
|
||||||
|
struct wl_resource *resource;
|
||||||
|
wl_resource_for_each(resource, &toplevel_output->toplevel->resources) {
|
||||||
|
if (wl_resource_get_client(resource) == client) {
|
||||||
|
send_output_to_resource(resource, toplevel_output->output, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toplevel_update_idle_source(toplevel_output->toplevel);
|
||||||
|
}
|
||||||
|
|
||||||
static void toplevel_handle_output_destroy(struct wl_listener *listener,
|
static void toplevel_handle_output_destroy(struct wl_listener *listener,
|
||||||
void *data) {
|
void *data) {
|
||||||
struct wlr_foreign_toplevel_handle_v1_output *toplevel_output =
|
struct wlr_foreign_toplevel_handle_v1_output *toplevel_output =
|
||||||
|
@ -285,6 +302,9 @@ void wlr_foreign_toplevel_handle_v1_output_enter(
|
||||||
toplevel_output->toplevel = toplevel;
|
toplevel_output->toplevel = toplevel;
|
||||||
wl_list_insert(&toplevel->outputs, &toplevel_output->link);
|
wl_list_insert(&toplevel->outputs, &toplevel_output->link);
|
||||||
|
|
||||||
|
toplevel_output->output_bind.notify = toplevel_handle_output_bind;
|
||||||
|
wl_signal_add(&output->events.bind, &toplevel_output->output_bind);
|
||||||
|
|
||||||
toplevel_output->output_destroy.notify = toplevel_handle_output_destroy;
|
toplevel_output->output_destroy.notify = toplevel_handle_output_destroy;
|
||||||
wl_signal_add(&output->events.destroy, &toplevel_output->output_destroy);
|
wl_signal_add(&output->events.destroy, &toplevel_output->output_destroy);
|
||||||
|
|
||||||
|
@ -294,6 +314,7 @@ void wlr_foreign_toplevel_handle_v1_output_enter(
|
||||||
static void toplevel_output_destroy(
|
static void toplevel_output_destroy(
|
||||||
struct wlr_foreign_toplevel_handle_v1_output *toplevel_output) {
|
struct wlr_foreign_toplevel_handle_v1_output *toplevel_output) {
|
||||||
wl_list_remove(&toplevel_output->link);
|
wl_list_remove(&toplevel_output->link);
|
||||||
|
wl_list_remove(&toplevel_output->output_bind.link);
|
||||||
wl_list_remove(&toplevel_output->output_destroy.link);
|
wl_list_remove(&toplevel_output->output_destroy.link);
|
||||||
free(toplevel_output);
|
free(toplevel_output);
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,9 +157,22 @@ static void popup_surface_surface_role_commit(struct wlr_surface *surface) {
|
||||||
&& popup_surface->input_method->client_active);
|
&& popup_surface->input_method->client_active);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void popup_surface_surface_role_precommit(struct wlr_surface *surface) {
|
||||||
|
struct wlr_input_popup_surface_v2 *popup_surface = surface->role_data;
|
||||||
|
if (popup_surface == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (surface->pending.committed & WLR_SURFACE_STATE_BUFFER &&
|
||||||
|
surface->pending.buffer == NULL) {
|
||||||
|
// This is a NULL commit
|
||||||
|
popup_surface_set_mapped(popup_surface, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const struct wlr_surface_role input_popup_surface_v2_role = {
|
static const struct wlr_surface_role input_popup_surface_v2_role = {
|
||||||
.name = "zwp_input_popup_surface_v2",
|
.name = "zwp_input_popup_surface_v2",
|
||||||
.commit = popup_surface_surface_role_commit,
|
.commit = popup_surface_surface_role_commit,
|
||||||
|
.precommit = popup_surface_surface_role_precommit,
|
||||||
};
|
};
|
||||||
|
|
||||||
bool wlr_surface_is_input_popup_surface_v2(struct wlr_surface *surface) {
|
bool wlr_surface_is_input_popup_surface_v2(struct wlr_surface *surface) {
|
||||||
|
|
|
@ -207,8 +207,12 @@ static void surface_update_damage(pixman_region32_t *buffer_damage,
|
||||||
pixman_region32_clear(buffer_damage);
|
pixman_region32_clear(buffer_damage);
|
||||||
|
|
||||||
if (pending->width != current->width ||
|
if (pending->width != current->width ||
|
||||||
pending->height != current->height) {
|
pending->height != current->height ||
|
||||||
// Damage the whole buffer on resize
|
pending->viewport.src.x != current->viewport.src.x ||
|
||||||
|
pending->viewport.src.y != current->viewport.src.y ||
|
||||||
|
pending->viewport.src.width != current->viewport.src.width ||
|
||||||
|
pending->viewport.src.height != current->viewport.src.height) {
|
||||||
|
// Damage the whole buffer on resize or viewport source box change
|
||||||
pixman_region32_union_rect(buffer_damage, buffer_damage, 0, 0,
|
pixman_region32_union_rect(buffer_damage, buffer_damage, 0, 0,
|
||||||
pending->buffer_width, pending->buffer_height);
|
pending->buffer_width, pending->buffer_height);
|
||||||
} else {
|
} else {
|
||||||
|
@ -530,6 +534,9 @@ static void subsurface_commit(struct wlr_subsurface *subsurface) {
|
||||||
}
|
}
|
||||||
subsurface->has_cache = true;
|
subsurface->has_cache = true;
|
||||||
subsurface->cached_seq = wlr_surface_lock_pending(surface);
|
subsurface->cached_seq = wlr_surface_lock_pending(surface);
|
||||||
|
} else if (subsurface->has_cache) {
|
||||||
|
wlr_surface_unlock_cached(surface, subsurface->cached_seq);
|
||||||
|
subsurface->has_cache = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ static bool verify_is_toplevel(struct wl_resource *client_resource,
|
||||||
if (wlr_surface_is_xdg_surface(surface)) {
|
if (wlr_surface_is_xdg_surface(surface)) {
|
||||||
struct wlr_xdg_surface *xdg_surface =
|
struct wlr_xdg_surface *xdg_surface =
|
||||||
wlr_xdg_surface_from_wlr_surface(surface);
|
wlr_xdg_surface_from_wlr_surface(surface);
|
||||||
if (xdg_surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) {
|
if (xdg_surface == NULL || xdg_surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) {
|
||||||
wl_resource_post_error(client_resource, -1,
|
wl_resource_post_error(client_resource, -1,
|
||||||
"surface must be an xdg_toplevel");
|
"surface must be an xdg_toplevel");
|
||||||
return false;
|
return false;
|
||||||
|
@ -151,8 +151,11 @@ static void destroy_imported(struct wlr_xdg_imported_v1 *imported) {
|
||||||
wl_list_for_each_safe(child, child_tmp, &imported->children, link) {
|
wl_list_for_each_safe(child, child_tmp, &imported->children, link) {
|
||||||
struct wlr_xdg_surface *xdg_child =
|
struct wlr_xdg_surface *xdg_child =
|
||||||
wlr_xdg_surface_from_wlr_surface(child->surface);
|
wlr_xdg_surface_from_wlr_surface(child->surface);
|
||||||
|
|
||||||
|
if (xdg_child != NULL) {
|
||||||
wlr_xdg_toplevel_set_parent(xdg_child, NULL);
|
wlr_xdg_toplevel_set_parent(xdg_child, NULL);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
wl_list_remove(&imported->exported_destroyed.link);
|
wl_list_remove(&imported->exported_destroyed.link);
|
||||||
wl_list_init(&imported->exported_destroyed.link);
|
wl_list_init(&imported->exported_destroyed.link);
|
||||||
|
|
|
@ -42,7 +42,7 @@ static bool verify_is_toplevel(struct wl_resource *client_resource,
|
||||||
|
|
||||||
struct wlr_xdg_surface *xdg_surface =
|
struct wlr_xdg_surface *xdg_surface =
|
||||||
wlr_xdg_surface_from_wlr_surface(surface);
|
wlr_xdg_surface_from_wlr_surface(surface);
|
||||||
if (xdg_surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) {
|
if (xdg_surface == NULL || xdg_surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) {
|
||||||
wl_resource_post_error(client_resource,
|
wl_resource_post_error(client_resource,
|
||||||
ZXDG_EXPORTER_V2_ERROR_INVALID_SURFACE,
|
ZXDG_EXPORTER_V2_ERROR_INVALID_SURFACE,
|
||||||
"surface must be an xdg_toplevel");
|
"surface must be an xdg_toplevel");
|
||||||
|
@ -157,8 +157,11 @@ static void destroy_imported(struct wlr_xdg_imported_v2 *imported) {
|
||||||
wl_list_for_each_safe(child, child_tmp, &imported->children, link) {
|
wl_list_for_each_safe(child, child_tmp, &imported->children, link) {
|
||||||
struct wlr_xdg_surface *xdg_child =
|
struct wlr_xdg_surface *xdg_child =
|
||||||
wlr_xdg_surface_from_wlr_surface(child->surface);
|
wlr_xdg_surface_from_wlr_surface(child->surface);
|
||||||
|
|
||||||
|
if (xdg_child != NULL) {
|
||||||
wlr_xdg_toplevel_set_parent(xdg_child, NULL);
|
wlr_xdg_toplevel_set_parent(xdg_child, NULL);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
wl_list_remove(&imported->exported_destroyed.link);
|
wl_list_remove(&imported->exported_destroyed.link);
|
||||||
wl_list_init(&imported->exported_destroyed.link);
|
wl_list_init(&imported->exported_destroyed.link);
|
||||||
|
|
Loading…
Reference in New Issue