зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1705877 - Add support for scaled cursors on GTK. r=stransky
I had overlooked the way to achieve this. This is possible using cairo surfaces, but they only support integer scale factors, so we ceil and potentially rasterize the image to a bigger size if needed. Differential Revision: https://phabricator.services.mozilla.com/D112477
This commit is contained in:
Родитель
cea51c8354
Коммит
6a5a33b978
|
@ -515,16 +515,8 @@ static void LoadWidgetIconPixbuf(GtkWidget* aWidgetIcon) {
|
|||
gtk_icon_size_lookup(gtkIconSize, &iconWidth, &iconHeight);
|
||||
|
||||
/* Those are available since Gtk+ 3.10 as well as GtkHeaderBar */
|
||||
static auto sGtkIconThemeLookupIconForScalePtr =
|
||||
(GtkIconInfo *
|
||||
(*)(GtkIconTheme*, const gchar*, gint, gint, GtkIconLookupFlags))
|
||||
dlsym(RTLD_DEFAULT, "gtk_icon_theme_lookup_icon_for_scale");
|
||||
static auto sGdkCairoSurfaceCreateFromPixbufPtr =
|
||||
(cairo_surface_t * (*)(const GdkPixbuf*, int, GdkWindow*))
|
||||
dlsym(RTLD_DEFAULT, "gdk_cairo_surface_create_from_pixbuf");
|
||||
|
||||
for (int scale = 1; scale < ICON_SCALE_VARIANTS + 1; scale++) {
|
||||
GtkIconInfo* gtkIconInfo = sGtkIconThemeLookupIconForScalePtr(
|
||||
GtkIconInfo* gtkIconInfo = gtk_icon_theme_lookup_icon_for_scale(
|
||||
gtk_icon_theme_get_default(), iconName, iconWidth, scale,
|
||||
(GtkIconLookupFlags)0);
|
||||
|
||||
|
@ -539,7 +531,7 @@ static void LoadWidgetIconPixbuf(GtkWidget* aWidgetIcon) {
|
|||
g_object_unref(G_OBJECT(gtkIconInfo));
|
||||
|
||||
cairo_surface_t* iconSurface =
|
||||
sGdkCairoSurfaceCreateFromPixbufPtr(iconPixbuf, scale, nullptr);
|
||||
gdk_cairo_surface_create_from_pixbuf(iconPixbuf, scale, nullptr);
|
||||
g_object_unref(iconPixbuf);
|
||||
|
||||
nsAutoCString surfaceName;
|
||||
|
|
|
@ -2388,18 +2388,11 @@ static GdkCursor* GetCursorForImage(const nsIWidget::Cursor& aCursor) {
|
|||
if (!aCursor.IsCustom()) {
|
||||
return nullptr;
|
||||
}
|
||||
// FIXME: GTK doesn't provide an API for custom cursors that have more than
|
||||
// native resolution, so this will scale the image instead, which is slightly
|
||||
// unfortunate.
|
||||
nsIntSize size = nsIWidget::CustomCursorSize(aCursor);
|
||||
GdkPixbuf* pixbuf =
|
||||
nsImageToPixbuf::ImageToPixbuf(aCursor.mContainer, Some(size));
|
||||
if (!pixbuf) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto CleanupPixBuf =
|
||||
mozilla::MakeScopeExit([&]() { g_object_unref(pixbuf); });
|
||||
// NOTE: GTK only allows integer scale factors, so we ceil to the closest
|
||||
// scale factor and then tell gtk to scale it down.
|
||||
int32_t gtkScale = std::ceil(aCursor.mResolution);
|
||||
|
||||
// Reject cursors greater than 128 pixels in some direction, to prevent
|
||||
// spoofing.
|
||||
|
@ -2412,6 +2405,13 @@ static GdkCursor* GetCursorForImage(const nsIWidget::Cursor& aCursor) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
nsIntSize rasterSize = size * gtkScale;
|
||||
GdkPixbuf* pixbuf =
|
||||
nsImageToPixbuf::ImageToPixbuf(aCursor.mContainer, Some(rasterSize));
|
||||
if (!pixbuf) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Looks like all cursors need an alpha channel (tested on Gtk 2.4.4). This
|
||||
// is of course not documented anywhere...
|
||||
// So add one if there isn't one yet
|
||||
|
@ -2424,7 +2424,19 @@ static GdkCursor* GetCursorForImage(const nsIWidget::Cursor& aCursor) {
|
|||
}
|
||||
}
|
||||
|
||||
return gdk_cursor_new_from_pixbuf(gdk_display_get_default(), pixbuf,
|
||||
auto CleanupPixBuf =
|
||||
mozilla::MakeScopeExit([&]() { g_object_unref(pixbuf); });
|
||||
|
||||
cairo_surface_t* surface =
|
||||
gdk_cairo_surface_create_from_pixbuf(pixbuf, gtkScale, nullptr);
|
||||
if (!surface) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto CleanupSurface =
|
||||
mozilla::MakeScopeExit([&]() { cairo_surface_destroy(surface); });
|
||||
|
||||
return gdk_cursor_new_from_surface(gdk_display_get_default(), surface,
|
||||
aCursor.mHotspotX, aCursor.mHotspotY);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче