aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backend/drm/drm.c2
-rw-r--r--backend/multi/backend.c2
-rw-r--r--examples/dmabuf-capture.c2
-rw-r--r--examples/meson.build10
-rw-r--r--include/render/gles2.h3
-rw-r--r--include/types/wlr_data_device.h1
-rw-r--r--include/wlr/render/dmabuf.h4
-rw-r--r--include/wlr/render/interface.h6
-rw-r--r--include/wlr/render/wlr_texture.h7
-rw-r--r--include/wlr/types/wlr_data_device.h1
-rw-r--r--meson.build2
-rw-r--r--render/egl.c51
-rw-r--r--render/gles2/texture.c17
-rw-r--r--render/meson.build8
-rw-r--r--render/wlr_texture.c8
-rw-r--r--rootston/output.c3
-rw-r--r--rootston/text_input.c4
-rw-r--r--types/data_device/wlr_data_device.c32
-rw-r--r--types/data_device/wlr_data_offer.c3
-rw-r--r--types/data_device/wlr_data_source.c5
-rw-r--r--types/wlr_buffer.c16
-rw-r--r--types/wlr_cursor.c10
-rw-r--r--types/wlr_linux_dmabuf_v1.c29
-rw-r--r--types/wlr_output_layout.c13
-rw-r--r--types/wlr_text_input_v3.c7
-rw-r--r--xwayland/xwm.c20
26 files changed, 177 insertions, 89 deletions
diff --git a/backend/drm/drm.c b/backend/drm/drm.c
index 1313e7fe..0b624717 100644
--- a/backend/drm/drm.c
+++ b/backend/drm/drm.c
@@ -1,4 +1,4 @@
-#define _POSIX_C_SOURCE 199309L
+#define _POSIX_C_SOURCE 200112L
#include <assert.h>
#include <drm_mode.h>
#include <EGL/egl.h>
diff --git a/backend/multi/backend.c b/backend/multi/backend.c
index cefaa361..50851109 100644
--- a/backend/multi/backend.c
+++ b/backend/multi/backend.c
@@ -1,4 +1,4 @@
-#define _POSIX_C_SOURCE 199309L
+#define _POSIX_C_SOURCE 200112L
#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
diff --git a/examples/dmabuf-capture.c b/examples/dmabuf-capture.c
index 2c510b5a..abdb146a 100644
--- a/examples/dmabuf-capture.c
+++ b/examples/dmabuf-capture.c
@@ -12,7 +12,7 @@
#include <unistd.h>
#include <pthread.h>
#include <stdbool.h>
-#include <libdrm/drm_fourcc.h>
+#include <drm_fourcc.h>
#include "wlr-export-dmabuf-unstable-v1-client-protocol.h"
struct wayland_output {
diff --git a/examples/meson.build b/examples/meson.build
index da7a5275..369c7049 100644
--- a/examples/meson.build
+++ b/examples/meson.build
@@ -6,6 +6,13 @@ libavutil = dependency('libavutil', version: '>=56.14.100', required: false)
libavcodec = dependency('libavcodec', version: '>=58.18.100', required: false)
libavformat = dependency('libavformat', version: '>=58.12.100', required: false)
+# epoll is a separate library in FreeBSD
+if host_machine.system() == 'freebsd'
+ libepoll = [dependency('epoll-shim')]
+else
+ libepoll = []
+endif
+
# Small hack until https://github.com/mesonbuild/meson/pull/3386/ is merged
foreach dep : ['libpng', 'libavutil', 'libavcodec', 'libavformat']
if not get_variable(dep).found()
@@ -80,6 +87,7 @@ examples = {
libavcodec,
libavformat,
libavutil,
+ drm.partial_dependency(compile_args: true), # <drm_fourcc.h>
threads,
wayland_client,
wlr_protos,
@@ -96,7 +104,7 @@ examples = {
},
'input-method': {
'src': 'input-method.c',
- 'dep': [wayland_client, wlr_protos, wlroots],
+ 'dep': [wayland_client, wlr_protos, wlroots] + libepoll,
},
'text-input': {
'src': 'text-input.c',
diff --git a/include/render/gles2.h b/include/render/gles2.h
index f649f3e2..7ff2f174 100644
--- a/include/render/gles2.h
+++ b/include/render/gles2.h
@@ -19,7 +19,7 @@
extern PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES;
struct wlr_gles2_pixel_format {
- uint32_t wl_format;
+ enum wl_shm_format wl_format;
GLint gl_format, gl_type;
int depth, bpp;
bool has_alpha;
@@ -72,6 +72,7 @@ struct wlr_gles2_texture {
enum wlr_gles2_texture_type type;
int width, height;
bool has_alpha;
+ enum wl_shm_format wl_format; // used to interpret upload data
bool inverted_y;
// Not set if WLR_GLES2_TEXTURE_GLTEX
diff --git a/include/types/wlr_data_device.h b/include/types/wlr_data_device.h
index 972294ff..388e91a5 100644
--- a/include/types/wlr_data_device.h
+++ b/include/types/wlr_data_device.h
@@ -11,6 +11,7 @@ struct wlr_client_data_source {
struct wlr_data_source source;
struct wlr_data_source_impl impl;
struct wl_resource *resource;
+ bool finalized;
};
extern const struct wlr_surface_role drag_icon_surface_role;
diff --git a/include/wlr/render/dmabuf.h b/include/wlr/render/dmabuf.h
index 33c3a129..32cfe874 100644
--- a/include/wlr/render/dmabuf.h
+++ b/include/wlr/render/dmabuf.h
@@ -16,6 +16,10 @@
#define DRM_FORMAT_MOD_INVALID ((1ULL<<56) - 1)
#endif
+#ifndef DRM_FORMAT_MOD_LINEAR
+#define DRM_FORMAT_MOD_LINEAR 0
+#endif
+
#define WLR_DMABUF_MAX_PLANES 4
enum wlr_dmabuf_attributes_flags {
diff --git a/include/wlr/render/interface.h b/include/wlr/render/interface.h
index 63f4265c..905d419f 100644
--- a/include/wlr/render/interface.h
+++ b/include/wlr/render/interface.h
@@ -66,9 +66,9 @@ struct wlr_texture_impl {
void (*get_size)(struct wlr_texture *texture, int *width, int *height);
bool (*is_opaque)(struct wlr_texture *texture);
bool (*write_pixels)(struct wlr_texture *texture,
- enum wl_shm_format wl_fmt, uint32_t stride, uint32_t width,
- uint32_t height, uint32_t src_x, uint32_t src_y, uint32_t dst_x,
- uint32_t dst_y, const void *data);
+ uint32_t stride, uint32_t width, uint32_t height,
+ uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y,
+ const void *data);
bool (*to_dmabuf)(struct wlr_texture *texture,
struct wlr_dmabuf_attributes *attribs);
void (*destroy)(struct wlr_texture *texture);
diff --git a/include/wlr/render/wlr_texture.h b/include/wlr/render/wlr_texture.h
index dbfabfee..f210717a 100644
--- a/include/wlr/render/wlr_texture.h
+++ b/include/wlr/render/wlr_texture.h
@@ -54,10 +54,11 @@ void wlr_texture_get_size(struct wlr_texture *texture, int *width, int *height);
bool wlr_texture_is_opaque(struct wlr_texture *texture);
/**
- * Update a texture with raw pixels. The texture must be mutable.
- */
+ * Update a texture with raw pixels. The texture must be mutable, and the input
+ * data must have the same pixel format that the texture was created with.
+ */
bool wlr_texture_write_pixels(struct wlr_texture *texture,
- enum wl_shm_format wl_fmt, uint32_t stride, uint32_t width, uint32_t height,
+ uint32_t stride, uint32_t width, uint32_t height,
uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y,
const void *data);
diff --git a/include/wlr/types/wlr_data_device.h b/include/wlr/types/wlr_data_device.h
index c45e8d1c..9ce8f400 100644
--- a/include/wlr/types/wlr_data_device.h
+++ b/include/wlr/types/wlr_data_device.h
@@ -73,7 +73,6 @@ struct wlr_data_source {
// source status
bool accepted;
struct wlr_data_offer *offer;
- struct wlr_seat_client *seat_client;
// drag'n'drop status
enum wl_data_device_manager_dnd_action current_dnd_action;
diff --git a/meson.build b/meson.build
index 9d40dbfc..9517168a 100644
--- a/meson.build
+++ b/meson.build
@@ -1,7 +1,7 @@
project(
'wlroots',
'c',
- version: '0.0.1',
+ version: '0.1.0',
license: 'MIT',
meson_version: '>=0.48.0',
default_options: [
diff --git a/render/egl.c b/render/egl.c
index 96e48c06..cfa37f20 100644
--- a/render/egl.c
+++ b/render/egl.c
@@ -3,6 +3,7 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <stdlib.h>
+#include <drm_fourcc.h>
#include <wlr/render/egl.h>
#include <wlr/util/log.h>
#include "glapi.h"
@@ -120,7 +121,7 @@ bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *remote_display,
if (platform == EGL_PLATFORM_SURFACELESS_MESA) {
assert(remote_display == NULL);
- egl->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ egl->display = eglGetPlatformDisplayEXT(platform, EGL_DEFAULT_DISPLAY, NULL);
} else {
egl->display = eglGetPlatformDisplayEXT(platform, remote_display, NULL);
}
@@ -382,13 +383,21 @@ EGLImageKHR wlr_egl_create_image_from_wl_drm(struct wlr_egl *egl,
EGLImageKHR wlr_egl_create_image_from_dmabuf(struct wlr_egl *egl,
struct wlr_dmabuf_attributes *attributes) {
- if (!egl->exts.image_base_khr) {
+ if (!egl->exts.image_base_khr || !egl->exts.image_dmabuf_import_ext) {
+ wlr_log(WLR_ERROR, "dmabuf import extension not present");
return NULL;
}
bool has_modifier = false;
- if (attributes->modifier != DRM_FORMAT_MOD_INVALID) {
+
+ // we assume the same way we assumed formats without the import_modifiers
+ // extension that mod_linear is supported. The special mod mod_invalid
+ // is sometimes used to signal modifier unawareness which is what we
+ // have here
+ if (attributes->modifier != DRM_FORMAT_MOD_INVALID &&
+ attributes->modifier != DRM_FORMAT_MOD_LINEAR) {
if (!egl->exts.image_dmabuf_import_modifiers_ext) {
+ wlr_log(WLR_ERROR, "dmabuf modifiers extension not present");
return NULL;
}
has_modifier = true;
@@ -460,12 +469,34 @@ EGLImageKHR wlr_egl_create_image_from_dmabuf(struct wlr_egl *egl,
int wlr_egl_get_dmabuf_formats(struct wlr_egl *egl,
int **formats) {
- if (!egl->exts.image_dmabuf_import_ext ||
- !egl->exts.image_dmabuf_import_modifiers_ext) {
- wlr_log(WLR_DEBUG, "dmabuf extension not present");
+ if (!egl->exts.image_dmabuf_import_ext) {
+ wlr_log(WLR_DEBUG, "dmabuf import extension not present");
return -1;
}
+ // when we only have the image_dmabuf_import extension we can't query
+ // which formats are supported. These two are on almost always
+ // supported; it's the intended way to just try to create buffers.
+ // Just a guess but better than not supporting dmabufs at all,
+ // given that the modifiers extension isn't supported everywhere.
+ if (!egl->exts.image_dmabuf_import_modifiers_ext) {
+ static const int fallback_formats[] = {
+ DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_XRGB8888,
+ };
+ static unsigned num = sizeof(fallback_formats) /
+ sizeof(fallback_formats[0]);
+
+ *formats = calloc(num, sizeof(int));
+ if (!*formats) {
+ wlr_log_errno(WLR_ERROR, "Allocation failed");
+ return -1;
+ }
+
+ memcpy(*formats, fallback_formats, num * sizeof(**formats));
+ return num;
+ }
+
EGLint num;
if (!eglQueryDmaBufFormatsEXT(egl->display, 0, NULL, &num)) {
wlr_log(WLR_ERROR, "failed to query number of dmabuf formats");
@@ -488,12 +519,16 @@ int wlr_egl_get_dmabuf_formats(struct wlr_egl *egl,
int wlr_egl_get_dmabuf_modifiers(struct wlr_egl *egl,
int format, uint64_t **modifiers) {
- if (!egl->exts.image_dmabuf_import_ext ||
- !egl->exts.image_dmabuf_import_modifiers_ext) {
+ if (!egl->exts.image_dmabuf_import_ext) {
wlr_log(WLR_DEBUG, "dmabuf extension not present");
return -1;
}
+ if(!egl->exts.image_dmabuf_import_modifiers_ext) {
+ *modifiers = NULL;
+ return 0;
+ }
+
EGLint num;
if (!eglQueryDmaBufModifiersEXT(egl->display, format, 0,
NULL, NULL, &num)) {
diff --git a/render/gles2/texture.c b/render/gles2/texture.c
index 22d02cde..d035841e 100644
--- a/render/gles2/texture.c
+++ b/render/gles2/texture.c
@@ -44,9 +44,9 @@ static bool gles2_texture_is_opaque(struct wlr_texture *wlr_texture) {
}
static bool gles2_texture_write_pixels(struct wlr_texture *wlr_texture,
- enum wl_shm_format wl_fmt, uint32_t stride, uint32_t width,
- uint32_t height, uint32_t src_x, uint32_t src_y, uint32_t dst_x,
- uint32_t dst_y, const void *data) {
+ uint32_t stride, uint32_t width, uint32_t height,
+ uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y,
+ const void *data) {
struct wlr_gles2_texture *texture =
get_gles2_texture_in_context(wlr_texture);
@@ -55,11 +55,9 @@ static bool gles2_texture_write_pixels(struct wlr_texture *wlr_texture,
return false;
}
- const struct wlr_gles2_pixel_format *fmt = get_gles2_format_from_wl(wl_fmt);
- if (fmt == NULL) {
- wlr_log(WLR_ERROR, "Unsupported pixel format %"PRIu32, wl_fmt);
- return false;
- }
+ const struct wlr_gles2_pixel_format *fmt =
+ get_gles2_format_from_wl(texture->wl_format);
+ assert(fmt);
// TODO: what if the unpack subimage extension isn't supported?
PUSH_GLES2_DEBUG;
@@ -167,6 +165,7 @@ struct wlr_texture *wlr_gles2_texture_from_pixels(struct wlr_egl *egl,
texture->height = height;
texture->type = WLR_GLES2_TEXTURE_GLTEX;
texture->has_alpha = fmt->has_alpha;
+ texture->wl_format = fmt->wl_format;
PUSH_GLES2_DEBUG;
@@ -203,6 +202,7 @@ struct wlr_texture *wlr_gles2_texture_from_wl_drm(struct wlr_egl *egl,
texture->wl_drm = data;
EGLint fmt;
+ texture->wl_format = 0xFFFFFFFF; // texture can't be written anyways
texture->image = wlr_egl_create_image_from_wl_drm(egl, data, &fmt,
&texture->width, &texture->height, &texture->inverted_y);
if (texture->image == NULL) {
@@ -283,6 +283,7 @@ struct wlr_texture *wlr_gles2_texture_from_dmabuf(struct wlr_egl *egl,
texture->height = attribs->height;
texture->type = WLR_GLES2_TEXTURE_DMABUF;
texture->has_alpha = true;
+ texture->wl_format = 0xFFFFFFFF; // texture can't be written anyways
texture->inverted_y =
(attribs->flags & WLR_DMABUF_ATTRIBUTES_FLAGS_Y_INVERT) != 0;
diff --git a/render/meson.build b/render/meson.build
index ab66eab0..e45ea90b 100644
--- a/render/meson.build
+++ b/render/meson.build
@@ -22,7 +22,13 @@ lib_wlr_render = static_library(
),
glapi,
include_directories: wlr_inc,
- dependencies: [egl, glesv2, pixman, wayland_server],
+ dependencies: [
+ egl,
+ drm.partial_dependency(compile_args: true), # <drm_fourcc.h>
+ glesv2,
+ pixman,
+ wayland_server
+ ],
)
wlr_render = declare_dependency(
diff --git a/render/wlr_texture.c b/render/wlr_texture.c
index 06872f1e..833032c9 100644
--- a/render/wlr_texture.c
+++ b/render/wlr_texture.c
@@ -55,10 +55,10 @@ bool wlr_texture_is_opaque(struct wlr_texture *texture) {
}
bool wlr_texture_write_pixels(struct wlr_texture *texture,
- enum wl_shm_format wl_fmt, uint32_t stride, uint32_t width,
- uint32_t height, uint32_t src_x, uint32_t src_y, uint32_t dst_x,
- uint32_t dst_y, const void *data) {
- return texture->impl->write_pixels(texture, wl_fmt, stride, width, height,
+ uint32_t stride, uint32_t width, uint32_t height,
+ uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y,
+ const void *data) {
+ return texture->impl->write_pixels(texture, stride, width, height,
src_x, src_y, dst_x, dst_y, data);
}
diff --git a/rootston/output.c b/rootston/output.c
index 9d376f8e..bd38f3ab 100644
--- a/rootston/output.c
+++ b/rootston/output.c
@@ -459,7 +459,8 @@ static void render_output(struct roots_output *output) {
output_box->y;
view_move(view, view_x, view_y);
- if (has_standalone_surface(view)) {
+ if (has_standalone_surface(view) &&
+ wl_list_empty(&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY])) {
wlr_output_set_fullscreen_surface(wlr_output, view->wlr_surface);
} else {
wlr_output_set_fullscreen_surface(wlr_output, NULL);
diff --git a/rootston/text_input.c b/rootston/text_input.c
index cca64353..70c92761 100644
--- a/rootston/text_input.c
+++ b/rootston/text_input.c
@@ -163,10 +163,6 @@ static void handle_text_input_disable(struct wl_listener *listener,
text_input_disable);
struct roots_text_input *text_input = text_input_to_roots(relay,
(struct wlr_text_input_v3*)data);
- if (!text_input->input->current_enabled) {
- wlr_log(WLR_DEBUG, "Inactive text input tried to disable itself");
- return;
- }
relay_disable_text_input(relay, text_input);
}
diff --git a/types/data_device/wlr_data_device.c b/types/data_device/wlr_data_device.c
index 40974de7..111c2de0 100644
--- a/types/data_device/wlr_data_device.c
+++ b/types/data_device/wlr_data_device.c
@@ -25,16 +25,21 @@ static struct wlr_seat_client *seat_client_from_data_device_resource(
static void data_device_set_selection(struct wl_client *client,
struct wl_resource *device_resource,
struct wl_resource *source_resource, uint32_t serial) {
+ struct wlr_seat_client *seat_client =
+ seat_client_from_data_device_resource(device_resource);
+
struct wlr_client_data_source *source = NULL;
if (source_resource != NULL) {
source = client_data_source_from_resource(source_resource);
}
- struct wlr_seat_client *seat_client =
- seat_client_from_data_device_resource(device_resource);
-
- struct wlr_data_source *wlr_source = (struct wlr_data_source *)source;
+ struct wlr_data_source *wlr_source =
+ source != NULL ? &source->source : NULL;
wlr_seat_set_selection(seat_client->seat, wlr_source, serial);
+
+ if (source != NULL) {
+ source->finalized = true;
+ }
}
static void data_device_start_drag(struct wl_client *client,
@@ -45,15 +50,13 @@ static void data_device_start_drag(struct wl_client *client,
struct wlr_seat_client *seat_client =
seat_client_from_data_device_resource(device_resource);
struct wlr_surface *origin = wlr_surface_from_resource(origin_resource);
- struct wlr_data_source *source = NULL;
- struct wlr_surface *icon = NULL;
- if (source_resource) {
- struct wlr_client_data_source *client_source =
- client_data_source_from_resource(source_resource);
- source = (struct wlr_data_source *)client_source;
+ struct wlr_client_data_source *source = NULL;
+ if (source_resource != NULL) {
+ source = client_data_source_from_resource(source_resource);
}
+ struct wlr_surface *icon = NULL;
if (icon_resource) {
icon = wlr_surface_from_resource(icon_resource);
if (!wlr_surface_set_role(icon, &drag_icon_surface_role, NULL,
@@ -62,13 +65,16 @@ static void data_device_start_drag(struct wl_client *client,
}
}
- if (!seat_client_start_drag(seat_client, source, icon, origin, serial)) {
+ struct wlr_data_source *wlr_source =
+ source != NULL ? &source->source : NULL;
+ if (!seat_client_start_drag(seat_client, wlr_source, icon,
+ origin, serial)) {
wl_resource_post_no_memory(device_resource);
return;
}
- if (source) {
- source->seat_client = seat_client;
+ if (source != NULL) {
+ source->finalized = true;
}
}
diff --git a/types/data_device/wlr_data_offer.c b/types/data_device/wlr_data_offer.c
index a5ea9183..9847e07c 100644
--- a/types/data_device/wlr_data_offer.c
+++ b/types/data_device/wlr_data_offer.c
@@ -41,8 +41,7 @@ static uint32_t data_offer_choose_action(struct wlr_data_offer *offer) {
return WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
}
- if (offer->source->seat_client &&
- offer->source->compositor_action & available_actions) {
+ if (offer->source->compositor_action & available_actions) {
return offer->source->compositor_action;
}
diff --git a/types/data_device/wlr_data_source.c b/types/data_device/wlr_data_source.c
index bf638f5a..59650170 100644
--- a/types/data_device/wlr_data_source.c
+++ b/types/data_device/wlr_data_source.c
@@ -207,11 +207,10 @@ static void data_source_set_actions(struct wl_client *client,
return;
}
- if (source->source.seat_client) {
+ if (source->finalized) {
wl_resource_post_error(source->resource,
WL_DATA_SOURCE_ERROR_INVALID_ACTION_MASK,
- "invalid action change after "
- "wl_data_device.start_drag");
+ "invalid action change after wl_data_device.start_drag");
return;
}
diff --git a/types/wlr_buffer.c b/types/wlr_buffer.c
index ce733f40..cec3475c 100644
--- a/types/wlr_buffer.c
+++ b/types/wlr_buffer.c
@@ -150,12 +150,20 @@ struct wlr_buffer *wlr_buffer_apply_damage(struct wlr_buffer *buffer,
}
struct wl_shm_buffer *shm_buf = wl_shm_buffer_get(resource);
- if (shm_buf == NULL) {
- // Uploading only damaged regions only works for wl_shm buffers
+ struct wl_shm_buffer *old_shm_buf = wl_shm_buffer_get(buffer->resource);
+ if (shm_buf == NULL || old_shm_buf == NULL) {
+ // Uploading only damaged regions only works for wl_shm buffers and
+ // mutable textures (created from wl_shm buffer)
+ return NULL;
+ }
+
+ enum wl_shm_format new_fmt = wl_shm_buffer_get_format(shm_buf);
+ enum wl_shm_format old_fmt = wl_shm_buffer_get_format(old_shm_buf);
+ if (new_fmt != old_fmt) {
+ // Uploading to textures can't change the format
return NULL;
}
- enum wl_shm_format fmt = wl_shm_buffer_get_format(shm_buf);
int32_t stride = wl_shm_buffer_get_stride(shm_buf);
int32_t width = wl_shm_buffer_get_width(shm_buf);
int32_t height = wl_shm_buffer_get_height(shm_buf);
@@ -173,7 +181,7 @@ struct wlr_buffer *wlr_buffer_apply_damage(struct wlr_buffer *buffer,
pixman_box32_t *rects = pixman_region32_rectangles(damage, &n);
for (int i = 0; i < n; ++i) {
pixman_box32_t *r = &rects[i];
- if (!wlr_texture_write_pixels(buffer->texture, fmt, stride,
+ if (!wlr_texture_write_pixels(buffer->texture, stride,
r->x2 - r->x1, r->y2 - r->y1, r->x1, r->y1,
r->x1, r->y1, data)) {
wl_shm_buffer_end_access(shm_buf);
diff --git a/types/wlr_cursor.c b/types/wlr_cursor.c
index e97dd840..8094ff18 100644
--- a/types/wlr_cursor.c
+++ b/types/wlr_cursor.c
@@ -620,8 +620,14 @@ static void handle_layout_output_destroy(struct wl_listener *listener,
static void layout_add(struct wlr_cursor_state *state,
struct wlr_output_layout_output *l_output) {
- struct wlr_cursor_output_cursor *output_cursor =
- calloc(1, sizeof(struct wlr_cursor_output_cursor));
+ struct wlr_cursor_output_cursor *output_cursor;
+ wl_list_for_each(output_cursor, &state->output_cursors, link) {
+ if (output_cursor->output_cursor->output == l_output->output) {
+ return; // already added
+ }
+ }
+
+ output_cursor = calloc(1, sizeof(struct wlr_cursor_output_cursor));
if (output_cursor == NULL) {
wlr_log(WLR_ERROR, "Failed to allocate wlr_cursor_output_cursor");
return;
diff --git a/types/wlr_linux_dmabuf_v1.c b/types/wlr_linux_dmabuf_v1.c
index f72e7c07..eb7b2f9e 100644
--- a/types/wlr_linux_dmabuf_v1.c
+++ b/types/wlr_linux_dmabuf_v1.c
@@ -103,6 +103,7 @@ static void params_add(struct wl_client *client,
close(fd);
return;
}
+
buffer->attributes.modifier = modifier;
buffer->has_modifier = true;
@@ -382,13 +383,9 @@ struct wlr_linux_dmabuf_v1 *wlr_linux_dmabuf_v1_from_resource(
return dmabuf;
}
-static void linux_dmabuf_send_modifiers(struct wlr_linux_dmabuf_v1 *linux_dmabuf,
- struct wl_resource *resource) {
+static void linux_dmabuf_send_formats(struct wlr_linux_dmabuf_v1 *linux_dmabuf,
+ struct wl_resource *resource, uint32_t version) {
struct wlr_renderer *renderer = linux_dmabuf->renderer;
- /*
- * Use EGL_EXT_image_dma_buf_import_modifiers to query and advertise
- * format/modifier codes.
- */
uint64_t modifier_invalid = DRM_FORMAT_MOD_INVALID;
int *formats = NULL;
int num_formats = wlr_renderer_get_dmabuf_formats(renderer, &formats);
@@ -410,10 +407,17 @@ static void linux_dmabuf_send_modifiers(struct wlr_linux_dmabuf_v1 *linux_dmabuf
modifiers = &modifier_invalid;
}
for (int j = 0; j < num_modifiers; j++) {
- uint32_t modifier_lo = modifiers[j] & 0xFFFFFFFF;
- uint32_t modifier_hi = modifiers[j] >> 32;
- zwp_linux_dmabuf_v1_send_modifier(resource, formats[i],
- modifier_hi, modifier_lo);
+ if (version >= ZWP_LINUX_DMABUF_V1_MODIFIER_SINCE_VERSION) {
+ uint32_t modifier_lo = modifiers[j] & 0xFFFFFFFF;
+ uint32_t modifier_hi = modifiers[j] >> 32;
+ zwp_linux_dmabuf_v1_send_modifier(resource,
+ formats[i],
+ modifier_hi,
+ modifier_lo);
+ } else if (modifiers[j] == DRM_FORMAT_MOD_LINEAR ||
+ modifiers == &modifier_invalid) {
+ zwp_linux_dmabuf_v1_send_format(resource, formats[i]);
+ }
}
if (modifiers != &modifier_invalid) {
free(modifiers);
@@ -439,10 +443,7 @@ static void linux_dmabuf_bind(struct wl_client *client, void *data,
wl_resource_set_implementation(resource, &linux_dmabuf_impl,
linux_dmabuf, linux_dmabuf_resource_destroy);
wl_list_insert(&linux_dmabuf->resources, wl_resource_get_link(resource));
-
- if (version >= ZWP_LINUX_DMABUF_V1_MODIFIER_SINCE_VERSION) {
- linux_dmabuf_send_modifiers(linux_dmabuf, resource);
- }
+ linux_dmabuf_send_formats(linux_dmabuf, resource, version);
}
void wlr_linux_dmabuf_v1_destroy(struct wlr_linux_dmabuf_v1 *linux_dmabuf) {
diff --git a/types/wlr_output_layout.c b/types/wlr_output_layout.c
index b51153ae..6ba856f8 100644
--- a/types/wlr_output_layout.c
+++ b/types/wlr_output_layout.c
@@ -204,6 +204,7 @@ void wlr_output_layout_add(struct wlr_output_layout *layout,
struct wlr_output *output, int lx, int ly) {
struct wlr_output_layout_output *l_output =
wlr_output_layout_get(layout, output);
+ bool is_new = l_output == NULL;
if (!l_output) {
l_output = output_layout_output_create(layout, output);
if (!l_output) {
@@ -211,12 +212,16 @@ void wlr_output_layout_add(struct wlr_output_layout *layout,
return;
}
}
+
l_output->x = lx;
l_output->y = ly;
l_output->state->auto_configured = false;
output_layout_reconfigure(layout);
output_update_global(output);
- wlr_signal_emit_safe(&layout->events.add, l_output);
+
+ if (is_new) {
+ wlr_signal_emit_safe(&layout->events.add, l_output);
+ }
}
struct wlr_output_layout_output *wlr_output_layout_get(
@@ -409,6 +414,7 @@ void wlr_output_layout_add_auto(struct wlr_output_layout *layout,
struct wlr_output *output) {
struct wlr_output_layout_output *l_output =
wlr_output_layout_get(layout, output);
+ bool is_new = l_output == NULL;
if (!l_output) {
l_output = output_layout_output_create(layout, output);
if (!l_output) {
@@ -420,7 +426,10 @@ void wlr_output_layout_add_auto(struct wlr_output_layout *layout,
l_output->state->auto_configured = true;
output_layout_reconfigure(layout);
output_update_global(output);
- wlr_signal_emit_safe(&layout->events.add, l_output);
+
+ if (is_new) {
+ wlr_signal_emit_safe(&layout->events.add, l_output);
+ }
}
struct wlr_output *wlr_output_layout_get_center_output(
diff --git a/types/wlr_text_input_v3.c b/types/wlr_text_input_v3.c
index 52c0fcc9..6ec0762a 100644
--- a/types/wlr_text_input_v3.c
+++ b/types/wlr_text_input_v3.c
@@ -175,11 +175,10 @@ static void text_input_commit(struct wl_client *client,
text_input->current_enabled = text_input->pending_enabled;
text_input->current_serial++;
- if (text_input->current_enabled && text_input->focused_surface == NULL) {
- wl_resource_post_error(text_input->resource, 0, "Text input was not"
- "entered, and cannot be enabled\n");
- return;
+ if (text_input->focused_surface == NULL) {
+ wlr_log(WLR_DEBUG, "Text input commit received without focus\n");
}
+
if (!old_enabled && text_input->current_enabled) {
wlr_signal_emit_safe(&text_input->events.enable, text_input);
} else if (old_enabled && !text_input->current_enabled) {
diff --git a/xwayland/xwm.c b/xwayland/xwm.c
index fce61f6b..8c1777b7 100644
--- a/xwayland/xwm.c
+++ b/xwayland/xwm.c
@@ -313,6 +313,7 @@ static void xwayland_surface_destroy(
wl_list_for_each_safe(child, next, &xsurface->children, parent_link) {
wl_list_remove(&child->parent_link);
wl_list_init(&child->parent_link);
+ child->parent = NULL;
}
if (xsurface->surface_id) {
@@ -803,8 +804,6 @@ static void xwm_handle_destroy_notify(struct wlr_xwm *xwm,
static void xwm_handle_configure_request(struct wlr_xwm *xwm,
xcb_configure_request_event_t *ev) {
- wlr_log(WLR_DEBUG, "XCB_CONFIGURE_REQUEST (%u) [%ux%u+%d,%d]", ev->window,
- ev->width, ev->height, ev->x, ev->y);
struct wlr_xwayland_surface *surface = lookup_surface(xwm, ev->window);
if (surface == NULL) {
return;
@@ -812,13 +811,22 @@ static void xwm_handle_configure_request(struct wlr_xwm *xwm,
// TODO: handle ev->{parent,sibling}?
+ uint16_t mask = ev->value_mask;
+ uint16_t geo_mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y |
+ XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
+ if ((mask & geo_mask) == 0) {
+ return;
+ }
+
struct wlr_xwayland_surface_configure_event wlr_event = {
.surface = surface,
- .x = ev->x,
- .y = ev->y,
- .width = ev->width,
- .height = ev->height,
+ .x = mask & XCB_CONFIG_WINDOW_X ? ev->x : surface->x,
+ .y = mask & XCB_CONFIG_WINDOW_Y ? ev->y : surface->y,
+ .width = mask & XCB_CONFIG_WINDOW_WIDTH ? ev->width : surface->width,
+ .height = mask & XCB_CONFIG_WINDOW_HEIGHT ? ev->height : surface->height,
};
+ wlr_log(WLR_DEBUG, "XCB_CONFIGURE_REQUEST (%u) [%ux%u+%d,%d]", ev->window,
+ wlr_event.width, wlr_event.height, wlr_event.x, wlr_event.y);
wlr_signal_emit_safe(&surface->events.request_configure, &wlr_event);
}