mirror of
https://github.com/brl/mutter.git
synced 2024-11-24 17:10:40 -05:00
cursor-sprite-xcursor: Emulate Wayland hotspot limitations
For HiDPI pointer cursors backed by Wayland surfaces, the hotspot must be placed using integers on the logical pixel grid. In practice what this means is that if the client loads a cursor sprite with the buffer scale 2, and it's hotspot is not dividable by 2, it will be rounded down to an integer that can. E.g. a wl_surface with buffer scale 2 and a cursor image with hotspot coordinate (7, 7) will have the coordinate (3.5, 3.5) in surface coordinate space, and will in practice be rounded down to (3, 3) as the hotspot position in wl_pointer only takes integers. To not potentially shift by 1 pixel on HiDPI monitors when switching between wl_surface backend cursor sprites and built-in ones, make the built in one emulate the restrictions put up by the Wayland protocol. This also initializes the theme scale of the xcursor sprite instances to 1, as they may not have been set prior to being used, it'll only happen in response to "prepare-at" signals being emitted prior to rendering. Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/1092 https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1107
This commit is contained in:
parent
8beef8ccd0
commit
40c345d6f3
@ -25,6 +25,7 @@
|
|||||||
#include "clutter/clutter.h"
|
#include "clutter/clutter.h"
|
||||||
#include "cogl/cogl.h"
|
#include "cogl/cogl.h"
|
||||||
#include "meta/prefs.h"
|
#include "meta/prefs.h"
|
||||||
|
#include "meta/util.h"
|
||||||
|
|
||||||
struct _MetaCursorSpriteXcursor
|
struct _MetaCursorSpriteXcursor
|
||||||
{
|
{
|
||||||
@ -124,6 +125,7 @@ load_from_current_xcursor_image (MetaCursorSpriteXcursor *sprite_xcursor)
|
|||||||
CoglContext *cogl_context;
|
CoglContext *cogl_context;
|
||||||
CoglTexture2D *texture;
|
CoglTexture2D *texture;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
int hotspot_x, hotspot_y;
|
||||||
|
|
||||||
g_assert (!meta_cursor_sprite_get_cogl_texture (sprite));
|
g_assert (!meta_cursor_sprite_get_cogl_texture (sprite));
|
||||||
|
|
||||||
@ -152,9 +154,21 @@ load_from_current_xcursor_image (MetaCursorSpriteXcursor *sprite_xcursor)
|
|||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (meta_is_wayland_compositor ())
|
||||||
|
{
|
||||||
|
hotspot_x = ((int) (xc_image->xhot / sprite_xcursor->theme_scale) *
|
||||||
|
sprite_xcursor->theme_scale);
|
||||||
|
hotspot_y = ((int) (xc_image->yhot / sprite_xcursor->theme_scale) *
|
||||||
|
sprite_xcursor->theme_scale);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hotspot_x = xc_image->xhot;
|
||||||
|
hotspot_y = xc_image->yhot;
|
||||||
|
}
|
||||||
meta_cursor_sprite_set_texture (sprite,
|
meta_cursor_sprite_set_texture (sprite,
|
||||||
COGL_TEXTURE (texture),
|
COGL_TEXTURE (texture),
|
||||||
xc_image->xhot, xc_image->yhot);
|
hotspot_x, hotspot_y);
|
||||||
|
|
||||||
g_clear_pointer (&texture, cogl_object_unref);
|
g_clear_pointer (&texture, cogl_object_unref);
|
||||||
}
|
}
|
||||||
@ -272,6 +286,7 @@ meta_cursor_sprite_xcursor_finalize (GObject *object)
|
|||||||
static void
|
static void
|
||||||
meta_cursor_sprite_xcursor_init (MetaCursorSpriteXcursor *sprite_xcursor)
|
meta_cursor_sprite_xcursor_init (MetaCursorSpriteXcursor *sprite_xcursor)
|
||||||
{
|
{
|
||||||
|
sprite_xcursor->theme_scale = 1;
|
||||||
sprite_xcursor->theme_dirty = TRUE;
|
sprite_xcursor->theme_dirty = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user