Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <campbell@blender.org>2022-06-10 09:32:22 +0300
committerCampbell Barton <campbell@blender.org>2022-06-10 11:36:10 +0300
commit00aa57594c74c69d53ba326e48d2d1339ab99b75 (patch)
treeadcf870d1c52930975858b92afe0e568606a8c2d
parent178c18482546ba7a9e8c7bfdf2164ef6c5993d1a (diff)
Fix dropping files in Wayland
There were two problems dropping files into blender: - The inputs `focus_pointer` was NULL, causing a crash. - The wl_data_device_manager version was set to 1, causing the Blender window to close (when dropping files in gnome-shell 42). Resolve by storing the drop surface separately from the pointer surface and bump the device manager version to 3.
-rw-r--r--intern/ghost/intern/GHOST_SystemWayland.cpp21
1 files changed, 15 insertions, 6 deletions
diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp
index c446963c082..b9696ab6354 100644
--- a/intern/ghost/intern/GHOST_SystemWayland.cpp
+++ b/intern/ghost/intern/GHOST_SystemWayland.cpp
@@ -38,6 +38,8 @@
#include <cstring>
+static GHOST_IWindow *get_window(struct wl_surface *surface);
+
/* -------------------------------------------------------------------- */
/** \name Private Types & Defines
* \{ */
@@ -131,6 +133,7 @@ struct input_t {
struct wl_surface *focus_pointer = nullptr;
struct wl_surface *focus_keyboard = nullptr;
+ struct wl_surface *focus_dnd = nullptr;
struct wl_data_device *data_device = nullptr;
/** Drag & Drop. */
@@ -508,7 +511,7 @@ static void dnd_events(const input_t *const input, const GHOST_TEventType event)
{
const uint64_t time = input->system->getMilliSeconds();
GHOST_IWindow *const window = static_cast<GHOST_WindowWayland *>(
- wl_surface_get_user_data(input->focus_pointer));
+ wl_surface_get_user_data(input->focus_dnd));
for (const std::string &type : mime_preference_order) {
input->system->pushEvent(new GHOST_EventDragnDrop(time,
event,
@@ -670,7 +673,7 @@ static void data_device_data_offer(void * /*data*/,
static void data_device_enter(void *data,
struct wl_data_device * /*wl_data_device*/,
uint32_t serial,
- struct wl_surface * /*surface*/,
+ struct wl_surface *surface,
wl_fixed_t x,
wl_fixed_t y,
struct wl_data_offer *id)
@@ -692,6 +695,7 @@ static void data_device_enter(void *data,
wl_data_offer_accept(id, serial, type.c_str());
}
+ input->focus_dnd = surface;
dnd_events(input, GHOST_kEventDraggingEntered);
}
@@ -700,6 +704,7 @@ static void data_device_leave(void *data, struct wl_data_device * /*wl_data_devi
input_t *input = static_cast<input_t *>(data);
dnd_events(input, GHOST_kEventDraggingExited);
+ input->focus_dnd = nullptr;
if (input->data_offer_dnd && !input->data_offer_dnd->in_use.load()) {
wl_data_offer_destroy(input->data_offer_dnd->id);
@@ -732,6 +737,7 @@ static void data_device_drop(void *data, struct wl_data_device * /*wl_data_devic
auto read_uris = [](input_t *const input,
data_offer_t *data_offer,
+ wl_surface *surface,
const std::string mime_receive) {
const int x = data_offer->dnd.x;
const int y = data_offer->dnd.y;
@@ -750,6 +756,9 @@ static void data_device_drop(void *data, struct wl_data_device * /*wl_data_devic
static constexpr const char *file_proto = "file://";
static constexpr const char *crlf = "\r\n";
+ GHOST_WindowWayland *win = static_cast<GHOST_WindowWayland *>(get_window(surface));
+ GHOST_ASSERT(win != nullptr, "Unable to find window for drop event from surface");
+
std::vector<std::string> uris;
size_t pos = 0;
@@ -773,8 +782,6 @@ static void data_device_drop(void *data, struct wl_data_device * /*wl_data_devic
flist->strings[i] = static_cast<uint8_t *>(malloc((uris[i].size() + 1) * sizeof(uint8_t)));
memcpy(flist->strings[i], uris[i].data(), uris[i].size() + 1);
}
- GHOST_IWindow *win = static_cast<GHOST_WindowWayland *>(
- wl_surface_get_user_data(input->focus_pointer));
system->pushEvent(new GHOST_EventDragnDrop(system->getMilliSeconds(),
GHOST_kEventDraggingDropDone,
GHOST_kDragnDropTypeFilenames,
@@ -790,7 +797,9 @@ static void data_device_drop(void *data, struct wl_data_device * /*wl_data_devic
wl_display_roundtrip(system->display());
};
- std::thread read_thread(read_uris, input, data_offer, mime_receive);
+ /* Pass in `input->focus_dnd` instead of accessing it from `input` since the leave callback
+ * (#data_device_leave) will clear the value once this function starts. */
+ std::thread read_thread(read_uris, input, data_offer, input->focus_dnd, mime_receive);
read_thread.detach();
}
@@ -1480,7 +1489,7 @@ static void global_add(void *data,
}
else if (!strcmp(interface, wl_data_device_manager_interface.name)) {
display->data_device_manager = static_cast<wl_data_device_manager *>(
- wl_registry_bind(wl_registry, name, &wl_data_device_manager_interface, 1));
+ wl_registry_bind(wl_registry, name, &wl_data_device_manager_interface, 3));
}
else if (!strcmp(interface, zwp_relative_pointer_manager_v1_interface.name)) {
display->relative_pointer_manager = static_cast<zwp_relative_pointer_manager_v1 *>(