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
path: root/intern
diff options
context:
space:
mode:
authorCampbell Barton <campbell@blender.org>2022-07-09 15:27:34 +0300
committerCampbell Barton <campbell@blender.org>2022-07-09 15:46:53 +0300
commit443690604f4ed5bdcf05cca40c8d6f1f88a1c29a (patch)
treee9f3f129112b4df4dc9ac4e7a296e2e88741d10d /intern
parent1de14061cbe33dd39ee48c65b609d550cac157ca (diff)
Fix cursor display size with tablet input in GHOST/Wayland
The scale for tablet cursor surfaces was never set, making them display larger. Now the outputs scale is set for mouse & tablet cursors.
Diffstat (limited to 'intern')
-rw-r--r--intern/ghost/intern/GHOST_SystemWayland.cpp191
-rw-r--r--intern/ghost/intern/GHOST_SystemWayland.h6
2 files changed, 133 insertions, 64 deletions
diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp
index 4b390615435..876f77732c2 100644
--- a/intern/ghost/intern/GHOST_SystemWayland.cpp
+++ b/intern/ghost/intern/GHOST_SystemWayland.cpp
@@ -146,10 +146,7 @@ struct cursor_t {
size_t custom_data_size = 0;
int size = 0;
std::string theme_name;
- /** Outputs on which the cursor is visible. */
- std::unordered_set<const output_t *> outputs;
- int theme_scale = 1;
int custom_scale = 1;
};
@@ -231,6 +228,11 @@ struct input_state_pointer_t {
*/
wl_fixed_t xy[2] = {0, 0};
+ /** Outputs on which the cursor is visible. */
+ std::unordered_set<const output_t *> outputs;
+
+ int theme_scale = 1;
+
/** The serial of the last used pointer or tablet. */
uint32_t serial = 0;
@@ -396,6 +398,19 @@ static input_state_pointer_t *input_state_pointer_active(input_t *input)
return nullptr;
}
+static input_state_pointer_t *input_state_pointer_from_cursor_surface(input_t *input,
+ const wl_surface *wl_surface)
+{
+ if (ghost_wl_surface_own_cursor_pointer(wl_surface)) {
+ return &input->pointer;
+ }
+ if (ghost_wl_surface_own_cursor_tablet(wl_surface)) {
+ return &input->tablet;
+ }
+ GHOST_ASSERT(0, "Surface found without pointer/tablet tag");
+ return nullptr;
+}
+
static void display_destroy(display_t *d)
{
if (d->data_device_manager) {
@@ -1358,19 +1373,22 @@ static const struct wl_buffer_listener cursor_buffer_listener = {
static CLG_LogRef LOG_WL_CURSOR_SURFACE = {"ghost.wl.handle.cursor_surface"};
#define LOG (&LOG_WL_CURSOR_SURFACE)
-static bool update_cursor_scale(cursor_t &cursor, wl_shm *shm)
+static bool update_cursor_scale(cursor_t &cursor,
+ wl_shm *shm,
+ input_state_pointer_t *input_state,
+ wl_surface *cursor_surface)
{
int scale = 0;
- for (const output_t *output : cursor.outputs) {
+ for (const output_t *output : input_state->outputs) {
if (output->scale > scale) {
scale = output->scale;
}
}
- if (scale > 0 && cursor.theme_scale != scale) {
- cursor.theme_scale = scale;
+ if (scale > 0 && input_state->theme_scale != scale) {
+ input_state->theme_scale = scale;
if (!cursor.is_custom) {
- wl_surface_set_buffer_scale(cursor.wl_surface, scale);
+ wl_surface_set_buffer_scale(cursor_surface, scale);
}
wl_cursor_theme_destroy(cursor.wl_theme);
cursor.wl_theme = wl_cursor_theme_load(cursor.theme_name.c_str(), scale * cursor.size, shm);
@@ -1380,7 +1398,7 @@ static bool update_cursor_scale(cursor_t &cursor, wl_shm *shm)
}
static void cursor_surface_handle_enter(void *data,
- struct wl_surface * /*wl_surface*/,
+ struct wl_surface *wl_surface,
struct wl_output *output)
{
if (!ghost_wl_output_own(output)) {
@@ -1390,13 +1408,14 @@ static void cursor_surface_handle_enter(void *data,
CLOG_INFO(LOG, 2, "handle_enter");
input_t *input = static_cast<input_t *>(data);
+ input_state_pointer_t *input_state = input_state_pointer_from_cursor_surface(input, wl_surface);
const output_t *reg_output = ghost_wl_output_user_data(output);
- input->cursor.outputs.insert(reg_output);
- update_cursor_scale(input->cursor, input->system->shm());
+ input_state->outputs.insert(reg_output);
+ update_cursor_scale(input->cursor, input->system->shm(), input_state, wl_surface);
}
static void cursor_surface_handle_leave(void *data,
- struct wl_surface * /*wl_surface*/,
+ struct wl_surface *wl_surface,
struct wl_output *output)
{
if (!(output && ghost_wl_output_own(output))) {
@@ -1406,9 +1425,10 @@ static void cursor_surface_handle_leave(void *data,
CLOG_INFO(LOG, 2, "handle_leave");
input_t *input = static_cast<input_t *>(data);
+ input_state_pointer_t *input_state = input_state_pointer_from_cursor_surface(input, wl_surface);
const output_t *reg_output = ghost_wl_output_user_data(output);
- input->cursor.outputs.erase(reg_output);
- update_cursor_scale(input->cursor, input->system->shm());
+ input_state->outputs.erase(reg_output);
+ update_cursor_scale(input->cursor, input->system->shm(), input_state, wl_surface);
}
static const struct wl_surface_listener cursor_surface_listener = {
@@ -1952,6 +1972,8 @@ static void tablet_seat_handle_tool_added(void *data,
/* Every tool has it's own cursor surface. */
tool_input->cursor_surface = wl_compositor_create_surface(input->system->compositor());
+ ghost_wl_surface_tag_cursor_tablet(tool_input->cursor_surface);
+
wl_surface_add_listener(tool_input->cursor_surface, &cursor_surface_listener, (void *)input);
zwp_tablet_tool_v2_add_listener(id, &tablet_tool_listner, tool_input);
@@ -2360,7 +2382,9 @@ static void seat_handle_capabilities(void *data,
input->cursor.size = default_cursor_size;
}
wl_pointer_add_listener(input->wl_pointer, &pointer_listener, data);
+
wl_surface_add_listener(input->cursor.wl_surface, &cursor_surface_listener, data);
+ ghost_wl_surface_tag_cursor_pointer(input->cursor.wl_surface);
}
if (capabilities & WL_SEAT_CAPABILITY_KEYBOARD) {
@@ -3211,19 +3235,30 @@ GHOST_IWindow *GHOST_SystemWayland::createWindow(const char *title,
static void cursor_buffer_show(const input_t *input)
{
const cursor_t *c = &input->cursor;
- const int scale = c->is_custom ? c->custom_scale : c->theme_scale;
- const int32_t hotspot_x = int32_t(c->wl_image.hotspot_x) / scale;
- const int32_t hotspot_y = int32_t(c->wl_image.hotspot_y) / scale;
- wl_pointer_set_cursor(
- input->wl_pointer, input->pointer.serial, c->wl_surface, hotspot_x, hotspot_y);
- for (struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2 : input->tablet_tools) {
- tablet_tool_input_t *tool_input = static_cast<tablet_tool_input_t *>(
- zwp_tablet_tool_v2_get_user_data(zwp_tablet_tool_v2));
- zwp_tablet_tool_v2_set_cursor(zwp_tablet_tool_v2,
- input->tablet.serial,
- tool_input->cursor_surface,
- hotspot_x,
- hotspot_y);
+
+ if (input->wl_pointer) {
+ const int scale = c->is_custom ? c->custom_scale : input->pointer.theme_scale;
+ const int32_t hotspot_x = int32_t(c->wl_image.hotspot_x) / scale;
+ const int32_t hotspot_y = int32_t(c->wl_image.hotspot_y) / scale;
+ if (input->wl_pointer) {
+ wl_pointer_set_cursor(
+ input->wl_pointer, input->pointer.serial, c->wl_surface, hotspot_x, hotspot_y);
+ }
+ }
+
+ if (!input->tablet_tools.empty()) {
+ const int scale = c->is_custom ? c->custom_scale : input->tablet.theme_scale;
+ const int32_t hotspot_x = int32_t(c->wl_image.hotspot_x) / scale;
+ const int32_t hotspot_y = int32_t(c->wl_image.hotspot_y) / scale;
+ for (struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2 : input->tablet_tools) {
+ tablet_tool_input_t *tool_input = static_cast<tablet_tool_input_t *>(
+ zwp_tablet_tool_v2_get_user_data(zwp_tablet_tool_v2));
+ zwp_tablet_tool_v2_set_cursor(zwp_tablet_tool_v2,
+ input->tablet.serial,
+ tool_input->cursor_surface,
+ hotspot_x,
+ hotspot_y);
+ }
}
}
@@ -3241,52 +3276,58 @@ static void cursor_buffer_hide(const input_t *input)
}
}
+static void cursor_buffer_set_surface_impl(const input_t *input,
+ wl_buffer *buffer,
+ struct wl_surface *wl_surface,
+ const int scale)
+{
+ const wl_cursor_image *wl_image = &input->cursor.wl_image;
+ const int32_t image_size_x = int32_t(wl_image->width);
+ const int32_t image_size_y = int32_t(wl_image->height);
+ GHOST_ASSERT((image_size_x % scale) == 0 && (image_size_y % scale) == 0,
+ "The size must be a multiple of the scale!");
+
+ wl_surface_set_buffer_scale(wl_surface, scale);
+ wl_surface_attach(wl_surface, buffer, 0, 0);
+ wl_surface_damage(wl_surface, 0, 0, image_size_x, image_size_y);
+ wl_surface_commit(wl_surface);
+}
+
static void cursor_buffer_set(const input_t *input, wl_buffer *buffer)
{
const cursor_t *c = &input->cursor;
- const int scale = c->is_custom ? c->custom_scale : c->theme_scale;
-
+ const wl_cursor_image *wl_image = &input->cursor.wl_image;
const bool visible = (c->visible && c->is_hardware);
- const int32_t image_size_x = int32_t(c->wl_image.width);
- const int32_t image_size_y = int32_t(c->wl_image.height);
-
/* This is a requirement of WAYLAND, when this isn't the case,
* it causes Blender's window to close intermittently. */
- GHOST_ASSERT((image_size_x % scale) == 0 && (image_size_y % scale) == 0,
- "The size must be a multiple of the scale!");
-
- const int32_t hotspot_x = int32_t(c->wl_image.hotspot_x) / scale;
- const int32_t hotspot_y = int32_t(c->wl_image.hotspot_y) / scale;
-
- wl_surface_set_buffer_scale(c->wl_surface, scale);
- wl_surface_attach(c->wl_surface, buffer, 0, 0);
- wl_surface_damage(c->wl_surface, 0, 0, image_size_x, image_size_y);
- wl_surface_commit(c->wl_surface);
-
- wl_pointer_set_cursor(input->wl_pointer,
- input->pointer.serial,
- visible ? c->wl_surface : nullptr,
- hotspot_x,
- hotspot_y);
+ if (input->wl_pointer) {
+ const int scale = c->is_custom ? c->custom_scale : input->pointer.theme_scale;
+ const int32_t hotspot_x = int32_t(wl_image->hotspot_x) / scale;
+ const int32_t hotspot_y = int32_t(wl_image->hotspot_y) / scale;
+ cursor_buffer_set_surface_impl(input, buffer, c->wl_surface, scale);
+ wl_pointer_set_cursor(input->wl_pointer,
+ input->pointer.serial,
+ visible ? c->wl_surface : nullptr,
+ hotspot_x,
+ hotspot_y);
+ }
/* Set the cursor for all tablet tools as well. */
- for (struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2 : input->tablet_tools) {
- tablet_tool_input_t *tool_input = static_cast<tablet_tool_input_t *>(
- zwp_tablet_tool_v2_get_user_data(zwp_tablet_tool_v2));
-
- /* FIXME: for some reason cursor scale is applied twice (when the scale isn't 1x),
- * this happens both in gnome-shell & KDE. Setting the surface scale here doesn't help. */
- wl_surface_set_buffer_scale(tool_input->cursor_surface, scale);
- wl_surface_attach(tool_input->cursor_surface, buffer, 0, 0);
- wl_surface_damage(tool_input->cursor_surface, 0, 0, image_size_x, image_size_y);
- wl_surface_commit(tool_input->cursor_surface);
-
- zwp_tablet_tool_v2_set_cursor(zwp_tablet_tool_v2,
- input->tablet.serial,
- visible ? tool_input->cursor_surface : nullptr,
- hotspot_x,
- hotspot_y);
+ if (!input->tablet_tools.empty()) {
+ const int scale = c->is_custom ? c->custom_scale : input->tablet.theme_scale;
+ const int32_t hotspot_x = int32_t(wl_image->hotspot_x) / scale;
+ const int32_t hotspot_y = int32_t(wl_image->hotspot_y) / scale;
+ for (struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2 : input->tablet_tools) {
+ tablet_tool_input_t *tool_input = static_cast<tablet_tool_input_t *>(
+ zwp_tablet_tool_v2_get_user_data(zwp_tablet_tool_v2));
+ cursor_buffer_set_surface_impl(input, buffer, tool_input->cursor_surface, scale);
+ zwp_tablet_tool_v2_set_cursor(zwp_tablet_tool_v2,
+ input->tablet.serial,
+ visible ? tool_input->cursor_surface : nullptr,
+ hotspot_x,
+ hotspot_y);
+ }
}
}
@@ -3585,6 +3626,8 @@ static input_grab_state_t input_grab_state_from_mode(const GHOST_TGrabCursorMode
static const char *ghost_wl_output_tag_id = "GHOST-output";
static const char *ghost_wl_surface_tag_id = "GHOST-window";
+static const char *ghost_wl_surface_cursor_pointer_tag_id = "GHOST-cursor-pointer";
+static const char *ghost_wl_surface_cursor_tablet_tag_id = "GHOST-cursor-tablet";
bool ghost_wl_output_own(const struct wl_output *output)
{
@@ -3596,6 +3639,16 @@ bool ghost_wl_surface_own(const struct wl_surface *surface)
return wl_proxy_get_tag((struct wl_proxy *)surface) == &ghost_wl_surface_tag_id;
}
+bool ghost_wl_surface_own_cursor_pointer(const struct wl_surface *surface)
+{
+ return wl_proxy_get_tag((struct wl_proxy *)surface) == &ghost_wl_surface_cursor_pointer_tag_id;
+}
+
+bool ghost_wl_surface_own_cursor_tablet(const struct wl_surface *surface)
+{
+ return wl_proxy_get_tag((struct wl_proxy *)surface) == &ghost_wl_surface_cursor_tablet_tag_id;
+}
+
void ghost_wl_output_tag(struct wl_output *output)
{
wl_proxy_set_tag((struct wl_proxy *)output, &ghost_wl_output_tag_id);
@@ -3606,6 +3659,16 @@ void ghost_wl_surface_tag(struct wl_surface *surface)
wl_proxy_set_tag((struct wl_proxy *)surface, &ghost_wl_surface_tag_id);
}
+void ghost_wl_surface_tag_cursor_pointer(struct wl_surface *surface)
+{
+ wl_proxy_set_tag((struct wl_proxy *)surface, &ghost_wl_surface_cursor_pointer_tag_id);
+}
+
+void ghost_wl_surface_tag_cursor_tablet(struct wl_surface *surface)
+{
+ wl_proxy_set_tag((struct wl_proxy *)surface, &ghost_wl_surface_cursor_tablet_tag_id);
+}
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/intern/ghost/intern/GHOST_SystemWayland.h b/intern/ghost/intern/GHOST_SystemWayland.h
index 0d51759aa2f..bdf5f2fc273 100644
--- a/intern/ghost/intern/GHOST_SystemWayland.h
+++ b/intern/ghost/intern/GHOST_SystemWayland.h
@@ -41,6 +41,12 @@ bool ghost_wl_surface_own(const struct wl_surface *surface);
void ghost_wl_surface_tag(struct wl_surface *surface);
GHOST_WindowWayland *ghost_wl_surface_user_data(struct wl_surface *surface);
+bool ghost_wl_surface_own_cursor_pointer(const struct wl_surface *surface);
+void ghost_wl_surface_tag_cursor_pointer(struct wl_surface *surface);
+
+bool ghost_wl_surface_own_cursor_tablet(const struct wl_surface *surface);
+void ghost_wl_surface_tag_cursor_tablet(struct wl_surface *surface);
+
#ifdef WITH_GHOST_WAYLAND_DYNLOAD
/**
* Return true when all required WAYLAND libraries are present,