Compare commits
60 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 42306022a0 | |||
| 0c990645de | |||
| daaf2a0d0f | |||
| 17e8846bf9 | |||
| e70de7a1c6 | |||
| a35db35996 | |||
| 2d850b0d03 | |||
| e08285fc78 | |||
| 0b06e2029c | |||
| 29463e9ea9 | |||
| 86a5f2c30e | |||
| 0ed5dbf9c4 | |||
| 3563bdcce7 | |||
| 8e6eb0da22 | |||
| 1e31befc1a | |||
| d22dbf7648 | |||
| 4e45126834 | |||
| 536a6676cb | |||
| a0fb6c8360 | |||
| 8e89015f4d | |||
| cdabe7db91 | |||
| 681a6ad229 | |||
| c3cf2df07f | |||
| dbcfc1f66e | |||
| 0f837618ed | |||
| 339d4ef757 | |||
| d36bc524da | |||
| bdc3343a88 | |||
| bcde0f387d | |||
| b5a5bd0717 | |||
| 3d2041524c | |||
| d5f56fcb8f | |||
| a5411cbe98 | |||
| 721c384f4f | |||
| c00611ca32 | |||
| a5698f6c06 | |||
| afb8f614f4 | |||
| 98481e95aa | |||
| b85c053e28 | |||
| 338f959bb5 | |||
| c3807bb122 | |||
| a6e4f5f0c4 | |||
| c64b269019 | |||
| a543702beb | |||
| d9abadbcee | |||
| e1ed8b50de | |||
| 04e4814f4f | |||
| a15998db18 | |||
| 42342d73b5 | |||
| 25e9052610 | |||
| 790f0cee51 | |||
| 26722dc1cb | |||
| 78b774cc8e | |||
| a95578e9e1 | |||
| d7abaae7bc | |||
| bb7e83399b | |||
| 6a98703c9a | |||
| 5931818450 | |||
| 7c34f6221f | |||
| 52d320e1a2 |
+12
-1
@@ -402,7 +402,7 @@ if test "x$enable_wayland_backend" = "xyes"; then
|
||||
GDK_WINDOWING="$GDK_WINDOWING
|
||||
#define GDK_WINDOWING_WAYLAND"
|
||||
DISABLE_ON_WAYLAND='%'
|
||||
WAYLAND_PACKAGES="wayland-client >= 1.0.0 xkbcommon >= 0.2.0 wayland-cursor"
|
||||
WAYLAND_PACKAGES="wayland-client >= 1.1.90 xkbcommon >= 0.2.0 wayland-cursor"
|
||||
AM_CONDITIONAL(USE_WAYLAND, true)
|
||||
else
|
||||
AM_CONDITIONAL(USE_WAYLAND, false)
|
||||
@@ -1263,6 +1263,17 @@ else
|
||||
LIBS="$gtk_save_LIBS"
|
||||
fi
|
||||
|
||||
# Check for cairo_set_device_scale, as we don't want to depend hard on
|
||||
# this until there is a stable release with it
|
||||
CAIRO_CFLAGS=`$PKG_CONFIG --cflags cairo`
|
||||
CAIRO_LIBS=`$PKG_CONFIG --libs cairo`
|
||||
CFLAGS="$CFLAGS $CAIRO_CFLAGS"
|
||||
gtk_save_LIBS="$LIBS"
|
||||
LIBS="$CAIRO_LIBS $LIBS"
|
||||
AC_CHECK_FUNCS(cairo_surface_set_device_scale)
|
||||
LIBS="$gtk_save_LIBS"
|
||||
|
||||
|
||||
CFLAGS="$saved_cflags"
|
||||
LDFLAGS="$saved_ldflags"
|
||||
|
||||
|
||||
@@ -119,6 +119,8 @@ RESOURCES= $(demos) \
|
||||
listbox.ui \
|
||||
alphatest.png \
|
||||
apple-red.png \
|
||||
brick.png \
|
||||
brick2.png \
|
||||
background.jpg \
|
||||
floppybuddy.gif \
|
||||
gnome-applets.png \
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 4.9 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
@@ -117,7 +117,7 @@ do_css_multiplebgs (GtkWidget *do_widget)
|
||||
gtk_widget_set_name (child, "bricks-button");
|
||||
gtk_widget_set_halign (child, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (child, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_size_request (child, 200, 80);
|
||||
gtk_widget_set_size_request (child, 250, 84);
|
||||
|
||||
paned = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (container), paned);
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
/*
|
||||
#bricks-button {
|
||||
background-color: #eef;
|
||||
background-image: url('resource:///css_multiplebgs/brick.png');
|
||||
background-image: -gtk-scaled(url('resource:///css_multiplebgs/brick.png'),url('resource:///css_multiplebgs/brick2.png'));
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
<gresource prefix="/css_multiplebgs">
|
||||
<file>css_multiplebgs.css</file>
|
||||
<file>brick.png</file>
|
||||
<file>brick2.png</file>
|
||||
<file>cssview.css</file>
|
||||
<file>reset.css</file>
|
||||
</gresource>
|
||||
|
||||
@@ -38,16 +38,16 @@ static void gdk_broadway_device_set_window_cursor (GdkDevice *device,
|
||||
GdkCursor *cursor);
|
||||
static void gdk_broadway_device_warp (GdkDevice *device,
|
||||
GdkScreen *screen,
|
||||
gint x,
|
||||
gint y);
|
||||
gdouble x,
|
||||
gdouble y);
|
||||
static void gdk_broadway_device_query_state (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
GdkWindow **root_window,
|
||||
GdkWindow **child_window,
|
||||
gint *root_x,
|
||||
gint *root_y,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *root_x,
|
||||
gdouble *root_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask);
|
||||
static GdkGrabStatus gdk_broadway_device_grab (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
@@ -59,8 +59,8 @@ static GdkGrabStatus gdk_broadway_device_grab (GdkDevice *device,
|
||||
static void gdk_broadway_device_ungrab (GdkDevice *device,
|
||||
guint32 time_);
|
||||
static GdkWindow * gdk_broadway_device_window_at_position (GdkDevice *device,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask,
|
||||
gboolean get_toplevel);
|
||||
static void gdk_broadway_device_select_window_events (GdkDevice *device,
|
||||
@@ -114,14 +114,14 @@ gdk_broadway_device_get_state (GdkDevice *device,
|
||||
gdouble *axes,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
gint x_int, y_int;
|
||||
gdouble x, y;
|
||||
|
||||
gdk_window_get_device_position (window, device, &x_int, &y_int, mask);
|
||||
gdk_window_get_device_position_double (window, device, &x, &y, mask);
|
||||
|
||||
if (axes)
|
||||
{
|
||||
axes[0] = x_int;
|
||||
axes[1] = y_int;
|
||||
axes[0] = x;
|
||||
axes[1] = y;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,8 +135,8 @@ gdk_broadway_device_set_window_cursor (GdkDevice *device,
|
||||
static void
|
||||
gdk_broadway_device_warp (GdkDevice *device,
|
||||
GdkScreen *screen,
|
||||
gint x,
|
||||
gint y)
|
||||
gdouble x,
|
||||
gdouble y)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -145,10 +145,10 @@ gdk_broadway_device_query_state (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
GdkWindow **root_window,
|
||||
GdkWindow **child_window,
|
||||
gint *root_x,
|
||||
gint *root_y,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *root_x,
|
||||
gdouble *root_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
GdkWindow *toplevel;
|
||||
@@ -335,8 +335,8 @@ gdk_broadway_device_ungrab (GdkDevice *device,
|
||||
|
||||
static GdkWindow *
|
||||
gdk_broadway_device_window_at_position (GdkDevice *device,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask,
|
||||
gboolean get_toplevel)
|
||||
{
|
||||
|
||||
@@ -750,8 +750,8 @@ gdk_broadway_window_get_frame_extents (GdkWindow *window,
|
||||
static gboolean
|
||||
gdk_window_broadway_get_device_state (GdkWindow *window,
|
||||
GdkDevice *device,
|
||||
gint *x,
|
||||
gint *y,
|
||||
gdouble *x,
|
||||
gdouble *y,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
GdkWindow *child;
|
||||
|
||||
+44
-23
@@ -176,24 +176,20 @@ gdk_cairo_region (cairo_t *cr,
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_cairo_set_source_pixbuf:
|
||||
* @cr: a cairo context
|
||||
* gdk_cairo_surface_create_from_pixbuf:
|
||||
* @pixbuf: a #GdkPixbuf
|
||||
* @pixbuf_x: X coordinate of location to place upper left corner of @pixbuf
|
||||
* @pixbuf_y: Y coordinate of location to place upper left corner of @pixbuf
|
||||
* @scale: the scale of the new surface, or 0 to use same as @window
|
||||
* @for_window: The window this will be drawn to, on %NULL.
|
||||
*
|
||||
* Sets the given pixbuf as the source pattern for @cr.
|
||||
* Creates an image surface with the same contents as
|
||||
* the pixbuf.
|
||||
*
|
||||
* The pattern has an extend mode of %CAIRO_EXTEND_NONE and is aligned
|
||||
* so that the origin of @pixbuf is @pixbuf_x, @pixbuf_y.
|
||||
*
|
||||
* Since: 2.8
|
||||
* Since: 3.10
|
||||
*/
|
||||
void
|
||||
gdk_cairo_set_source_pixbuf (cairo_t *cr,
|
||||
const GdkPixbuf *pixbuf,
|
||||
gdouble pixbuf_x,
|
||||
gdouble pixbuf_y)
|
||||
cairo_surface_t *
|
||||
gdk_cairo_surface_create_from_pixbuf (const GdkPixbuf *pixbuf,
|
||||
int scale,
|
||||
GdkWindow *for_window)
|
||||
{
|
||||
gint width = gdk_pixbuf_get_width (pixbuf);
|
||||
gint height = gdk_pixbuf_get_height (pixbuf);
|
||||
@@ -204,7 +200,6 @@ gdk_cairo_set_source_pixbuf (cairo_t *cr,
|
||||
guchar *cairo_pixels;
|
||||
cairo_format_t format;
|
||||
cairo_surface_t *surface;
|
||||
static const cairo_user_data_key_t key;
|
||||
int j;
|
||||
|
||||
if (n_channels == 3)
|
||||
@@ -212,14 +207,13 @@ gdk_cairo_set_source_pixbuf (cairo_t *cr,
|
||||
else
|
||||
format = CAIRO_FORMAT_ARGB32;
|
||||
|
||||
cairo_stride = cairo_format_stride_for_width (format, width);
|
||||
cairo_pixels = g_malloc (height * cairo_stride);
|
||||
surface = cairo_image_surface_create_for_data ((unsigned char *)cairo_pixels,
|
||||
format,
|
||||
width, height, cairo_stride);
|
||||
|
||||
cairo_surface_set_user_data (surface, &key,
|
||||
cairo_pixels, (cairo_destroy_func_t)g_free);
|
||||
surface =
|
||||
gdk_window_create_similar_image_surface (for_window,
|
||||
format,
|
||||
width, height,
|
||||
scale);
|
||||
cairo_stride = cairo_image_surface_get_stride (surface);
|
||||
cairo_pixels = cairo_image_surface_get_data (surface);
|
||||
|
||||
for (j = height; j; j--)
|
||||
{
|
||||
@@ -277,6 +271,33 @@ gdk_cairo_set_source_pixbuf (cairo_t *cr,
|
||||
cairo_pixels += cairo_stride;
|
||||
}
|
||||
|
||||
cairo_surface_mark_dirty (surface);
|
||||
return surface;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_cairo_set_source_pixbuf:
|
||||
* @cr: a cairo context
|
||||
* @pixbuf: a #GdkPixbuf
|
||||
* @pixbuf_x: X coordinate of location to place upper left corner of @pixbuf
|
||||
* @pixbuf_y: Y coordinate of location to place upper left corner of @pixbuf
|
||||
*
|
||||
* Sets the given pixbuf as the source pattern for @cr.
|
||||
*
|
||||
* The pattern has an extend mode of %CAIRO_EXTEND_NONE and is aligned
|
||||
* so that the origin of @pixbuf is @pixbuf_x, @pixbuf_y.
|
||||
*
|
||||
* Since: 2.8
|
||||
*/
|
||||
void
|
||||
gdk_cairo_set_source_pixbuf (cairo_t *cr,
|
||||
const GdkPixbuf *pixbuf,
|
||||
gdouble pixbuf_x,
|
||||
gdouble pixbuf_y)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
|
||||
surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, 1, NULL);
|
||||
cairo_set_source_surface (cr, surface, pixbuf_x, pixbuf_y);
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
|
||||
@@ -66,6 +66,16 @@ GDK_DEPRECATED_IN_3_4_FOR(gdk_cairo_set_source_rgba)
|
||||
void gdk_cairo_set_source_color (cairo_t *cr,
|
||||
const GdkColor *color);
|
||||
|
||||
GDK_AVAILABLE_IN_3_10
|
||||
cairo_surface_t * gdk_cairo_surface_create_similar (cairo_surface_t *surface,
|
||||
cairo_content_t content,
|
||||
int width,
|
||||
int height);
|
||||
GDK_AVAILABLE_IN_3_10
|
||||
cairo_surface_t * gdk_cairo_surface_create_from_pixbuf (const GdkPixbuf *pixbuf,
|
||||
int scale,
|
||||
GdkWindow *for_window);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_CAIRO_H__ */
|
||||
|
||||
+105
-38
@@ -24,6 +24,9 @@
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkintl.h"
|
||||
|
||||
/* for the use of round() */
|
||||
#include "fallback-c89.c"
|
||||
|
||||
/**
|
||||
* SECTION:gdkdevice
|
||||
* @Short_description: Object representing an input device
|
||||
@@ -406,28 +409,28 @@ gdk_device_get_state (GdkDevice *device,
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_device_get_position:
|
||||
* gdk_device_get_position_double:
|
||||
* @device: pointer device to query status about.
|
||||
* @screen: (out) (transfer none) (allow-none): location to store the #GdkScreen
|
||||
* the @device is on, or %NULL.
|
||||
* @x: (out) (allow-none): location to store root window X coordinate of @device, or %NULL.
|
||||
* @y: (out) (allow-none): location to store root window Y coordinate of @device, or %NULL.
|
||||
*
|
||||
* Gets the current location of @device. As a slave device
|
||||
* Gets the current location of @device in double precision. As a slave device
|
||||
* coordinates are those of its master pointer, This function
|
||||
* may not be called on devices of type %GDK_DEVICE_TYPE_SLAVE,
|
||||
* unless there is an ongoing grab on them, see gdk_device_grab().
|
||||
*
|
||||
* Since: 3.0
|
||||
* Since: 3.10
|
||||
**/
|
||||
void
|
||||
gdk_device_get_position (GdkDevice *device,
|
||||
GdkScreen **screen,
|
||||
gint *x,
|
||||
gint *y)
|
||||
gdk_device_get_position_double (GdkDevice *device,
|
||||
GdkScreen **screen,
|
||||
gdouble *x,
|
||||
gdouble *y)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
gint tmp_x, tmp_y;
|
||||
gdouble tmp_x, tmp_y;
|
||||
GdkScreen *default_screen;
|
||||
GdkWindow *root;
|
||||
|
||||
@@ -455,6 +458,87 @@ gdk_device_get_position (GdkDevice *device,
|
||||
*y = tmp_y;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_device_get_position:
|
||||
* @device: pointer device to query status about.
|
||||
* @screen: (out) (transfer none) (allow-none): location to store the #GdkScreen
|
||||
* the @device is on, or %NULL.
|
||||
* @x: (out) (allow-none): location to store root window X coordinate of @device, or %NULL.
|
||||
* @y: (out) (allow-none): location to store root window Y coordinate of @device, or %NULL.
|
||||
*
|
||||
* Gets the current location of @device. As a slave device
|
||||
* coordinates are those of its master pointer, This function
|
||||
* may not be called on devices of type %GDK_DEVICE_TYPE_SLAVE,
|
||||
* unless there is an ongoing grab on them, see gdk_device_grab().
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
void
|
||||
gdk_device_get_position (GdkDevice *device,
|
||||
GdkScreen **screen,
|
||||
gint *x,
|
||||
gint *y)
|
||||
{
|
||||
gdouble tmp_x, tmp_y;
|
||||
|
||||
gdk_device_get_position_double (device, screen, &tmp_x, &tmp_y);
|
||||
if (x)
|
||||
*x = round (tmp_x);
|
||||
if (y)
|
||||
*y = round (tmp_y);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gdk_device_get_window_at_position_double:
|
||||
* @device: pointer #GdkDevice to query info to.
|
||||
* @win_x: (out) (allow-none): return location for the X coordinate of the device location,
|
||||
* relative to the window origin, or %NULL.
|
||||
* @win_y: (out) (allow-none): return location for the Y coordinate of the device location,
|
||||
* relative to the window origin, or %NULL.
|
||||
*
|
||||
* Obtains the window underneath @device, returning the location of the device in @win_x and @win_y in
|
||||
* double precision. Returns %NULL if the window tree under @device is not known to GDK (for example,
|
||||
* belongs to another application).
|
||||
*
|
||||
* As a slave device coordinates are those of its master pointer, This
|
||||
* function may not be called on devices of type %GDK_DEVICE_TYPE_SLAVE,
|
||||
* unless there is an ongoing grab on them, see gdk_device_grab().
|
||||
*
|
||||
* Returns: (transfer none): the #GdkWindow under the device position, or %NULL.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
GdkWindow *
|
||||
gdk_device_get_window_at_position_double (GdkDevice *device,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y)
|
||||
{
|
||||
gdouble tmp_x, tmp_y;
|
||||
GdkWindow *window;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
|
||||
g_return_val_if_fail (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD, NULL);
|
||||
g_return_val_if_fail (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_SLAVE ||
|
||||
gdk_display_device_is_grabbed (gdk_device_get_display (device), device), NULL);
|
||||
|
||||
window = _gdk_device_window_at_position (device, &tmp_x, &tmp_y, NULL, FALSE);
|
||||
|
||||
/* This might need corrections, as the native window returned
|
||||
may contain client side children */
|
||||
if (window)
|
||||
window = _gdk_window_find_descendant_at (window,
|
||||
tmp_x, tmp_y,
|
||||
&tmp_x, &tmp_y);
|
||||
|
||||
if (win_x)
|
||||
*win_x = tmp_x;
|
||||
if (win_y)
|
||||
*win_y = tmp_y;
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_device_get_window_at_position:
|
||||
* @device: pointer #GdkDevice to query info to.
|
||||
@@ -479,33 +563,16 @@ gdk_device_get_window_at_position (GdkDevice *device,
|
||||
gint *win_x,
|
||||
gint *win_y)
|
||||
{
|
||||
gint tmp_x, tmp_y;
|
||||
gdouble tmp_x, tmp_y;
|
||||
GdkWindow *window;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
|
||||
g_return_val_if_fail (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD, NULL);
|
||||
g_return_val_if_fail (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_SLAVE ||
|
||||
gdk_display_device_is_grabbed (gdk_device_get_display (device), device), NULL);
|
||||
|
||||
window = _gdk_device_window_at_position (device, &tmp_x, &tmp_y, NULL, FALSE);
|
||||
|
||||
/* This might need corrections, as the native window returned
|
||||
may contain client side children */
|
||||
if (window)
|
||||
{
|
||||
double xx, yy;
|
||||
|
||||
window = _gdk_window_find_descendant_at (window,
|
||||
tmp_x, tmp_y,
|
||||
&xx, &yy);
|
||||
tmp_x = floor (xx + 0.5);
|
||||
tmp_y = floor (yy + 0.5);
|
||||
}
|
||||
window =
|
||||
gdk_device_get_window_at_position_double (device, &tmp_x, &tmp_y);
|
||||
|
||||
if (win_x)
|
||||
*win_x = tmp_x;
|
||||
*win_x = round (tmp_x);
|
||||
if (win_y)
|
||||
*win_y = tmp_y;
|
||||
*win_y = round (tmp_y);
|
||||
|
||||
return window;
|
||||
}
|
||||
@@ -1535,8 +1602,8 @@ _gdk_device_translate_window_coord (GdkDevice *device,
|
||||
gboolean
|
||||
_gdk_device_translate_screen_coord (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
gint window_root_x,
|
||||
gint window_root_y,
|
||||
gdouble window_root_x,
|
||||
gdouble window_root_y,
|
||||
guint index_,
|
||||
gdouble value,
|
||||
gdouble *axis_value)
|
||||
@@ -1616,10 +1683,10 @@ _gdk_device_query_state (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
GdkWindow **root_window,
|
||||
GdkWindow **child_window,
|
||||
gint *root_x,
|
||||
gint *root_y,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *root_x,
|
||||
gdouble *root_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
GDK_DEVICE_GET_CLASS (device)->query_state (device,
|
||||
@@ -1635,8 +1702,8 @@ _gdk_device_query_state (GdkDevice *device,
|
||||
|
||||
GdkWindow *
|
||||
_gdk_device_window_at_position (GdkDevice *device,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask,
|
||||
gboolean get_toplevel)
|
||||
{
|
||||
|
||||
@@ -198,6 +198,17 @@ GdkWindow *
|
||||
(GdkDevice *device,
|
||||
gint *win_x,
|
||||
gint *win_y);
|
||||
GDK_AVAILABLE_IN_3_10
|
||||
void gdk_device_get_position_double (GdkDevice *device,
|
||||
GdkScreen **screen,
|
||||
gdouble *x,
|
||||
gdouble *y);
|
||||
GDK_AVAILABLE_IN_3_10
|
||||
GdkWindow *
|
||||
gdk_device_get_window_at_position_double
|
||||
(GdkDevice *device,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_device_get_history (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
|
||||
+16
-16
@@ -80,16 +80,16 @@ struct _GdkDeviceClass
|
||||
|
||||
void (* warp) (GdkDevice *device,
|
||||
GdkScreen *screen,
|
||||
gint x,
|
||||
gint y);
|
||||
gdouble x,
|
||||
gdouble y);
|
||||
void (* query_state) (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
GdkWindow **root_window,
|
||||
GdkWindow **child_window,
|
||||
gint *root_x,
|
||||
gint *root_y,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *root_x,
|
||||
gdouble *root_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask);
|
||||
GdkGrabStatus (* grab) (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
@@ -102,8 +102,8 @@ struct _GdkDeviceClass
|
||||
guint32 time_);
|
||||
|
||||
GdkWindow * (* window_at_position) (GdkDevice *device,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
double *win_x,
|
||||
double *win_y,
|
||||
GdkModifierType *mask,
|
||||
gboolean get_toplevel);
|
||||
void (* select_window_events) (GdkDevice *device,
|
||||
@@ -140,8 +140,8 @@ gboolean _gdk_device_translate_window_coord (GdkDevice *device,
|
||||
|
||||
gboolean _gdk_device_translate_screen_coord (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
gint window_root_x,
|
||||
gint window_root_y,
|
||||
gdouble window_root_x,
|
||||
gdouble window_root_y,
|
||||
guint index,
|
||||
gdouble value,
|
||||
gdouble *axis_value);
|
||||
@@ -162,14 +162,14 @@ void _gdk_device_query_state (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
GdkWindow **root_window,
|
||||
GdkWindow **child_window,
|
||||
gint *root_x,
|
||||
gint *root_y,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *root_x,
|
||||
gdouble *root_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask);
|
||||
GdkWindow * _gdk_device_window_at_position (GdkDevice *device,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask,
|
||||
gboolean get_toplevel);
|
||||
|
||||
|
||||
+22
-19
@@ -32,8 +32,11 @@
|
||||
#include "gdkmarshalers.h"
|
||||
#include "gdkscreen.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <glib.h>
|
||||
|
||||
/* for the use of round() */
|
||||
#include "fallback-c89.c"
|
||||
|
||||
/**
|
||||
* SECTION:gdkdisplay
|
||||
@@ -546,7 +549,7 @@ gdk_display_get_pointer (GdkDisplay *display,
|
||||
{
|
||||
GdkScreen *default_screen;
|
||||
GdkWindow *root;
|
||||
gint tmp_x, tmp_y;
|
||||
gdouble tmp_x, tmp_y;
|
||||
GdkModifierType tmp_mask;
|
||||
|
||||
g_return_if_fail (GDK_IS_DISPLAY (display));
|
||||
@@ -569,9 +572,9 @@ gdk_display_get_pointer (GdkDisplay *display,
|
||||
if (screen)
|
||||
*screen = gdk_window_get_screen (root);
|
||||
if (x)
|
||||
*x = tmp_x;
|
||||
*x = round (tmp_x);
|
||||
if (y)
|
||||
*y = tmp_y;
|
||||
*y = round (tmp_y);
|
||||
if (mask)
|
||||
*mask = tmp_mask;
|
||||
}
|
||||
@@ -792,7 +795,7 @@ synthesize_crossing_events (GdkDisplay *display,
|
||||
{
|
||||
GdkWindow *src_toplevel, *dest_toplevel;
|
||||
GdkModifierType state;
|
||||
int x, y;
|
||||
double x, y;
|
||||
|
||||
if (src_window)
|
||||
src_toplevel = gdk_window_get_toplevel (src_window);
|
||||
@@ -810,9 +813,9 @@ synthesize_crossing_events (GdkDisplay *display,
|
||||
src_toplevel == dest_toplevel)
|
||||
{
|
||||
/* Same toplevels */
|
||||
gdk_window_get_device_position (dest_toplevel,
|
||||
device,
|
||||
&x, &y, &state);
|
||||
gdk_window_get_device_position_double (dest_toplevel,
|
||||
device,
|
||||
&x, &y, &state);
|
||||
_gdk_synthesize_crossing_events (display,
|
||||
src_window,
|
||||
dest_window,
|
||||
@@ -825,9 +828,9 @@ synthesize_crossing_events (GdkDisplay *display,
|
||||
}
|
||||
else if (dest_toplevel == NULL)
|
||||
{
|
||||
gdk_window_get_device_position (src_toplevel,
|
||||
device,
|
||||
&x, &y, &state);
|
||||
gdk_window_get_device_position_double (src_toplevel,
|
||||
device,
|
||||
&x, &y, &state);
|
||||
_gdk_synthesize_crossing_events (display,
|
||||
src_window,
|
||||
NULL,
|
||||
@@ -841,9 +844,9 @@ synthesize_crossing_events (GdkDisplay *display,
|
||||
else
|
||||
{
|
||||
/* Different toplevels */
|
||||
gdk_window_get_device_position (src_toplevel,
|
||||
device,
|
||||
&x, &y, &state);
|
||||
gdk_window_get_device_position_double (src_toplevel,
|
||||
device,
|
||||
&x, &y, &state);
|
||||
_gdk_synthesize_crossing_events (display,
|
||||
src_window,
|
||||
NULL,
|
||||
@@ -853,9 +856,9 @@ synthesize_crossing_events (GdkDisplay *display,
|
||||
time,
|
||||
NULL,
|
||||
serial, FALSE);
|
||||
gdk_window_get_device_position (dest_toplevel,
|
||||
device,
|
||||
&x, &y, &state);
|
||||
gdk_window_get_device_position_double (dest_toplevel,
|
||||
device,
|
||||
&x, &y, &state);
|
||||
_gdk_synthesize_crossing_events (display,
|
||||
NULL,
|
||||
dest_window,
|
||||
@@ -876,7 +879,7 @@ get_current_toplevel (GdkDisplay *display,
|
||||
GdkModifierType *state_out)
|
||||
{
|
||||
GdkWindow *pointer_window;
|
||||
int x, y;
|
||||
gdouble x, y;
|
||||
GdkModifierType state;
|
||||
|
||||
pointer_window = _gdk_device_window_at_position (device, &x, &y, &state, TRUE);
|
||||
@@ -887,8 +890,8 @@ get_current_toplevel (GdkDisplay *display,
|
||||
GDK_WINDOW_TYPE (pointer_window) == GDK_WINDOW_FOREIGN))
|
||||
pointer_window = NULL;
|
||||
|
||||
*x_out = x;
|
||||
*y_out = y;
|
||||
*x_out = round (x);
|
||||
*y_out = round (y);
|
||||
*state_out = state;
|
||||
|
||||
return pointer_window;
|
||||
|
||||
+3
-3
@@ -358,7 +358,7 @@ void _gdk_window_invalidate_for_expose (GdkWindow *window,
|
||||
cairo_region_t *region);
|
||||
|
||||
GdkWindow * _gdk_window_find_child_at (GdkWindow *window,
|
||||
int x, int y);
|
||||
double x, double y);
|
||||
GdkWindow * _gdk_window_find_descendant_at (GdkWindow *toplevel,
|
||||
double x, double y,
|
||||
double *found_x,
|
||||
@@ -380,8 +380,8 @@ void _gdk_synthesize_crossing_events (GdkDisplay *display,
|
||||
GdkDevice *device,
|
||||
GdkDevice *source_device,
|
||||
GdkCrossingMode mode,
|
||||
gint toplevel_x,
|
||||
gint toplevel_y,
|
||||
gdouble toplevel_x,
|
||||
gdouble toplevel_y,
|
||||
GdkModifierType mask,
|
||||
guint32 time_,
|
||||
GdkEvent *event_in_queue,
|
||||
|
||||
+22
-18
@@ -141,18 +141,11 @@ _gdk_offscreen_window_create_surface (GdkWindow *offscreen,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
cairo_surface_t *similar;
|
||||
cairo_surface_t *surface;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_OFFSCREEN_WINDOW (offscreen->impl), NULL);
|
||||
|
||||
similar = _gdk_window_ref_cairo_surface (offscreen->parent);
|
||||
|
||||
surface = cairo_surface_create_similar (similar, CAIRO_CONTENT_COLOR_ALPHA, width, height);
|
||||
|
||||
cairo_surface_destroy (similar);
|
||||
|
||||
return surface;
|
||||
return gdk_window_create_similar_surface (offscreen->parent,
|
||||
CAIRO_CONTENT_COLOR_ALPHA,
|
||||
width, height);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -287,12 +280,12 @@ gdk_offscreen_window_get_root_coords (GdkWindow *window,
|
||||
static gboolean
|
||||
gdk_offscreen_window_get_device_state (GdkWindow *window,
|
||||
GdkDevice *device,
|
||||
gint *x,
|
||||
gint *y,
|
||||
gdouble *x,
|
||||
gdouble *y,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
GdkOffscreenWindow *offscreen;
|
||||
int tmpx, tmpy;
|
||||
double tmpx, tmpy;
|
||||
double dtmpx, dtmpy;
|
||||
GdkModifierType tmpmask;
|
||||
|
||||
@@ -303,18 +296,18 @@ gdk_offscreen_window_get_device_state (GdkWindow *window,
|
||||
offscreen = GDK_OFFSCREEN_WINDOW (window->impl);
|
||||
if (offscreen->embedder != NULL)
|
||||
{
|
||||
gdk_window_get_device_position (offscreen->embedder, device, &tmpx, &tmpy, &tmpmask);
|
||||
gdk_window_get_device_position_double (offscreen->embedder, device, &tmpx, &tmpy, &tmpmask);
|
||||
from_embedder (window,
|
||||
tmpx, tmpy,
|
||||
&dtmpx, &dtmpy);
|
||||
tmpx = floor (dtmpx + 0.5);
|
||||
tmpy = floor (dtmpy + 0.5);
|
||||
tmpx = dtmpx;
|
||||
tmpy = dtmpy;
|
||||
}
|
||||
|
||||
if (x)
|
||||
*x = tmpx;
|
||||
*x = round (tmpx);
|
||||
if (y)
|
||||
*y = tmpy;
|
||||
*y = round (tmpy);
|
||||
if (mask)
|
||||
*mask = tmpmask;
|
||||
return TRUE;
|
||||
@@ -687,6 +680,16 @@ gdk_offscreen_window_get_frame_extents (GdkWindow *window,
|
||||
rect->height = window->height;
|
||||
}
|
||||
|
||||
static gint
|
||||
gdk_offscreen_window_get_scale_factor (GdkWindow *window)
|
||||
{
|
||||
|
||||
if (GDK_WINDOW_DESTROYED (window))
|
||||
return 1;
|
||||
|
||||
return gdk_window_get_scale_factor (window->parent);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_offscreen_window_class_init (GdkOffscreenWindowClass *klass)
|
||||
{
|
||||
@@ -773,4 +776,5 @@ gdk_offscreen_window_class_init (GdkOffscreenWindowClass *klass)
|
||||
impl_class->get_property = NULL;
|
||||
impl_class->change_property = NULL;
|
||||
impl_class->delete_property = NULL;
|
||||
impl_class->get_scale_factor = gdk_offscreen_window_get_scale_factor;
|
||||
}
|
||||
|
||||
@@ -1048,3 +1048,37 @@ gdk_screen_get_setting (GdkScreen *screen,
|
||||
|
||||
return GDK_SCREEN_GET_CLASS (screen)->get_setting (screen, name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_screen_get_monitor_scale_factor:
|
||||
* @screen: screen to get scale factor for
|
||||
* @monitor_num: number of the monitor, between 0 and gdk_screen_get_n_monitors (screen)
|
||||
*
|
||||
* Returns the internal scale factor that maps from monitor coordiantes
|
||||
* to the actual device pixels. On traditional systems this is 1, but
|
||||
* on very high density outputs this can be a higher value (often 2).
|
||||
*
|
||||
* This can be used if you want to create pixel based data for a
|
||||
* particula monitor, but most of the time you're drawing to a window
|
||||
* where it is better to use gdk_window_get_scale_factor() instead.
|
||||
*
|
||||
* Since: 3.10
|
||||
* Return value: the scale factor
|
||||
*/
|
||||
gint
|
||||
gdk_screen_get_monitor_scale_factor (GdkScreen *screen,
|
||||
gint monitor_num)
|
||||
{
|
||||
GdkScreenClass *screen_class;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_SCREEN (screen), 1);
|
||||
g_return_val_if_fail (monitor_num >= 0, 1);
|
||||
g_return_val_if_fail (monitor_num < gdk_screen_get_n_monitors (screen), 1);
|
||||
|
||||
screen_class = GDK_SCREEN_GET_CLASS (screen);
|
||||
|
||||
if (screen_class->get_monitor_scale_factor)
|
||||
return screen_class->get_monitor_scale_factor (screen, monitor_num);
|
||||
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
@@ -99,6 +99,9 @@ gint gdk_screen_get_monitor_height_mm (GdkScreen *screen,
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gchar * gdk_screen_get_monitor_plug_name (GdkScreen *screen,
|
||||
gint monitor_num);
|
||||
GDK_AVAILABLE_IN_3_10
|
||||
gint gdk_screen_get_monitor_scale_factor (GdkScreen *screen,
|
||||
gint monitor_num);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkScreen *gdk_screen_get_default (void);
|
||||
|
||||
@@ -91,7 +91,8 @@ struct _GdkScreenClass
|
||||
void (* query_visual_types) (GdkScreen *screen,
|
||||
GdkVisualType **visual_types,
|
||||
gint *count);
|
||||
|
||||
gint (* get_monitor_scale_factor) (GdkScreen *screen,
|
||||
gint monitor_num);
|
||||
|
||||
/* Signals: */
|
||||
void (*size_changed) (GdkScreen *screen);
|
||||
|
||||
+175
-17
@@ -2756,6 +2756,7 @@ gdk_window_begin_paint_region (GdkWindow *window,
|
||||
GdkWindowImplClass *impl_class;
|
||||
GdkWindowPaint *paint;
|
||||
GSList *list;
|
||||
double sx, sy;
|
||||
gboolean needs_surface;
|
||||
|
||||
g_return_if_fail (GDK_IS_WINDOW (window));
|
||||
@@ -2782,7 +2783,11 @@ gdk_window_begin_paint_region (GdkWindow *window,
|
||||
gdk_window_get_content (window),
|
||||
MAX (clip_box.width, 1),
|
||||
MAX (clip_box.height, 1));
|
||||
cairo_surface_set_device_offset (paint->surface, -clip_box.x, -clip_box.y);
|
||||
sx = sy = 1;
|
||||
#ifdef HAVE_CAIRO_SURFACE_SET_DEVICE_SCALE
|
||||
cairo_surface_get_device_scale (paint->surface, &sx, &sy);
|
||||
#endif
|
||||
cairo_surface_set_device_offset (paint->surface, -clip_box.x*sx, -clip_box.y*sy);
|
||||
}
|
||||
|
||||
for (list = window->paint_stack; list != NULL; list = list->next)
|
||||
@@ -4420,30 +4425,30 @@ gdk_window_get_pointer (GdkWindow *window,
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_window_get_device_position:
|
||||
* gdk_window_get_device_position_double:
|
||||
* @window: a #GdkWindow.
|
||||
* @device: pointer #GdkDevice to query to.
|
||||
* @x: (out) (allow-none): return location for the X coordinate of @device, or %NULL.
|
||||
* @y: (out) (allow-none): return location for the Y coordinate of @device, or %NULL.
|
||||
* @mask: (out) (allow-none): return location for the modifier mask, or %NULL.
|
||||
*
|
||||
* Obtains the current device position and modifier state.
|
||||
* Obtains the current device position in doubles and modifier state.
|
||||
* The position is given in coordinates relative to the upper left
|
||||
* corner of @window.
|
||||
*
|
||||
* Return value: (transfer none): The window underneath @device (as with
|
||||
* gdk_device_get_window_at_position()), or %NULL if the window is not known to GDK.
|
||||
*
|
||||
* Since: 3.0
|
||||
* Since: 3.10
|
||||
**/
|
||||
GdkWindow *
|
||||
gdk_window_get_device_position (GdkWindow *window,
|
||||
GdkDevice *device,
|
||||
gint *x,
|
||||
gint *y,
|
||||
GdkModifierType *mask)
|
||||
gdk_window_get_device_position_double (GdkWindow *window,
|
||||
GdkDevice *device,
|
||||
double *x,
|
||||
double *y,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
gint tmp_x, tmp_y;
|
||||
gdouble tmp_x, tmp_y;
|
||||
GdkModifierType tmp_mask;
|
||||
gboolean normal_child;
|
||||
|
||||
@@ -4473,6 +4478,44 @@ gdk_window_get_device_position (GdkWindow *window,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_window_get_device_position:
|
||||
* @window: a #GdkWindow.
|
||||
* @device: pointer #GdkDevice to query to.
|
||||
* @x: (out) (allow-none): return location for the X coordinate of @device, or %NULL.
|
||||
* @y: (out) (allow-none): return location for the Y coordinate of @device, or %NULL.
|
||||
* @mask: (out) (allow-none): return location for the modifier mask, or %NULL.
|
||||
*
|
||||
* Obtains the current device position and modifier state.
|
||||
* The position is given in coordinates relative to the upper left
|
||||
* corner of @window.
|
||||
*
|
||||
* Use gdk_window_get_device_position_double() if you need subpixel precision.
|
||||
*
|
||||
* Return value: (transfer none): The window underneath @device (as with
|
||||
* gdk_device_get_window_at_position()), or %NULL if the window is not known to GDK.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
GdkWindow *
|
||||
gdk_window_get_device_position (GdkWindow *window,
|
||||
GdkDevice *device,
|
||||
gint *x,
|
||||
gint *y,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
gdouble tmp_x, tmp_y;
|
||||
|
||||
window = gdk_window_get_device_position_double (window, device,
|
||||
&tmp_x, &tmp_y, mask);
|
||||
if (x)
|
||||
*x = round (tmp_x);
|
||||
if (y)
|
||||
*y = round (tmp_y);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_get_default_root_window:
|
||||
*
|
||||
@@ -6948,8 +6991,8 @@ pick_embedded_child (GdkWindow *window,
|
||||
|
||||
GdkWindow *
|
||||
_gdk_window_find_child_at (GdkWindow *window,
|
||||
int x,
|
||||
int y)
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
GdkWindow *sub;
|
||||
double child_x, child_y;
|
||||
@@ -7390,8 +7433,8 @@ send_crossing_event (GdkDisplay *display,
|
||||
GdkWindow *subwindow,
|
||||
GdkDevice *device,
|
||||
GdkDevice *source_device,
|
||||
gint toplevel_x,
|
||||
gint toplevel_y,
|
||||
gdouble toplevel_x,
|
||||
gdouble toplevel_y,
|
||||
GdkModifierType mask,
|
||||
guint32 time_,
|
||||
GdkEvent *event_in_queue,
|
||||
@@ -7506,8 +7549,8 @@ _gdk_synthesize_crossing_events (GdkDisplay *display,
|
||||
GdkDevice *device,
|
||||
GdkDevice *source_device,
|
||||
GdkCrossingMode mode,
|
||||
gint toplevel_x,
|
||||
gint toplevel_y,
|
||||
double toplevel_x,
|
||||
double toplevel_y,
|
||||
GdkModifierType mask,
|
||||
guint32 time_,
|
||||
GdkEvent *event_in_queue,
|
||||
@@ -9197,10 +9240,18 @@ gdk_window_create_similar_surface (GdkWindow * window,
|
||||
int height)
|
||||
{
|
||||
cairo_surface_t *window_surface, *surface;
|
||||
double sx, sy;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
|
||||
|
||||
|
||||
window_surface = gdk_window_ref_impl_surface (window);
|
||||
sx = sy = 1;
|
||||
#ifdef HAVE_CAIRO_SURFACE_SET_DEVICE_SCALE
|
||||
cairo_surface_get_device_scale (window_surface, &sx, &sy);
|
||||
#endif
|
||||
|
||||
width = width * sx;
|
||||
height = height * sy;
|
||||
|
||||
switch (_gdk_rendering_mode)
|
||||
{
|
||||
@@ -9223,11 +9274,80 @@ gdk_window_create_similar_surface (GdkWindow * window,
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef HAVE_CAIRO_SURFACE_SET_DEVICE_SCALE
|
||||
cairo_surface_set_device_scale (surface, sx, sy);
|
||||
#endif
|
||||
|
||||
cairo_surface_destroy (window_surface);
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gdk_window_create_similar_image_surface:
|
||||
* @window: window to make new surface similar to, or %NULL if none
|
||||
* @format: (type int): the format for the new surface
|
||||
* @width: width of the new surface
|
||||
* @height: height of the new surface
|
||||
* @scale: the scale of the new surface, or 0 to use same as @window
|
||||
*
|
||||
* Create a new image surface that is efficient to draw on the
|
||||
* given @window.
|
||||
*
|
||||
* Initially the surface contents are all 0 (transparent if contents
|
||||
* have transparency, black otherwise.)
|
||||
*
|
||||
* Returns: a pointer to the newly allocated surface. The caller
|
||||
* owns the surface and should call cairo_surface_destroy() when done
|
||||
* with it.
|
||||
*
|
||||
* This function always returns a valid pointer, but it will return a
|
||||
* pointer to a "nil" surface if @other is already in an error state
|
||||
* or any other error occurs.
|
||||
*
|
||||
* Since: 3.10
|
||||
**/
|
||||
cairo_surface_t *
|
||||
gdk_window_create_similar_image_surface (GdkWindow * window,
|
||||
cairo_format_t format,
|
||||
int width,
|
||||
int height,
|
||||
int scale)
|
||||
{
|
||||
cairo_surface_t *window_surface, *surface;
|
||||
GdkDisplay *display;
|
||||
GdkScreen *screen;
|
||||
|
||||
g_return_val_if_fail (window ==NULL || GDK_IS_WINDOW (window), NULL);
|
||||
|
||||
if (window == NULL)
|
||||
{
|
||||
display = gdk_display_get_default ();
|
||||
screen = gdk_display_get_default_screen (display);
|
||||
window = gdk_screen_get_root_window (screen);
|
||||
}
|
||||
|
||||
window_surface = gdk_window_ref_impl_surface (window);
|
||||
if (scale == 0)
|
||||
scale = gdk_window_get_scale_factor (window);
|
||||
|
||||
surface =
|
||||
cairo_surface_create_similar_image (window_surface,
|
||||
format,
|
||||
width,
|
||||
height);
|
||||
|
||||
cairo_surface_destroy (window_surface);
|
||||
|
||||
#ifdef HAVE_CAIRO_SURFACE_SET_DEVICE_SCALE
|
||||
cairo_surface_set_device_scale (surface, scale, scale);
|
||||
#endif
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gdk_window_focus:
|
||||
* @window: a #GdkWindow
|
||||
@@ -10620,3 +10740,41 @@ gdk_window_get_frame_clock (GdkWindow *window)
|
||||
|
||||
return toplevel->frame_clock;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_window_get_scale_factor:
|
||||
* @window: window to get scale factor for
|
||||
*
|
||||
* Returns the internal scale factor that maps from window coordiantes
|
||||
* to the actual device pixels. On traditional systems this is 1, but
|
||||
* on very high density outputs this can be a higher value (often 2).
|
||||
*
|
||||
* A higher value means that drawing is automatically scaled up to
|
||||
* a higher resolution, so any code doing drawing will automatically look
|
||||
* nicer. However, if you are supplying pixel-based data the scale
|
||||
* value can be used to determine whether to use a pixel resource
|
||||
* with higher resolution data.
|
||||
*
|
||||
* The scale of a window may change during runtime, if this happens
|
||||
* a configure event will be sent to the toplevel window.
|
||||
*
|
||||
* Since: 3.10
|
||||
* Return value: the scale factor
|
||||
*/
|
||||
gint
|
||||
gdk_window_get_scale_factor (GdkWindow *window)
|
||||
{
|
||||
GdkWindowImplClass *impl_class;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_WINDOW (window), 1);
|
||||
|
||||
if (GDK_WINDOW_DESTROYED (window))
|
||||
return 1;
|
||||
|
||||
impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
|
||||
|
||||
if (impl_class->get_scale_factor)
|
||||
return impl_class->get_scale_factor (window);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -829,6 +829,9 @@ GDK_AVAILABLE_IN_ALL
|
||||
void gdk_window_get_frame_extents (GdkWindow *window,
|
||||
GdkRectangle *rect);
|
||||
|
||||
GDK_AVAILABLE_IN_3_10
|
||||
gint gdk_window_get_scale_factor (GdkWindow *window);
|
||||
|
||||
#ifndef GDK_MULTIDEVICE_SAFE
|
||||
GDK_DEPRECATED_IN_3_0_FOR(gdk_window_get_device_position)
|
||||
GdkWindow * gdk_window_get_pointer (GdkWindow *window,
|
||||
@@ -842,6 +845,12 @@ GdkWindow * gdk_window_get_device_position (GdkWindow *window,
|
||||
gint *x,
|
||||
gint *y,
|
||||
GdkModifierType *mask);
|
||||
GDK_AVAILABLE_IN_3_10
|
||||
GdkWindow * gdk_window_get_device_position_double (GdkWindow *window,
|
||||
GdkDevice *device,
|
||||
gdouble *x,
|
||||
gdouble *y,
|
||||
GdkModifierType *mask);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkWindow * gdk_window_get_parent (GdkWindow *window);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
@@ -908,6 +917,13 @@ cairo_surface_t *
|
||||
cairo_content_t content,
|
||||
int width,
|
||||
int height);
|
||||
GDK_AVAILABLE_IN_3_10
|
||||
cairo_surface_t *
|
||||
gdk_window_create_similar_image_surface (GdkWindow *window,
|
||||
cairo_format_t format,
|
||||
int width,
|
||||
int height,
|
||||
int scale);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_window_beep (GdkWindow *window);
|
||||
|
||||
+4
-2
@@ -98,8 +98,8 @@ struct _GdkWindowImplClass
|
||||
gint *root_y);
|
||||
gboolean (* get_device_state) (GdkWindow *window,
|
||||
GdkDevice *device,
|
||||
gint *x,
|
||||
gint *y,
|
||||
gdouble *x,
|
||||
gdouble *y,
|
||||
GdkModifierType *mask);
|
||||
gboolean (* begin_paint_region) (GdkWindow *window,
|
||||
const cairo_region_t *region);
|
||||
@@ -285,6 +285,8 @@ struct _GdkWindowImplClass
|
||||
gint n_elements);
|
||||
void (*delete_property) (GdkWindow *window,
|
||||
GdkAtom property);
|
||||
|
||||
gint (* get_scale_factor) (GdkWindow *window);
|
||||
};
|
||||
|
||||
/* Interface Functions */
|
||||
|
||||
@@ -58,10 +58,10 @@ static void gdk_quartz_device_core_query_state (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
GdkWindow **root_window,
|
||||
GdkWindow **child_window,
|
||||
gint *root_x,
|
||||
gint *root_y,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *root_x,
|
||||
gdouble *root_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask);
|
||||
static GdkGrabStatus gdk_quartz_device_core_grab (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
@@ -73,8 +73,8 @@ static GdkGrabStatus gdk_quartz_device_core_grab (GdkDevice *device,
|
||||
static void gdk_quartz_device_core_ungrab (GdkDevice *device,
|
||||
guint32 time_);
|
||||
static GdkWindow * gdk_quartz_device_core_window_at_position (GdkDevice *device,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask,
|
||||
gboolean get_toplevel);
|
||||
static void gdk_quartz_device_core_select_window_events (GdkDevice *device,
|
||||
@@ -181,8 +181,8 @@ gdk_quartz_device_core_set_window_cursor (GdkDevice *device,
|
||||
static void
|
||||
gdk_quartz_device_core_warp (GdkDevice *device,
|
||||
GdkScreen *screen,
|
||||
gint x,
|
||||
gint y)
|
||||
gdouble x,
|
||||
gdouble y)
|
||||
{
|
||||
CGDisplayMoveCursorToPoint (CGMainDisplayID (), CGPointMake (x, y));
|
||||
}
|
||||
@@ -190,8 +190,8 @@ gdk_quartz_device_core_warp (GdkDevice *device,
|
||||
static GdkWindow *
|
||||
gdk_quartz_device_core_query_state_helper (GdkWindow *window,
|
||||
GdkDevice *device,
|
||||
gint *x,
|
||||
gint *y,
|
||||
gdouble *x,
|
||||
gdouble *y,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
GdkWindow *toplevel;
|
||||
@@ -260,10 +260,10 @@ gdk_quartz_device_core_query_state (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
GdkWindow **root_window,
|
||||
GdkWindow **child_window,
|
||||
gint *root_x,
|
||||
gint *root_y,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *root_x,
|
||||
gdouble *root_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
GdkWindow *found_window;
|
||||
@@ -318,8 +318,8 @@ gdk_quartz_device_core_ungrab (GdkDevice *device,
|
||||
|
||||
static GdkWindow *
|
||||
gdk_quartz_device_core_window_at_position (GdkDevice *device,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask,
|
||||
gboolean get_toplevel)
|
||||
{
|
||||
|
||||
@@ -427,6 +427,35 @@ gdk_quartz_screen_get_monitor_workarea (GdkScreen *screen,
|
||||
GDK_QUARTZ_RELEASE_POOL;
|
||||
}
|
||||
|
||||
/* Protocol to build cleanly for OSX < 10.7 */
|
||||
@protocol ScaleFactor
|
||||
- (CGFloat) backingScaleFactor;
|
||||
@end
|
||||
|
||||
gint
|
||||
_gdk_quartz_screen_get_monitor_scale_factor (GdkScreen *screen,
|
||||
gint monitor_num)
|
||||
{
|
||||
GdkQuartzScreen *quartz_screen;
|
||||
NSArray *array;
|
||||
NSScreen *nsscreen;
|
||||
gint scale_factor = 1;
|
||||
|
||||
quartz_screen = GDK_QUARTZ_SCREEN (screen);
|
||||
|
||||
GDK_QUARTZ_ALLOC_POOL;
|
||||
|
||||
array = [NSScreen screens];
|
||||
nsscreen = [array objectAtIndex:monitor_num];
|
||||
|
||||
if (gdk_quartz_osx_version() >= GDK_OSX_LION)
|
||||
scale_factor = [(id <ScaleFactor>) nsscreen backingScaleFactor];
|
||||
|
||||
GDK_QUARTZ_RELEASE_POOL;
|
||||
|
||||
return scale_factor;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
gdk_quartz_screen_make_display_name (GdkScreen *screen)
|
||||
{
|
||||
@@ -491,4 +520,5 @@ gdk_quartz_screen_class_init (GdkQuartzScreenClass *klass)
|
||||
screen_class->query_depths = _gdk_quartz_screen_query_depths;
|
||||
screen_class->query_visual_types = _gdk_quartz_screen_query_visual_types;
|
||||
screen_class->list_visuals = _gdk_quartz_screen_list_visuals;
|
||||
screen_class->get_monitor_scale_factor = _gdk_quartz_screen_get_monitor_scale_factor;
|
||||
}
|
||||
|
||||
+26
-105
@@ -1818,8 +1818,8 @@ gdk_quartz_window_get_root_origin (GdkWindow *window,
|
||||
static GdkWindow *
|
||||
gdk_window_quartz_get_device_state_helper (GdkWindow *window,
|
||||
GdkDevice *device,
|
||||
gint *x,
|
||||
gint *y,
|
||||
gdouble *x,
|
||||
gdouble *y,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
NSPoint point;
|
||||
@@ -1880,8 +1880,8 @@ gdk_window_quartz_get_device_state_helper (GdkWindow *window,
|
||||
static gboolean
|
||||
gdk_window_quartz_get_device_state (GdkWindow *window,
|
||||
GdkDevice *device,
|
||||
gint *x,
|
||||
gint *y,
|
||||
gdouble *x,
|
||||
gdouble *y,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
return gdk_window_quartz_get_device_state_helper (window,
|
||||
@@ -1889,100 +1889,7 @@ gdk_window_quartz_get_device_state (GdkWindow *window,
|
||||
x, y, mask) != NULL;
|
||||
}
|
||||
|
||||
/* Returns coordinates relative to the root. */
|
||||
void
|
||||
_gdk_windowing_get_device_state (GdkDisplay *display,
|
||||
GdkDevice *device,
|
||||
GdkScreen **screen,
|
||||
gint *x,
|
||||
gint *y,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
g_return_if_fail (display == _gdk_display);
|
||||
|
||||
*screen = _gdk_screen;
|
||||
gdk_window_quartz_get_device_state_helper (_gdk_root, device, x, y, mask);
|
||||
}
|
||||
|
||||
/* Returns coordinates relative to the found window. */
|
||||
GdkWindow *
|
||||
_gdk_windowing_window_at_pointer (GdkDisplay *display,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
GdkModifierType *mask,
|
||||
gboolean get_toplevel)
|
||||
{
|
||||
GdkWindow *found_window;
|
||||
gint x, y;
|
||||
GdkModifierType tmp_mask = 0;
|
||||
|
||||
found_window = gdk_window_quartz_get_device_state_helper (_gdk_root,
|
||||
display->core_pointer,
|
||||
&x, &y,
|
||||
&tmp_mask);
|
||||
if (found_window)
|
||||
{
|
||||
/* The coordinates returned above are relative the root, we want
|
||||
* coordinates relative the window here.
|
||||
*/
|
||||
while (found_window != _gdk_root)
|
||||
{
|
||||
x -= found_window->x;
|
||||
y -= found_window->y;
|
||||
|
||||
found_window = found_window->parent;
|
||||
}
|
||||
|
||||
*win_x = x;
|
||||
*win_y = y;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Mimic the X backend here, -1,-1 for unknown windows. */
|
||||
*win_x = -1;
|
||||
*win_y = -1;
|
||||
}
|
||||
|
||||
if (mask)
|
||||
*mask = tmp_mask;
|
||||
|
||||
if (get_toplevel)
|
||||
{
|
||||
/* Requested toplevel, find it. */
|
||||
/* TODO: This can be implemented more efficient by never
|
||||
recursing into children in the first place */
|
||||
if (found_window)
|
||||
{
|
||||
/* Convert to toplevel */
|
||||
while (found_window->parent != NULL &&
|
||||
found_window->parent->window_type != GDK_WINDOW_ROOT)
|
||||
{
|
||||
*win_x += found_window->x;
|
||||
*win_y += found_window->y;
|
||||
found_window = found_window->parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return found_window;
|
||||
}
|
||||
|
||||
GdkWindow*
|
||||
_gdk_windowing_window_at_device_position (GdkDisplay *display,
|
||||
GdkDevice *device,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
GdkModifierType *mask,
|
||||
gboolean get_toplevel)
|
||||
{
|
||||
return GDK_DEVICE_GET_CLASS (device)->window_at_position (device,
|
||||
win_x, win_y,
|
||||
mask,
|
||||
get_toplevel);
|
||||
}
|
||||
|
||||
|
||||
static GdkEventMask
|
||||
static GdkEventMask
|
||||
gdk_window_quartz_get_events (GdkWindow *window)
|
||||
{
|
||||
if (GDK_WINDOW_DESTROYED (window))
|
||||
@@ -2683,13 +2590,6 @@ gdk_quartz_window_set_functions (GdkWindow *window,
|
||||
/* FIXME: Implement */
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_windowing_window_queue_antiexpose (GdkWindow *window,
|
||||
cairo_region_t *area)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_window_stick (GdkWindow *window)
|
||||
{
|
||||
@@ -3001,6 +2901,26 @@ gdk_quartz_window_get_input_shape (GdkWindow *window)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Protocol to build cleanly for OSX < 10.7 */
|
||||
@protocol ScaleFactor
|
||||
- (CGFloat) backingScaleFactor;
|
||||
@end
|
||||
|
||||
static gint
|
||||
gdk_quartz_window_get_scale_factor (GdkWindow *window)
|
||||
{
|
||||
GdkWindowImplQuartz *impl;
|
||||
|
||||
if (GDK_WINDOW_DESTROYED (window))
|
||||
return 1;
|
||||
|
||||
impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
|
||||
|
||||
if (gdk_quartz_osx_version() >= GDK_OSX_LION)
|
||||
return [(id <ScaleFactor>) impl->toplevel backingScaleFactor];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_window_impl_quartz_class_init (GdkWindowImplQuartzClass *klass)
|
||||
@@ -3040,6 +2960,7 @@ gdk_window_impl_quartz_class_init (GdkWindowImplQuartzClass *klass)
|
||||
impl_class->get_input_shape = gdk_quartz_window_get_input_shape;
|
||||
impl_class->begin_paint_region = gdk_window_impl_quartz_begin_paint_region;
|
||||
impl_class->end_paint = gdk_window_impl_quartz_end_paint;
|
||||
impl_class->get_scale_factor = gdk_quartz_window_get_scale_factor;
|
||||
|
||||
impl_class->focus = gdk_quartz_window_focus;
|
||||
impl_class->set_type_hint = gdk_quartz_window_set_type_hint;
|
||||
|
||||
@@ -135,14 +135,14 @@ gdk_wayland_device_get_state (GdkDevice *device,
|
||||
gdouble *axes,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
gint x_int, y_int;
|
||||
gdouble x, y;
|
||||
|
||||
gdk_window_get_device_position (window, device, &x_int, &y_int, mask);
|
||||
gdk_window_get_device_position_double (window, device, &x, &y, mask);
|
||||
|
||||
if (axes)
|
||||
{
|
||||
axes[0] = x_int;
|
||||
axes[1] = y_int;
|
||||
axes[0] = x;
|
||||
axes[1] = y;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,8 +228,8 @@ gdk_wayland_device_set_window_cursor (GdkDevice *device,
|
||||
static void
|
||||
gdk_wayland_device_warp (GdkDevice *device,
|
||||
GdkScreen *screen,
|
||||
gint x,
|
||||
gint y)
|
||||
gdouble x,
|
||||
gdouble y)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -238,10 +238,10 @@ gdk_wayland_device_query_state (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
GdkWindow **root_window,
|
||||
GdkWindow **child_window,
|
||||
gint *root_x,
|
||||
gint *root_y,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *root_x,
|
||||
gdouble *root_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
GdkWaylandDeviceData *wd;
|
||||
@@ -345,8 +345,8 @@ gdk_wayland_device_ungrab (GdkDevice *device,
|
||||
|
||||
static GdkWindow *
|
||||
gdk_wayland_device_window_at_position (GdkDevice *device,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask,
|
||||
gboolean get_toplevel)
|
||||
{
|
||||
|
||||
@@ -168,8 +168,8 @@ gdk_registry_handle_global(void *data, struct wl_registry *registry, uint32_t id
|
||||
wl_registry_bind(display_wayland->wl_registry, id, &wl_shell_interface, 1);
|
||||
} else if (strcmp(interface, "wl_output") == 0) {
|
||||
output =
|
||||
wl_registry_bind(display_wayland->wl_registry, id, &wl_output_interface, 1);
|
||||
_gdk_wayland_screen_add_output(display_wayland->screen, id, output);
|
||||
wl_registry_bind(display_wayland->wl_registry, id, &wl_output_interface, 2);
|
||||
_gdk_wayland_screen_add_output(display_wayland->screen, id, output, version);
|
||||
/* We need another roundtrip to receive the modes and geometry
|
||||
* events for the output, which gives us the physical properties
|
||||
* and available modes on the output. */
|
||||
|
||||
@@ -161,11 +161,14 @@ GdkWindow *_gdk_wayland_screen_create_root_window (GdkScreen *screen,
|
||||
GdkScreen *_gdk_wayland_screen_new (GdkDisplay *display);
|
||||
void _gdk_wayland_screen_add_output (GdkScreen *screen,
|
||||
guint32 id,
|
||||
struct wl_output *output);
|
||||
struct wl_output *output,
|
||||
guint32 version);
|
||||
void _gdk_wayland_screen_remove_output (GdkScreen *screen,
|
||||
guint32 id);
|
||||
int _gdk_wayland_screen_get_output_refresh_rate (GdkScreen *screen,
|
||||
struct wl_output *output);
|
||||
guint32 _gdk_wayland_screen_get_output_scale (GdkScreen *screen,
|
||||
struct wl_output *output);
|
||||
|
||||
void _gdk_wayland_window_set_device_grabbed (GdkWindow *window,
|
||||
GdkDevice *device,
|
||||
|
||||
@@ -77,10 +77,13 @@ struct _GdkWaylandScreenClass
|
||||
void (* window_manager_changed) (GdkWaylandScreen *screen_wayland);
|
||||
};
|
||||
|
||||
#define OUTPUT_VERSION_WITH_DONE 2
|
||||
|
||||
struct _GdkWaylandMonitor
|
||||
{
|
||||
GdkWaylandScreen *screen;
|
||||
guint32 id;
|
||||
guint32 version;
|
||||
struct wl_output *output;
|
||||
GdkRectangle geometry;
|
||||
int width_mm;
|
||||
@@ -88,6 +91,7 @@ struct _GdkWaylandMonitor
|
||||
char * output_name;
|
||||
char * manufacturer;
|
||||
int refresh_rate;
|
||||
gint scale;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GdkWaylandScreen, _gdk_wayland_screen, GDK_TYPE_SCREEN)
|
||||
@@ -249,6 +253,21 @@ gdk_wayland_screen_get_monitor_geometry (GdkScreen *screen,
|
||||
*dest = monitor->geometry;
|
||||
}
|
||||
|
||||
static gint
|
||||
gdk_wayland_screen_get_monitor_scale_factor (GdkScreen *screen,
|
||||
gint monitor_num)
|
||||
{
|
||||
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
||||
GdkWaylandMonitor *monitor;
|
||||
|
||||
if (monitor_num >= screen_wayland->monitors->len)
|
||||
return 1;
|
||||
|
||||
monitor = g_ptr_array_index(screen_wayland->monitors, monitor_num);
|
||||
|
||||
return monitor->scale;
|
||||
}
|
||||
|
||||
static GdkVisual *
|
||||
gdk_wayland_screen_get_system_visual (GdkScreen * screen)
|
||||
{
|
||||
@@ -822,6 +841,7 @@ _gdk_wayland_screen_class_init (GdkWaylandScreenClass *klass)
|
||||
screen_class->get_monitor_plug_name = gdk_wayland_screen_get_monitor_plug_name;
|
||||
screen_class->get_monitor_geometry = gdk_wayland_screen_get_monitor_geometry;
|
||||
screen_class->get_monitor_workarea = gdk_wayland_screen_get_monitor_geometry;
|
||||
screen_class->get_monitor_scale_factor = gdk_wayland_screen_get_monitor_scale_factor;
|
||||
screen_class->get_system_visual = gdk_wayland_screen_get_system_visual;
|
||||
screen_class->get_rgba_visual = gdk_wayland_screen_get_rgba_visual;
|
||||
screen_class->is_composited = gdk_wayland_screen_is_composited;
|
||||
@@ -888,13 +908,33 @@ output_handle_geometry(void *data,
|
||||
monitor->manufacturer = g_strdup (make);
|
||||
monitor->output_name = g_strdup (model);
|
||||
|
||||
if (monitor->geometry.width != 0)
|
||||
if (monitor->geometry.width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
|
||||
{
|
||||
g_signal_emit_by_name (monitor->screen, "monitors-changed");
|
||||
update_screen_size (monitor->screen);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
output_handle_done(void *data,
|
||||
struct wl_output *wl_output)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)data;
|
||||
|
||||
g_signal_emit_by_name (monitor->screen, "monitors-changed");
|
||||
update_screen_size (monitor->screen);
|
||||
}
|
||||
|
||||
static void
|
||||
output_handle_scale(void *data,
|
||||
struct wl_output *wl_output,
|
||||
int32_t factor)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)data;
|
||||
|
||||
monitor->scale = factor;
|
||||
}
|
||||
|
||||
static void
|
||||
output_handle_mode(void *data,
|
||||
struct wl_output *wl_output,
|
||||
@@ -912,27 +952,35 @@ output_handle_mode(void *data,
|
||||
monitor->geometry.height = height;
|
||||
monitor->refresh_rate = refresh;
|
||||
|
||||
g_signal_emit_by_name (monitor->screen, "monitors-changed");
|
||||
update_screen_size (monitor->screen);
|
||||
if (monitor->geometry.width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
|
||||
{
|
||||
g_signal_emit_by_name (monitor->screen, "monitors-changed");
|
||||
update_screen_size (monitor->screen);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct wl_output_listener output_listener =
|
||||
{
|
||||
output_handle_geometry,
|
||||
output_handle_mode
|
||||
output_handle_mode,
|
||||
output_handle_done,
|
||||
output_handle_scale,
|
||||
};
|
||||
|
||||
void
|
||||
_gdk_wayland_screen_add_output (GdkScreen *screen,
|
||||
guint32 id,
|
||||
struct wl_output *output)
|
||||
struct wl_output *output,
|
||||
guint32 version)
|
||||
{
|
||||
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
||||
GdkWaylandMonitor *monitor = g_new0(GdkWaylandMonitor, 1);
|
||||
|
||||
monitor->id = id;
|
||||
monitor->output = output;
|
||||
monitor->version = version;
|
||||
monitor->screen = screen_wayland;
|
||||
monitor->scale = 1;
|
||||
g_ptr_array_add(screen_wayland->monitors, monitor);
|
||||
|
||||
wl_output_add_listener(output, &output_listener, monitor);
|
||||
@@ -977,3 +1025,21 @@ _gdk_wayland_screen_get_output_refresh_rate (GdkScreen *screen,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
guint32
|
||||
_gdk_wayland_screen_get_output_scale (GdkScreen *screen,
|
||||
struct wl_output *output)
|
||||
{
|
||||
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < screen_wayland->monitors->len; i++)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = screen_wayland->monitors->pdata[i];
|
||||
|
||||
if (monitor->output == output)
|
||||
return monitor->scale;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -145,6 +145,7 @@ struct _GdkWindowImplWayland
|
||||
|
||||
gboolean use_custom_surface;
|
||||
|
||||
guint32 scale;
|
||||
gboolean pending_commit;
|
||||
gint64 pending_frame_counter;
|
||||
};
|
||||
@@ -154,11 +155,15 @@ struct _GdkWindowImplWaylandClass
|
||||
GdkWindowImplClass parent_class;
|
||||
};
|
||||
|
||||
static void gdk_wayland_window_configure (GdkWindow *window,
|
||||
int width, int height, int edges);
|
||||
|
||||
G_DEFINE_TYPE (GdkWindowImplWayland, _gdk_window_impl_wayland, GDK_TYPE_WINDOW_IMPL)
|
||||
|
||||
static void
|
||||
_gdk_window_impl_wayland_init (GdkWindowImplWayland *impl)
|
||||
{
|
||||
impl->scale = 1;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -391,6 +396,7 @@ typedef struct _GdkWaylandCairoSurfaceData {
|
||||
struct wl_buffer *buffer;
|
||||
GdkWaylandDisplay *display;
|
||||
int32_t width, height;
|
||||
uint32_t scale;
|
||||
gboolean busy;
|
||||
} GdkWaylandCairoSurfaceData;
|
||||
|
||||
@@ -419,6 +425,44 @@ on_frame_clock_after_paint (GdkFrameClock *clock,
|
||||
data->busy = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
window_update_scale (GdkWindow *window)
|
||||
{
|
||||
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
||||
GdkWaylandDisplay *wayland_display = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
|
||||
guint32 scale;
|
||||
GSList *l;
|
||||
|
||||
scale = 1;
|
||||
for (l = impl->outputs; l != NULL; l = l->next)
|
||||
{
|
||||
guint32 output_scale =
|
||||
_gdk_wayland_screen_get_output_scale (wayland_display->screen,
|
||||
l->data);
|
||||
scale = MAX (scale, output_scale);
|
||||
}
|
||||
|
||||
#ifndef HAVE_CAIRO_SURFACE_SET_DEVICE_SCALE
|
||||
/* Don't announce a scale if we can't support it */
|
||||
scale = 1;
|
||||
#endif
|
||||
|
||||
if (scale != impl->scale)
|
||||
{
|
||||
impl->scale = scale;
|
||||
|
||||
/* Notify app that scale changed */
|
||||
gdk_wayland_window_configure (window, window->width, window->height, impl->resize_edges);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_monitors_changed (GdkScreen *screen,
|
||||
GdkWindow *window)
|
||||
{
|
||||
window_update_scale (window);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_wayland_display_create_window_impl (GdkDisplay *display,
|
||||
GdkWindow *window,
|
||||
@@ -449,6 +493,9 @@ _gdk_wayland_display_create_window_impl (GdkDisplay *display,
|
||||
|
||||
g_object_ref (window);
|
||||
|
||||
/* More likely to be right than just assuming 1 */
|
||||
impl->scale = gdk_screen_get_monitor_scale_factor (screen, 0);
|
||||
|
||||
impl->title = NULL;
|
||||
|
||||
switch (GDK_WINDOW_TYPE (window))
|
||||
@@ -477,6 +524,9 @@ _gdk_wayland_display_create_window_impl (GdkDisplay *display,
|
||||
G_CALLBACK (on_frame_clock_before_paint), window);
|
||||
g_signal_connect (frame_clock, "after-paint",
|
||||
G_CALLBACK (on_frame_clock_after_paint), window);
|
||||
|
||||
g_signal_connect (screen, "monitors-changed",
|
||||
G_CALLBACK (on_monitors_changed), window);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -528,6 +578,8 @@ gdk_wayland_window_attach_image (GdkWindow *window)
|
||||
|
||||
/* Attach this new buffer to the surface */
|
||||
wl_surface_attach (impl->surface, data->buffer, dx, dy);
|
||||
wl_surface_set_buffer_scale (impl->surface, data->scale);
|
||||
|
||||
impl->pending_commit = TRUE;
|
||||
}
|
||||
|
||||
@@ -609,7 +661,7 @@ static const struct wl_buffer_listener buffer_listener = {
|
||||
|
||||
static cairo_surface_t *
|
||||
gdk_wayland_create_cairo_surface (GdkWaylandDisplay *display,
|
||||
int width, int height)
|
||||
int width, int height, guint scale)
|
||||
{
|
||||
GdkWaylandCairoSurfaceData *data;
|
||||
cairo_surface_t *surface = NULL;
|
||||
@@ -621,29 +673,34 @@ gdk_wayland_create_cairo_surface (GdkWaylandDisplay *display,
|
||||
data->buffer = NULL;
|
||||
data->width = width;
|
||||
data->height = height;
|
||||
data->scale = scale;
|
||||
data->busy = FALSE;
|
||||
|
||||
stride = width * 4;
|
||||
|
||||
data->pool = _create_shm_pool (display->shm,
|
||||
width, height,
|
||||
width*scale, height*scale,
|
||||
&data->buf_length,
|
||||
&data->buf);
|
||||
|
||||
data->buffer = wl_shm_pool_create_buffer (data->pool, 0,
|
||||
width, height,
|
||||
stride, WL_SHM_FORMAT_ARGB8888);
|
||||
width*scale, height*scale,
|
||||
stride*scale, WL_SHM_FORMAT_ARGB8888);
|
||||
wl_buffer_add_listener (data->buffer, &buffer_listener, data);
|
||||
|
||||
surface = cairo_image_surface_create_for_data (data->buf,
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
width,
|
||||
height,
|
||||
stride);
|
||||
width*scale,
|
||||
height*scale,
|
||||
stride*scale);
|
||||
|
||||
cairo_surface_set_user_data (surface, &gdk_wayland_cairo_key,
|
||||
data, gdk_wayland_cairo_surface_destroy);
|
||||
|
||||
#ifdef HAVE_CAIRO_SURFACE_SET_DEVICE_SCALE
|
||||
cairo_surface_set_device_scale (surface, scale, scale);
|
||||
#endif
|
||||
|
||||
status = cairo_surface_status (surface);
|
||||
if (status != CAIRO_STATUS_SUCCESS)
|
||||
{
|
||||
@@ -665,8 +722,9 @@ gdk_wayland_window_ensure_cairo_surface (GdkWindow *window)
|
||||
|
||||
impl->cairo_surface =
|
||||
gdk_wayland_create_cairo_surface (display_wayland,
|
||||
impl->wrapper->width,
|
||||
impl->wrapper->height);
|
||||
impl->wrapper->width,
|
||||
impl->wrapper->height,
|
||||
impl->scale);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -727,7 +785,7 @@ gdk_wayland_window_configure (GdkWindow *window,
|
||||
|
||||
display = gdk_window_get_display (window);
|
||||
|
||||
/* TODO: Only generate a configure event if width or height have actually
|
||||
/* TODO: Only generate a configure event if width/height/scale have actually
|
||||
* changed?
|
||||
*/
|
||||
event = gdk_event_new (GDK_CONFIGURE);
|
||||
@@ -841,6 +899,8 @@ surface_enter (void *data,
|
||||
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
||||
|
||||
impl->outputs = g_slist_prepend (impl->outputs, output);
|
||||
|
||||
window_update_scale (window);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -852,8 +912,11 @@ surface_leave (void *data,
|
||||
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
||||
|
||||
impl->outputs = g_slist_remove (impl->outputs, output);
|
||||
|
||||
window_update_scale (window);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
shell_surface_handle_configure(void *data,
|
||||
struct wl_shell_surface *shell_surface,
|
||||
@@ -1174,8 +1237,8 @@ gdk_window_wayland_get_root_coords (GdkWindow *window,
|
||||
static gboolean
|
||||
gdk_window_wayland_get_device_state (GdkWindow *window,
|
||||
GdkDevice *device,
|
||||
gint *x,
|
||||
gint *y,
|
||||
gdouble *x,
|
||||
gdouble *y,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
gboolean return_val;
|
||||
@@ -1905,6 +1968,18 @@ gdk_wayland_window_delete_property (GdkWindow *window,
|
||||
{
|
||||
}
|
||||
|
||||
static gint
|
||||
gdk_wayland_window_get_scale_factor (GdkWindow *window)
|
||||
{
|
||||
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
||||
|
||||
if (GDK_WINDOW_DESTROYED (window))
|
||||
return 1;
|
||||
|
||||
return impl->scale;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_gdk_window_impl_wayland_class_init (GdkWindowImplWaylandClass *klass)
|
||||
{
|
||||
@@ -1991,6 +2066,7 @@ _gdk_window_impl_wayland_class_init (GdkWindowImplWaylandClass *klass)
|
||||
impl_class->get_property = gdk_wayland_window_get_property;
|
||||
impl_class->change_property = gdk_wayland_window_change_property;
|
||||
impl_class->delete_property = gdk_wayland_window_delete_property;
|
||||
impl_class->get_scale_factor = gdk_wayland_window_get_scale_factor;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -47,10 +47,10 @@ static void gdk_device_virtual_query_state (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
GdkWindow **root_window,
|
||||
GdkWindow **child_window,
|
||||
gint *root_x,
|
||||
gint *root_y,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *root_x,
|
||||
gdouble *root_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask);
|
||||
static GdkGrabStatus gdk_device_virtual_grab (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
@@ -62,8 +62,8 @@ static GdkGrabStatus gdk_device_virtual_grab (GdkDevice *device,
|
||||
static void gdk_device_virtual_ungrab (GdkDevice *device,
|
||||
guint32 time_);
|
||||
static GdkWindow * gdk_device_virtual_window_at_position (GdkDevice *device,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask,
|
||||
gboolean get_toplevel);
|
||||
static void gdk_device_virtual_select_window_events (GdkDevice *device,
|
||||
@@ -245,10 +245,10 @@ gdk_device_virtual_query_state (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
GdkWindow **root_window,
|
||||
GdkWindow **child_window,
|
||||
gint *root_x,
|
||||
gint *root_y,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *root_x,
|
||||
gdouble *root_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
GdkDeviceVirtual *virtual = GDK_DEVICE_VIRTUAL (device);
|
||||
@@ -342,8 +342,8 @@ screen_to_client (HWND hwnd, POINT screen_pt, POINT *client_pt)
|
||||
|
||||
static GdkWindow *
|
||||
gdk_device_virtual_window_at_position (GdkDevice *device,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask,
|
||||
gboolean get_toplevel)
|
||||
{
|
||||
|
||||
+14
-14
@@ -47,10 +47,10 @@ static void gdk_device_win32_query_state (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
GdkWindow **root_window,
|
||||
GdkWindow **child_window,
|
||||
gint *root_x,
|
||||
gint *root_y,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *root_x,
|
||||
gdouble *root_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask);
|
||||
static GdkGrabStatus gdk_device_win32_grab (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
@@ -62,8 +62,8 @@ static GdkGrabStatus gdk_device_win32_grab (GdkDevice *device,
|
||||
static void gdk_device_win32_ungrab (GdkDevice *device,
|
||||
guint32 time_);
|
||||
static GdkWindow * gdk_device_win32_window_at_position (GdkDevice *device,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask,
|
||||
gboolean get_toplevel);
|
||||
static void gdk_device_win32_select_window_events (GdkDevice *device,
|
||||
@@ -138,8 +138,8 @@ gdk_device_win32_set_window_cursor (GdkDevice *device,
|
||||
static void
|
||||
gdk_device_win32_warp (GdkDevice *device,
|
||||
GdkScreen *screen,
|
||||
gint x,
|
||||
gint y)
|
||||
gdouble x,
|
||||
gdouble y)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -174,10 +174,10 @@ gdk_device_win32_query_state (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
GdkWindow **root_window,
|
||||
GdkWindow **child_window,
|
||||
gint *root_x,
|
||||
gint *root_y,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *root_x,
|
||||
gdouble *root_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
POINT point;
|
||||
@@ -259,8 +259,8 @@ screen_to_client (HWND hwnd, POINT screen_pt, POINT *client_pt)
|
||||
|
||||
static GdkWindow *
|
||||
gdk_device_win32_window_at_position (GdkDevice *device,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask,
|
||||
gboolean get_toplevel)
|
||||
{
|
||||
|
||||
@@ -46,10 +46,10 @@ static void gdk_device_wintab_query_state (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
GdkWindow **root_window,
|
||||
GdkWindow **child_window,
|
||||
gint *root_x,
|
||||
gint *root_y,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *root_x,
|
||||
gdouble *root_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask);
|
||||
static GdkGrabStatus gdk_device_wintab_grab (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
@@ -61,8 +61,8 @@ static GdkGrabStatus gdk_device_wintab_grab (GdkDevice *device,
|
||||
static void gdk_device_wintab_ungrab (GdkDevice *device,
|
||||
guint32 time_);
|
||||
static GdkWindow * gdk_device_wintab_window_at_position (GdkDevice *device,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask,
|
||||
gboolean get_toplevel);
|
||||
static void gdk_device_wintab_select_window_events (GdkDevice *device,
|
||||
@@ -180,10 +180,10 @@ gdk_device_wintab_query_state (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
GdkWindow **root_window,
|
||||
GdkWindow **child_window,
|
||||
gint *root_x,
|
||||
gint *root_y,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *root_x,
|
||||
gdouble *root_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
GdkDeviceWintab *device_wintab;
|
||||
@@ -268,8 +268,8 @@ gdk_device_wintab_ungrab (GdkDevice *device,
|
||||
|
||||
static GdkWindow *
|
||||
gdk_device_wintab_window_at_position (GdkDevice *device,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask,
|
||||
gboolean get_toplevel)
|
||||
{
|
||||
|
||||
@@ -33,12 +33,6 @@
|
||||
#undef HAVE_MONITOR_INFO
|
||||
#endif
|
||||
|
||||
void
|
||||
_gdk_windowing_set_default_display (GdkDisplay *display)
|
||||
{
|
||||
g_assert (display == NULL || _gdk_display == display);
|
||||
}
|
||||
|
||||
static gulong
|
||||
gdk_win32_display_get_next_serial (GdkDisplay *display)
|
||||
{
|
||||
|
||||
@@ -2128,8 +2128,8 @@ gdk_win32_window_get_frame_extents (GdkWindow *window,
|
||||
static gboolean
|
||||
gdk_window_win32_get_device_state (GdkWindow *window,
|
||||
GdkDevice *device,
|
||||
gint *x,
|
||||
gint *y,
|
||||
gdouble *x,
|
||||
gdouble *y,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
GdkWindow *child;
|
||||
@@ -2143,27 +2143,6 @@ gdk_window_win32_get_device_state (GdkWindow *window,
|
||||
return (child != NULL);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_windowing_get_device_state (GdkDisplay *display,
|
||||
GdkDevice *device,
|
||||
GdkScreen **screen,
|
||||
gint *x,
|
||||
gint *y,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
g_return_if_fail (display == _gdk_display);
|
||||
|
||||
if (screen)
|
||||
*screen = _gdk_screen;
|
||||
|
||||
GDK_DEVICE_GET_CLASS (device)->query_state (device,
|
||||
gdk_screen_get_root_window (_gdk_screen),
|
||||
NULL, NULL,
|
||||
x, y,
|
||||
NULL, NULL,
|
||||
mask);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_display_warp_device (GdkDisplay *display,
|
||||
GdkDevice *device,
|
||||
@@ -2179,17 +2158,6 @@ gdk_display_warp_device (GdkDisplay *display,
|
||||
GDK_DEVICE_GET_CLASS (device)->warp (device, screen, x, y);
|
||||
}
|
||||
|
||||
GdkWindow*
|
||||
_gdk_windowing_window_at_device_position (GdkDisplay *display,
|
||||
GdkDevice *device,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
GdkModifierType *mask,
|
||||
gboolean get_toplevel)
|
||||
{
|
||||
return GDK_DEVICE_GET_CLASS (device)->window_at_position (device, win_x, win_y, mask, get_toplevel);
|
||||
}
|
||||
|
||||
static GdkEventMask
|
||||
gdk_win32_window_get_events (GdkWindow *window)
|
||||
{
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
#include "gdkx11device-core.h"
|
||||
#include "gdkdeviceprivate.h"
|
||||
|
||||
@@ -25,6 +26,11 @@
|
||||
#include "gdkprivate-x11.h"
|
||||
#include "gdkasync.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/* for the use of round() */
|
||||
#include "fallback-c89.c"
|
||||
|
||||
struct _GdkX11DeviceCore
|
||||
{
|
||||
GdkDevice parent_instance;
|
||||
@@ -50,16 +56,16 @@ static void gdk_x11_device_core_set_window_cursor (GdkDevice *device,
|
||||
GdkCursor *cursor);
|
||||
static void gdk_x11_device_core_warp (GdkDevice *device,
|
||||
GdkScreen *screen,
|
||||
gint x,
|
||||
gint y);
|
||||
gdouble x,
|
||||
gdouble y);
|
||||
static void gdk_x11_device_core_query_state (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
GdkWindow **root_window,
|
||||
GdkWindow **child_window,
|
||||
gint *root_x,
|
||||
gint *root_y,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *root_x,
|
||||
gdouble *root_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask);
|
||||
static GdkGrabStatus gdk_x11_device_core_grab (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
@@ -71,8 +77,8 @@ static GdkGrabStatus gdk_x11_device_core_grab (GdkDevice *device,
|
||||
static void gdk_x11_device_core_ungrab (GdkDevice *device,
|
||||
guint32 time_);
|
||||
static GdkWindow * gdk_x11_device_core_window_at_position (GdkDevice *device,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask,
|
||||
gboolean get_toplevel);
|
||||
static void gdk_x11_device_core_select_window_events (GdkDevice *device,
|
||||
@@ -135,10 +141,12 @@ gdk_x11_device_core_get_history (GdkDevice *device,
|
||||
XTimeCoord *xcoords;
|
||||
GdkTimeCoord **coords;
|
||||
GdkWindow *impl_window;
|
||||
GdkWindowImplX11 *impl;
|
||||
int tmp_n_events;
|
||||
int i, j;
|
||||
|
||||
impl_window = _gdk_window_get_impl_window (window);
|
||||
impl = GDK_WINDOW_IMPL_X11 (impl_window->impl);
|
||||
xcoords = XGetMotionEvents (GDK_WINDOW_XDISPLAY (window),
|
||||
GDK_WINDOW_XID (impl_window),
|
||||
start, stop, &tmp_n_events);
|
||||
@@ -149,11 +157,13 @@ gdk_x11_device_core_get_history (GdkDevice *device,
|
||||
|
||||
for (i = 0, j = 0; i < tmp_n_events; i++)
|
||||
{
|
||||
if (impl_coord_in_window (window, xcoords[i].x, xcoords[i].y))
|
||||
if (impl_coord_in_window (window,
|
||||
xcoords[i].x / impl->window_scale,
|
||||
xcoords[i].y / impl->window_scale))
|
||||
{
|
||||
coords[j]->time = xcoords[i].time;
|
||||
coords[j]->axes[0] = xcoords[i].x - window->abs_x;
|
||||
coords[j]->axes[1] = xcoords[i].y - window->abs_y;
|
||||
coords[j]->axes[0] = (double)xcoords[i].x / impl->window_scale - window->abs_x;
|
||||
coords[j]->axes[1] = (double)xcoords[i].y / impl->window_scale - window->abs_y;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
@@ -192,14 +202,14 @@ gdk_x11_device_core_get_state (GdkDevice *device,
|
||||
gdouble *axes,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
gint x_int, y_int;
|
||||
gdouble x, y;
|
||||
|
||||
gdk_window_get_device_position (window, device, &x_int, &y_int, mask);
|
||||
gdk_window_get_device_position_double (window, device, &x, &y, mask);
|
||||
|
||||
if (axes)
|
||||
{
|
||||
axes[0] = x_int;
|
||||
axes[1] = y_int;
|
||||
axes[0] = x;
|
||||
axes[1] = y;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,8 +233,8 @@ gdk_x11_device_core_set_window_cursor (GdkDevice *device,
|
||||
static void
|
||||
gdk_x11_device_core_warp (GdkDevice *device,
|
||||
GdkScreen *screen,
|
||||
gint x,
|
||||
gint y)
|
||||
gdouble x,
|
||||
gdouble y)
|
||||
{
|
||||
Display *xdisplay;
|
||||
Window dest;
|
||||
@@ -232,7 +242,9 @@ gdk_x11_device_core_warp (GdkDevice *device,
|
||||
xdisplay = GDK_DISPLAY_XDISPLAY (gdk_device_get_display (device));
|
||||
dest = GDK_WINDOW_XID (gdk_screen_get_root_window (screen));
|
||||
|
||||
XWarpPointer (xdisplay, None, dest, 0, 0, 0, 0, x, y);
|
||||
XWarpPointer (xdisplay, None, dest, 0, 0, 0, 0,
|
||||
round (x * GDK_X11_SCREEN (screen)->window_scale),
|
||||
round (y * GDK_X11_SCREEN (screen)->window_scale));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -240,12 +252,13 @@ gdk_x11_device_core_query_state (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
GdkWindow **root_window,
|
||||
GdkWindow **child_window,
|
||||
gint *root_x,
|
||||
gint *root_y,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *root_x,
|
||||
gdouble *root_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (window->impl);
|
||||
GdkDisplay *display;
|
||||
GdkScreen *default_screen;
|
||||
Window xroot_window, xchild_window;
|
||||
@@ -291,16 +304,16 @@ gdk_x11_device_core_query_state (GdkDevice *device,
|
||||
*child_window = gdk_x11_window_lookup_for_display (display, xchild_window);
|
||||
|
||||
if (root_x)
|
||||
*root_x = xroot_x;
|
||||
*root_x = (double)xroot_x / impl->window_scale;
|
||||
|
||||
if (root_y)
|
||||
*root_y = xroot_y;
|
||||
*root_y = (double)xroot_y / impl->window_scale;
|
||||
|
||||
if (win_x)
|
||||
*win_x = xwin_x;
|
||||
*win_x = (double)xwin_x / impl->window_scale;
|
||||
|
||||
if (win_y)
|
||||
*win_y = xwin_y;
|
||||
*win_y = (double)xwin_y / impl->window_scale;
|
||||
|
||||
if (mask)
|
||||
*mask = xmask;
|
||||
@@ -408,11 +421,12 @@ gdk_x11_device_core_ungrab (GdkDevice *device,
|
||||
|
||||
static GdkWindow *
|
||||
gdk_x11_device_core_window_at_position (GdkDevice *device,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask,
|
||||
gboolean get_toplevel)
|
||||
{
|
||||
GdkWindowImplX11 *impl;
|
||||
GdkDisplay *display;
|
||||
GdkScreen *screen;
|
||||
Display *xdisplay;
|
||||
@@ -464,6 +478,7 @@ gdk_x11_device_core_window_at_position (GdkDevice *device,
|
||||
for (list = toplevels; list != NULL; list = g_list_next (list))
|
||||
{
|
||||
window = GDK_WINDOW (list->data);
|
||||
impl = GDK_WINDOW_IMPL_X11 (window->impl);
|
||||
xwindow = GDK_WINDOW_XID (window);
|
||||
gdk_x11_display_error_trap_push (display);
|
||||
XQueryPointer (xdisplay, xwindow,
|
||||
@@ -479,7 +494,7 @@ gdk_x11_device_core_window_at_position (GdkDevice *device,
|
||||
break;
|
||||
}
|
||||
gdk_window_get_geometry (window, NULL, NULL, &width, &height);
|
||||
if (winx >= 0 && winy >= 0 && winx < width && winy < height)
|
||||
if (winx >= 0 && winy >= 0 && winx < width * impl->window_scale && winy < height * impl->window_scale)
|
||||
{
|
||||
/* A childless toplevel, or below another window? */
|
||||
XSetWindowAttributes attributes;
|
||||
@@ -532,12 +547,15 @@ gdk_x11_device_core_window_at_position (GdkDevice *device,
|
||||
gdk_x11_display_ungrab (display);
|
||||
|
||||
window = gdk_x11_window_lookup_for_display (display, last);
|
||||
impl = NULL;
|
||||
if (window)
|
||||
impl = GDK_WINDOW_IMPL_X11 (window->impl);
|
||||
|
||||
if (win_x)
|
||||
*win_x = (window) ? xwin_x : -1;
|
||||
*win_x = (window) ? (double)xwin_x / impl->window_scale : -1;
|
||||
|
||||
if (win_y)
|
||||
*win_y = (window) ? xwin_y : -1;
|
||||
*win_y = (window) ? (double)xwin_y / impl->window_scale : -1;
|
||||
|
||||
if (mask)
|
||||
*mask = xmask;
|
||||
|
||||
+34
-23
@@ -29,6 +29,10 @@
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/extensions/XInput2.h>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/* for the use of round() */
|
||||
#include "fallback-c89.c"
|
||||
|
||||
typedef struct _ScrollValuator ScrollValuator;
|
||||
|
||||
@@ -76,16 +80,16 @@ static void gdk_x11_device_xi2_set_window_cursor (GdkDevice *device,
|
||||
GdkCursor *cursor);
|
||||
static void gdk_x11_device_xi2_warp (GdkDevice *device,
|
||||
GdkScreen *screen,
|
||||
gint x,
|
||||
gint y);
|
||||
gdouble x,
|
||||
gdouble y);
|
||||
static void gdk_x11_device_xi2_query_state (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
GdkWindow **root_window,
|
||||
GdkWindow **child_window,
|
||||
gint *root_x,
|
||||
gint *root_y,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *root_x,
|
||||
gdouble *root_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask);
|
||||
|
||||
static GdkGrabStatus gdk_x11_device_xi2_grab (GdkDevice *device,
|
||||
@@ -99,8 +103,8 @@ static void gdk_x11_device_xi2_ungrab (GdkDevice *device,
|
||||
guint32 time_);
|
||||
|
||||
static GdkWindow * gdk_x11_device_xi2_window_at_position (GdkDevice *device,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask,
|
||||
gboolean get_toplevel);
|
||||
static void gdk_x11_device_xi2_select_window_events (GdkDevice *device,
|
||||
@@ -292,8 +296,8 @@ gdk_x11_device_xi2_set_window_cursor (GdkDevice *device,
|
||||
static void
|
||||
gdk_x11_device_xi2_warp (GdkDevice *device,
|
||||
GdkScreen *screen,
|
||||
gint x,
|
||||
gint y)
|
||||
gdouble x,
|
||||
gdouble y)
|
||||
{
|
||||
GdkX11DeviceXI2 *device_xi2 = GDK_X11_DEVICE_XI2 (device);
|
||||
Window dest;
|
||||
@@ -303,7 +307,9 @@ gdk_x11_device_xi2_warp (GdkDevice *device,
|
||||
XIWarpPointer (GDK_SCREEN_XDISPLAY (screen),
|
||||
device_xi2->device_id,
|
||||
None, dest,
|
||||
0, 0, 0, 0, x, y);
|
||||
0, 0, 0, 0,
|
||||
round (x * GDK_X11_SCREEN(screen)->window_scale),
|
||||
round (y * GDK_X11_SCREEN(screen)->window_scale));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -311,12 +317,13 @@ gdk_x11_device_xi2_query_state (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
GdkWindow **root_window,
|
||||
GdkWindow **child_window,
|
||||
gint *root_x,
|
||||
gint *root_y,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *root_x,
|
||||
gdouble *root_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (window->impl);
|
||||
GdkX11DeviceXI2 *device_xi2 = GDK_X11_DEVICE_XI2 (device);
|
||||
GdkDisplay *display;
|
||||
GdkScreen *default_screen;
|
||||
@@ -381,16 +388,16 @@ gdk_x11_device_xi2_query_state (GdkDevice *device,
|
||||
*child_window = gdk_x11_window_lookup_for_display (display, xchild_window);
|
||||
|
||||
if (root_x)
|
||||
*root_x = (gint) xroot_x;
|
||||
*root_x = xroot_x / impl->window_scale;
|
||||
|
||||
if (root_y)
|
||||
*root_y = (gint) xroot_y;
|
||||
*root_y = xroot_y / impl->window_scale;
|
||||
|
||||
if (win_x)
|
||||
*win_x = (gint) xwin_x;
|
||||
*win_x = xwin_x / impl->window_scale;
|
||||
|
||||
if (win_y)
|
||||
*win_y = (gint) xwin_y;
|
||||
*win_y = xwin_y / impl->window_scale;
|
||||
|
||||
if (mask)
|
||||
*mask = _gdk_x11_device_xi2_translate_state (&mod_state, &button_state, &group_state);
|
||||
@@ -474,11 +481,12 @@ gdk_x11_device_xi2_ungrab (GdkDevice *device,
|
||||
|
||||
static GdkWindow *
|
||||
gdk_x11_device_xi2_window_at_position (GdkDevice *device,
|
||||
gint *win_x,
|
||||
gint *win_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask,
|
||||
gboolean get_toplevel)
|
||||
{
|
||||
GdkWindowImplX11 *impl;
|
||||
GdkX11DeviceXI2 *device_xi2 = GDK_X11_DEVICE_XI2 (device);
|
||||
GdkDisplay *display;
|
||||
GdkScreen *screen;
|
||||
@@ -624,12 +632,15 @@ gdk_x11_device_xi2_window_at_position (GdkDevice *device,
|
||||
gdk_x11_display_ungrab (display);
|
||||
|
||||
window = gdk_x11_window_lookup_for_display (display, last);
|
||||
impl = NULL;
|
||||
if (window)
|
||||
impl = GDK_WINDOW_IMPL_X11 (window->impl);
|
||||
|
||||
if (win_x)
|
||||
*win_x = (window) ? (gint) xwin_x : -1;
|
||||
*win_x = (window) ? (xwin_x / impl->window_scale) : -1;
|
||||
|
||||
if (win_y)
|
||||
*win_y = (window) ? (gint) xwin_y : -1;
|
||||
*win_y = (window) ? (xwin_y / impl->window_scale) : -1;
|
||||
|
||||
if (mask)
|
||||
*mask = _gdk_x11_device_xi2_translate_state (&mod_state, &button_state, &group_state);
|
||||
|
||||
@@ -332,9 +332,11 @@ gdk_x11_device_manager_core_translate_event (GdkEventTranslator *translator,
|
||||
GdkEvent *event,
|
||||
XEvent *xevent)
|
||||
{
|
||||
GdkWindowImplX11 *impl;
|
||||
GdkX11DeviceManagerCore *device_manager;
|
||||
GdkWindow *window;
|
||||
gboolean return_val;
|
||||
int scale;
|
||||
GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
|
||||
|
||||
device_manager = GDK_X11_DEVICE_MANAGER_CORE (translator);
|
||||
@@ -342,14 +344,18 @@ gdk_x11_device_manager_core_translate_event (GdkEventTranslator *translator,
|
||||
|
||||
window = get_event_window (translator, xevent);
|
||||
|
||||
scale = 1;
|
||||
if (window)
|
||||
{
|
||||
if (GDK_WINDOW_DESTROYED (window) || !GDK_IS_WINDOW (window))
|
||||
return FALSE;
|
||||
|
||||
g_object_ref (window);
|
||||
impl = GDK_WINDOW_IMPL_X11 (window->impl);
|
||||
scale = impl->window_scale;
|
||||
}
|
||||
|
||||
|
||||
event->any.window = window;
|
||||
event->any.send_event = xevent->xany.send_event ? TRUE : FALSE;
|
||||
|
||||
@@ -458,10 +464,10 @@ gdk_x11_device_manager_core_translate_event (GdkEventTranslator *translator,
|
||||
|
||||
event->scroll.window = window;
|
||||
event->scroll.time = xevent->xbutton.time;
|
||||
event->scroll.x = (gdouble) xevent->xbutton.x;
|
||||
event->scroll.y = (gdouble) xevent->xbutton.y;
|
||||
event->scroll.x_root = (gdouble) xevent->xbutton.x_root;
|
||||
event->scroll.y_root = (gdouble) xevent->xbutton.y_root;
|
||||
event->scroll.x = (gdouble) xevent->xbutton.x / scale;
|
||||
event->scroll.y = (gdouble) xevent->xbutton.y / scale;
|
||||
event->scroll.x_root = (gdouble) xevent->xbutton.x_root / scale;
|
||||
event->scroll.y_root = (gdouble) xevent->xbutton.y_root / scale;
|
||||
event->scroll.state = (GdkModifierType) xevent->xbutton.state;
|
||||
event->scroll.device = device_manager->core_pointer;
|
||||
|
||||
@@ -480,10 +486,10 @@ gdk_x11_device_manager_core_translate_event (GdkEventTranslator *translator,
|
||||
event->button.type = GDK_BUTTON_PRESS;
|
||||
event->button.window = window;
|
||||
event->button.time = xevent->xbutton.time;
|
||||
event->button.x = (gdouble) xevent->xbutton.x;
|
||||
event->button.y = (gdouble) xevent->xbutton.y;
|
||||
event->button.x_root = (gdouble) xevent->xbutton.x_root;
|
||||
event->button.y_root = (gdouble) xevent->xbutton.y_root;
|
||||
event->button.x = (gdouble) xevent->xbutton.x / scale;
|
||||
event->button.y = (gdouble) xevent->xbutton.y / scale;
|
||||
event->button.x_root = (gdouble) xevent->xbutton.x_root / scale;
|
||||
event->button.y_root = (gdouble) xevent->xbutton.y_root / scale;
|
||||
event->button.axes = NULL;
|
||||
event->button.state = (GdkModifierType) xevent->xbutton.state;
|
||||
event->button.button = xevent->xbutton.button;
|
||||
@@ -523,10 +529,10 @@ gdk_x11_device_manager_core_translate_event (GdkEventTranslator *translator,
|
||||
event->button.type = GDK_BUTTON_RELEASE;
|
||||
event->button.window = window;
|
||||
event->button.time = xevent->xbutton.time;
|
||||
event->button.x = (gdouble) xevent->xbutton.x;
|
||||
event->button.y = (gdouble) xevent->xbutton.y;
|
||||
event->button.x_root = (gdouble) xevent->xbutton.x_root;
|
||||
event->button.y_root = (gdouble) xevent->xbutton.y_root;
|
||||
event->button.x = (gdouble) xevent->xbutton.x / scale;
|
||||
event->button.y = (gdouble) xevent->xbutton.y / scale;
|
||||
event->button.x_root = (gdouble) xevent->xbutton.x_root / scale;
|
||||
event->button.y_root = (gdouble) xevent->xbutton.y_root / scale;
|
||||
event->button.axes = NULL;
|
||||
event->button.state = (GdkModifierType) xevent->xbutton.state;
|
||||
event->button.button = xevent->xbutton.button;
|
||||
@@ -553,10 +559,10 @@ gdk_x11_device_manager_core_translate_event (GdkEventTranslator *translator,
|
||||
event->motion.type = GDK_MOTION_NOTIFY;
|
||||
event->motion.window = window;
|
||||
event->motion.time = xevent->xmotion.time;
|
||||
event->motion.x = (gdouble) xevent->xmotion.x;
|
||||
event->motion.y = (gdouble) xevent->xmotion.y;
|
||||
event->motion.x_root = (gdouble) xevent->xmotion.x_root;
|
||||
event->motion.y_root = (gdouble) xevent->xmotion.y_root;
|
||||
event->motion.x = (gdouble) xevent->xmotion.x / scale;
|
||||
event->motion.y = (gdouble) xevent->xmotion.y / scale;
|
||||
event->motion.x_root = (gdouble) xevent->xmotion.x_root / scale;
|
||||
event->motion.y_root = (gdouble) xevent->xmotion.y_root / scale;
|
||||
event->motion.axes = NULL;
|
||||
event->motion.state = (GdkModifierType) xevent->xmotion.state;
|
||||
event->motion.is_hint = xevent->xmotion.is_hint;
|
||||
@@ -602,10 +608,10 @@ gdk_x11_device_manager_core_translate_event (GdkEventTranslator *translator,
|
||||
event->crossing.subwindow = NULL;
|
||||
|
||||
event->crossing.time = xevent->xcrossing.time;
|
||||
event->crossing.x = (gdouble) xevent->xcrossing.x;
|
||||
event->crossing.y = (gdouble) xevent->xcrossing.y;
|
||||
event->crossing.x_root = (gdouble) xevent->xcrossing.x_root;
|
||||
event->crossing.y_root = (gdouble) xevent->xcrossing.y_root;
|
||||
event->crossing.x = (gdouble) xevent->xcrossing.x / scale;
|
||||
event->crossing.y = (gdouble) xevent->xcrossing.y / scale;
|
||||
event->crossing.x_root = (gdouble) xevent->xcrossing.x_root / scale;
|
||||
event->crossing.y_root = (gdouble) xevent->xcrossing.y_root / scale;
|
||||
|
||||
event->crossing.mode = translate_crossing_mode (xevent->xcrossing.mode);
|
||||
event->crossing.detail = translate_notify_type (xevent->xcrossing.detail);
|
||||
@@ -646,10 +652,10 @@ gdk_x11_device_manager_core_translate_event (GdkEventTranslator *translator,
|
||||
event->crossing.subwindow = NULL;
|
||||
|
||||
event->crossing.time = xevent->xcrossing.time;
|
||||
event->crossing.x = (gdouble) xevent->xcrossing.x;
|
||||
event->crossing.y = (gdouble) xevent->xcrossing.y;
|
||||
event->crossing.x_root = (gdouble) xevent->xcrossing.x_root;
|
||||
event->crossing.y_root = (gdouble) xevent->xcrossing.y_root;
|
||||
event->crossing.x = (gdouble) xevent->xcrossing.x / scale;
|
||||
event->crossing.y = (gdouble) xevent->xcrossing.y / scale;
|
||||
event->crossing.x_root = (gdouble) xevent->xcrossing.x_root / scale;
|
||||
event->crossing.y_root = (gdouble) xevent->xcrossing.y_root / scale;
|
||||
|
||||
event->crossing.mode = translate_crossing_mode (xevent->xcrossing.mode);
|
||||
event->crossing.detail = translate_notify_type (xevent->xcrossing.detail);
|
||||
|
||||
@@ -1113,6 +1113,8 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
XGenericEventCookie *cookie;
|
||||
gboolean return_val = TRUE;
|
||||
GdkWindow *window;
|
||||
GdkWindowImplX11 *impl;
|
||||
int scale;
|
||||
XIEvent *ev;
|
||||
|
||||
device_manager = (GdkX11DeviceManagerXI2 *) translator;
|
||||
@@ -1134,6 +1136,13 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
if (window && GDK_WINDOW_DESTROYED (window))
|
||||
return FALSE;
|
||||
|
||||
scale = 1;
|
||||
if (window)
|
||||
{
|
||||
impl = GDK_WINDOW_IMPL_X11 (window->impl);
|
||||
scale = impl->window_scale;
|
||||
}
|
||||
|
||||
if (ev->evtype == XI_Motion ||
|
||||
ev->evtype == XI_ButtonRelease)
|
||||
{
|
||||
@@ -1230,10 +1239,10 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
|
||||
event->scroll.window = window;
|
||||
event->scroll.time = xev->time;
|
||||
event->scroll.x = (gdouble) xev->event_x;
|
||||
event->scroll.y = (gdouble) xev->event_y;
|
||||
event->scroll.x_root = (gdouble) xev->root_x;
|
||||
event->scroll.y_root = (gdouble) xev->root_y;
|
||||
event->scroll.x = (gdouble) xev->event_x / scale;
|
||||
event->scroll.y = (gdouble) xev->event_y / scale;
|
||||
event->scroll.x_root = (gdouble) xev->root_x / scale;
|
||||
event->scroll.y_root = (gdouble) xev->root_y / scale;
|
||||
event->scroll.delta_x = 0;
|
||||
event->scroll.delta_y = 0;
|
||||
|
||||
@@ -1257,10 +1266,10 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
|
||||
event->button.window = window;
|
||||
event->button.time = xev->time;
|
||||
event->button.x = (gdouble) xev->event_x;
|
||||
event->button.y = (gdouble) xev->event_y;
|
||||
event->button.x_root = (gdouble) xev->root_x;
|
||||
event->button.y_root = (gdouble) xev->root_y;
|
||||
event->button.x = (gdouble) xev->event_x / scale;
|
||||
event->button.y = (gdouble) xev->event_y / scale;
|
||||
event->button.x_root = (gdouble) xev->root_x / scale;
|
||||
event->button.y_root = (gdouble) xev->root_y / scale;
|
||||
|
||||
event->button.device = g_hash_table_lookup (device_manager->id_table,
|
||||
GUINT_TO_POINTER (xev->deviceid));
|
||||
@@ -1348,10 +1357,10 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
|
||||
event->scroll.window = window;
|
||||
event->scroll.time = xev->time;
|
||||
event->scroll.x = (gdouble) xev->event_x;
|
||||
event->scroll.y = (gdouble) xev->event_y;
|
||||
event->scroll.x_root = (gdouble) xev->root_x;
|
||||
event->scroll.y_root = (gdouble) xev->root_y;
|
||||
event->scroll.x = (gdouble) xev->event_x / scale;
|
||||
event->scroll.y = (gdouble) xev->event_y / scale;
|
||||
event->scroll.x_root = (gdouble) xev->root_x / scale;
|
||||
event->scroll.y_root = (gdouble) xev->root_y / scale;
|
||||
event->scroll.delta_x = delta_x;
|
||||
event->scroll.delta_y = delta_y;
|
||||
|
||||
@@ -1365,10 +1374,10 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
event->motion.type = GDK_MOTION_NOTIFY;
|
||||
event->motion.window = window;
|
||||
event->motion.time = xev->time;
|
||||
event->motion.x = (gdouble) xev->event_x;
|
||||
event->motion.y = (gdouble) xev->event_y;
|
||||
event->motion.x_root = (gdouble) xev->root_x;
|
||||
event->motion.y_root = (gdouble) xev->root_y;
|
||||
event->motion.x = (gdouble) xev->event_x / scale;
|
||||
event->motion.y = (gdouble) xev->event_y / scale;
|
||||
event->motion.x_root = (gdouble) xev->root_x / scale;
|
||||
event->motion.y_root = (gdouble) xev->root_y / scale;
|
||||
|
||||
event->motion.device = device;
|
||||
gdk_event_set_source_device (event, source_device);
|
||||
@@ -1421,10 +1430,10 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
|
||||
event->touch.window = window;
|
||||
event->touch.time = xev->time;
|
||||
event->touch.x = (gdouble) xev->event_x;
|
||||
event->touch.y = (gdouble) xev->event_y;
|
||||
event->touch.x_root = (gdouble) xev->root_x;
|
||||
event->touch.y_root = (gdouble) xev->root_y;
|
||||
event->touch.x = (gdouble) xev->event_x / scale;
|
||||
event->touch.y = (gdouble) xev->event_y / scale;
|
||||
event->touch.x_root = (gdouble) xev->root_x / scale;
|
||||
event->touch.y_root = (gdouble) xev->root_y / scale;
|
||||
|
||||
event->touch.device = g_hash_table_lookup (device_manager->id_table,
|
||||
GUINT_TO_POINTER (xev->deviceid));
|
||||
@@ -1490,10 +1499,10 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
event->touch.sequence = GUINT_TO_POINTER (xev->detail);
|
||||
event->touch.type = GDK_TOUCH_UPDATE;
|
||||
event->touch.time = xev->time;
|
||||
event->touch.x = (gdouble) xev->event_x;
|
||||
event->touch.y = (gdouble) xev->event_y;
|
||||
event->touch.x_root = (gdouble) xev->root_x;
|
||||
event->touch.y_root = (gdouble) xev->root_y;
|
||||
event->touch.x = (gdouble) xev->event_x / scale;
|
||||
event->touch.y = (gdouble) xev->event_y / scale;
|
||||
event->touch.x_root = (gdouble) xev->root_x / scale;
|
||||
event->touch.y_root = (gdouble) xev->root_y / scale;
|
||||
|
||||
event->touch.device = g_hash_table_lookup (device_manager->id_table,
|
||||
GINT_TO_POINTER (xev->deviceid));
|
||||
@@ -1538,10 +1547,10 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
|
||||
event->crossing.type = (ev->evtype == XI_Enter) ? GDK_ENTER_NOTIFY : GDK_LEAVE_NOTIFY;
|
||||
|
||||
event->crossing.x = (gdouble) xev->event_x;
|
||||
event->crossing.y = (gdouble) xev->event_y;
|
||||
event->crossing.x_root = (gdouble) xev->root_x;
|
||||
event->crossing.y_root = (gdouble) xev->root_y;
|
||||
event->crossing.x = (gdouble) xev->event_x / scale;
|
||||
event->crossing.y = (gdouble) xev->event_y / scale;
|
||||
event->crossing.x_root = (gdouble) xev->root_x / scale;
|
||||
event->crossing.y_root = (gdouble) xev->root_y / scale;
|
||||
event->crossing.time = xev->time;
|
||||
event->crossing.focus = xev->focus;
|
||||
|
||||
|
||||
+36
-22
@@ -558,11 +558,16 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
|
||||
|
||||
{
|
||||
GdkRectangle expose_rect;
|
||||
int x2, y2;
|
||||
|
||||
expose_rect.x = xevent->xexpose.x;
|
||||
expose_rect.y = xevent->xexpose.y;
|
||||
expose_rect.width = xevent->xexpose.width;
|
||||
expose_rect.height = xevent->xexpose.height;
|
||||
expose_rect.x = xevent->xexpose.x / window_impl->window_scale;
|
||||
expose_rect.y = xevent->xexpose.y / window_impl->window_scale;
|
||||
|
||||
x2 = (xevent->xexpose.x + xevent->xexpose.width + window_impl->window_scale -1) / window_impl->window_scale;
|
||||
expose_rect.width = x2 - expose_rect.x;
|
||||
|
||||
y2 = (xevent->xexpose.y + xevent->xexpose.height + window_impl->window_scale -1) / window_impl->window_scale;
|
||||
expose_rect.height = y2 - expose_rect.y;
|
||||
|
||||
_gdk_x11_window_process_expose (window, xevent->xexpose.serial, &expose_rect);
|
||||
return_val = FALSE;
|
||||
@@ -573,6 +578,7 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
|
||||
case GraphicsExpose:
|
||||
{
|
||||
GdkRectangle expose_rect;
|
||||
int x2, y2;
|
||||
|
||||
GDK_NOTE (EVENTS,
|
||||
g_message ("graphics expose:\tdrawable: %ld",
|
||||
@@ -584,10 +590,14 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
|
||||
break;
|
||||
}
|
||||
|
||||
expose_rect.x = xevent->xgraphicsexpose.x;
|
||||
expose_rect.y = xevent->xgraphicsexpose.y;
|
||||
expose_rect.width = xevent->xgraphicsexpose.width;
|
||||
expose_rect.height = xevent->xgraphicsexpose.height;
|
||||
expose_rect.x = xevent->xgraphicsexpose.x / window_impl->window_scale;
|
||||
expose_rect.y = xevent->xgraphicsexpose.y / window_impl->window_scale;
|
||||
|
||||
x2 = (xevent->xgraphicsexpose.x + xevent->xgraphicsexpose.width + window_impl->window_scale -1) / window_impl->window_scale;
|
||||
expose_rect.width = x2 - expose_rect.x;
|
||||
|
||||
y2 = (xevent->xgraphicsexpose.y + xevent->xgraphicsexpose.height + window_impl->window_scale -1) / window_impl->window_scale;
|
||||
expose_rect.height = y2 - expose_rect.y;
|
||||
|
||||
_gdk_x11_window_process_expose (window, xevent->xgraphicsexpose.serial, &expose_rect);
|
||||
return_val = FALSE;
|
||||
@@ -773,8 +783,8 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
|
||||
: ""));
|
||||
if (window && GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT)
|
||||
{
|
||||
window->width = xevent->xconfigure.width;
|
||||
window->height = xevent->xconfigure.height;
|
||||
window->width = xevent->xconfigure.width / window_impl->window_scale;
|
||||
window->height = xevent->xconfigure.height / window_impl->window_scale;
|
||||
|
||||
_gdk_window_update_size (window);
|
||||
_gdk_x11_window_update_size (GDK_WINDOW_IMPL_X11 (window->impl));
|
||||
@@ -799,8 +809,8 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
|
||||
{
|
||||
event->configure.type = GDK_CONFIGURE;
|
||||
event->configure.window = window;
|
||||
event->configure.width = xevent->xconfigure.width;
|
||||
event->configure.height = xevent->xconfigure.height;
|
||||
event->configure.width = xevent->xconfigure.width / window_impl->window_scale;
|
||||
event->configure.height = xevent->xconfigure.height / window_impl->window_scale;
|
||||
|
||||
if (!xevent->xconfigure.send_event &&
|
||||
!xevent->xconfigure.override_redirect &&
|
||||
@@ -818,22 +828,22 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
|
||||
&tx, &ty,
|
||||
&child_window))
|
||||
{
|
||||
event->configure.x = tx;
|
||||
event->configure.y = ty;
|
||||
event->configure.x = tx / window_impl->window_scale;
|
||||
event->configure.y = ty / window_impl->window_scale;
|
||||
}
|
||||
gdk_x11_display_error_trap_pop_ignored (display);
|
||||
}
|
||||
else
|
||||
{
|
||||
event->configure.x = xevent->xconfigure.x;
|
||||
event->configure.y = xevent->xconfigure.y;
|
||||
event->configure.x = xevent->xconfigure.x / window_impl->window_scale;
|
||||
event->configure.y = xevent->xconfigure.y / window_impl->window_scale;
|
||||
}
|
||||
if (!is_substructure)
|
||||
{
|
||||
window->x = event->configure.x;
|
||||
window->y = event->configure.y;
|
||||
window->width = xevent->xconfigure.width;
|
||||
window->height = xevent->xconfigure.height;
|
||||
window->width = xevent->xconfigure.width / window_impl->window_scale;
|
||||
window->height = xevent->xconfigure.height / window_impl->window_scale;
|
||||
|
||||
_gdk_window_update_size (window);
|
||||
_gdk_x11_window_update_size (GDK_WINDOW_IMPL_X11 (window->impl));
|
||||
@@ -1015,11 +1025,15 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
|
||||
XDamageNotifyEvent *damage_event = (XDamageNotifyEvent *) xevent;
|
||||
XserverRegion repair;
|
||||
GdkRectangle rect;
|
||||
int x2, y2;
|
||||
|
||||
rect.x = window->x + damage_event->area.x;
|
||||
rect.y = window->y + damage_event->area.y;
|
||||
rect.width = damage_event->area.width;
|
||||
rect.height = damage_event->area.height;
|
||||
rect.x = window->x + damage_event->area.x / window_impl->window_scale;
|
||||
rect.y = window->y + damage_event->area.y / window_impl->window_scale;
|
||||
|
||||
x2 = (rect.x * window_impl->window_scale + damage_event->area.width + window_impl->window_scale -1) / window_impl->window_scale;
|
||||
y2 = (rect.y * window_impl->window_scale + damage_event->area.height + window_impl->window_scale -1) / window_impl->window_scale;
|
||||
rect.width = x2 - rect.x;
|
||||
rect.height = y2 - rect.y;
|
||||
|
||||
repair = XFixesCreateRegion (display_x11->xdisplay,
|
||||
&damage_event->area, 1);
|
||||
|
||||
+25
-10
@@ -510,15 +510,19 @@ gdk_window_cache_new (GdkScreen *screen)
|
||||
{
|
||||
GList *toplevel_windows, *list;
|
||||
GdkWindow *window;
|
||||
GdkWindowImplX11 *impl;
|
||||
gint x, y, width, height;
|
||||
|
||||
toplevel_windows = gdk_screen_get_toplevel_windows (screen);
|
||||
for (list = toplevel_windows; list; list = list->next)
|
||||
{
|
||||
window = GDK_WINDOW (list->data);
|
||||
impl = GDK_WINDOW_IMPL_X11 (window->impl);
|
||||
gdk_window_get_geometry (window, &x, &y, &width, &height);
|
||||
gdk_window_cache_add (result, GDK_WINDOW_XID (window),
|
||||
x, y, width, height,
|
||||
x * impl->window_scale, y * impl->window_scale,
|
||||
width * impl->window_scale,
|
||||
height * impl->window_scale,
|
||||
gdk_window_is_visible (window));
|
||||
}
|
||||
g_list_free (toplevel_windows);
|
||||
@@ -556,7 +560,10 @@ gdk_window_cache_new (GdkScreen *screen)
|
||||
if (gdk_screen_is_composited (screen))
|
||||
{
|
||||
cow = XCompositeGetOverlayWindow (xdisplay, GDK_WINDOW_XID (root_window));
|
||||
gdk_window_cache_add (result, cow, 0, 0, gdk_screen_get_width (screen), gdk_screen_get_height (screen), TRUE);
|
||||
gdk_window_cache_add (result, cow, 0, 0,
|
||||
gdk_screen_get_width (screen) * GDK_X11_SCREEN(screen)->window_scale,
|
||||
gdk_screen_get_height (screen) * GDK_X11_SCREEN(screen)->window_scale,
|
||||
TRUE);
|
||||
XCompositeReleaseOverlayWindow (xdisplay, GDK_WINDOW_XID (root_window));
|
||||
}
|
||||
#endif
|
||||
@@ -651,12 +658,12 @@ is_pointer_within_shape (GdkDisplay *display,
|
||||
child->shape = NULL;
|
||||
if (gdk_display_supports_shapes (display))
|
||||
child->shape = _gdk_x11_xwindow_get_shape (display_x11->xdisplay,
|
||||
child->xid, ShapeBounding);
|
||||
child->xid, 1, ShapeBounding);
|
||||
#ifdef ShapeInput
|
||||
input_shape = NULL;
|
||||
if (gdk_display_supports_input_shapes (display))
|
||||
input_shape = _gdk_x11_xwindow_get_shape (display_x11->xdisplay,
|
||||
child->xid, ShapeInput);
|
||||
child->xid, 1, ShapeInput);
|
||||
|
||||
if (child->shape && input_shape)
|
||||
{
|
||||
@@ -1744,6 +1751,7 @@ xdnd_position_filter (GdkXEvent *xev,
|
||||
GdkEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
GdkWindowImplX11 *impl;
|
||||
XEvent *xevent = (XEvent *)xev;
|
||||
guint32 source_window = xevent->xclient.data.l[0];
|
||||
gint16 x_root = xevent->xclient.data.l[2] >> 16;
|
||||
@@ -1774,6 +1782,8 @@ xdnd_position_filter (GdkXEvent *xev,
|
||||
(context->protocol == GDK_DRAG_PROTO_XDND) &&
|
||||
(GDK_WINDOW_XID (context->source_window) == source_window))
|
||||
{
|
||||
impl = GDK_WINDOW_IMPL_X11 (event->any.window->impl);
|
||||
|
||||
context_x11 = GDK_X11_DRAG_CONTEXT (context);
|
||||
|
||||
event->dnd.type = GDK_DRAG_MOTION;
|
||||
@@ -1788,11 +1798,11 @@ xdnd_position_filter (GdkXEvent *xev,
|
||||
if (!context_x11->xdnd_have_actions)
|
||||
context->actions = context->suggested_action;
|
||||
|
||||
event->dnd.x_root = x_root;
|
||||
event->dnd.y_root = y_root;
|
||||
event->dnd.x_root = x_root / impl->window_scale;
|
||||
event->dnd.y_root = y_root / impl->window_scale;
|
||||
|
||||
context_x11->last_x = x_root;
|
||||
context_x11->last_y = y_root;
|
||||
context_x11->last_x = x_root / impl->window_scale;
|
||||
context_x11->last_y = y_root / impl->window_scale;
|
||||
|
||||
return GDK_FILTER_TRANSLATE;
|
||||
}
|
||||
@@ -2015,6 +2025,7 @@ gdk_x11_drag_context_find_window (GdkDragContext *context,
|
||||
gint y_root,
|
||||
GdkDragProtocol *protocol)
|
||||
{
|
||||
GdkX11Screen *screen_x11 = GDK_X11_SCREEN(screen);
|
||||
GdkX11DragContext *context_x11 = GDK_X11_DRAG_CONTEXT (context);
|
||||
GdkWindowCache *window_cache;
|
||||
GdkDisplay *display;
|
||||
@@ -2028,7 +2039,8 @@ gdk_x11_drag_context_find_window (GdkDragContext *context,
|
||||
dest = get_client_window_at_coords (window_cache,
|
||||
drag_window && GDK_WINDOW_IS_X11 (drag_window) ?
|
||||
GDK_WINDOW_XID (drag_window) : None,
|
||||
x_root, y_root);
|
||||
x_root * screen_x11->window_scale,
|
||||
y_root * screen_x11->window_scale);
|
||||
|
||||
if (context_x11->dest_xid != dest)
|
||||
{
|
||||
@@ -2075,6 +2087,7 @@ gdk_x11_drag_context_drag_motion (GdkDragContext *context,
|
||||
guint32 time)
|
||||
{
|
||||
GdkX11DragContext *context_x11 = GDK_X11_DRAG_CONTEXT (context);
|
||||
GdkWindowImplX11 *impl;
|
||||
|
||||
context_x11->old_actions = context->actions;
|
||||
context->actions = possible_actions;
|
||||
@@ -2198,12 +2211,14 @@ gdk_x11_drag_context_drag_motion (GdkDragContext *context,
|
||||
|
||||
if (context->dest_window)
|
||||
{
|
||||
impl = GDK_WINDOW_IMPL_X11 (context->dest_window->impl);
|
||||
|
||||
if (context_x11->drag_status == GDK_DRAG_STATUS_DRAG)
|
||||
{
|
||||
switch (context->protocol)
|
||||
{
|
||||
case GDK_DRAG_PROTO_XDND:
|
||||
xdnd_send_motion (context_x11, x_root, y_root, suggested_action, time);
|
||||
xdnd_send_motion (context_x11, x_root * impl->window_scale, y_root * impl->window_scale, suggested_action, time);
|
||||
break;
|
||||
|
||||
case GDK_DRAG_PROTO_ROOTWIN:
|
||||
|
||||
@@ -42,18 +42,22 @@ _gdk_x11_window_move_resize_child (GdkWindow *window,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
GdkWindowImplX11 *impl;
|
||||
|
||||
g_return_if_fail (window != NULL);
|
||||
g_return_if_fail (GDK_IS_WINDOW (window));
|
||||
|
||||
if (width > 65535 ||
|
||||
height > 65535)
|
||||
impl = GDK_WINDOW_IMPL_X11 (window->impl);
|
||||
|
||||
if (width * impl->window_scale > 65535 ||
|
||||
height * impl->window_scale > 65535)
|
||||
{
|
||||
g_warning ("Native children wider or taller than 65535 pixels are not supported");
|
||||
|
||||
if (width > 65535)
|
||||
width = 65535;
|
||||
if (height > 65535)
|
||||
height = 65535;
|
||||
if (width * impl->window_scale > 65535)
|
||||
width = 65535 / impl->window_scale;
|
||||
if (height * impl->window_scale > 65535)
|
||||
height = 65535 / impl->window_scale;
|
||||
}
|
||||
|
||||
window->x = x;
|
||||
@@ -69,9 +73,10 @@ _gdk_x11_window_move_resize_child (GdkWindow *window,
|
||||
_gdk_x11_window_tmp_unset_bg (window, TRUE);
|
||||
XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window),
|
||||
GDK_WINDOW_XID (window),
|
||||
window->x + window->parent->abs_x,
|
||||
window->y + window->parent->abs_y,
|
||||
width, height);
|
||||
(window->x + window->parent->abs_x) * impl->window_scale,
|
||||
(window->y + window->parent->abs_y) * impl->window_scale,
|
||||
width * impl->window_scale,
|
||||
height * impl->window_scale);
|
||||
_gdk_x11_window_tmp_reset_parent_bg (window);
|
||||
_gdk_x11_window_tmp_reset_bg (window, TRUE);
|
||||
}
|
||||
|
||||
@@ -368,6 +368,7 @@ void
|
||||
_gdk_x11_region_get_xrectangles (const cairo_region_t *region,
|
||||
gint x_offset,
|
||||
gint y_offset,
|
||||
gint scale,
|
||||
XRectangle **rects,
|
||||
gint *n_rects)
|
||||
{
|
||||
@@ -381,10 +382,10 @@ _gdk_x11_region_get_xrectangles (const cairo_region_t *region,
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
cairo_region_get_rectangle (region, i, &box);
|
||||
rectangles[i].x = CLAMP (box.x + x_offset, G_MINSHORT, G_MAXSHORT);
|
||||
rectangles[i].y = CLAMP (box.y + y_offset, G_MINSHORT, G_MAXSHORT);
|
||||
rectangles[i].width = CLAMP (box.width, G_MINSHORT, G_MAXSHORT);
|
||||
rectangles[i].height = CLAMP (box.height, G_MINSHORT, G_MAXSHORT);
|
||||
rectangles[i].x = CLAMP ((box.x + x_offset) * scale, G_MINSHORT, G_MAXSHORT);
|
||||
rectangles[i].y = CLAMP ((box.y + y_offset) * scale, G_MINSHORT, G_MAXSHORT);
|
||||
rectangles[i].width = CLAMP (box.width * scale, G_MINSHORT, G_MAXSHORT);
|
||||
rectangles[i].height = CLAMP (box.height * scale, G_MINSHORT, G_MAXSHORT);
|
||||
}
|
||||
|
||||
*n_rects = n;
|
||||
|
||||
@@ -140,11 +140,13 @@ gboolean _gdk_x11_selection_filter_clear_event (XSelectionClearEvent *event);
|
||||
|
||||
cairo_region_t* _gdk_x11_xwindow_get_shape (Display *xdisplay,
|
||||
Window window,
|
||||
gint scale,
|
||||
gint shape_type);
|
||||
|
||||
void _gdk_x11_region_get_xrectangles (const cairo_region_t *region,
|
||||
gint x_offset,
|
||||
gint y_offset,
|
||||
gint scale,
|
||||
XRectangle **rects,
|
||||
gint *n_rects);
|
||||
|
||||
|
||||
+65
-6
@@ -96,13 +96,13 @@ gdk_x11_screen_get_display (GdkScreen *screen)
|
||||
static gint
|
||||
gdk_x11_screen_get_width (GdkScreen *screen)
|
||||
{
|
||||
return WidthOfScreen (GDK_X11_SCREEN (screen)->xscreen);
|
||||
return WidthOfScreen (GDK_X11_SCREEN (screen)->xscreen) / GDK_X11_SCREEN (screen)->window_scale;
|
||||
}
|
||||
|
||||
static gint
|
||||
gdk_x11_screen_get_height (GdkScreen *screen)
|
||||
{
|
||||
return HeightOfScreen (GDK_X11_SCREEN (screen)->xscreen);
|
||||
return HeightOfScreen (GDK_X11_SCREEN (screen)->xscreen) / GDK_X11_SCREEN (screen)->window_scale;
|
||||
}
|
||||
|
||||
static gint
|
||||
@@ -253,7 +253,13 @@ gdk_x11_screen_get_monitor_geometry (GdkScreen *screen,
|
||||
GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen);
|
||||
|
||||
if (dest)
|
||||
*dest = x11_screen->monitors[monitor_num].geometry;
|
||||
{
|
||||
*dest = x11_screen->monitors[monitor_num].geometry;
|
||||
dest->x /= x11_screen->window_scale;
|
||||
dest->y /= x11_screen->window_scale;
|
||||
dest->width /= x11_screen->window_scale;
|
||||
dest->height /= x11_screen->window_scale;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -297,6 +303,7 @@ static void
|
||||
get_work_area (GdkScreen *screen,
|
||||
GdkRectangle *area)
|
||||
{
|
||||
GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen);
|
||||
Atom workarea;
|
||||
Atom type;
|
||||
Window win;
|
||||
@@ -318,8 +325,8 @@ get_work_area (GdkScreen *screen,
|
||||
/* Defaults in case of error */
|
||||
area->x = 0;
|
||||
area->y = 0;
|
||||
area->width = gdk_screen_get_width (screen);
|
||||
area->height = gdk_screen_get_height (screen);
|
||||
area->width = gdk_screen_get_width (screen) / x11_screen->window_scale;
|
||||
area->height = gdk_screen_get_height (screen) / x11_screen->window_scale;
|
||||
|
||||
if (!gdk_x11_screen_supports_net_wm_hint (screen,
|
||||
gdk_atom_intern_static_string ("_NET_WORKAREA")))
|
||||
@@ -356,6 +363,11 @@ get_work_area (GdkScreen *screen,
|
||||
area->width = workareas[desktop * 4 + 2];
|
||||
area->height = workareas[desktop * 4 + 3];
|
||||
|
||||
area->x /= x11_screen->window_scale;
|
||||
area->y /= x11_screen->window_scale;
|
||||
area->width /= x11_screen->window_scale;
|
||||
area->height /= x11_screen->window_scale;
|
||||
|
||||
XFree (ret_workarea);
|
||||
}
|
||||
|
||||
@@ -382,6 +394,15 @@ gdk_x11_screen_get_monitor_workarea (GdkScreen *screen,
|
||||
}
|
||||
}
|
||||
|
||||
static gint
|
||||
gdk_x11_screen_get_monitor_scale_factor (GdkScreen *screen,
|
||||
gint monitor_num)
|
||||
{
|
||||
GdkX11Screen *screen_x11 = GDK_X11_SCREEN (screen);
|
||||
|
||||
return screen_x11->window_scale;
|
||||
}
|
||||
|
||||
static GdkVisual *
|
||||
gdk_x11_screen_get_rgba_visual (GdkScreen *screen)
|
||||
{
|
||||
@@ -1029,6 +1050,7 @@ _gdk_x11_screen_new (GdkDisplay *display,
|
||||
GdkScreen *screen;
|
||||
GdkX11Screen *x11_screen;
|
||||
GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
|
||||
const char *scale_str;
|
||||
|
||||
screen = g_object_new (GDK_TYPE_X11_SCREEN, NULL);
|
||||
|
||||
@@ -1041,7 +1063,22 @@ _gdk_x11_screen_new (GdkDisplay *display,
|
||||
x11_screen->wmspec_check_window = None;
|
||||
/* we want this to be always non-null */
|
||||
x11_screen->window_manager_name = g_strdup ("unknown");
|
||||
|
||||
|
||||
#ifdef HAVE_CAIRO_SURFACE_SET_DEVICE_SCALE
|
||||
scale_str = g_getenv ("GDK_SCALE");
|
||||
#else
|
||||
scale_str = NULL;
|
||||
#endif
|
||||
if (scale_str)
|
||||
{
|
||||
x11_screen->fixed_window_scale = TRUE;
|
||||
x11_screen->window_scale = atol (scale_str);
|
||||
if (x11_screen->window_scale == 0)
|
||||
x11_screen->window_scale = 1;
|
||||
}
|
||||
else
|
||||
x11_screen->window_scale = 1;
|
||||
|
||||
init_multihead (screen);
|
||||
init_randr_support (screen);
|
||||
|
||||
@@ -1051,6 +1088,27 @@ _gdk_x11_screen_new (GdkDisplay *display,
|
||||
return screen;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_x11_screen_set_window_scale (GdkX11Screen *x11_screen,
|
||||
int scale)
|
||||
{
|
||||
GList *toplevels, *l;
|
||||
|
||||
if (x11_screen->window_scale == scale)
|
||||
return;
|
||||
|
||||
x11_screen->window_scale = scale;
|
||||
|
||||
toplevels = gdk_screen_get_toplevel_windows (GDK_SCREEN (x11_screen));
|
||||
|
||||
for (l = toplevels; l != NULL; l = l->next)
|
||||
{
|
||||
GdkWindow *window = l->data;
|
||||
|
||||
_gdk_x11_window_set_window_scale (window, scale);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* It is important that we first request the selection
|
||||
* notification, and then setup the initial state of
|
||||
@@ -1627,6 +1685,7 @@ gdk_x11_screen_class_init (GdkX11ScreenClass *klass)
|
||||
screen_class->get_monitor_plug_name = gdk_x11_screen_get_monitor_plug_name;
|
||||
screen_class->get_monitor_geometry = gdk_x11_screen_get_monitor_geometry;
|
||||
screen_class->get_monitor_workarea = gdk_x11_screen_get_monitor_workarea;
|
||||
screen_class->get_monitor_scale_factor = gdk_x11_screen_get_monitor_scale_factor;
|
||||
screen_class->get_system_visual = _gdk_x11_screen_get_system_visual;
|
||||
screen_class->get_rgba_visual = gdk_x11_screen_get_rgba_visual;
|
||||
screen_class->is_composited = gdk_x11_screen_is_composited;
|
||||
|
||||
@@ -47,6 +47,9 @@ struct _GdkX11Screen
|
||||
GdkX11Monitor *monitors;
|
||||
gint primary_monitor;
|
||||
|
||||
gint window_scale;
|
||||
gboolean fixed_window_scale;
|
||||
|
||||
/* Xft resources for the display, used for default values for
|
||||
* the Xft/ XSETTINGS
|
||||
*/
|
||||
@@ -119,6 +122,8 @@ void _gdk_x11_screen_get_edge_monitors (GdkScreen *screen,
|
||||
gint *bottom,
|
||||
gint *left,
|
||||
gint *right);
|
||||
void _gdk_x11_screen_set_window_scale (GdkX11Screen *x11_screen,
|
||||
int scale);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -62,7 +62,12 @@ static const struct {
|
||||
{"Gtk/ShellShowsMenubar", "gtk-shell-shows-menubar"},
|
||||
{"Gtk/EnablePrimaryPaste", "gtk-enable-primary-paste"},
|
||||
{"Gtk/RecentFilesMaxAge", "gtk-recent-files-max-age"},
|
||||
{"Gtk/RecentFilesEnabled", "gtk-recent-files-enabled"}
|
||||
{"Gtk/RecentFilesEnabled", "gtk-recent-files-enabled"},
|
||||
|
||||
/* These are here in order to be recognized, but are not sent to
|
||||
gtk as they are handled internally by gdk: */
|
||||
{"Gdk/WindowScalingFactor", "gdk-window-scaling-factor"},
|
||||
{"Gdk/UnscaledDPI", "gdk-unscaled-dpi"}
|
||||
};
|
||||
|
||||
static const char *
|
||||
|
||||
+213
-74
@@ -156,6 +156,7 @@ gdk_window_impl_x11_init (GdkWindowImplX11 *impl)
|
||||
{
|
||||
impl->device_cursor = g_hash_table_new_full (NULL, NULL,
|
||||
NULL, g_object_unref);
|
||||
impl->window_scale = 1;
|
||||
}
|
||||
|
||||
GdkToplevelX11 *
|
||||
@@ -194,8 +195,8 @@ _gdk_x11_window_update_size (GdkWindowImplX11 *impl)
|
||||
if (impl->cairo_surface)
|
||||
{
|
||||
cairo_xlib_surface_set_size (impl->cairo_surface,
|
||||
gdk_window_get_width (impl->wrapper),
|
||||
gdk_window_get_height (impl->wrapper));
|
||||
gdk_window_get_width (impl->wrapper) * impl->window_scale,
|
||||
gdk_window_get_height (impl->wrapper) * impl->window_scale);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -464,8 +465,11 @@ gdk_x11_ref_cairo_surface (GdkWindow *window)
|
||||
if (!impl->cairo_surface)
|
||||
{
|
||||
impl->cairo_surface = gdk_x11_create_cairo_surface (impl,
|
||||
gdk_window_get_width (window),
|
||||
gdk_window_get_height (window));
|
||||
gdk_window_get_width (window) * impl->window_scale,
|
||||
gdk_window_get_height (window) * impl->window_scale);
|
||||
#ifdef HAVE_CAIRO_SURFACE_SET_DEVICE_SCALE
|
||||
cairo_surface_set_device_scale (impl->cairo_surface, impl->window_scale, impl->window_scale);
|
||||
#endif
|
||||
|
||||
if (impl->cairo_surface)
|
||||
cairo_surface_set_user_data (impl->cairo_surface, &gdk_x11_cairo_key,
|
||||
@@ -727,6 +731,7 @@ _gdk_x11_screen_init_root_window (GdkScreen *screen)
|
||||
|
||||
impl->xid = x11_screen->xroot_window;
|
||||
impl->wrapper = window;
|
||||
impl->window_scale = x11_screen->window_scale;
|
||||
|
||||
window->window_type = GDK_WINDOW_ROOT;
|
||||
window->depth = DefaultDepthOfScreen (x11_screen->xscreen);
|
||||
@@ -735,8 +740,8 @@ _gdk_x11_screen_init_root_window (GdkScreen *screen)
|
||||
window->y = 0;
|
||||
window->abs_x = 0;
|
||||
window->abs_y = 0;
|
||||
window->width = WidthOfScreen (x11_screen->xscreen);
|
||||
window->height = HeightOfScreen (x11_screen->xscreen);
|
||||
window->width = WidthOfScreen (x11_screen->xscreen) / impl->window_scale;
|
||||
window->height = HeightOfScreen (x11_screen->xscreen) / impl->window_scale;
|
||||
window->viewable = TRUE;
|
||||
|
||||
/* see init_randr_support() in gdkscreen-x11.c */
|
||||
@@ -872,6 +877,7 @@ setup_toplevel_window (GdkWindow *window,
|
||||
GdkWindow *parent)
|
||||
{
|
||||
GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
|
||||
GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (window->impl);
|
||||
GdkDisplay *display = gdk_window_get_display (window);
|
||||
Display *xdisplay = GDK_WINDOW_XDISPLAY (window);
|
||||
XID xid = GDK_WINDOW_XID (window);
|
||||
@@ -900,8 +906,8 @@ setup_toplevel_window (GdkWindow *window,
|
||||
* correct value???
|
||||
*/
|
||||
size_hints.flags = PSize;
|
||||
size_hints.width = window->width;
|
||||
size_hints.height = window->height;
|
||||
size_hints.width = window->width * impl->window_scale;
|
||||
size_hints.height = window->height * impl->window_scale;
|
||||
|
||||
XSetWMNormalHints (xdisplay, xid, &size_hints);
|
||||
|
||||
@@ -1006,6 +1012,7 @@ _gdk_x11_display_create_window_impl (GdkDisplay *display,
|
||||
impl = g_object_new (GDK_TYPE_WINDOW_IMPL_X11, NULL);
|
||||
window->impl = GDK_WINDOW_IMPL (impl);
|
||||
impl->wrapper = GDK_WINDOW (window);
|
||||
impl->window_scale = x11_screen->window_scale;
|
||||
|
||||
xdisplay = x11_screen->xdisplay;
|
||||
|
||||
@@ -1076,21 +1083,21 @@ _gdk_x11_display_create_window_impl (GdkDisplay *display,
|
||||
class = InputOnly;
|
||||
}
|
||||
|
||||
if (window->width > 65535 ||
|
||||
window->height > 65535)
|
||||
if (window->width * impl->window_scale > 65535 ||
|
||||
window->height * impl->window_scale > 65535)
|
||||
{
|
||||
g_warning ("Native Windows wider or taller than 65535 pixels are not supported");
|
||||
|
||||
if (window->width > 65535)
|
||||
window->width = 65535;
|
||||
if (window->height > 65535)
|
||||
window->height = 65535;
|
||||
if (window->width * impl->window_scale > 65535)
|
||||
window->width = 65535 / impl->window_scale;
|
||||
if (window->height * impl->window_scale > 65535)
|
||||
window->height = 65535 / impl->window_scale;
|
||||
}
|
||||
|
||||
impl->xid = XCreateWindow (xdisplay, xparent,
|
||||
window->x + window->parent->abs_x,
|
||||
window->y + window->parent->abs_y,
|
||||
window->width, window->height,
|
||||
(window->x + window->parent->abs_x) * impl->window_scale,
|
||||
(window->y + window->parent->abs_y) * impl->window_scale,
|
||||
window->width * impl->window_scale, window->height * impl->window_scale,
|
||||
0, window->depth, class, xvisual,
|
||||
xattributes_mask, &xattributes);
|
||||
|
||||
@@ -1219,6 +1226,7 @@ gdk_x11_window_foreign_new_for_display (GdkDisplay *display,
|
||||
|
||||
impl = GDK_WINDOW_IMPL_X11 (win->impl);
|
||||
impl->wrapper = win;
|
||||
impl->window_scale = GDK_X11_SCREEN (screen)->window_scale;
|
||||
|
||||
win->parent = gdk_x11_window_lookup_for_display (display, parent);
|
||||
|
||||
@@ -1231,10 +1239,10 @@ gdk_x11_window_foreign_new_for_display (GdkDisplay *display,
|
||||
|
||||
impl->xid = window;
|
||||
|
||||
win->x = attrs.x;
|
||||
win->y = attrs.y;
|
||||
win->width = attrs.width;
|
||||
win->height = attrs.height;
|
||||
win->x = attrs.x / impl->window_scale;
|
||||
win->y = attrs.y / impl->window_scale;
|
||||
win->width = attrs.width / impl->window_scale;
|
||||
win->height = attrs.height / impl->window_scale;
|
||||
win->window_type = GDK_WINDOW_FOREIGN;
|
||||
win->destroyed = FALSE;
|
||||
|
||||
@@ -1765,7 +1773,7 @@ window_x11_move (GdkWindow *window,
|
||||
{
|
||||
XMoveWindow (GDK_WINDOW_XDISPLAY (window),
|
||||
GDK_WINDOW_XID (window),
|
||||
x, y);
|
||||
x * impl->window_scale, y * impl->window_scale);
|
||||
|
||||
if (impl->override_redirect)
|
||||
{
|
||||
@@ -1800,7 +1808,7 @@ window_x11_resize (GdkWindow *window,
|
||||
|
||||
XResizeWindow (GDK_WINDOW_XDISPLAY (window),
|
||||
GDK_WINDOW_XID (window),
|
||||
width, height);
|
||||
width * impl->window_scale, height * impl->window_scale);
|
||||
|
||||
if (impl->override_redirect)
|
||||
{
|
||||
@@ -1814,8 +1822,6 @@ window_x11_resize (GdkWindow *window,
|
||||
window->resize_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
_gdk_x11_window_update_size (GDK_WINDOW_IMPL_X11 (window->impl));
|
||||
}
|
||||
|
||||
static inline void
|
||||
@@ -1844,7 +1850,8 @@ window_x11_move_resize (GdkWindow *window,
|
||||
|
||||
XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window),
|
||||
GDK_WINDOW_XID (window),
|
||||
x, y, width, height);
|
||||
x * impl->window_scale, y * impl->window_scale,
|
||||
width * impl->window_scale, height * impl->window_scale);
|
||||
|
||||
if (impl->override_redirect)
|
||||
{
|
||||
@@ -1883,6 +1890,75 @@ gdk_window_x11_move_resize (GdkWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_scale_recursive (GdkWindow *window, int scale)
|
||||
{
|
||||
GdkWindow *child;
|
||||
GList *l;
|
||||
|
||||
for (l = window->children; l; l = l->next)
|
||||
{
|
||||
child = l->data;
|
||||
|
||||
if (child->impl != window->impl)
|
||||
_gdk_x11_window_set_window_scale (child, scale);
|
||||
else
|
||||
set_scale_recursive (child, scale);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_x11_window_set_window_scale (GdkWindow *window,
|
||||
int scale)
|
||||
{
|
||||
GdkWindowImplX11 *impl;
|
||||
GdkToplevelX11 *toplevel;
|
||||
GdkWindowHints geom_mask;
|
||||
|
||||
if (window->window_type == GDK_WINDOW_OFFSCREEN)
|
||||
return;
|
||||
|
||||
g_print ("_gdk_x11_window_set_window_scale %p %d\n", window, scale);
|
||||
|
||||
impl = GDK_WINDOW_IMPL_X11 (window->impl);
|
||||
|
||||
impl->window_scale = scale;
|
||||
|
||||
toplevel = _gdk_x11_window_get_toplevel (window);
|
||||
if (toplevel && window->window_type != GDK_WINDOW_FOREIGN)
|
||||
{
|
||||
/* These are affected by window scale: */
|
||||
geom_mask = toplevel->last_geometry_hints_mask &
|
||||
(GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE | GDK_HINT_BASE_SIZE | GDK_HINT_RESIZE_INC);
|
||||
if (geom_mask)
|
||||
gdk_window_set_geometry_hints (window,
|
||||
&toplevel->last_geometry_hints,
|
||||
geom_mask);
|
||||
}
|
||||
|
||||
if (window->window_type == GDK_WINDOW_FOREIGN)
|
||||
XMoveWindow (GDK_WINDOW_XDISPLAY (window),
|
||||
GDK_WINDOW_XID (window),
|
||||
(window->x + window->parent->abs_x) * impl->window_scale,
|
||||
(window->y + window->parent->abs_y) * impl->window_scale);
|
||||
else if (WINDOW_IS_TOPLEVEL(window))
|
||||
XResizeWindow (GDK_WINDOW_XDISPLAY (window),
|
||||
GDK_WINDOW_XID (window),
|
||||
window->width * impl->window_scale,
|
||||
window->height * impl->window_scale);
|
||||
else
|
||||
XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window),
|
||||
GDK_WINDOW_XID (window),
|
||||
(window->x + window->parent->abs_x) * impl->window_scale,
|
||||
(window->y + window->parent->abs_y) * impl->window_scale,
|
||||
window->width * impl->window_scale,
|
||||
window->height * impl->window_scale);
|
||||
|
||||
gdk_window_invalidate_rect (window, NULL, TRUE);
|
||||
|
||||
set_scale_recursive (window, scale);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_window_x11_reparent (GdkWindow *window,
|
||||
GdkWindow *new_parent,
|
||||
@@ -1898,7 +1974,8 @@ gdk_window_x11_reparent (GdkWindow *window,
|
||||
XReparentWindow (GDK_WINDOW_XDISPLAY (window),
|
||||
GDK_WINDOW_XID (window),
|
||||
GDK_WINDOW_XID (new_parent),
|
||||
new_parent->abs_x + x, new_parent->abs_y + y);
|
||||
(new_parent->abs_x + x) * impl->window_scale,
|
||||
(new_parent->abs_y + y) * impl->window_scale);
|
||||
_gdk_x11_window_tmp_reset_parent_bg (window);
|
||||
_gdk_x11_window_tmp_reset_bg (window, TRUE);
|
||||
|
||||
@@ -2390,11 +2467,20 @@ gdk_x11_window_set_geometry_hints (GdkWindow *window,
|
||||
const GdkGeometry *geometry,
|
||||
GdkWindowHints geom_mask)
|
||||
{
|
||||
GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (window->impl);
|
||||
XSizeHints size_hints;
|
||||
|
||||
GdkToplevelX11 *toplevel;
|
||||
|
||||
if (GDK_WINDOW_DESTROYED (window) ||
|
||||
!WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
|
||||
return;
|
||||
|
||||
toplevel = _gdk_x11_window_get_toplevel (window);
|
||||
if (toplevel)
|
||||
{
|
||||
toplevel->last_geometry_hints = *geometry;
|
||||
toplevel->last_geometry_hints_mask = geom_mask;
|
||||
}
|
||||
|
||||
size_hints.flags = 0;
|
||||
|
||||
@@ -2422,31 +2508,37 @@ gdk_x11_window_set_geometry_hints (GdkWindow *window,
|
||||
if (geom_mask & GDK_HINT_MIN_SIZE)
|
||||
{
|
||||
size_hints.flags |= PMinSize;
|
||||
size_hints.min_width = geometry->min_width;
|
||||
size_hints.min_height = geometry->min_height;
|
||||
size_hints.min_width = geometry->min_width * impl->window_scale;
|
||||
size_hints.min_height = geometry->min_height * impl->window_scale;
|
||||
}
|
||||
|
||||
if (geom_mask & GDK_HINT_MAX_SIZE)
|
||||
{
|
||||
size_hints.flags |= PMaxSize;
|
||||
size_hints.max_width = MAX (geometry->max_width, 1);
|
||||
size_hints.max_height = MAX (geometry->max_height, 1);
|
||||
size_hints.max_width = MAX (geometry->max_width, 1) * impl->window_scale;
|
||||
size_hints.max_height = MAX (geometry->max_height, 1) * impl->window_scale;
|
||||
}
|
||||
|
||||
if (geom_mask & GDK_HINT_BASE_SIZE)
|
||||
{
|
||||
size_hints.flags |= PBaseSize;
|
||||
size_hints.base_width = geometry->base_width;
|
||||
size_hints.base_height = geometry->base_height;
|
||||
size_hints.base_width = geometry->base_width * impl->window_scale;
|
||||
size_hints.base_height = geometry->base_height * impl->window_scale;
|
||||
}
|
||||
|
||||
if (geom_mask & GDK_HINT_RESIZE_INC)
|
||||
{
|
||||
size_hints.flags |= PResizeInc;
|
||||
size_hints.width_inc = geometry->width_inc;
|
||||
size_hints.height_inc = geometry->height_inc;
|
||||
size_hints.width_inc = geometry->width_inc * impl->window_scale;
|
||||
size_hints.height_inc = geometry->height_inc * impl->window_scale;
|
||||
}
|
||||
|
||||
else if (impl->window_scale > 1)
|
||||
{
|
||||
size_hints.flags |= PResizeInc;
|
||||
size_hints.width_inc = impl->window_scale;
|
||||
size_hints.height_inc = impl->window_scale;
|
||||
}
|
||||
|
||||
if (geom_mask & GDK_HINT_ASPECT)
|
||||
{
|
||||
size_hints.flags |= PAspect;
|
||||
@@ -2491,6 +2583,7 @@ gdk_window_get_geometry_hints (GdkWindow *window,
|
||||
GdkGeometry *geometry,
|
||||
GdkWindowHints *geom_mask)
|
||||
{
|
||||
GdkWindowImplX11 *impl;
|
||||
XSizeHints *size_hints;
|
||||
glong junk_supplied_mask = 0;
|
||||
|
||||
@@ -2504,6 +2597,8 @@ gdk_window_get_geometry_hints (GdkWindow *window,
|
||||
!WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
|
||||
return;
|
||||
|
||||
impl = GDK_WINDOW_IMPL_X11 (window->impl);
|
||||
|
||||
size_hints = XAllocSizeHints ();
|
||||
if (!size_hints)
|
||||
return;
|
||||
@@ -2517,22 +2612,22 @@ gdk_window_get_geometry_hints (GdkWindow *window,
|
||||
if (size_hints->flags & PMinSize)
|
||||
{
|
||||
*geom_mask |= GDK_HINT_MIN_SIZE;
|
||||
geometry->min_width = size_hints->min_width;
|
||||
geometry->min_height = size_hints->min_height;
|
||||
geometry->min_width = size_hints->min_width / impl->window_scale;
|
||||
geometry->min_height = size_hints->min_height / impl->window_scale;
|
||||
}
|
||||
|
||||
if (size_hints->flags & PMaxSize)
|
||||
{
|
||||
*geom_mask |= GDK_HINT_MAX_SIZE;
|
||||
geometry->max_width = MAX (size_hints->max_width, 1);
|
||||
geometry->max_height = MAX (size_hints->max_height, 1);
|
||||
geometry->max_width = MAX (size_hints->max_width, 1) / impl->window_scale;
|
||||
geometry->max_height = MAX (size_hints->max_height, 1) / impl->window_scale;
|
||||
}
|
||||
|
||||
if (size_hints->flags & PResizeInc)
|
||||
{
|
||||
*geom_mask |= GDK_HINT_RESIZE_INC;
|
||||
geometry->width_inc = size_hints->width_inc;
|
||||
geometry->height_inc = size_hints->height_inc;
|
||||
geometry->width_inc = size_hints->width_inc / impl->window_scale;
|
||||
geometry->height_inc = size_hints->height_inc / impl->window_scale;
|
||||
}
|
||||
|
||||
if (size_hints->flags & PAspect)
|
||||
@@ -2793,6 +2888,7 @@ static void
|
||||
gdk_window_x11_set_background (GdkWindow *window,
|
||||
cairo_pattern_t *pattern)
|
||||
{
|
||||
GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (window->impl);
|
||||
double r, g, b, a;
|
||||
cairo_surface_t *surface;
|
||||
cairo_matrix_t matrix;
|
||||
@@ -2831,12 +2927,17 @@ gdk_window_x11_set_background (GdkWindow *window,
|
||||
cairo_xlib_surface_get_visual (surface) == GDK_VISUAL_XVISUAL (gdk_window_get_visual ((window))) &&
|
||||
cairo_xlib_surface_get_display (surface) == GDK_WINDOW_XDISPLAY (window))
|
||||
{
|
||||
double x, y;
|
||||
double x, y, sx, sy;
|
||||
|
||||
cairo_surface_get_device_offset (surface, &x, &y);
|
||||
sx = sy = 1.;
|
||||
#ifdef HAVE_CAIRO_SURFACE_SET_DEVICE_SCALE
|
||||
cairo_surface_get_device_scale (surface, &sx, &sy);
|
||||
#endif
|
||||
/* XXX: This still bombs for non-pixmaps, but there's no way to
|
||||
* detect we're not a pixmap in Cairo... */
|
||||
if (x == 0.0 && y == 0.0)
|
||||
if (x == 0.0 && y == 0.0 &&
|
||||
sx == impl->window_scale && sy == impl->window_scale)
|
||||
{
|
||||
XSetWindowBackgroundPixmap (GDK_WINDOW_XDISPLAY (window),
|
||||
GDK_WINDOW_XID (window),
|
||||
@@ -2900,6 +3001,7 @@ gdk_window_x11_get_geometry (GdkWindow *window,
|
||||
gint *width,
|
||||
gint *height)
|
||||
{
|
||||
GdkWindowImplX11 *impl;
|
||||
Window root;
|
||||
gint tx;
|
||||
gint ty;
|
||||
@@ -2910,18 +3012,20 @@ gdk_window_x11_get_geometry (GdkWindow *window,
|
||||
|
||||
if (!GDK_WINDOW_DESTROYED (window))
|
||||
{
|
||||
impl = GDK_WINDOW_IMPL_X11 (window->impl);
|
||||
|
||||
XGetGeometry (GDK_WINDOW_XDISPLAY (window),
|
||||
GDK_WINDOW_XID (window),
|
||||
&root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
|
||||
|
||||
if (x)
|
||||
*x = tx;
|
||||
*x = tx / impl->window_scale;
|
||||
if (y)
|
||||
*y = ty;
|
||||
*y = ty / impl->window_scale;
|
||||
if (width)
|
||||
*width = twidth;
|
||||
*width = twidth / impl->window_scale;
|
||||
if (height)
|
||||
*height = theight;
|
||||
*height = theight / impl->window_scale;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2932,6 +3036,7 @@ gdk_window_x11_get_root_coords (GdkWindow *window,
|
||||
gint *root_x,
|
||||
gint *root_y)
|
||||
{
|
||||
GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (window->impl);
|
||||
gint return_val;
|
||||
Window child;
|
||||
gint tx;
|
||||
@@ -2940,13 +3045,13 @@ gdk_window_x11_get_root_coords (GdkWindow *window,
|
||||
return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window),
|
||||
GDK_WINDOW_XID (window),
|
||||
GDK_WINDOW_XROOTWIN (window),
|
||||
x, y, &tx, &ty,
|
||||
x * impl->window_scale, y * impl->window_scale, &tx, &ty,
|
||||
&child);
|
||||
|
||||
if (root_x)
|
||||
*root_x = tx;
|
||||
*root_x = tx / impl->window_scale;
|
||||
if (root_y)
|
||||
*root_y = ty;
|
||||
*root_y = ty / impl->window_scale;
|
||||
|
||||
return return_val;
|
||||
}
|
||||
@@ -3001,13 +3106,14 @@ gdk_x11_window_get_frame_extents (GdkWindow *window,
|
||||
while (window->parent && (window->parent)->parent)
|
||||
window = window->parent;
|
||||
|
||||
/* Refine our fallback answer a bit using local information */
|
||||
rect->x = window->x;
|
||||
rect->y = window->y;
|
||||
rect->width = window->width;
|
||||
rect->height = window->height;
|
||||
|
||||
impl = GDK_WINDOW_IMPL_X11 (window->impl);
|
||||
|
||||
/* Refine our fallback answer a bit using local information */
|
||||
rect->x = window->x * impl->window_scale;
|
||||
rect->y = window->y * impl->window_scale;
|
||||
rect->width = window->width * impl->window_scale;
|
||||
rect->height = window->height * impl->window_scale;
|
||||
|
||||
if (GDK_WINDOW_DESTROYED (window) || impl->override_redirect)
|
||||
return;
|
||||
|
||||
@@ -3126,14 +3232,18 @@ gdk_x11_window_get_frame_extents (GdkWindow *window,
|
||||
if (vroots)
|
||||
XFree (vroots);
|
||||
|
||||
rect->x /= impl->window_scale;
|
||||
rect->y /= impl->window_scale;
|
||||
rect->width /= impl->window_scale;
|
||||
rect->height /= impl->window_scale;
|
||||
gdk_x11_display_error_trap_pop_ignored (display);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_window_x11_get_device_state (GdkWindow *window,
|
||||
GdkDevice *device,
|
||||
gint *x,
|
||||
gint *y,
|
||||
gdouble *x,
|
||||
gdouble *y,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
GdkWindow *child;
|
||||
@@ -3143,6 +3253,7 @@ gdk_window_x11_get_device_state (GdkWindow *window,
|
||||
if (GDK_WINDOW_DESTROYED (window))
|
||||
return FALSE;
|
||||
|
||||
/*HIDPI: handle coords here?*/
|
||||
GDK_DEVICE_GET_CLASS (device)->query_state (device, window,
|
||||
NULL, &child,
|
||||
NULL, NULL,
|
||||
@@ -3199,6 +3310,8 @@ do_shape_combine_region (GdkWindow *window,
|
||||
gint offset_y,
|
||||
gint shape)
|
||||
{
|
||||
GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (window->impl);
|
||||
|
||||
if (GDK_WINDOW_DESTROYED (window))
|
||||
return;
|
||||
|
||||
@@ -3237,7 +3350,7 @@ do_shape_combine_region (GdkWindow *window,
|
||||
XRectangle *xrects = NULL;
|
||||
|
||||
_gdk_x11_region_get_xrectangles (shape_region,
|
||||
0, 0,
|
||||
0, 0, impl->window_scale,
|
||||
&xrects, &n_rects);
|
||||
|
||||
if (shape == ShapeBounding)
|
||||
@@ -3248,7 +3361,8 @@ do_shape_combine_region (GdkWindow *window,
|
||||
XShapeCombineRectangles (GDK_WINDOW_XDISPLAY (window),
|
||||
GDK_WINDOW_XID (window),
|
||||
shape,
|
||||
offset_x, offset_y,
|
||||
offset_x * impl->window_scale,
|
||||
offset_y * impl->window_scale,
|
||||
xrects, n_rects,
|
||||
ShapeSet,
|
||||
YXBanded);
|
||||
@@ -4307,6 +4421,7 @@ gdk_x11_window_set_functions (GdkWindow *window,
|
||||
cairo_region_t *
|
||||
_gdk_x11_xwindow_get_shape (Display *xdisplay,
|
||||
Window window,
|
||||
gint scale,
|
||||
gint shape_type)
|
||||
{
|
||||
cairo_region_t *shape;
|
||||
@@ -4340,13 +4455,15 @@ _gdk_x11_xwindow_get_shape (Display *xdisplay,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* NOTE: The scale divisions here may lose some precision if someone
|
||||
else set the shape to be non-scale precision */
|
||||
rl = g_new (GdkRectangle, rn);
|
||||
for (i = 0; i < rn; i++)
|
||||
{
|
||||
rl[i].x = xrl[i].x;
|
||||
rl[i].y = xrl[i].y;
|
||||
rl[i].width = xrl[i].width;
|
||||
rl[i].height = xrl[i].height;
|
||||
rl[i].x = xrl[i].x / scale;
|
||||
rl[i].y = xrl[i].y / scale;
|
||||
rl[i].width = xrl[i].width / scale;
|
||||
rl[i].height = xrl[i].height / scale;
|
||||
}
|
||||
XFree (xrl);
|
||||
|
||||
@@ -4360,10 +4477,13 @@ _gdk_x11_xwindow_get_shape (Display *xdisplay,
|
||||
static cairo_region_t *
|
||||
gdk_x11_window_get_shape (GdkWindow *window)
|
||||
{
|
||||
GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (window->impl);
|
||||
|
||||
if (!GDK_WINDOW_DESTROYED (window) &&
|
||||
gdk_display_supports_shapes (GDK_WINDOW_DISPLAY (window)))
|
||||
return _gdk_x11_xwindow_get_shape (GDK_WINDOW_XDISPLAY (window),
|
||||
GDK_WINDOW_XID (window),
|
||||
impl->window_scale,
|
||||
ShapeBounding);
|
||||
|
||||
return NULL;
|
||||
@@ -4373,10 +4493,13 @@ static cairo_region_t *
|
||||
gdk_x11_window_get_input_shape (GdkWindow *window)
|
||||
{
|
||||
#if defined(ShapeInput)
|
||||
GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (window->impl);
|
||||
|
||||
if (!GDK_WINDOW_DESTROYED (window) &&
|
||||
gdk_display_supports_input_shapes (GDK_WINDOW_DISPLAY (window)))
|
||||
return _gdk_x11_xwindow_get_shape (GDK_WINDOW_XDISPLAY (window),
|
||||
GDK_WINDOW_XID (window),
|
||||
impl->window_scale,
|
||||
ShapeInput);
|
||||
#endif
|
||||
|
||||
@@ -4467,6 +4590,7 @@ wmspec_send_message (GdkDisplay *display,
|
||||
gint action,
|
||||
gint button)
|
||||
{
|
||||
GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (window->impl);
|
||||
XClientMessageEvent xclient;
|
||||
|
||||
memset (&xclient, 0, sizeof (xclient));
|
||||
@@ -4475,8 +4599,8 @@ wmspec_send_message (GdkDisplay *display,
|
||||
xclient.message_type =
|
||||
gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_MOVERESIZE");
|
||||
xclient.format = 32;
|
||||
xclient.data.l[0] = root_x;
|
||||
xclient.data.l[1] = root_y;
|
||||
xclient.data.l[0] = root_x * impl->window_scale;
|
||||
xclient.data.l[1] = root_y * impl->window_scale;
|
||||
xclient.data.l[2] = action;
|
||||
xclient.data.l[3] = button;
|
||||
xclient.data.l[4] = 1; /* source indication */
|
||||
@@ -4798,6 +4922,7 @@ _gdk_x11_moveresize_handle_event (XEvent *event)
|
||||
guint button_mask = 0;
|
||||
GdkDisplay *display = gdk_x11_lookup_xdisplay (event->xany.display);
|
||||
MoveResizeData *mv_resize = get_move_resize_data (display, FALSE);
|
||||
GdkWindowImplX11 *impl;
|
||||
|
||||
if (!mv_resize || !mv_resize->moveresize_window)
|
||||
{
|
||||
@@ -4805,6 +4930,8 @@ _gdk_x11_moveresize_handle_event (XEvent *event)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
impl = GDK_WINDOW_IMPL_X11 (mv_resize->moveresize_window->impl);
|
||||
|
||||
button_mask = GDK_BUTTON1_MASK << (mv_resize->moveresize_button - 1);
|
||||
|
||||
switch (event->xany.type)
|
||||
@@ -4824,8 +4951,8 @@ _gdk_x11_moveresize_handle_event (XEvent *event)
|
||||
break;
|
||||
|
||||
update_pos (mv_resize,
|
||||
event->xmotion.x_root,
|
||||
event->xmotion.y_root);
|
||||
event->xmotion.x_root / impl->window_scale,
|
||||
event->xmotion.y_root / impl->window_scale);
|
||||
|
||||
/* This should never be triggered in normal cases, but in the
|
||||
* case where the drag started without an implicit grab being
|
||||
@@ -4839,8 +4966,8 @@ _gdk_x11_moveresize_handle_event (XEvent *event)
|
||||
|
||||
case ButtonRelease:
|
||||
update_pos (mv_resize,
|
||||
event->xbutton.x_root,
|
||||
event->xbutton.y_root);
|
||||
event->xbutton.x_root / impl->window_scale,
|
||||
event->xbutton.y_root / impl->window_scale);
|
||||
|
||||
if (event->xbutton.button == mv_resize->moveresize_button)
|
||||
finish_drag (mv_resize);
|
||||
@@ -4856,14 +4983,14 @@ _gdk_x11_moveresize_handle_event (XEvent *event)
|
||||
switch (ev->evtype)
|
||||
{
|
||||
case XI_Motion:
|
||||
update_pos (mv_resize, xev->root_x, xev->root_y);
|
||||
update_pos (mv_resize, xev->root_x / impl->window_scale, xev->root_y / impl->window_scale);
|
||||
state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
|
||||
if ((state & button_mask) == 0)
|
||||
finish_drag (mv_resize);
|
||||
break;
|
||||
|
||||
case XI_ButtonRelease:
|
||||
update_pos (mv_resize, xev->root_x, xev->root_y);
|
||||
update_pos (mv_resize, xev->root_x / impl->window_scale, xev->root_y / impl->window_scale);
|
||||
if (xev->detail == mv_resize->moveresize_button)
|
||||
finish_drag (mv_resize);
|
||||
break;
|
||||
@@ -5307,6 +5434,17 @@ gdk_x11_window_get_xid (GdkWindow *window)
|
||||
return GDK_WINDOW_IMPL_X11 (window->impl)->xid;
|
||||
}
|
||||
|
||||
static gint
|
||||
gdk_x11_window_get_scale_factor (GdkWindow *window)
|
||||
{
|
||||
GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (window->impl);
|
||||
|
||||
if (GDK_WINDOW_DESTROYED (window))
|
||||
return 1;
|
||||
|
||||
return impl->window_scale;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass)
|
||||
{
|
||||
@@ -5394,4 +5532,5 @@ gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass)
|
||||
impl_class->get_property = _gdk_x11_window_get_property;
|
||||
impl_class->change_property = _gdk_x11_window_change_property;
|
||||
impl_class->delete_property = _gdk_x11_window_delete_property;
|
||||
impl_class->get_scale_factor = gdk_x11_window_get_scale_factor;
|
||||
}
|
||||
|
||||
@@ -64,6 +64,8 @@ struct _GdkWindowImplX11
|
||||
|
||||
Window xid;
|
||||
|
||||
gint window_scale;
|
||||
|
||||
GdkToplevelX11 *toplevel; /* Toplevel-specific information */
|
||||
GdkCursor *cursor;
|
||||
GHashTable *device_cursor;
|
||||
@@ -150,7 +152,10 @@ struct _GdkToplevelX11
|
||||
* that might not even be part of this app
|
||||
*/
|
||||
Window focus_window;
|
||||
|
||||
|
||||
GdkWindowHints last_geometry_hints_mask;
|
||||
GdkGeometry last_geometry_hints;
|
||||
|
||||
#ifdef HAVE_XSYNC
|
||||
XID update_counter;
|
||||
XID extended_update_counter;
|
||||
@@ -183,6 +188,8 @@ void _gdk_x11_window_tmp_reset_parent_bg (GdkWindow *window);
|
||||
GdkCursor *_gdk_x11_window_get_cursor (GdkWindow *window);
|
||||
|
||||
void _gdk_x11_window_update_size (GdkWindowImplX11 *impl);
|
||||
void _gdk_x11_window_set_window_scale (GdkWindow *window,
|
||||
int scale);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -68,6 +68,9 @@ gdk_xsettings_notify (GdkX11Screen *x11_screen,
|
||||
{
|
||||
GdkEvent new_event;
|
||||
|
||||
if (!g_str_has_prefix (name, "gtk-"))
|
||||
return;
|
||||
|
||||
new_event.type = GDK_SETTING;
|
||||
new_event.setting.window = gdk_screen_get_root_window (GDK_SCREEN (x11_screen));
|
||||
new_event.setting.send_event = FALSE;
|
||||
@@ -406,6 +409,8 @@ read_settings (GdkX11Screen *x11_screen,
|
||||
int result;
|
||||
|
||||
GHashTable *old_list = x11_screen->xsettings;
|
||||
GValue value = G_VALUE_INIT;
|
||||
GValue *setting, *copy;
|
||||
|
||||
x11_screen->xsettings = NULL;
|
||||
|
||||
@@ -439,10 +444,32 @@ read_settings (GdkX11Screen *x11_screen,
|
||||
}
|
||||
}
|
||||
|
||||
/* Since we support scaling we look at the specific Gdk/UnscaledDPI
|
||||
setting if it exists and use that instead of Xft/DPI if it is set */
|
||||
if (x11_screen->xsettings && !x11_screen->fixed_window_scale)
|
||||
{
|
||||
setting = g_hash_table_lookup (x11_screen->xsettings, "gdk-unscaled-dpi");
|
||||
if (setting)
|
||||
{
|
||||
copy = g_new0 (GValue, 1);
|
||||
g_value_init (copy, G_VALUE_TYPE (setting));
|
||||
g_value_copy (setting, copy);
|
||||
g_hash_table_insert (x11_screen->xsettings,
|
||||
"gtk-xft-dpi", copy);
|
||||
}
|
||||
}
|
||||
|
||||
if (do_notify)
|
||||
notify_changes (x11_screen, old_list);
|
||||
if (old_list)
|
||||
g_hash_table_unref (old_list);
|
||||
|
||||
g_value_init (&value, G_TYPE_INT);
|
||||
if (!x11_screen->fixed_window_scale &&
|
||||
gdk_screen_get_setting (GDK_SCREEN (x11_screen),
|
||||
"gdk-window-scaling-factor", &value))
|
||||
_gdk_x11_screen_set_window_scale (x11_screen,
|
||||
g_value_get_int (&value));
|
||||
}
|
||||
|
||||
static Atom
|
||||
|
||||
@@ -449,6 +449,7 @@ gtk_private_h_sources = \
|
||||
gtkcssimageprivate.h \
|
||||
gtkcssimagesurfaceprivate.h \
|
||||
gtkcssimageurlprivate.h \
|
||||
gtkcssimagescaledprivate.h \
|
||||
gtkcssimagevalueprivate.h \
|
||||
gtkcssimagewin32private.h \
|
||||
gtkcssinheritvalueprivate.h \
|
||||
@@ -683,6 +684,7 @@ gtk_base_c_sources = \
|
||||
gtkcssimagelinear.c \
|
||||
gtkcssimagesurface.c \
|
||||
gtkcssimageurl.c \
|
||||
gtkcssimagescaled.c \
|
||||
gtkcssimagevalue.c \
|
||||
gtkcssimagewin32.c \
|
||||
gtkcssinheritvalue.c \
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "config.h"
|
||||
#include <stdlib.h>
|
||||
#include <cairo-gobject.h>
|
||||
#include "gtkcellrendererpixbuf.h"
|
||||
#include "gtkiconfactory.h"
|
||||
#include "gtkiconhelperprivate.h"
|
||||
@@ -74,6 +75,7 @@ enum {
|
||||
PROP_PIXBUF,
|
||||
PROP_PIXBUF_EXPANDER_OPEN,
|
||||
PROP_PIXBUF_EXPANDER_CLOSED,
|
||||
PROP_SURFACE,
|
||||
PROP_STOCK_ID,
|
||||
PROP_STOCK_SIZE,
|
||||
PROP_STOCK_DETAIL,
|
||||
@@ -168,6 +170,13 @@ gtk_cell_renderer_pixbuf_class_init (GtkCellRendererPixbufClass *class)
|
||||
P_("Pixbuf for closed expander"),
|
||||
GDK_TYPE_PIXBUF,
|
||||
GTK_PARAM_READWRITE));
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_SURFACE,
|
||||
g_param_spec_boxed ("surface",
|
||||
P_("surface"),
|
||||
P_("The surface to render"),
|
||||
CAIRO_GOBJECT_TYPE_SURFACE,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* GtkCellRendererPixbuf:stock-id:
|
||||
@@ -279,6 +288,9 @@ gtk_cell_renderer_pixbuf_get_property (GObject *object,
|
||||
case PROP_PIXBUF_EXPANDER_CLOSED:
|
||||
g_value_set_object (value, priv->pixbuf_expander_closed);
|
||||
break;
|
||||
case PROP_SURFACE:
|
||||
g_value_set_boxed (value, _gtk_icon_helper_peek_surface (priv->icon_helper));
|
||||
break;
|
||||
case PROP_STOCK_ID:
|
||||
g_value_set_string (value, _gtk_icon_helper_get_stock_id (priv->icon_helper));
|
||||
break;
|
||||
@@ -311,6 +323,9 @@ gtk_cell_renderer_pixbuf_reset (GtkCellRendererPixbuf *cellpixbuf)
|
||||
|
||||
switch (storage_type)
|
||||
{
|
||||
case GTK_IMAGE_SURFACE:
|
||||
g_object_notify (G_OBJECT (cellpixbuf), "surface");
|
||||
break;
|
||||
case GTK_IMAGE_PIXBUF:
|
||||
g_object_notify (G_OBJECT (cellpixbuf), "pixbuf");
|
||||
break;
|
||||
@@ -356,6 +371,10 @@ gtk_cell_renderer_pixbuf_set_property (GObject *object,
|
||||
g_object_unref (priv->pixbuf_expander_closed);
|
||||
priv->pixbuf_expander_closed = (GdkPixbuf*) g_value_dup_object (value);
|
||||
break;
|
||||
case PROP_SURFACE:
|
||||
gtk_cell_renderer_pixbuf_reset (cellpixbuf);
|
||||
_gtk_icon_helper_set_surface (priv->icon_helper, g_value_get_boxed (value));
|
||||
break;
|
||||
case PROP_STOCK_ID:
|
||||
gtk_cell_renderer_pixbuf_reset (cellpixbuf);
|
||||
_gtk_icon_helper_set_stock_id (priv->icon_helper, g_value_get_string (value), priv->icon_size);
|
||||
@@ -552,6 +571,8 @@ gtk_cell_renderer_pixbuf_render (GtkCellRenderer *cell,
|
||||
if (icon_helper == NULL)
|
||||
icon_helper = g_object_ref (priv->icon_helper);
|
||||
|
||||
_gtk_icon_helper_set_window (icon_helper,
|
||||
gtk_widget_get_window (widget));
|
||||
_gtk_icon_helper_draw (icon_helper,
|
||||
context, cr,
|
||||
pix_rect.x, pix_rect.y);
|
||||
|
||||
@@ -46,6 +46,7 @@ static GtkCssValue *
|
||||
gtk_css_value_array_compute (GtkCssValue *value,
|
||||
guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies)
|
||||
@@ -58,7 +59,7 @@ gtk_css_value_array_compute (GtkCssValue *value,
|
||||
result = NULL;
|
||||
for (i = 0; i < value->n_values; i++)
|
||||
{
|
||||
i_value = _gtk_css_value_compute (value->values[i], property_id, provider, values, parent_values, &child_deps);
|
||||
i_value = _gtk_css_value_compute (value->values[i], property_id, provider, scale, values, parent_values, &child_deps);
|
||||
|
||||
*dependencies = _gtk_css_dependencies_union (*dependencies, child_deps);
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ static GtkCssValue *
|
||||
gtk_css_value_bg_size_compute (GtkCssValue *value,
|
||||
guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies)
|
||||
@@ -58,10 +59,10 @@ gtk_css_value_bg_size_compute (GtkCssValue *value,
|
||||
x = y = NULL;
|
||||
|
||||
if (value->x)
|
||||
x = _gtk_css_value_compute (value->x, property_id, provider, values, parent_values, &x_deps);
|
||||
x = _gtk_css_value_compute (value->x, property_id, provider, scale, values, parent_values, &x_deps);
|
||||
|
||||
if (value->y)
|
||||
y = _gtk_css_value_compute (value->y, property_id, provider, values, parent_values, &y_deps);
|
||||
y = _gtk_css_value_compute (value->y, property_id, provider, scale, values, parent_values, &y_deps);
|
||||
|
||||
*dependencies = _gtk_css_dependencies_union (x_deps, y_deps);
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ static GtkCssValue *
|
||||
gtk_css_value_border_compute (GtkCssValue *value,
|
||||
guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies)
|
||||
@@ -61,7 +62,7 @@ gtk_css_value_border_compute (GtkCssValue *value,
|
||||
{
|
||||
if (value->values[i])
|
||||
{
|
||||
computed->values[i] = _gtk_css_value_compute (value->values[i], property_id, provider, values, parent_values, &child_deps);
|
||||
computed->values[i] = _gtk_css_value_compute (value->values[i], property_id, provider, scale, values, parent_values, &child_deps);
|
||||
*dependencies = _gtk_css_dependencies_union (*dependencies, child_deps);
|
||||
changed |= (computed->values[i] != value->values[i]);
|
||||
}
|
||||
|
||||
@@ -101,6 +101,7 @@ gtk_css_value_color_free (GtkCssValue *color)
|
||||
static GtkCssValue *
|
||||
gtk_css_value_color_get_fallback (guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values)
|
||||
{
|
||||
@@ -124,6 +125,7 @@ gtk_css_value_color_get_fallback (guint property_id,
|
||||
return _gtk_css_value_compute (_gtk_css_style_property_get_initial_value (_gtk_css_style_property_lookup_by_id (property_id)),
|
||||
property_id,
|
||||
provider,
|
||||
scale,
|
||||
values,
|
||||
parent_values,
|
||||
NULL);
|
||||
@@ -297,6 +299,7 @@ static GtkCssValue *
|
||||
gtk_css_value_color_compute (GtkCssValue *value,
|
||||
guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies)
|
||||
@@ -335,7 +338,7 @@ gtk_css_value_color_compute (GtkCssValue *value,
|
||||
NULL);
|
||||
|
||||
if (resolved == NULL)
|
||||
return gtk_css_value_color_get_fallback (property_id, provider, values, parent_values);
|
||||
return gtk_css_value_color_get_fallback (property_id, provider, scale, values, parent_values);
|
||||
|
||||
return resolved;
|
||||
}
|
||||
|
||||
@@ -113,6 +113,7 @@ maybe_unref_section (gpointer section)
|
||||
void
|
||||
_gtk_css_computed_values_compute_value (GtkCssComputedValues *values,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *parent_values,
|
||||
guint id,
|
||||
GtkCssValue *specified,
|
||||
@@ -142,7 +143,7 @@ _gtk_css_computed_values_compute_value (GtkCssComputedValues *values,
|
||||
else
|
||||
_gtk_css_value_ref (specified);
|
||||
|
||||
value = _gtk_css_value_compute (specified, id, provider, values, parent_values, &dependencies);
|
||||
value = _gtk_css_value_compute (specified, id, provider, scale, values, parent_values, &dependencies);
|
||||
|
||||
_gtk_css_computed_values_set_value (values, id, value, dependencies, section);
|
||||
|
||||
@@ -445,6 +446,7 @@ gtk_css_computed_values_create_css_animations (GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
gint64 timestamp,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *source)
|
||||
{
|
||||
GtkCssValue *durations, *delays, *timing_functions, *animations;
|
||||
@@ -489,7 +491,7 @@ gtk_css_computed_values_create_css_animations (GtkCssComputedValues *values,
|
||||
if (keyframes == NULL)
|
||||
continue;
|
||||
|
||||
keyframes = _gtk_css_keyframes_compute (keyframes, provider, values, parent_values);
|
||||
keyframes = _gtk_css_keyframes_compute (keyframes, provider, scale, values, parent_values);
|
||||
|
||||
animation = _gtk_css_animation_new (name,
|
||||
keyframes,
|
||||
@@ -514,11 +516,12 @@ _gtk_css_computed_values_create_animations (GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
gint64 timestamp,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *source)
|
||||
{
|
||||
if (source != NULL)
|
||||
gtk_css_computed_values_create_css_transitions (values, timestamp, source);
|
||||
gtk_css_computed_values_create_css_animations (values, parent_values, timestamp, provider, source);
|
||||
gtk_css_computed_values_create_css_animations (values, parent_values, timestamp, provider, scale, source);
|
||||
}
|
||||
|
||||
GtkBitmask *
|
||||
|
||||
@@ -66,6 +66,7 @@ GtkCssComputedValues * _gtk_css_computed_values_new (void);
|
||||
|
||||
void _gtk_css_computed_values_compute_value (GtkCssComputedValues *values,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *parent_values,
|
||||
guint id,
|
||||
GtkCssValue *specified,
|
||||
@@ -94,6 +95,7 @@ void _gtk_css_computed_values_create_animations (GtkCssCom
|
||||
GtkCssComputedValues *parent_values,
|
||||
gint64 timestamp,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *source);
|
||||
GtkBitmask * _gtk_css_computed_values_advance (GtkCssComputedValues *values,
|
||||
gint64 timestamp);
|
||||
|
||||
@@ -40,6 +40,7 @@ static GtkCssValue *
|
||||
gtk_css_value_corner_compute (GtkCssValue *corner,
|
||||
guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies)
|
||||
@@ -47,8 +48,8 @@ gtk_css_value_corner_compute (GtkCssValue *corner,
|
||||
GtkCssValue *x, *y;
|
||||
GtkCssDependencies x_deps, y_deps;
|
||||
|
||||
x = _gtk_css_value_compute (corner->x, property_id, provider, values, parent_values, &x_deps);
|
||||
y = _gtk_css_value_compute (corner->y, property_id, provider, values, parent_values, &y_deps);
|
||||
x = _gtk_css_value_compute (corner->x, property_id, provider, scale, values, parent_values, &x_deps);
|
||||
y = _gtk_css_value_compute (corner->y, property_id, provider, scale, values, parent_values, &y_deps);
|
||||
*dependencies = _gtk_css_dependencies_union (x_deps, y_deps);
|
||||
if (x == corner->x && y == corner->y)
|
||||
{
|
||||
|
||||
@@ -53,6 +53,7 @@ static GtkCssValue *
|
||||
gtk_css_value_ease_compute (GtkCssValue *value,
|
||||
guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies)
|
||||
|
||||
@@ -38,6 +38,7 @@ static GtkCssValue *
|
||||
gtk_css_value_engine_compute (GtkCssValue *value,
|
||||
guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies)
|
||||
|
||||
@@ -41,6 +41,7 @@ static GtkCssValue *
|
||||
gtk_css_value_enum_compute (GtkCssValue *value,
|
||||
guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies)
|
||||
@@ -164,6 +165,7 @@ static GtkCssValue *
|
||||
gtk_css_value_font_size_compute (GtkCssValue *value,
|
||||
guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies)
|
||||
|
||||
+5
-1
@@ -28,6 +28,7 @@
|
||||
#include "gtk/gtkcssimagegradientprivate.h"
|
||||
#include "gtk/gtkcssimagelinearprivate.h"
|
||||
#include "gtk/gtkcssimageurlprivate.h"
|
||||
#include "gtk/gtkcssimagescaledprivate.h"
|
||||
#include "gtk/gtkcssimagewin32private.h"
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (GtkCssImage, _gtk_css_image, G_TYPE_OBJECT)
|
||||
@@ -62,6 +63,7 @@ static GtkCssImage *
|
||||
gtk_css_image_real_compute (GtkCssImage *image,
|
||||
guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies)
|
||||
@@ -146,6 +148,7 @@ GtkCssImage *
|
||||
_gtk_css_image_compute (GtkCssImage *image,
|
||||
guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies)
|
||||
@@ -163,7 +166,7 @@ _gtk_css_image_compute (GtkCssImage *image,
|
||||
|
||||
klass = GTK_CSS_IMAGE_GET_CLASS (image);
|
||||
|
||||
return klass->compute (image, property_id, provider, values, parent_values, dependencies);
|
||||
return klass->compute (image, property_id, provider, scale, values, parent_values, dependencies);
|
||||
}
|
||||
|
||||
GtkCssImage *
|
||||
@@ -417,6 +420,7 @@ gtk_css_image_get_parser_type (GtkCssParser *parser)
|
||||
} image_types[] = {
|
||||
{ "url", _gtk_css_image_url_get_type },
|
||||
{ "-gtk-gradient", _gtk_css_image_gradient_get_type },
|
||||
{ "-gtk-scaled", _gtk_css_image_scaled_get_type },
|
||||
{ "-gtk-win32-theme-part", _gtk_css_image_win32_get_type },
|
||||
{ "linear-gradient", _gtk_css_image_linear_get_type },
|
||||
{ "repeating-linear-gradient", _gtk_css_image_linear_get_type },
|
||||
|
||||
@@ -34,6 +34,7 @@ static GtkCssImage *
|
||||
gtk_css_image_gradient_compute (GtkCssImage *image,
|
||||
guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies)
|
||||
|
||||
@@ -420,6 +420,7 @@ static GtkCssImage *
|
||||
gtk_css_image_linear_compute (GtkCssImage *image,
|
||||
guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies)
|
||||
@@ -431,7 +432,7 @@ gtk_css_image_linear_compute (GtkCssImage *image,
|
||||
copy = g_object_new (GTK_TYPE_CSS_IMAGE_LINEAR, NULL);
|
||||
copy->repeating = linear->repeating;
|
||||
|
||||
copy->angle = _gtk_css_value_compute (linear->angle, property_id, provider, values, parent_values, dependencies);
|
||||
copy->angle = _gtk_css_value_compute (linear->angle, property_id, provider, scale, values, parent_values, dependencies);
|
||||
|
||||
g_array_set_size (copy->stops, linear->stops->len);
|
||||
for (i = 0; i < linear->stops->len; i++)
|
||||
@@ -442,12 +443,12 @@ gtk_css_image_linear_compute (GtkCssImage *image,
|
||||
stop = &g_array_index (linear->stops, GtkCssImageLinearColorStop, i);
|
||||
scopy = &g_array_index (copy->stops, GtkCssImageLinearColorStop, i);
|
||||
|
||||
scopy->color = _gtk_css_value_compute (stop->color, property_id, provider, values, parent_values, &child_deps);
|
||||
scopy->color = _gtk_css_value_compute (stop->color, property_id, provider, scale, values, parent_values, &child_deps);
|
||||
*dependencies = _gtk_css_dependencies_union (*dependencies, child_deps);
|
||||
|
||||
if (stop->offset)
|
||||
{
|
||||
scopy->offset = _gtk_css_value_compute (stop->offset, property_id, provider, values, parent_values, &child_deps);
|
||||
scopy->offset = _gtk_css_value_compute (stop->offset, property_id, provider, scale, values, parent_values, &child_deps);
|
||||
*dependencies = _gtk_css_dependencies_union (*dependencies, child_deps);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -58,6 +58,7 @@ struct _GtkCssImageClass
|
||||
GtkCssImage *(* compute) (GtkCssImage *image,
|
||||
guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies);
|
||||
@@ -95,6 +96,7 @@ double _gtk_css_image_get_aspect_ratio (GtkCssImage *
|
||||
GtkCssImage * _gtk_css_image_compute (GtkCssImage *image,
|
||||
guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies);
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright © 2013 Red Hat Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Alexander Larsson <alexl@gnome.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkcssimagescaledprivate.h"
|
||||
|
||||
G_DEFINE_TYPE (GtkCssImageScaled, _gtk_css_image_scaled, GTK_TYPE_CSS_IMAGE)
|
||||
|
||||
static int
|
||||
gtk_css_image_scaled_get_width (GtkCssImage *image)
|
||||
{
|
||||
GtkCssImageScaled *scaled = GTK_CSS_IMAGE_SCALED (image);
|
||||
|
||||
return _gtk_css_image_get_width (scaled->images[scaled->scale - 1]) / scaled->scale;
|
||||
}
|
||||
|
||||
static int
|
||||
gtk_css_image_scaled_get_height (GtkCssImage *image)
|
||||
{
|
||||
GtkCssImageScaled *scaled = GTK_CSS_IMAGE_SCALED (image);
|
||||
|
||||
return _gtk_css_image_get_height (scaled->images[scaled->scale - 1]) / scaled->scale;
|
||||
}
|
||||
|
||||
static double
|
||||
gtk_css_image_scaled_get_aspect_ratio (GtkCssImage *image)
|
||||
{
|
||||
GtkCssImageScaled *scaled = GTK_CSS_IMAGE_SCALED (image);
|
||||
|
||||
return _gtk_css_image_get_aspect_ratio (scaled->images[scaled->scale - 1]);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_image_scaled_draw (GtkCssImage *image,
|
||||
cairo_t *cr,
|
||||
double width,
|
||||
double height)
|
||||
{
|
||||
GtkCssImageScaled *scaled = GTK_CSS_IMAGE_SCALED (image);
|
||||
|
||||
_gtk_css_image_draw (scaled->images[scaled->scale - 1], cr, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_image_scaled_print (GtkCssImage *image,
|
||||
GString *string)
|
||||
{
|
||||
GtkCssImageScaled *scaled = GTK_CSS_IMAGE_SCALED (image);
|
||||
int i;
|
||||
|
||||
g_string_append (string, "-gtk-scaled(");
|
||||
for (i = 0; i < scaled->n_images; i++)
|
||||
{
|
||||
_gtk_css_image_print (scaled->images[i], string);
|
||||
if (i != scaled->n_images - 1)
|
||||
g_string_append (string, ",");
|
||||
}
|
||||
g_string_append (string, ")");
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_image_scaled_dispose (GObject *object)
|
||||
{
|
||||
GtkCssImageScaled *scaled = GTK_CSS_IMAGE_SCALED (object);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < scaled->n_images; i++)
|
||||
g_object_unref (scaled->images[i]);
|
||||
g_free (scaled->images);
|
||||
scaled->images = NULL;
|
||||
|
||||
G_OBJECT_CLASS (_gtk_css_image_scaled_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
|
||||
static GtkCssImage *
|
||||
gtk_css_image_scaled_compute (GtkCssImage *image,
|
||||
guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies)
|
||||
{
|
||||
GtkCssImageScaled *scaled = GTK_CSS_IMAGE_SCALED (image);
|
||||
GtkCssImageScaled *copy;
|
||||
int i;
|
||||
|
||||
scale = MAX(MIN (scale, scaled->n_images), 1);
|
||||
|
||||
if (scaled->scale == scale)
|
||||
return g_object_ref (scaled);
|
||||
else
|
||||
{
|
||||
copy = g_object_new (_gtk_css_image_scaled_get_type (), NULL);
|
||||
copy->scale = scale;
|
||||
copy->n_images = scaled->n_images;
|
||||
copy->images = g_new (GtkCssImage *, scaled->n_images);
|
||||
for (i = 0; i < scaled->n_images; i++)
|
||||
{
|
||||
if (i == scale - 1)
|
||||
copy->images[i] = _gtk_css_image_compute (scaled->images[i],
|
||||
property_id,
|
||||
provider,
|
||||
scale,
|
||||
values,
|
||||
parent_values,
|
||||
dependencies);
|
||||
else
|
||||
copy->images[i] = g_object_ref (scaled->images[i]);
|
||||
}
|
||||
|
||||
return GTK_CSS_IMAGE (copy);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_image_scaled_parse (GtkCssImage *image,
|
||||
GtkCssParser *parser)
|
||||
{
|
||||
GtkCssImageScaled *scaled = GTK_CSS_IMAGE_SCALED (image);
|
||||
GPtrArray *images;
|
||||
GtkCssImage *child;
|
||||
|
||||
if (!_gtk_css_parser_try (parser, "-gtk-scaled", TRUE))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "'-gtk-scaled'");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!_gtk_css_parser_try (parser, "(", TRUE))
|
||||
{
|
||||
_gtk_css_parser_error (parser,
|
||||
"Expected '(' after '-gtk-scaled'");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
images = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
|
||||
do
|
||||
{
|
||||
child = _gtk_css_image_new_parse (parser);
|
||||
if (child == NULL)
|
||||
{
|
||||
g_ptr_array_free (images, TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
g_ptr_array_add (images, child);
|
||||
|
||||
}
|
||||
while ( _gtk_css_parser_try (parser, ",", TRUE));
|
||||
|
||||
if (!_gtk_css_parser_try (parser, ")", TRUE))
|
||||
{
|
||||
g_ptr_array_free (images, TRUE);
|
||||
_gtk_css_parser_error (parser,
|
||||
"Expected ')' at end of '-gtk-scaled'");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
scaled->n_images = images->len;
|
||||
scaled->images = (GtkCssImage **) g_ptr_array_free (images, FALSE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_css_image_scaled_class_init (GtkCssImageScaledClass *klass)
|
||||
{
|
||||
GtkCssImageClass *image_class = GTK_CSS_IMAGE_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
image_class->get_width = gtk_css_image_scaled_get_width;
|
||||
image_class->get_height = gtk_css_image_scaled_get_height;
|
||||
image_class->get_aspect_ratio = gtk_css_image_scaled_get_aspect_ratio;
|
||||
image_class->draw = gtk_css_image_scaled_draw;
|
||||
image_class->parse = gtk_css_image_scaled_parse;
|
||||
image_class->compute = gtk_css_image_scaled_compute;
|
||||
image_class->print = gtk_css_image_scaled_print;
|
||||
|
||||
object_class->dispose = gtk_css_image_scaled_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_css_image_scaled_init (GtkCssImageScaled *image_scaled)
|
||||
{
|
||||
image_scaled->scale = 1;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright © 2013 Red Hat Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Alexander Larsson <alexl@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef __GTK_CSS_IMAGE_SCALED_PRIVATE_H__
|
||||
#define __GTK_CSS_IMAGE_SCALED_PRIVATE_H__
|
||||
|
||||
#include "gtk/gtkcssimageprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_CSS_IMAGE_SCALED (_gtk_css_image_scaled_get_type ())
|
||||
#define GTK_CSS_IMAGE_SCALED(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_IMAGE_SCALED, GtkCssImageScaled))
|
||||
#define GTK_CSS_IMAGE_SCALED_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_IMAGE_SCALED, GtkCssImageScaledClass))
|
||||
#define GTK_IS_CSS_IMAGE_SCALED(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_CSS_IMAGE_SCALED))
|
||||
#define GTK_IS_CSS_IMAGE_SCALED_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_CSS_IMAGE_SCALED))
|
||||
#define GTK_CSS_IMAGE_SCALED_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CSS_IMAGE_SCALED, GtkCssImageScaledClass))
|
||||
|
||||
typedef struct _GtkCssImageScaled GtkCssImageScaled;
|
||||
typedef struct _GtkCssImageScaledClass GtkCssImageScaledClass;
|
||||
|
||||
struct _GtkCssImageScaled
|
||||
{
|
||||
GtkCssImage parent;
|
||||
|
||||
int scale;
|
||||
GtkCssImage **images;
|
||||
int n_images;
|
||||
};
|
||||
|
||||
struct _GtkCssImageScaledClass
|
||||
{
|
||||
GtkCssImageClass parent_class;
|
||||
};
|
||||
|
||||
GType _gtk_css_image_scaled_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_CSS_IMAGE_SCALED_PRIVATE_H__ */
|
||||
@@ -142,20 +142,12 @@ _gtk_css_image_surface_new_for_pixbuf (GdkPixbuf *pixbuf)
|
||||
{
|
||||
GtkCssImage *image;
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
|
||||
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
gdk_pixbuf_get_width (pixbuf),
|
||||
gdk_pixbuf_get_height (pixbuf));
|
||||
cr = cairo_create (surface);
|
||||
gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
|
||||
cairo_paint (cr);
|
||||
cairo_destroy (cr);
|
||||
surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, 1, NULL);
|
||||
|
||||
image = _gtk_css_image_surface_new (surface);
|
||||
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
return image;
|
||||
|
||||
@@ -120,6 +120,7 @@ static GtkCssImage *
|
||||
gtk_css_image_url_compute (GtkCssImage *image,
|
||||
guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies)
|
||||
|
||||
@@ -37,6 +37,7 @@ static GtkCssValue *
|
||||
gtk_css_value_image_compute (GtkCssValue *value,
|
||||
guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies)
|
||||
@@ -48,7 +49,7 @@ gtk_css_value_image_compute (GtkCssValue *value,
|
||||
if (image == NULL)
|
||||
return _gtk_css_value_ref (value);
|
||||
|
||||
computed = _gtk_css_image_compute (image, property_id, provider, values, parent_values, dependencies);
|
||||
computed = _gtk_css_image_compute (image, property_id, provider, scale, values, parent_values, dependencies);
|
||||
|
||||
if (computed == image)
|
||||
{
|
||||
|
||||
@@ -37,6 +37,7 @@ static GtkCssValue *
|
||||
gtk_css_value_inherit_compute (GtkCssValue *value,
|
||||
guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies)
|
||||
@@ -51,6 +52,7 @@ gtk_css_value_inherit_compute (GtkCssValue *value,
|
||||
return _gtk_css_value_compute (_gtk_css_initial_value_get (),
|
||||
property_id,
|
||||
provider,
|
||||
scale,
|
||||
values,
|
||||
parent_values,
|
||||
dependencies);
|
||||
|
||||
@@ -40,6 +40,7 @@ static GtkCssValue *
|
||||
gtk_css_value_initial_compute (GtkCssValue *value,
|
||||
guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies)
|
||||
@@ -80,6 +81,7 @@ gtk_css_value_initial_compute (GtkCssValue *value,
|
||||
return _gtk_css_value_compute (_gtk_css_style_property_get_initial_value (_gtk_css_style_property_lookup_by_id (property_id)),
|
||||
property_id,
|
||||
provider,
|
||||
scale,
|
||||
values,
|
||||
parent_values,
|
||||
dependencies);
|
||||
|
||||
@@ -427,6 +427,7 @@ _gtk_css_keyframes_print (GtkCssKeyframes *keyframes,
|
||||
GtkCssKeyframes *
|
||||
_gtk_css_keyframes_compute (GtkCssKeyframes *keyframes,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values)
|
||||
{
|
||||
@@ -455,6 +456,7 @@ _gtk_css_keyframes_compute (GtkCssKeyframes *keyframes,
|
||||
KEYFRAMES_VALUE (resolved, k, p) = _gtk_css_value_compute (KEYFRAMES_VALUE (keyframes, k, p),
|
||||
resolved->property_ids[p],
|
||||
provider,
|
||||
scale,
|
||||
values,
|
||||
parent_values,
|
||||
NULL);
|
||||
|
||||
@@ -38,6 +38,7 @@ void _gtk_css_keyframes_print (GtkCssKeyframes
|
||||
|
||||
GtkCssKeyframes * _gtk_css_keyframes_compute (GtkCssKeyframes *keyframes,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values);
|
||||
|
||||
|
||||
@@ -140,6 +140,7 @@ _gtk_css_lookup_set_computed (GtkCssLookup *lookup,
|
||||
void
|
||||
_gtk_css_lookup_resolve (GtkCssLookup *lookup,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values)
|
||||
{
|
||||
@@ -164,6 +165,7 @@ _gtk_css_lookup_resolve (GtkCssLookup *lookup,
|
||||
_gtk_bitmask_get (lookup->missing, i))
|
||||
_gtk_css_computed_values_compute_value (values,
|
||||
provider,
|
||||
scale,
|
||||
parent_values,
|
||||
i,
|
||||
lookup->values[i].value,
|
||||
|
||||
@@ -55,6 +55,7 @@ void _gtk_css_lookup_set_computed (GtkCssLookup
|
||||
GtkCssValue *value);
|
||||
void _gtk_css_lookup_resolve (GtkCssLookup *lookup,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values);
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@ static GtkCssValue *
|
||||
gtk_css_value_number_compute (GtkCssValue *number,
|
||||
guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies)
|
||||
|
||||
@@ -40,6 +40,7 @@ static GtkCssValue *
|
||||
gtk_css_value_position_compute (GtkCssValue *position,
|
||||
guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies)
|
||||
@@ -47,8 +48,8 @@ gtk_css_value_position_compute (GtkCssValue *position,
|
||||
GtkCssValue *x, *y;
|
||||
GtkCssDependencies x_deps, y_deps;
|
||||
|
||||
x = _gtk_css_value_compute (position->x, property_id, provider, values, parent_values, &x_deps);
|
||||
y = _gtk_css_value_compute (position->y, property_id, provider, values, parent_values, &y_deps);
|
||||
x = _gtk_css_value_compute (position->x, property_id, provider, scale, values, parent_values, &x_deps);
|
||||
y = _gtk_css_value_compute (position->y, property_id, provider, scale, values, parent_values, &y_deps);
|
||||
*dependencies = _gtk_css_dependencies_union (x_deps, y_deps);
|
||||
if (x == position->x && y == position->y)
|
||||
{
|
||||
|
||||
@@ -37,6 +37,7 @@ static GtkCssValue *
|
||||
gtk_css_value_repeat_compute (GtkCssValue *value,
|
||||
guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies)
|
||||
|
||||
@@ -37,6 +37,7 @@ static GtkCssValue *
|
||||
gtk_css_value_rgba_compute (GtkCssValue *value,
|
||||
guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies)
|
||||
|
||||
@@ -51,6 +51,7 @@ static GtkCssValue *
|
||||
gtk_css_value_shadows_compute (GtkCssValue *value,
|
||||
guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies)
|
||||
@@ -65,7 +66,7 @@ gtk_css_value_shadows_compute (GtkCssValue *value,
|
||||
result = gtk_css_shadows_value_new (value->values, value->len);
|
||||
for (i = 0; i < value->len; i++)
|
||||
{
|
||||
result->values[i] = _gtk_css_value_compute (value->values[i], property_id, provider, values, parent_values, &child_deps);
|
||||
result->values[i] = _gtk_css_value_compute (value->values[i], property_id, provider, scale, values, parent_values, &child_deps);
|
||||
*dependencies = _gtk_css_dependencies_union (*dependencies, child_deps);
|
||||
}
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@ static GtkCssValue *
|
||||
gtk_css_value_shadow_compute (GtkCssValue *shadow,
|
||||
guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies)
|
||||
@@ -78,23 +79,23 @@ gtk_css_value_shadow_compute (GtkCssValue *shadow,
|
||||
GtkCssDependencies child_deps;
|
||||
|
||||
child_deps = 0;
|
||||
hoffset = _gtk_css_value_compute (shadow->hoffset, property_id, provider, values, parent_values, &child_deps);
|
||||
hoffset = _gtk_css_value_compute (shadow->hoffset, property_id, provider, scale, values, parent_values, &child_deps);
|
||||
*dependencies = _gtk_css_dependencies_union (*dependencies, child_deps);
|
||||
|
||||
child_deps = 0;
|
||||
voffset = _gtk_css_value_compute (shadow->voffset, property_id, provider, values, parent_values, &child_deps);
|
||||
voffset = _gtk_css_value_compute (shadow->voffset, property_id, provider, scale, values, parent_values, &child_deps);
|
||||
*dependencies = _gtk_css_dependencies_union (*dependencies, child_deps);
|
||||
|
||||
child_deps = 0;
|
||||
radius = _gtk_css_value_compute (shadow->radius, property_id, provider, values, parent_values, &child_deps);
|
||||
radius = _gtk_css_value_compute (shadow->radius, property_id, provider, scale, values, parent_values, &child_deps);
|
||||
*dependencies = _gtk_css_dependencies_union (*dependencies, child_deps);
|
||||
|
||||
child_deps = 0;
|
||||
spread = _gtk_css_value_compute (shadow->spread, property_id, provider, values, parent_values, &child_deps),
|
||||
spread = _gtk_css_value_compute (shadow->spread, property_id, provider, scale, values, parent_values, &child_deps),
|
||||
*dependencies = _gtk_css_dependencies_union (*dependencies, child_deps);
|
||||
|
||||
child_deps = 0;
|
||||
color = _gtk_css_value_compute (shadow->color, property_id, provider, values, parent_values, &child_deps);
|
||||
color = _gtk_css_value_compute (shadow->color, property_id, provider, scale, values, parent_values, &child_deps);
|
||||
*dependencies = _gtk_css_dependencies_union (*dependencies, child_deps);
|
||||
|
||||
return gtk_css_shadow_value_new (hoffset, voffset, radius, spread, shadow->inset, color);
|
||||
|
||||
@@ -37,6 +37,7 @@ static GtkCssValue *
|
||||
gtk_css_value_string_compute (GtkCssValue *value,
|
||||
guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies)
|
||||
|
||||
@@ -766,7 +766,6 @@ pattern_value_parse (GtkCssParser *parser,
|
||||
GFile *file;
|
||||
cairo_surface_t *surface;
|
||||
cairo_pattern_t *pattern;
|
||||
cairo_t *cr;
|
||||
cairo_matrix_t matrix;
|
||||
|
||||
file = _gtk_css_parser_read_url (parser);
|
||||
@@ -784,21 +783,15 @@ pattern_value_parse (GtkCssParser *parser,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
gdk_pixbuf_get_width (pixbuf),
|
||||
gdk_pixbuf_get_height (pixbuf));
|
||||
cr = cairo_create (surface);
|
||||
gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
|
||||
cairo_paint (cr);
|
||||
surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, 1, NULL);
|
||||
pattern = cairo_pattern_create_for_surface (surface);
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
cairo_matrix_init_scale (&matrix,
|
||||
gdk_pixbuf_get_width (pixbuf),
|
||||
gdk_pixbuf_get_height (pixbuf));
|
||||
cairo_pattern_set_matrix (pattern, &matrix);
|
||||
|
||||
cairo_surface_destroy (surface);
|
||||
cairo_destroy (cr);
|
||||
g_object_unref (pixbuf);
|
||||
|
||||
g_value_take_boxed (value, pattern);
|
||||
|
||||
@@ -38,6 +38,7 @@ static GtkCssValue *
|
||||
gtk_css_value_typed_compute (GtkCssValue *value,
|
||||
guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies)
|
||||
|
||||
+2
-1
@@ -88,6 +88,7 @@ GtkCssValue *
|
||||
_gtk_css_value_compute (GtkCssValue *value,
|
||||
guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies)
|
||||
@@ -103,7 +104,7 @@ _gtk_css_value_compute (GtkCssValue *value,
|
||||
dependencies = &fallback;
|
||||
*dependencies = 0;
|
||||
|
||||
return value->class->compute (value, property_id, provider, values, parent_values, dependencies);
|
||||
return value->class->compute (value, property_id, provider, scale, values, parent_values, dependencies);
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
||||
@@ -43,6 +43,7 @@ struct _GtkCssValueClass {
|
||||
GtkCssValue * (* compute) (GtkCssValue *value,
|
||||
guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies);
|
||||
@@ -68,6 +69,7 @@ void _gtk_css_value_unref (GtkCssValue
|
||||
GtkCssValue *_gtk_css_value_compute (GtkCssValue *value,
|
||||
guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
int scale,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies);
|
||||
|
||||
@@ -3047,6 +3047,10 @@ realize_icon_info (GtkWidget *widget,
|
||||
gtk_widget_register_window (widget, icon_info->window);
|
||||
|
||||
gtk_widget_queue_resize (widget);
|
||||
|
||||
_gtk_icon_helper_set_window (icon_info->icon_helper,
|
||||
gtk_widget_get_window (widget));
|
||||
|
||||
}
|
||||
|
||||
static EntryIconInfo*
|
||||
@@ -3233,6 +3237,8 @@ gtk_entry_unrealize (GtkWidget *widget)
|
||||
{
|
||||
if ((icon_info = priv->icons[i]) != NULL)
|
||||
{
|
||||
_gtk_icon_helper_set_window (icon_info->icon_helper, NULL);
|
||||
|
||||
if (icon_info->window != NULL)
|
||||
{
|
||||
gtk_widget_unregister_window (widget, icon_info->window);
|
||||
|
||||
+97
-77
@@ -1321,7 +1321,7 @@ change_icon_theme_get_info_cb (GCancellable *cancellable,
|
||||
gpointer user_data)
|
||||
{
|
||||
gboolean cancelled = g_cancellable_is_cancelled (cancellable);
|
||||
GdkPixbuf *pixbuf;
|
||||
cairo_surface_t *surface;
|
||||
struct ChangeIconThemeData *data = user_data;
|
||||
|
||||
if (!g_slist_find (data->button->priv->change_icon_theme_cancellables, cancellable))
|
||||
@@ -1333,15 +1333,15 @@ change_icon_theme_get_info_cb (GCancellable *cancellable,
|
||||
if (cancelled || error)
|
||||
goto out;
|
||||
|
||||
pixbuf = _gtk_file_info_render_icon (info, GTK_WIDGET (data->button), data->button->priv->icon_size);
|
||||
surface = _gtk_file_info_render_icon (info, GTK_WIDGET (data->button), data->button->priv->icon_size);
|
||||
|
||||
if (pixbuf)
|
||||
if (surface)
|
||||
{
|
||||
gint width = 0;
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path;
|
||||
|
||||
width = MAX (width, gdk_pixbuf_get_width (pixbuf));
|
||||
width = MAX (width, data->button->priv->icon_size);
|
||||
|
||||
path = gtk_tree_row_reference_get_path (data->row_ref);
|
||||
if (path)
|
||||
@@ -1350,14 +1350,14 @@ change_icon_theme_get_info_cb (GCancellable *cancellable,
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
gtk_list_store_set (GTK_LIST_STORE (data->button->priv->model), &iter,
|
||||
ICON_COLUMN, pixbuf,
|
||||
ICON_COLUMN, surface,
|
||||
-1);
|
||||
|
||||
g_object_set (data->button->priv->icon_cell,
|
||||
"width", width,
|
||||
NULL);
|
||||
}
|
||||
g_object_unref (pixbuf);
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
|
||||
out:
|
||||
@@ -1398,7 +1398,7 @@ change_icon_theme (GtkFileChooserButton *button)
|
||||
|
||||
do
|
||||
{
|
||||
GdkPixbuf *pixbuf = NULL;
|
||||
cairo_surface_t *surface = NULL;
|
||||
gchar type;
|
||||
gpointer data;
|
||||
|
||||
@@ -1435,39 +1435,47 @@ change_icon_theme (GtkFileChooserButton *button)
|
||||
info);
|
||||
button->priv->change_icon_theme_cancellables =
|
||||
g_slist_append (button->priv->change_icon_theme_cancellables, cancellable);
|
||||
pixbuf = NULL;
|
||||
surface = NULL;
|
||||
}
|
||||
else
|
||||
/* Don't call get_info for remote paths to avoid latency and
|
||||
* auth dialogs.
|
||||
* If we switch to a better bookmarks file format (XBEL), we
|
||||
* should use mime info to get a better icon.
|
||||
*/
|
||||
pixbuf = gtk_icon_theme_load_icon (theme, "folder-remote",
|
||||
priv->icon_size, 0, NULL);
|
||||
{
|
||||
/* Don't call get_info for remote paths to avoid latency and
|
||||
* auth dialogs.
|
||||
* If we switch to a better bookmarks file format (XBEL), we
|
||||
* should use mime info to get a better icon.
|
||||
*/
|
||||
surface = gtk_icon_theme_load_surface (theme, "folder-remote",
|
||||
priv->icon_size,
|
||||
gtk_widget_get_scale_factor (GTK_WIDGET (button)),
|
||||
gtk_widget_get_window (GTK_WIDGET (button)),
|
||||
0, NULL);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ROW_TYPE_VOLUME:
|
||||
if (data)
|
||||
pixbuf = _gtk_file_system_volume_render_icon (data,
|
||||
GTK_WIDGET (button),
|
||||
priv->icon_size,
|
||||
NULL);
|
||||
{
|
||||
surface = _gtk_file_system_volume_render_icon (data,
|
||||
GTK_WIDGET (button),
|
||||
priv->icon_size,
|
||||
NULL);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
if (pixbuf)
|
||||
width = MAX (width, gdk_pixbuf_get_width (pixbuf));
|
||||
if (surface)
|
||||
width = MAX (width, priv->icon_size);
|
||||
|
||||
gtk_list_store_set (GTK_LIST_STORE (priv->model), &iter,
|
||||
ICON_COLUMN, pixbuf,
|
||||
ICON_COLUMN, surface,
|
||||
-1);
|
||||
|
||||
if (pixbuf)
|
||||
g_object_unref (pixbuf);
|
||||
if (surface)
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
while (gtk_tree_model_iter_next (priv->model, &iter));
|
||||
|
||||
@@ -1526,7 +1534,7 @@ set_info_get_info_cb (GCancellable *cancellable,
|
||||
gpointer callback_data)
|
||||
{
|
||||
gboolean cancelled = g_cancellable_is_cancelled (cancellable);
|
||||
GdkPixbuf *pixbuf;
|
||||
cairo_surface_t *surface;
|
||||
GtkTreePath *path;
|
||||
GtkTreeIter iter;
|
||||
GCancellable *model_cancellable = NULL;
|
||||
@@ -1560,7 +1568,7 @@ set_info_get_info_cb (GCancellable *cancellable,
|
||||
/* There was an error, leave the fallback name in there */
|
||||
goto out;
|
||||
|
||||
pixbuf = _gtk_file_info_render_icon (info, GTK_WIDGET (data->button), data->button->priv->icon_size);
|
||||
surface = _gtk_file_info_render_icon (info, GTK_WIDGET (data->button), data->button->priv->icon_size);
|
||||
|
||||
if (!data->label)
|
||||
data->label = g_strdup (g_file_info_get_display_name (info));
|
||||
@@ -1568,13 +1576,13 @@ set_info_get_info_cb (GCancellable *cancellable,
|
||||
is_folder = _gtk_file_info_consider_as_directory (info);
|
||||
|
||||
gtk_list_store_set (GTK_LIST_STORE (data->button->priv->model), &iter,
|
||||
ICON_COLUMN, pixbuf,
|
||||
ICON_COLUMN, surface,
|
||||
DISPLAY_NAME_COLUMN, data->label,
|
||||
IS_FOLDER_COLUMN, is_folder,
|
||||
-1);
|
||||
|
||||
if (pixbuf)
|
||||
g_object_unref (pixbuf);
|
||||
if (surface)
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
out:
|
||||
g_object_unref (data->button);
|
||||
@@ -1716,7 +1724,7 @@ model_add_special_get_info_cb (GCancellable *cancellable,
|
||||
gboolean cancelled = g_cancellable_is_cancelled (cancellable);
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path;
|
||||
GdkPixbuf *pixbuf;
|
||||
cairo_surface_t *surface;
|
||||
GCancellable *model_cancellable = NULL;
|
||||
struct ChangeIconThemeData *data = user_data;
|
||||
gchar *name;
|
||||
@@ -1746,14 +1754,13 @@ model_add_special_get_info_cb (GCancellable *cancellable,
|
||||
if (cancelled || error)
|
||||
goto out;
|
||||
|
||||
pixbuf = _gtk_file_info_render_icon (info, GTK_WIDGET (data->button), data->button->priv->icon_size);
|
||||
|
||||
if (pixbuf)
|
||||
surface = _gtk_file_info_render_icon (info, GTK_WIDGET (data->button), data->button->priv->icon_size);
|
||||
if (surface)
|
||||
{
|
||||
gtk_list_store_set (GTK_LIST_STORE (data->button->priv->model), &iter,
|
||||
ICON_COLUMN, pixbuf,
|
||||
ICON_COLUMN, surface,
|
||||
-1);
|
||||
g_object_unref (pixbuf);
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
|
||||
gtk_tree_model_get (data->button->priv->model, &iter,
|
||||
@@ -1881,7 +1888,7 @@ model_add_volumes (GtkFileChooserButton *button,
|
||||
{
|
||||
GtkFileSystemVolume *volume;
|
||||
GtkTreeIter iter;
|
||||
GdkPixbuf *pixbuf;
|
||||
cairo_surface_t *surface;
|
||||
gchar *display_name;
|
||||
|
||||
volume = l->data;
|
||||
@@ -1906,23 +1913,23 @@ model_add_volumes (GtkFileChooserButton *button,
|
||||
}
|
||||
}
|
||||
|
||||
pixbuf = _gtk_file_system_volume_render_icon (volume,
|
||||
GTK_WIDGET (button),
|
||||
button->priv->icon_size,
|
||||
NULL);
|
||||
surface = _gtk_file_system_volume_render_icon (volume,
|
||||
GTK_WIDGET (button),
|
||||
button->priv->icon_size,
|
||||
NULL);
|
||||
display_name = _gtk_file_system_volume_get_display_name (volume);
|
||||
|
||||
gtk_list_store_insert (store, &iter, pos);
|
||||
gtk_list_store_set (store, &iter,
|
||||
ICON_COLUMN, pixbuf,
|
||||
ICON_COLUMN, surface,
|
||||
DISPLAY_NAME_COLUMN, display_name,
|
||||
TYPE_COLUMN, ROW_TYPE_VOLUME,
|
||||
DATA_COLUMN, _gtk_file_system_volume_ref (volume),
|
||||
IS_FOLDER_COLUMN, TRUE,
|
||||
-1);
|
||||
|
||||
if (pixbuf)
|
||||
g_object_unref (pixbuf);
|
||||
if (surface)
|
||||
cairo_surface_destroy (surface);
|
||||
g_free (display_name);
|
||||
|
||||
button->priv->n_volumes++;
|
||||
@@ -1971,7 +1978,7 @@ model_add_bookmarks (GtkFileChooserButton *button,
|
||||
{
|
||||
gchar *label;
|
||||
GtkIconTheme *icon_theme;
|
||||
GdkPixbuf *pixbuf;
|
||||
cairo_surface_t *surface = NULL;
|
||||
|
||||
if (local_only)
|
||||
continue;
|
||||
@@ -1986,12 +1993,15 @@ model_add_bookmarks (GtkFileChooserButton *button,
|
||||
label = _gtk_file_chooser_label_for_file (file);
|
||||
|
||||
icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (button)));
|
||||
pixbuf = gtk_icon_theme_load_icon (icon_theme, "folder-remote",
|
||||
button->priv->icon_size, 0, NULL);
|
||||
surface = gtk_icon_theme_load_surface (icon_theme, "folder-remote",
|
||||
button->priv->icon_size,
|
||||
gtk_widget_get_scale_factor (GTK_WIDGET (button)),
|
||||
gtk_widget_get_window (GTK_WIDGET (button)),
|
||||
0, NULL);
|
||||
|
||||
gtk_list_store_insert (store, &iter, pos);
|
||||
gtk_list_store_set (store, &iter,
|
||||
ICON_COLUMN, pixbuf,
|
||||
ICON_COLUMN, surface,
|
||||
DISPLAY_NAME_COLUMN, label,
|
||||
TYPE_COLUMN, ROW_TYPE_BOOKMARK,
|
||||
DATA_COLUMN, g_object_ref (file),
|
||||
@@ -1999,7 +2009,8 @@ model_add_bookmarks (GtkFileChooserButton *button,
|
||||
-1);
|
||||
|
||||
g_free (label);
|
||||
g_object_unref (pixbuf);
|
||||
if (surface)
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
|
||||
button->priv->n_bookmarks++;
|
||||
@@ -2077,7 +2088,7 @@ model_update_current_folder (GtkFileChooserButton *button,
|
||||
{
|
||||
gchar *label;
|
||||
GtkIconTheme *icon_theme;
|
||||
GdkPixbuf *pixbuf;
|
||||
cairo_surface_t *surface;
|
||||
|
||||
/* Don't call get_info for remote paths to avoid latency and
|
||||
* auth dialogs.
|
||||
@@ -2091,14 +2102,20 @@ model_update_current_folder (GtkFileChooserButton *button,
|
||||
icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (button)));
|
||||
|
||||
if (g_file_is_native (file))
|
||||
pixbuf = gtk_icon_theme_load_icon (icon_theme, "folder",
|
||||
button->priv->icon_size, 0, NULL);
|
||||
surface = gtk_icon_theme_load_surface (icon_theme, "folder",
|
||||
button->priv->icon_size,
|
||||
gtk_widget_get_scale_factor (GTK_WIDGET (button)),
|
||||
gtk_widget_get_window (GTK_WIDGET (button)),
|
||||
0, NULL);
|
||||
else
|
||||
pixbuf = gtk_icon_theme_load_icon (icon_theme, "folder-remote",
|
||||
button->priv->icon_size, 0, NULL);
|
||||
surface = gtk_icon_theme_load_surface (icon_theme, "folder-remote",
|
||||
button->priv->icon_size,
|
||||
gtk_widget_get_scale_factor (GTK_WIDGET (button)),
|
||||
gtk_widget_get_window (GTK_WIDGET (button)),
|
||||
0, NULL);
|
||||
|
||||
gtk_list_store_set (store, &iter,
|
||||
ICON_COLUMN, pixbuf,
|
||||
ICON_COLUMN, surface,
|
||||
DISPLAY_NAME_COLUMN, label,
|
||||
TYPE_COLUMN, ROW_TYPE_CURRENT_FOLDER,
|
||||
DATA_COLUMN, g_object_ref (file),
|
||||
@@ -2106,7 +2123,8 @@ model_update_current_folder (GtkFileChooserButton *button,
|
||||
-1);
|
||||
|
||||
g_free (label);
|
||||
g_object_unref (pixbuf);
|
||||
if (surface)
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2442,7 +2460,7 @@ update_label_get_info_cb (GCancellable *cancellable,
|
||||
gpointer data)
|
||||
{
|
||||
gboolean cancelled = g_cancellable_is_cancelled (cancellable);
|
||||
GdkPixbuf *pixbuf;
|
||||
cairo_surface_t *surface;
|
||||
GtkFileChooserButton *button = data;
|
||||
GtkFileChooserButtonPrivate *priv = button->priv;
|
||||
|
||||
@@ -2456,11 +2474,10 @@ update_label_get_info_cb (GCancellable *cancellable,
|
||||
|
||||
gtk_label_set_text (GTK_LABEL (priv->label), g_file_info_get_display_name (info));
|
||||
|
||||
pixbuf = _gtk_file_info_render_icon (info, GTK_WIDGET (priv->image), priv->icon_size);
|
||||
|
||||
gtk_image_set_from_pixbuf (GTK_IMAGE (priv->image), pixbuf);
|
||||
if (pixbuf)
|
||||
g_object_unref (pixbuf);
|
||||
surface = _gtk_file_info_render_icon (info, GTK_WIDGET (priv->image), priv->icon_size);
|
||||
gtk_image_set_from_surface (GTK_IMAGE (priv->image), surface);
|
||||
if (surface)
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
out:
|
||||
emit_selection_changed_if_changing_selection (button);
|
||||
@@ -2500,16 +2517,16 @@ update_label_and_image (GtkFileChooserButton *button)
|
||||
base_file = _gtk_file_system_volume_get_root (volume);
|
||||
if (base_file && g_file_equal (base_file, file))
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
cairo_surface_t *surface;
|
||||
|
||||
label_text = _gtk_file_system_volume_get_display_name (volume);
|
||||
pixbuf = _gtk_file_system_volume_render_icon (volume,
|
||||
GTK_WIDGET (button),
|
||||
priv->icon_size,
|
||||
NULL);
|
||||
gtk_image_set_from_pixbuf (GTK_IMAGE (priv->image), pixbuf);
|
||||
if (pixbuf)
|
||||
g_object_unref (pixbuf);
|
||||
surface = _gtk_file_system_volume_render_icon (volume,
|
||||
GTK_WIDGET (button),
|
||||
priv->icon_size,
|
||||
NULL);
|
||||
gtk_image_set_from_surface (GTK_IMAGE (priv->image), surface);
|
||||
if (surface)
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
|
||||
if (base_file)
|
||||
@@ -2534,15 +2551,18 @@ update_label_and_image (GtkFileChooserButton *button)
|
||||
}
|
||||
else
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
cairo_surface_t *surface;
|
||||
|
||||
label_text = _gtk_bookmarks_manager_get_bookmark_label (button->priv->bookmarks_manager, file);
|
||||
pixbuf = gtk_icon_theme_load_icon (get_icon_theme (GTK_WIDGET (priv->image)),
|
||||
"text-x-generic",
|
||||
priv->icon_size, 0, NULL);
|
||||
gtk_image_set_from_pixbuf (GTK_IMAGE (priv->image), pixbuf);
|
||||
if (pixbuf)
|
||||
g_object_unref (pixbuf);
|
||||
surface = gtk_icon_theme_load_surface (get_icon_theme (GTK_WIDGET (priv->image)),
|
||||
"text-x-generic",
|
||||
priv->icon_size,
|
||||
gtk_widget_get_scale_factor (GTK_WIDGET (button)),
|
||||
gtk_widget_get_window (GTK_WIDGET (button)),
|
||||
0, NULL);
|
||||
gtk_image_set_from_surface (GTK_IMAGE (priv->image), surface);
|
||||
if (surface)
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
done_changing_selection = TRUE;
|
||||
}
|
||||
@@ -2566,7 +2586,7 @@ out:
|
||||
else
|
||||
{
|
||||
gtk_label_set_text (GTK_LABEL (priv->label), _(FALLBACK_DISPLAY_NAME));
|
||||
gtk_image_set_from_pixbuf (GTK_IMAGE (priv->image), NULL);
|
||||
gtk_image_set_from_surface (GTK_IMAGE (priv->image), NULL);
|
||||
}
|
||||
|
||||
if (done_changing_selection)
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
<child>
|
||||
<object class="GtkCellRendererPixbuf" id="icon_cell"/>
|
||||
<attributes>
|
||||
<attribute name="pixbuf">0</attribute>
|
||||
<attribute name="surface">0</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
<child>
|
||||
@@ -104,7 +104,7 @@
|
||||
<object class="GtkListStore" id="model">
|
||||
<columns>
|
||||
<!-- column-name icon -->
|
||||
<column type="GdkPixbuf"/>
|
||||
<column type="CairoSurface"/>
|
||||
<!-- column-name display-name -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name type -->
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
#include "gtkorientable.h"
|
||||
#include "gtkintl.h"
|
||||
|
||||
#include <cairo-gobject.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
@@ -364,7 +365,7 @@ enum {
|
||||
MODEL_COL_NAME_COLLATED,
|
||||
MODEL_COL_IS_FOLDER,
|
||||
MODEL_COL_IS_SENSITIVE,
|
||||
MODEL_COL_PIXBUF,
|
||||
MODEL_COL_SURFACE,
|
||||
MODEL_COL_SIZE_TEXT,
|
||||
MODEL_COL_MTIME_TEXT,
|
||||
MODEL_COL_ELLIPSIZE,
|
||||
@@ -381,7 +382,7 @@ enum {
|
||||
G_TYPE_STRING, /* MODEL_COL_NAME_COLLATED */ \
|
||||
G_TYPE_BOOLEAN, /* MODEL_COL_IS_FOLDER */ \
|
||||
G_TYPE_BOOLEAN, /* MODEL_COL_IS_SENSITIVE */ \
|
||||
GDK_TYPE_PIXBUF, /* MODEL_COL_PIXBUF */ \
|
||||
CAIRO_GOBJECT_TYPE_SURFACE, /* MODEL_COL_SURFACE */ \
|
||||
G_TYPE_STRING, /* MODEL_COL_SIZE_TEXT */ \
|
||||
G_TYPE_STRING, /* MODEL_COL_MTIME_TEXT */ \
|
||||
PANGO_TYPE_ELLIPSIZE_MODE /* MODEL_COL_ELLIPSIZE */
|
||||
@@ -3132,7 +3133,7 @@ change_icon_theme (GtkFileChooserDefault *impl)
|
||||
set_icon_cell_renderer_fixed_size (impl);
|
||||
|
||||
if (priv->browse_files_model)
|
||||
_gtk_file_system_model_clear_cache (priv->browse_files_model, MODEL_COL_PIXBUF);
|
||||
_gtk_file_system_model_clear_cache (priv->browse_files_model, MODEL_COL_SURFACE);
|
||||
gtk_widget_queue_resize (priv->browse_files_tree_view);
|
||||
|
||||
profile_end ("end", NULL);
|
||||
@@ -4152,12 +4153,12 @@ file_system_model_set (GtkFileSystemModel *model,
|
||||
else
|
||||
g_value_set_boolean (value, TRUE);
|
||||
break;
|
||||
case MODEL_COL_PIXBUF:
|
||||
case MODEL_COL_SURFACE:
|
||||
if (info)
|
||||
{
|
||||
if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_ICON))
|
||||
{
|
||||
g_value_take_object (value, _gtk_file_info_render_icon (info, GTK_WIDGET (impl), priv->icon_size));
|
||||
g_value_take_boxed (value, _gtk_file_info_render_icon (info, GTK_WIDGET (impl), priv->icon_size));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -7069,7 +7070,7 @@ update_cell_renderer_attributes (GtkFileChooserDefault *impl)
|
||||
if (GTK_IS_CELL_RENDERER_PIXBUF (renderer))
|
||||
{
|
||||
gtk_tree_view_column_set_attributes (column, renderer,
|
||||
"pixbuf", MODEL_COL_PIXBUF,
|
||||
"surface", MODEL_COL_SURFACE,
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
|
||||
+40
-28
@@ -709,42 +709,45 @@ _gtk_file_system_volume_get_root (GtkFileSystemVolume *volume)
|
||||
return file;
|
||||
}
|
||||
|
||||
static GdkPixbuf *
|
||||
get_pixbuf_from_gicon (GIcon *icon,
|
||||
GtkWidget *widget,
|
||||
gint icon_size,
|
||||
GError **error)
|
||||
static cairo_surface_t *
|
||||
get_surface_from_gicon (GIcon *icon,
|
||||
GtkWidget *widget,
|
||||
gint icon_size,
|
||||
GError **error)
|
||||
{
|
||||
GdkScreen *screen;
|
||||
GtkIconTheme *icon_theme;
|
||||
GtkIconInfo *icon_info;
|
||||
GdkPixbuf *pixbuf;
|
||||
cairo_surface_t *surface;
|
||||
|
||||
screen = gtk_widget_get_screen (GTK_WIDGET (widget));
|
||||
icon_theme = gtk_icon_theme_get_for_screen (screen);
|
||||
|
||||
icon_info = gtk_icon_theme_lookup_by_gicon (icon_theme,
|
||||
icon,
|
||||
icon_size,
|
||||
GTK_ICON_LOOKUP_USE_BUILTIN);
|
||||
icon_info = gtk_icon_theme_lookup_by_gicon_for_scale (icon_theme,
|
||||
icon,
|
||||
icon_size,
|
||||
gtk_widget_get_scale_factor (widget),
|
||||
GTK_ICON_LOOKUP_USE_BUILTIN);
|
||||
|
||||
if (!icon_info)
|
||||
return NULL;
|
||||
|
||||
pixbuf = gtk_icon_info_load_icon (icon_info, error);
|
||||
surface = gtk_icon_info_load_surface (icon_info,
|
||||
gtk_widget_get_window (widget), error);
|
||||
|
||||
g_object_unref (icon_info);
|
||||
|
||||
return pixbuf;
|
||||
return surface;
|
||||
}
|
||||
|
||||
GdkPixbuf *
|
||||
cairo_surface_t *
|
||||
_gtk_file_system_volume_render_icon (GtkFileSystemVolume *volume,
|
||||
GtkWidget *widget,
|
||||
gint icon_size,
|
||||
GError **error)
|
||||
{
|
||||
GIcon *icon = NULL;
|
||||
GdkPixbuf *pixbuf;
|
||||
cairo_surface_t *surface;
|
||||
|
||||
DEBUG ("volume_get_icon_name");
|
||||
|
||||
@@ -760,11 +763,11 @@ _gtk_file_system_volume_render_icon (GtkFileSystemVolume *volume,
|
||||
if (!icon)
|
||||
return NULL;
|
||||
|
||||
pixbuf = get_pixbuf_from_gicon (icon, widget, icon_size, error);
|
||||
surface = get_surface_from_gicon (icon, widget, icon_size, error);
|
||||
|
||||
g_object_unref (icon);
|
||||
|
||||
return pixbuf;
|
||||
return surface;
|
||||
}
|
||||
|
||||
GtkFileSystemVolume *
|
||||
@@ -795,39 +798,48 @@ _gtk_file_system_volume_unref (GtkFileSystemVolume *volume)
|
||||
}
|
||||
|
||||
/* GFileInfo helper functions */
|
||||
GdkPixbuf *
|
||||
cairo_surface_t *
|
||||
_gtk_file_info_render_icon (GFileInfo *info,
|
||||
GtkWidget *widget,
|
||||
gint icon_size)
|
||||
GtkWidget *widget,
|
||||
gint icon_size)
|
||||
{
|
||||
GIcon *icon;
|
||||
GdkPixbuf *pixbuf = NULL;
|
||||
GdkPixbuf *pixbuf;
|
||||
const gchar *thumbnail_path;
|
||||
cairo_surface_t *surface = NULL;
|
||||
int scale;
|
||||
|
||||
thumbnail_path = g_file_info_get_attribute_byte_string (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH);
|
||||
|
||||
if (thumbnail_path)
|
||||
pixbuf = gdk_pixbuf_new_from_file_at_size (thumbnail_path,
|
||||
icon_size, icon_size,
|
||||
NULL);
|
||||
{
|
||||
scale = gtk_widget_get_scale_factor (widget);
|
||||
pixbuf = gdk_pixbuf_new_from_file_at_size (thumbnail_path,
|
||||
icon_size*scale, icon_size*scale,
|
||||
NULL);
|
||||
|
||||
if (!pixbuf)
|
||||
surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale,
|
||||
gtk_widget_get_window (widget));
|
||||
g_object_unref (pixbuf);
|
||||
}
|
||||
|
||||
if (!surface)
|
||||
{
|
||||
icon = g_file_info_get_icon (info);
|
||||
|
||||
if (icon)
|
||||
pixbuf = get_pixbuf_from_gicon (icon, widget, icon_size, NULL);
|
||||
surface = get_surface_from_gicon (icon, widget, icon_size, NULL);
|
||||
|
||||
if (!pixbuf)
|
||||
if (!surface)
|
||||
{
|
||||
/* Use general fallback for all files without icon */
|
||||
icon = g_themed_icon_new ("text-x-generic");
|
||||
pixbuf = get_pixbuf_from_gicon (icon, widget, icon_size, NULL);
|
||||
surface = get_surface_from_gicon (icon, widget, icon_size, NULL);
|
||||
g_object_unref (icon);
|
||||
}
|
||||
}
|
||||
|
||||
return pixbuf;
|
||||
return surface;
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
||||
+4
-4
@@ -93,7 +93,7 @@ GtkFileSystemVolume * _gtk_file_system_get_volume_for_file (GtkFileSystem
|
||||
gchar * _gtk_file_system_volume_get_display_name (GtkFileSystemVolume *volume);
|
||||
gboolean _gtk_file_system_volume_is_mounted (GtkFileSystemVolume *volume);
|
||||
GFile * _gtk_file_system_volume_get_root (GtkFileSystemVolume *volume);
|
||||
GdkPixbuf * _gtk_file_system_volume_render_icon (GtkFileSystemVolume *volume,
|
||||
cairo_surface_t * _gtk_file_system_volume_render_icon (GtkFileSystemVolume *volume,
|
||||
GtkWidget *widget,
|
||||
gint icon_size,
|
||||
GError **error);
|
||||
@@ -102,9 +102,9 @@ GtkFileSystemVolume *_gtk_file_system_volume_ref (GtkFileSystemVol
|
||||
void _gtk_file_system_volume_unref (GtkFileSystemVolume *volume);
|
||||
|
||||
/* GFileInfo helper functions */
|
||||
GdkPixbuf * _gtk_file_info_render_icon (GFileInfo *info,
|
||||
GtkWidget *widget,
|
||||
gint icon_size);
|
||||
cairo_surface_t * _gtk_file_info_render_icon (GFileInfo *info,
|
||||
GtkWidget *widget,
|
||||
gint icon_size);
|
||||
|
||||
gboolean _gtk_file_info_consider_as_directory (GFileInfo *info);
|
||||
|
||||
|
||||
+112
-44
@@ -995,12 +995,14 @@ static GdkPixbuf *find_in_cache (GtkIconSet *icon_set,
|
||||
GtkStyleContext *style_context,
|
||||
GtkTextDirection direction,
|
||||
GtkStateType state,
|
||||
GtkIconSize size);
|
||||
GtkIconSize size,
|
||||
gint scale);
|
||||
static void add_to_cache (GtkIconSet *icon_set,
|
||||
GtkStyleContext *style_context,
|
||||
GtkTextDirection direction,
|
||||
GtkStateType state,
|
||||
GtkIconSize size,
|
||||
gint scale,
|
||||
GdkPixbuf *pixbuf);
|
||||
/* Clear icon set contents, drop references to all contained
|
||||
* GdkPixbuf objects and forget all GtkIconSources. Used to
|
||||
@@ -1289,7 +1291,8 @@ ensure_filename_pixbuf (GtkIconSet *icon_set,
|
||||
static GdkPixbuf *
|
||||
render_icon_name_pixbuf (GtkIconSource *icon_source,
|
||||
GtkStyleContext *context,
|
||||
GtkIconSize size)
|
||||
GtkIconSize size,
|
||||
gint scale)
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
GdkPixbuf *tmp_pixbuf;
|
||||
@@ -1359,9 +1362,10 @@ render_icon_name_pixbuf (GtkIconSource *icon_source,
|
||||
names[1] = icon_source->source.icon_name;
|
||||
names[2] = NULL;
|
||||
|
||||
info = gtk_icon_theme_choose_icon (icon_theme,
|
||||
(const char **) names,
|
||||
pixel_size, GTK_ICON_LOOKUP_USE_BUILTIN);
|
||||
info = gtk_icon_theme_choose_icon_for_scale (icon_theme,
|
||||
(const char **) names,
|
||||
pixel_size, scale,
|
||||
GTK_ICON_LOOKUP_USE_BUILTIN);
|
||||
g_free (names[0]);
|
||||
if (info)
|
||||
{
|
||||
@@ -1373,10 +1377,10 @@ render_icon_name_pixbuf (GtkIconSource *icon_source,
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_pixbuf = gtk_icon_theme_load_icon (icon_theme,
|
||||
icon_source->source.icon_name,
|
||||
pixel_size, 0,
|
||||
&error);
|
||||
tmp_pixbuf = gtk_icon_theme_load_icon_for_scale (icon_theme,
|
||||
icon_source->source.icon_name,
|
||||
pixel_size, scale, 0,
|
||||
&error);
|
||||
}
|
||||
|
||||
if (!tmp_pixbuf)
|
||||
@@ -1407,7 +1411,8 @@ find_and_render_icon_source (GtkIconSet *icon_set,
|
||||
GtkStyleContext *context,
|
||||
GtkTextDirection direction,
|
||||
GtkStateType state,
|
||||
GtkIconSize size)
|
||||
GtkIconSize size,
|
||||
gint scale)
|
||||
{
|
||||
GSList *failed = NULL;
|
||||
GdkPixbuf *pixbuf = NULL;
|
||||
@@ -1442,10 +1447,21 @@ find_and_render_icon_source (GtkIconSet *icon_set,
|
||||
g_warning ("Failed to render icon");
|
||||
failed = g_slist_prepend (failed, source);
|
||||
}
|
||||
|
||||
if (scale != 1)
|
||||
{
|
||||
GdkPixbuf *tmp = pixbuf;
|
||||
pixbuf = gdk_pixbuf_scale_simple (pixbuf,
|
||||
gdk_pixbuf_get_width (pixbuf) * scale,
|
||||
gdk_pixbuf_get_height (pixbuf) * scale,
|
||||
GDK_INTERP_BILINEAR);
|
||||
g_object_unref (tmp);
|
||||
}
|
||||
break;
|
||||
case GTK_ICON_SOURCE_ICON_NAME:
|
||||
case GTK_ICON_SOURCE_STATIC_ICON_NAME:
|
||||
pixbuf = render_icon_name_pixbuf (source, context, size);
|
||||
pixbuf = render_icon_name_pixbuf (source, context,
|
||||
size, scale);
|
||||
if (!pixbuf)
|
||||
failed = g_slist_prepend (failed, source);
|
||||
break;
|
||||
@@ -1489,6 +1505,51 @@ render_fallback_image (GtkStyleContext *context,
|
||||
return gtk_render_icon_pixbuf (context, &fallback_source, size);
|
||||
}
|
||||
|
||||
static GdkPixbuf*
|
||||
gtk_icon_set_render_icon_pixbuf_for_scale (GtkIconSet *icon_set,
|
||||
GtkStyleContext *context,
|
||||
GtkIconSize size,
|
||||
gint scale)
|
||||
{
|
||||
GdkPixbuf *icon = NULL;
|
||||
GtkStateFlags flags = 0;
|
||||
GtkStateType state;
|
||||
GtkTextDirection direction;
|
||||
|
||||
g_return_val_if_fail (icon_set != NULL, NULL);
|
||||
g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), NULL);
|
||||
|
||||
flags = gtk_style_context_get_state (context);
|
||||
if (flags & GTK_STATE_FLAG_INSENSITIVE)
|
||||
state = GTK_STATE_INSENSITIVE;
|
||||
else if (flags & GTK_STATE_FLAG_PRELIGHT)
|
||||
state = GTK_STATE_PRELIGHT;
|
||||
else
|
||||
state = GTK_STATE_NORMAL;
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
direction = gtk_style_context_get_direction (context);
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
|
||||
if (icon_set->sources)
|
||||
{
|
||||
icon = find_in_cache (icon_set, context, direction, state, size, scale);
|
||||
if (icon)
|
||||
return g_object_ref (icon);
|
||||
}
|
||||
|
||||
if (icon_set->sources)
|
||||
icon = find_and_render_icon_source (icon_set, context, direction, state,
|
||||
size, scale);
|
||||
|
||||
if (icon == NULL)
|
||||
icon = render_fallback_image (context, direction, state, size);
|
||||
|
||||
add_to_cache (icon_set, context, direction, state, size, scale, icon);
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_icon_set_render_icon_pixbuf:
|
||||
* @icon_set: a #GtkIconSet
|
||||
@@ -1514,45 +1575,48 @@ gtk_icon_set_render_icon_pixbuf (GtkIconSet *icon_set,
|
||||
GtkStyleContext *context,
|
||||
GtkIconSize size)
|
||||
{
|
||||
GdkPixbuf *icon = NULL;
|
||||
GtkStateFlags flags = 0;
|
||||
GtkStateType state;
|
||||
GtkTextDirection direction;
|
||||
|
||||
g_return_val_if_fail (icon_set != NULL, NULL);
|
||||
g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), NULL);
|
||||
|
||||
flags = gtk_style_context_get_state (context);
|
||||
if (flags & GTK_STATE_FLAG_INSENSITIVE)
|
||||
state = GTK_STATE_INSENSITIVE;
|
||||
else if (flags & GTK_STATE_FLAG_PRELIGHT)
|
||||
state = GTK_STATE_PRELIGHT;
|
||||
else
|
||||
state = GTK_STATE_NORMAL;
|
||||
return gtk_icon_set_render_icon_pixbuf_for_scale (icon_set, context, size, 1);
|
||||
}
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
direction = gtk_style_context_get_direction (context);
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
/**
|
||||
* gtk_icon_set_render_icon_surface:
|
||||
* @icon_set: a #GtkIconSet
|
||||
* @context: a #GtkStyleContext
|
||||
* @size: (type int): icon size. A size of (GtkIconSize)-1
|
||||
* means render at the size of the source and don't scale.
|
||||
* @scale: the window scale to render for
|
||||
* @for_window: (allow-none): #GdkWindow to optimize drawing for, or %NULL
|
||||
*
|
||||
* Renders an icon using gtk_render_icon_pixbuf() and converts it to a
|
||||
* cairo surface.
|
||||
*
|
||||
* This function never returns %NULL; if the icon can't be rendered
|
||||
* (perhaps because an image file fails to load), a default "missing
|
||||
* image" icon will be returned instead.
|
||||
*
|
||||
* Return value: (transfer full): a #cairo_surface_t to be displayed
|
||||
*
|
||||
* Since: 3.10
|
||||
*/
|
||||
cairo_surface_t *
|
||||
gtk_icon_set_render_icon_surface (GtkIconSet *icon_set,
|
||||
GtkStyleContext *context,
|
||||
GtkIconSize size,
|
||||
gint scale,
|
||||
GdkWindow *for_window)
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
cairo_surface_t *surface;
|
||||
|
||||
if (icon_set->sources)
|
||||
{
|
||||
icon = find_in_cache (icon_set, context, direction, state, size);
|
||||
if (icon)
|
||||
{
|
||||
g_object_ref (icon);
|
||||
return icon;
|
||||
}
|
||||
}
|
||||
pixbuf = gtk_icon_set_render_icon_pixbuf_for_scale (icon_set, context, size, scale);
|
||||
|
||||
if (icon_set->sources)
|
||||
icon = find_and_render_icon_source (icon_set, context, direction, state, size);
|
||||
surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, for_window);
|
||||
g_object_unref (pixbuf);
|
||||
|
||||
if (icon == NULL)
|
||||
icon = render_fallback_image (context, direction, state, size);
|
||||
|
||||
add_to_cache (icon_set, context, direction, state, size, icon);
|
||||
|
||||
return icon;
|
||||
return surface;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2402,6 +2466,7 @@ struct _CachedIcon
|
||||
GtkTextDirection direction;
|
||||
GtkStateType state;
|
||||
GtkIconSize size;
|
||||
gint scale;
|
||||
|
||||
GdkPixbuf *pixbuf;
|
||||
};
|
||||
@@ -2430,7 +2495,8 @@ find_in_cache (GtkIconSet *icon_set,
|
||||
GtkStyleContext *style_context,
|
||||
GtkTextDirection direction,
|
||||
GtkStateType state,
|
||||
GtkIconSize size)
|
||||
GtkIconSize size,
|
||||
gint scale)
|
||||
{
|
||||
GSList *tmp_list;
|
||||
GSList *prev;
|
||||
@@ -2472,6 +2538,7 @@ add_to_cache (GtkIconSet *icon_set,
|
||||
GtkTextDirection direction,
|
||||
GtkStateType state,
|
||||
GtkIconSize size,
|
||||
gint scale,
|
||||
GdkPixbuf *pixbuf)
|
||||
{
|
||||
CachedIcon *icon;
|
||||
@@ -2488,6 +2555,7 @@ add_to_cache (GtkIconSet *icon_set,
|
||||
icon->direction = direction;
|
||||
icon->state = state;
|
||||
icon->size = size;
|
||||
icon->scale = scale;
|
||||
icon->pixbuf = pixbuf;
|
||||
attach_to_style (icon_set, icon->style);
|
||||
|
||||
|
||||
+469
-24
@@ -19,6 +19,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <math.h>
|
||||
#include "gtkiconhelperprivate.h"
|
||||
|
||||
G_DEFINE_TYPE (GtkIconHelper, _gtk_icon_helper, G_TYPE_OBJECT)
|
||||
@@ -26,12 +27,16 @@ G_DEFINE_TYPE (GtkIconHelper, _gtk_icon_helper, G_TYPE_OBJECT)
|
||||
struct _GtkIconHelperPrivate {
|
||||
GtkImageType storage_type;
|
||||
|
||||
GdkWindow *window;
|
||||
|
||||
GdkPixbuf *orig_pixbuf;
|
||||
int orig_pixbuf_scale;
|
||||
GdkPixbufAnimation *animation;
|
||||
GIcon *gicon;
|
||||
GtkIconSet *icon_set;
|
||||
gchar *icon_name;
|
||||
gchar *stock_id;
|
||||
cairo_surface_t *orig_surface;
|
||||
|
||||
GtkIconSize icon_size;
|
||||
gint pixel_size;
|
||||
@@ -41,6 +46,12 @@ struct _GtkIconHelperPrivate {
|
||||
|
||||
GdkPixbuf *rendered_pixbuf;
|
||||
GtkStateFlags last_rendered_state;
|
||||
|
||||
cairo_surface_t *rendered_surface;
|
||||
gint rendered_surface_width;
|
||||
gint rendered_surface_height;
|
||||
GtkStateFlags last_surface_state;
|
||||
gint last_surface_scale;
|
||||
};
|
||||
|
||||
void
|
||||
@@ -50,6 +61,19 @@ _gtk_icon_helper_clear (GtkIconHelper *self)
|
||||
g_clear_object (&self->priv->orig_pixbuf);
|
||||
g_clear_object (&self->priv->animation);
|
||||
g_clear_object (&self->priv->rendered_pixbuf);
|
||||
g_clear_object (&self->priv->window);
|
||||
|
||||
if (self->priv->orig_surface)
|
||||
{
|
||||
cairo_surface_destroy (self->priv->orig_surface);
|
||||
self->priv->orig_surface = NULL;
|
||||
}
|
||||
|
||||
if (self->priv->rendered_surface)
|
||||
{
|
||||
cairo_surface_destroy (self->priv->rendered_surface);
|
||||
self->priv->rendered_surface = NULL;
|
||||
}
|
||||
|
||||
if (self->priv->icon_set != NULL)
|
||||
{
|
||||
@@ -68,6 +92,8 @@ _gtk_icon_helper_clear (GtkIconHelper *self)
|
||||
self->priv->storage_type = GTK_IMAGE_EMPTY;
|
||||
self->priv->icon_size = GTK_ICON_SIZE_INVALID;
|
||||
self->priv->last_rendered_state = GTK_STATE_FLAG_NORMAL;
|
||||
self->priv->last_surface_state = GTK_STATE_FLAG_NORMAL;
|
||||
self->priv->last_surface_scale = 0;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -76,6 +102,17 @@ _gtk_icon_helper_invalidate (GtkIconHelper *self)
|
||||
g_clear_object (&self->priv->rendered_pixbuf);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_icon_helper_set_window (GtkIconHelper *self,
|
||||
GdkWindow *window)
|
||||
{
|
||||
if (window)
|
||||
g_object_ref (window);
|
||||
g_clear_object (&self->priv->window);
|
||||
self->priv->window = window;
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_helper_finalize (GObject *object)
|
||||
{
|
||||
@@ -106,6 +143,7 @@ _gtk_icon_helper_init (GtkIconHelper *self)
|
||||
self->priv->icon_size = GTK_ICON_SIZE_INVALID;
|
||||
self->priv->pixel_size = -1;
|
||||
self->priv->last_rendered_state = GTK_STATE_FLAG_NORMAL;
|
||||
self->priv->orig_pixbuf_scale = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -286,6 +324,64 @@ ensure_pixbuf_for_icon_set (GtkIconHelper *self,
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
}
|
||||
|
||||
static void
|
||||
get_surface_size (GtkIconHelper *self,
|
||||
GtkStyleContext *context,
|
||||
cairo_surface_t *surface,
|
||||
int *width,
|
||||
int *height)
|
||||
{
|
||||
double x_scale, y_scale;
|
||||
|
||||
if (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_IMAGE)
|
||||
{
|
||||
x_scale = y_scale = 1;
|
||||
|
||||
#ifdef HAVE_CAIRO_SURFACE_SET_DEVICE_SCALE
|
||||
cairo_surface_get_device_scale (surface, &x_scale, &y_scale);
|
||||
#endif
|
||||
|
||||
/* Assume any set scaling is icon scale */
|
||||
*width =
|
||||
ceil (cairo_image_surface_get_width (surface) / x_scale);
|
||||
*height =
|
||||
ceil (cairo_image_surface_get_height (surface) / y_scale);
|
||||
}
|
||||
else
|
||||
ensure_icon_size (self, context, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_pixbuf_from_surface (GtkIconHelper *self,
|
||||
GtkStyleContext *context)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
gint width, height;
|
||||
cairo_t *cr;
|
||||
|
||||
|
||||
if (!check_invalidate_pixbuf (self, context))
|
||||
return;
|
||||
|
||||
if (self->priv->rendered_pixbuf)
|
||||
return;
|
||||
|
||||
get_surface_size (self, context, self->priv->orig_surface, &width, &height);
|
||||
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
width, height);
|
||||
|
||||
cr = cairo_create (surface);
|
||||
cairo_set_source_surface (cr, self->priv->orig_surface, 0, 0);
|
||||
cairo_paint (cr);
|
||||
cairo_destroy (cr);
|
||||
|
||||
self->priv->rendered_pixbuf =
|
||||
gdk_pixbuf_get_from_surface (surface, 0, 0, width, height);
|
||||
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_pixbuf_at_size (GtkIconHelper *self,
|
||||
GtkStyleContext *context)
|
||||
@@ -298,17 +394,34 @@ ensure_pixbuf_at_size (GtkIconHelper *self,
|
||||
if (self->priv->rendered_pixbuf)
|
||||
return;
|
||||
|
||||
if (self->priv->pixel_size != -1 ||
|
||||
self->priv->icon_size != GTK_ICON_SIZE_INVALID)
|
||||
if (self->priv->force_scale_pixbuf &&
|
||||
(self->priv->pixel_size != -1 ||
|
||||
self->priv->icon_size != GTK_ICON_SIZE_INVALID))
|
||||
{
|
||||
ensure_icon_size (self, context, &width, &height);
|
||||
|
||||
if (width < gdk_pixbuf_get_width (self->priv->orig_pixbuf) ||
|
||||
if (self->priv->orig_pixbuf_scale > 1 ||
|
||||
/* These should divide the orig_pixbuf size by scale, but need not
|
||||
due to the above scale > 1 check */
|
||||
width < gdk_pixbuf_get_width (self->priv->orig_pixbuf) ||
|
||||
height < gdk_pixbuf_get_height (self->priv->orig_pixbuf))
|
||||
self->priv->rendered_pixbuf =
|
||||
gdk_pixbuf_scale_simple (self->priv->orig_pixbuf,
|
||||
width, height,
|
||||
GDK_INTERP_BILINEAR);
|
||||
{
|
||||
width = MIN (width, gdk_pixbuf_get_width (self->priv->orig_pixbuf) / self->priv->orig_pixbuf_scale);
|
||||
height = MIN (height, gdk_pixbuf_get_height (self->priv->orig_pixbuf) / self->priv->orig_pixbuf_scale);
|
||||
self->priv->rendered_pixbuf =
|
||||
gdk_pixbuf_scale_simple (self->priv->orig_pixbuf,
|
||||
width, height,
|
||||
GDK_INTERP_BILINEAR);
|
||||
}
|
||||
}
|
||||
else if (self->priv->orig_pixbuf_scale > 1)
|
||||
{
|
||||
width = gdk_pixbuf_get_width (self->priv->orig_pixbuf) / self->priv->orig_pixbuf_scale;
|
||||
height =gdk_pixbuf_get_height (self->priv->orig_pixbuf) / self->priv->orig_pixbuf_scale;
|
||||
self->priv->rendered_pixbuf =
|
||||
gdk_pixbuf_scale_simple (self->priv->orig_pixbuf,
|
||||
width, height,
|
||||
GDK_INTERP_BILINEAR);
|
||||
}
|
||||
|
||||
if (!self->priv->rendered_pixbuf)
|
||||
@@ -324,11 +437,12 @@ _gtk_icon_helper_ensure_pixbuf (GtkIconHelper *self,
|
||||
|
||||
switch (self->priv->storage_type)
|
||||
{
|
||||
case GTK_IMAGE_SURFACE:
|
||||
ensure_pixbuf_from_surface (self, context);
|
||||
break;
|
||||
|
||||
case GTK_IMAGE_PIXBUF:
|
||||
if (self->priv->force_scale_pixbuf)
|
||||
ensure_pixbuf_at_size (self, context);
|
||||
else
|
||||
pixbuf = g_object_ref (self->priv->orig_pixbuf);
|
||||
ensure_pixbuf_at_size (self, context);
|
||||
break;
|
||||
|
||||
case GTK_IMAGE_STOCK:
|
||||
@@ -365,24 +479,320 @@ _gtk_icon_helper_ensure_pixbuf (GtkIconHelper *self,
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
static gint
|
||||
get_scale_factor (GtkIconHelper *self,
|
||||
GtkStyleContext *context)
|
||||
{
|
||||
GdkScreen *screen;
|
||||
|
||||
if (self->priv->window)
|
||||
return gdk_window_get_scale_factor (self->priv->window);
|
||||
|
||||
screen = gtk_style_context_get_screen (context);
|
||||
|
||||
/* else fall back to something that is more likely to be right than
|
||||
* just returning 1:
|
||||
*/
|
||||
return gdk_screen_get_monitor_scale_factor (screen, 0);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_invalidate_surface (GtkIconHelper *self,
|
||||
GtkStyleContext *context)
|
||||
{
|
||||
GtkStateFlags state;
|
||||
int scale;
|
||||
|
||||
state = gtk_style_context_get_state (context);
|
||||
scale = get_scale_factor (self, context);
|
||||
|
||||
if ((self->priv->rendered_surface != NULL) &&
|
||||
(self->priv->last_surface_state == state) &&
|
||||
(self->priv->last_surface_scale == scale))
|
||||
return FALSE;
|
||||
|
||||
self->priv->last_surface_state = state;
|
||||
self->priv->last_surface_scale = scale;
|
||||
|
||||
if (self->priv->rendered_surface)
|
||||
cairo_surface_destroy (self->priv->rendered_surface);
|
||||
self->priv->rendered_surface = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_surface_from_surface (GtkIconHelper *self,
|
||||
GtkStyleContext *context)
|
||||
{
|
||||
if (!check_invalidate_surface (self, context))
|
||||
return;
|
||||
|
||||
if (self->priv->rendered_surface)
|
||||
return;
|
||||
|
||||
self->priv->rendered_surface =
|
||||
cairo_surface_reference (self->priv->orig_surface);
|
||||
|
||||
get_surface_size (self, context, self->priv->orig_surface,
|
||||
&self->priv->rendered_surface_width,
|
||||
&self->priv->rendered_surface_height);
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_surface_from_pixbuf (GtkIconHelper *self,
|
||||
GtkStyleContext *context)
|
||||
{
|
||||
gint width, height;
|
||||
GdkPixbuf *pixbuf;
|
||||
int scale;
|
||||
|
||||
if (!check_invalidate_surface (self, context))
|
||||
return;
|
||||
|
||||
if (self->priv->rendered_surface)
|
||||
return;
|
||||
|
||||
scale = get_scale_factor (self, context);
|
||||
|
||||
if (self->priv->force_scale_pixbuf &&
|
||||
(self->priv->pixel_size != -1 ||
|
||||
self->priv->icon_size != GTK_ICON_SIZE_INVALID))
|
||||
{
|
||||
ensure_icon_size (self, context, &width, &height);
|
||||
|
||||
if (scale != self->priv->orig_pixbuf_scale ||
|
||||
width < gdk_pixbuf_get_width (self->priv->orig_pixbuf) / self->priv->orig_pixbuf_scale ||
|
||||
height < gdk_pixbuf_get_height (self->priv->orig_pixbuf) / self->priv->orig_pixbuf_scale)
|
||||
{
|
||||
width = MIN (width * scale, gdk_pixbuf_get_width (self->priv->orig_pixbuf) * scale / self->priv->orig_pixbuf_scale);
|
||||
height = MIN (height * scale, gdk_pixbuf_get_height (self->priv->orig_pixbuf) * scale / self->priv->orig_pixbuf_scale);
|
||||
|
||||
pixbuf = gdk_pixbuf_scale_simple (self->priv->orig_pixbuf,
|
||||
width, height,
|
||||
GDK_INTERP_BILINEAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
pixbuf = g_object_ref (self->priv->orig_pixbuf);
|
||||
scale = self->priv->orig_pixbuf_scale;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pixbuf = g_object_ref (self->priv->orig_pixbuf);
|
||||
scale = self->priv->orig_pixbuf_scale;
|
||||
}
|
||||
|
||||
self->priv->rendered_surface_width = (gdk_pixbuf_get_width (pixbuf) + scale - 1) / scale;
|
||||
self->priv->rendered_surface_height = (gdk_pixbuf_get_height (pixbuf) + scale - 1) / scale;
|
||||
|
||||
self->priv->rendered_surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, self->priv->window);
|
||||
g_object_unref (pixbuf);
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_surface_for_icon_set (GtkIconHelper *self,
|
||||
GtkStyleContext *context,
|
||||
GtkIconSet *icon_set)
|
||||
{
|
||||
gint scale;
|
||||
|
||||
if (!check_invalidate_surface (self, context))
|
||||
return;
|
||||
|
||||
scale = get_scale_factor (self, context);
|
||||
|
||||
self->priv->rendered_surface =
|
||||
gtk_icon_set_render_icon_surface (icon_set, context,
|
||||
self->priv->icon_size,
|
||||
scale, self->priv->window);
|
||||
|
||||
if (self->priv->rendered_surface)
|
||||
get_surface_size (self, context, self->priv->rendered_surface,
|
||||
&self->priv->rendered_surface_width,
|
||||
&self->priv->rendered_surface_height);
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_stated_surface_from_info (GtkIconHelper *self,
|
||||
GtkStyleContext *context,
|
||||
GtkIconInfo *info,
|
||||
int scale)
|
||||
{
|
||||
GdkPixbuf *destination = NULL;
|
||||
cairo_surface_t *surface;
|
||||
gboolean symbolic;
|
||||
|
||||
symbolic = FALSE;
|
||||
|
||||
if (info)
|
||||
destination =
|
||||
gtk_icon_info_load_symbolic_for_context (info,
|
||||
context,
|
||||
&symbolic,
|
||||
NULL);
|
||||
|
||||
if (destination == NULL)
|
||||
{
|
||||
GtkIconSet *icon_set;
|
||||
icon_set = gtk_style_context_lookup_icon_set (context, GTK_STOCK_MISSING_IMAGE);
|
||||
|
||||
destination =
|
||||
gtk_icon_set_render_icon_pixbuf (icon_set, context, self->priv->icon_size);
|
||||
}
|
||||
else if (!symbolic)
|
||||
{
|
||||
GtkIconSource *source;
|
||||
GdkPixbuf *rendered;
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
|
||||
source = gtk_icon_source_new ();
|
||||
gtk_icon_source_set_pixbuf (source, destination);
|
||||
/* The size here is arbitrary; since size isn't
|
||||
* wildcarded in the source, it isn't supposed to be
|
||||
* scaled by the engine function
|
||||
*/
|
||||
gtk_icon_source_set_size (source,
|
||||
GTK_ICON_SIZE_SMALL_TOOLBAR);
|
||||
gtk_icon_source_set_size_wildcarded (source, FALSE);
|
||||
|
||||
rendered = gtk_render_icon_pixbuf (context, source, (GtkIconSize) -1);
|
||||
gtk_icon_source_free (source);
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
|
||||
g_object_unref (destination);
|
||||
destination = rendered;
|
||||
}
|
||||
|
||||
surface = NULL;
|
||||
if (destination)
|
||||
{
|
||||
surface = gdk_cairo_surface_create_from_pixbuf (destination, scale, self->priv->window);
|
||||
|
||||
self->priv->rendered_surface_width =
|
||||
(gdk_pixbuf_get_width (destination) + scale - 1) / scale;
|
||||
self->priv->rendered_surface_height =
|
||||
(gdk_pixbuf_get_height (destination) + scale - 1) / scale;
|
||||
}
|
||||
|
||||
self->priv->rendered_surface = surface;
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_surface_for_icon_name_or_gicon (GtkIconHelper *self,
|
||||
GtkStyleContext *context)
|
||||
{
|
||||
GtkIconTheme *icon_theme;
|
||||
gint width, height, scale;
|
||||
GtkIconInfo *info;
|
||||
GtkIconLookupFlags flags;
|
||||
|
||||
if (!check_invalidate_surface (self, context))
|
||||
return;
|
||||
|
||||
icon_theme = gtk_icon_theme_get_default ();
|
||||
flags = get_icon_lookup_flags (self);
|
||||
|
||||
ensure_icon_size (self, context, &width, &height);
|
||||
scale = get_scale_factor (self, context);
|
||||
|
||||
if (self->priv->storage_type == GTK_IMAGE_ICON_NAME &&
|
||||
self->priv->icon_name != NULL)
|
||||
{
|
||||
info = gtk_icon_theme_lookup_icon_for_scale (icon_theme,
|
||||
self->priv->icon_name,
|
||||
MIN (width, height),
|
||||
scale, flags);
|
||||
}
|
||||
else if (self->priv->storage_type == GTK_IMAGE_GICON &&
|
||||
self->priv->gicon != NULL)
|
||||
{
|
||||
info = gtk_icon_theme_lookup_by_gicon_for_scale (icon_theme,
|
||||
self->priv->gicon,
|
||||
MIN (width, height),
|
||||
scale, flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert_not_reached ();
|
||||
return;
|
||||
}
|
||||
|
||||
ensure_stated_surface_from_info (self, context, info, scale);
|
||||
|
||||
if (info)
|
||||
g_object_unref (info);
|
||||
}
|
||||
|
||||
cairo_surface_t *
|
||||
_gtk_icon_helper_ensure_surface (GtkIconHelper *self,
|
||||
GtkStyleContext *context)
|
||||
{
|
||||
cairo_surface_t *surface = NULL;
|
||||
GtkIconSet *icon_set;
|
||||
|
||||
switch (self->priv->storage_type)
|
||||
{
|
||||
case GTK_IMAGE_SURFACE:
|
||||
ensure_surface_from_surface (self, context);
|
||||
break;
|
||||
|
||||
case GTK_IMAGE_PIXBUF:
|
||||
ensure_surface_from_pixbuf (self, context);
|
||||
break;
|
||||
|
||||
case GTK_IMAGE_STOCK:
|
||||
icon_set = gtk_style_context_lookup_icon_set (context, self->priv->stock_id);
|
||||
if (icon_set != NULL)
|
||||
ensure_surface_for_icon_set (self, context, icon_set);
|
||||
else
|
||||
surface = NULL;
|
||||
break;
|
||||
|
||||
case GTK_IMAGE_ICON_SET:
|
||||
icon_set = self->priv->icon_set;
|
||||
ensure_surface_for_icon_set (self, context, icon_set);
|
||||
break;
|
||||
|
||||
case GTK_IMAGE_ICON_NAME:
|
||||
case GTK_IMAGE_GICON:
|
||||
ensure_surface_for_icon_name_or_gicon (self, context);
|
||||
break;
|
||||
|
||||
case GTK_IMAGE_ANIMATION:
|
||||
case GTK_IMAGE_EMPTY:
|
||||
default:
|
||||
surface = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (surface == NULL &&
|
||||
self->priv->rendered_surface != NULL)
|
||||
surface = cairo_surface_reference (self->priv->rendered_surface);
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_icon_helper_get_size (GtkIconHelper *self,
|
||||
GtkStyleContext *context,
|
||||
gint *width_out,
|
||||
gint *height_out)
|
||||
{
|
||||
GdkPixbuf *pix;
|
||||
cairo_surface_t *surface;
|
||||
gint width, height;
|
||||
|
||||
width = height = 0;
|
||||
pix = _gtk_icon_helper_ensure_pixbuf (self, context);
|
||||
surface = _gtk_icon_helper_ensure_surface (self, context);
|
||||
|
||||
if (pix != NULL)
|
||||
if (surface != NULL)
|
||||
{
|
||||
width = gdk_pixbuf_get_width (pix);
|
||||
height = gdk_pixbuf_get_height (pix);
|
||||
|
||||
g_object_unref (pix);
|
||||
width = self->priv->rendered_surface_width;
|
||||
height = self->priv->rendered_surface_height;
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
else if (self->priv->storage_type == GTK_IMAGE_ANIMATION)
|
||||
{
|
||||
@@ -474,6 +884,19 @@ _gtk_icon_helper_set_animation (GtkIconHelper *self,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_icon_helper_set_surface (GtkIconHelper *self,
|
||||
cairo_surface_t *surface)
|
||||
{
|
||||
_gtk_icon_helper_clear (self);
|
||||
|
||||
if (surface != NULL)
|
||||
{
|
||||
self->priv->storage_type = GTK_IMAGE_SURFACE;
|
||||
self->priv->orig_surface = cairo_surface_reference (surface);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_icon_helper_set_stock_id (GtkIconHelper *self,
|
||||
const gchar *stock_id,
|
||||
@@ -571,6 +994,12 @@ _gtk_icon_helper_peek_icon_set (GtkIconHelper *self)
|
||||
return self->priv->icon_set;
|
||||
}
|
||||
|
||||
cairo_surface_t *
|
||||
_gtk_icon_helper_peek_surface (GtkIconHelper *self)
|
||||
{
|
||||
return self->priv->orig_surface;
|
||||
}
|
||||
|
||||
const gchar *
|
||||
_gtk_icon_helper_get_stock_id (GtkIconHelper *self)
|
||||
{
|
||||
@@ -596,14 +1025,13 @@ _gtk_icon_helper_draw (GtkIconHelper *self,
|
||||
gdouble x,
|
||||
gdouble y)
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
cairo_surface_t *surface;
|
||||
|
||||
pixbuf = _gtk_icon_helper_ensure_pixbuf (self, context);
|
||||
|
||||
if (pixbuf != NULL)
|
||||
surface = _gtk_icon_helper_ensure_surface (self, context);
|
||||
if (surface != NULL)
|
||||
{
|
||||
gtk_render_icon (context, cr, pixbuf, x, y);
|
||||
g_object_unref (pixbuf);
|
||||
gtk_render_icon_surface (context, cr, surface, x, y);
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -629,3 +1057,20 @@ _gtk_icon_helper_set_force_scale_pixbuf (GtkIconHelper *self,
|
||||
_gtk_icon_helper_invalidate (self);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_icon_helper_set_pixbuf_scale (GtkIconHelper *self,
|
||||
int scale)
|
||||
{
|
||||
if (self->priv->orig_pixbuf_scale != scale)
|
||||
{
|
||||
self->priv->orig_pixbuf_scale = scale;
|
||||
_gtk_icon_helper_invalidate (self);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
_gtk_icon_helper_get_pixbuf_scale (GtkIconHelper *self)
|
||||
{
|
||||
return self->priv->orig_pixbuf_scale;
|
||||
}
|
||||
|
||||
@@ -70,6 +70,8 @@ GtkIconHelper *_gtk_icon_helper_new (void);
|
||||
|
||||
void _gtk_icon_helper_clear (GtkIconHelper *self);
|
||||
void _gtk_icon_helper_invalidate (GtkIconHelper *self);
|
||||
void _gtk_icon_helper_set_window (GtkIconHelper *self,
|
||||
GdkWindow *window);
|
||||
|
||||
gboolean _gtk_icon_helper_get_is_empty (GtkIconHelper *self);
|
||||
|
||||
@@ -77,7 +79,10 @@ void _gtk_icon_helper_set_gicon (GtkIconHelper *self,
|
||||
GIcon *gicon,
|
||||
GtkIconSize icon_size);
|
||||
void _gtk_icon_helper_set_pixbuf (GtkIconHelper *self,
|
||||
GdkPixbuf *pixbuf);
|
||||
GdkPixbuf *pixbuf);
|
||||
void _gtk_icon_helper_set_pixbuf_scale (GtkIconHelper *self,
|
||||
int scale);
|
||||
int _gtk_icon_helper_get_pixbuf_scale (GtkIconHelper *self);
|
||||
void _gtk_icon_helper_set_animation (GtkIconHelper *self,
|
||||
GdkPixbufAnimation *animation);
|
||||
void _gtk_icon_helper_set_icon_set (GtkIconHelper *self,
|
||||
@@ -90,6 +95,8 @@ void _gtk_icon_helper_set_icon_name (GtkIconHelper *self,
|
||||
void _gtk_icon_helper_set_stock_id (GtkIconHelper *self,
|
||||
const gchar *stock_id,
|
||||
GtkIconSize icon_size);
|
||||
void _gtk_icon_helper_set_surface (GtkIconHelper *self,
|
||||
cairo_surface_t *surface);
|
||||
|
||||
void _gtk_icon_helper_set_icon_size (GtkIconHelper *self,
|
||||
GtkIconSize icon_size);
|
||||
@@ -107,6 +114,7 @@ GdkPixbuf *_gtk_icon_helper_peek_pixbuf (GtkIconHelper *self);
|
||||
GIcon *_gtk_icon_helper_peek_gicon (GtkIconHelper *self);
|
||||
GtkIconSet *_gtk_icon_helper_peek_icon_set (GtkIconHelper *self);
|
||||
GdkPixbufAnimation *_gtk_icon_helper_peek_animation (GtkIconHelper *self);
|
||||
cairo_surface_t *_gtk_icon_helper_peek_surface (GtkIconHelper *self);
|
||||
|
||||
const gchar *_gtk_icon_helper_get_stock_id (GtkIconHelper *self);
|
||||
const gchar *_gtk_icon_helper_get_icon_name (GtkIconHelper *self);
|
||||
|
||||
+470
-114
@@ -55,6 +55,10 @@
|
||||
|
||||
#include "deprecated/gtkstyle.h"
|
||||
|
||||
/* this is in case round() is not provided by the compiler,
|
||||
* such as in the case of C89 compilers, like MSVC
|
||||
*/
|
||||
#include "fallback-c89.c"
|
||||
|
||||
/**
|
||||
* SECTION:gtkicontheme
|
||||
@@ -208,6 +212,7 @@ struct _GtkIconThemePrivate
|
||||
typedef struct {
|
||||
gchar **icon_names;
|
||||
gint size;
|
||||
gint scale;
|
||||
GtkIconLookupFlags flags;
|
||||
} IconInfoKey;
|
||||
|
||||
@@ -252,11 +257,13 @@ struct _GtkIconInfo
|
||||
*/
|
||||
IconThemeDirType dir_type;
|
||||
gint dir_size;
|
||||
gint dir_scale;
|
||||
gint threshold;
|
||||
|
||||
/* Parameters influencing the scaled icon
|
||||
*/
|
||||
gint desired_size;
|
||||
gint desired_scale;
|
||||
guint raw_coordinates : 1;
|
||||
guint forced_size : 1;
|
||||
guint emblems_applied : 1;
|
||||
@@ -294,6 +301,7 @@ typedef struct
|
||||
int min_size;
|
||||
int max_size;
|
||||
int threshold;
|
||||
int scale;
|
||||
|
||||
char *dir;
|
||||
char *subdir;
|
||||
@@ -332,6 +340,7 @@ static void theme_destroy (IconTheme *theme);
|
||||
static GtkIconInfo *theme_lookup_icon (IconTheme *theme,
|
||||
const char *icon_name,
|
||||
int size,
|
||||
gint scale,
|
||||
gboolean allow_svg,
|
||||
gboolean use_default_icons);
|
||||
static void theme_list_icons (IconTheme *theme,
|
||||
@@ -367,8 +376,8 @@ static IconSuffix suffix_from_name (const char *name);
|
||||
|
||||
static BuiltinIcon *find_builtin_icon (const gchar *icon_name,
|
||||
gint size,
|
||||
gint *min_difference_p,
|
||||
gboolean *has_larger_p);
|
||||
gint scale,
|
||||
gint *min_difference_p);
|
||||
static void remove_from_lru_cache (GtkIconTheme *icon_theme,
|
||||
GtkIconInfo *icon_info);
|
||||
|
||||
@@ -390,7 +399,8 @@ icon_info_key_hash (gconstpointer _key)
|
||||
h ^= g_str_hash (key->icon_names[i]);
|
||||
|
||||
h ^= key->size * 0x10001;
|
||||
h ^= key->flags * 0x1000010;
|
||||
h ^= key->scale * 0x1000010;
|
||||
h ^= key->flags * 0x100000100;
|
||||
|
||||
return h;
|
||||
}
|
||||
@@ -406,6 +416,9 @@ icon_info_key_equal (gconstpointer _a,
|
||||
if (a->size != b->size)
|
||||
return FALSE;
|
||||
|
||||
if (a->scale != b->scale)
|
||||
return FALSE;
|
||||
|
||||
if (a->flags != b->flags)
|
||||
return FALSE;
|
||||
|
||||
@@ -1342,11 +1355,11 @@ _gtk_icon_theme_ensure_builtin_cache (void)
|
||||
IconThemeDir *dir;
|
||||
static IconThemeDir dirs[5] =
|
||||
{
|
||||
{ ICON_THEME_DIR_THRESHOLD, 0, 16, 16, 16, 2, NULL, "16", -1, NULL, NULL, NULL },
|
||||
{ ICON_THEME_DIR_THRESHOLD, 0, 20, 20, 20, 2, NULL, "20", -1, NULL, NULL, NULL },
|
||||
{ ICON_THEME_DIR_THRESHOLD, 0, 24, 24, 24, 2, NULL, "24", -1, NULL, NULL, NULL },
|
||||
{ ICON_THEME_DIR_THRESHOLD, 0, 32, 32, 32, 2, NULL, "32", -1, NULL, NULL, NULL },
|
||||
{ ICON_THEME_DIR_THRESHOLD, 0, 48, 48, 48, 2, NULL, "48", -1, NULL, NULL, NULL }
|
||||
{ ICON_THEME_DIR_THRESHOLD, 0, 16, 16, 16, 2, 1, NULL, "16", -1, NULL, NULL, NULL },
|
||||
{ ICON_THEME_DIR_THRESHOLD, 0, 20, 20, 20, 2, 1, NULL, "20", -1, NULL, NULL, NULL },
|
||||
{ ICON_THEME_DIR_THRESHOLD, 0, 24, 24, 24, 2, 1, NULL, "24", -1, NULL, NULL, NULL },
|
||||
{ ICON_THEME_DIR_THRESHOLD, 0, 32, 32, 32, 2, 1, NULL, "32", -1, NULL, NULL, NULL },
|
||||
{ ICON_THEME_DIR_THRESHOLD, 0, 48, 48, 48, 2, 1, NULL, "48", -1, NULL, NULL, NULL }
|
||||
};
|
||||
gint i;
|
||||
|
||||
@@ -1574,6 +1587,7 @@ static GtkIconInfo *
|
||||
choose_icon (GtkIconTheme *icon_theme,
|
||||
const gchar *icon_names[],
|
||||
gint size,
|
||||
gint scale,
|
||||
GtkIconLookupFlags flags)
|
||||
{
|
||||
GtkIconThemePrivate *priv;
|
||||
@@ -1591,6 +1605,7 @@ choose_icon (GtkIconTheme *icon_theme,
|
||||
|
||||
key.icon_names = (char **)icon_names;
|
||||
key.size = size;
|
||||
key.scale = scale;
|
||||
key.flags = flags;
|
||||
|
||||
icon_info = g_hash_table_lookup (priv->info_cache, &key);
|
||||
@@ -1628,7 +1643,7 @@ choose_icon (GtkIconTheme *icon_theme,
|
||||
for (l = priv->themes; l; l = l->next)
|
||||
{
|
||||
IconTheme *theme = l->data;
|
||||
icon_info = theme_lookup_icon (theme, icon_names[0], size, allow_svg, use_builtin);
|
||||
icon_info = theme_lookup_icon (theme, icon_names[0], size, scale, allow_svg, use_builtin);
|
||||
if (icon_info)
|
||||
goto out;
|
||||
}
|
||||
@@ -1640,7 +1655,7 @@ choose_icon (GtkIconTheme *icon_theme,
|
||||
|
||||
for (i = 0; icon_names[i]; i++)
|
||||
{
|
||||
icon_info = theme_lookup_icon (theme, icon_names[i], size, allow_svg, use_builtin);
|
||||
icon_info = theme_lookup_icon (theme, icon_names[i], size, scale, allow_svg, use_builtin);
|
||||
if (icon_info)
|
||||
goto out;
|
||||
}
|
||||
@@ -1674,6 +1689,7 @@ choose_icon (GtkIconTheme *icon_theme,
|
||||
DestroyIcon (hIcon);
|
||||
icon_info->dir_type = ICON_THEME_DIR_UNTHEMED;
|
||||
icon_info->dir_size = size;
|
||||
icon_info->dir_scale = 1;
|
||||
}
|
||||
g_strfreev (resources);
|
||||
}
|
||||
@@ -1698,16 +1714,19 @@ choose_icon (GtkIconTheme *icon_theme,
|
||||
|
||||
icon_info->dir_type = ICON_THEME_DIR_UNTHEMED;
|
||||
icon_info->dir_size = size;
|
||||
icon_info->dir_scale = 1;
|
||||
}
|
||||
|
||||
out:
|
||||
if (icon_info)
|
||||
{
|
||||
icon_info->desired_size = size;
|
||||
icon_info->desired_scale = scale;
|
||||
icon_info->forced_size = (flags & GTK_ICON_LOOKUP_FORCE_SIZE) != 0;
|
||||
|
||||
icon_info->key.icon_names = g_strdupv ((char **)icon_names);
|
||||
icon_info->key.size = size;
|
||||
icon_info->key.scale = scale;
|
||||
icon_info->key.flags = flags;
|
||||
icon_info->in_cache = icon_theme;
|
||||
DEBUG_CACHE (("adding %p (%s %d 0x%x) to cache (cache size %d)\n",
|
||||
@@ -1776,6 +1795,44 @@ gtk_icon_theme_lookup_icon (GtkIconTheme *icon_theme,
|
||||
const gchar *icon_name,
|
||||
gint size,
|
||||
GtkIconLookupFlags flags)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_ICON_THEME (icon_theme), NULL);
|
||||
g_return_val_if_fail (icon_name != NULL, NULL);
|
||||
g_return_val_if_fail ((flags & GTK_ICON_LOOKUP_NO_SVG) == 0 ||
|
||||
(flags & GTK_ICON_LOOKUP_FORCE_SVG) == 0, NULL);
|
||||
|
||||
GTK_NOTE (ICONTHEME,
|
||||
g_print ("gtk_icon_theme_lookup_icon %s\n", icon_name));
|
||||
|
||||
return gtk_icon_theme_lookup_icon_for_scale (icon_theme, icon_name,
|
||||
size, 1, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_icon_theme_lookup_icon_for_scale:
|
||||
* @icon_theme: a #GtkIconTheme
|
||||
* @icon_name: the name of the icon to lookup
|
||||
* @size: desired icon size
|
||||
* @scale: the desired scale
|
||||
* @flags: flags modifying the behavior of the icon lookup
|
||||
*
|
||||
* Looks up a named icon for a particular window scale and returns a
|
||||
* structure containing information such as the filename of the
|
||||
* icon. The icon can then be rendered into a pixbuf using
|
||||
* gtk_icon_info_load_icon(). (gtk_icon_theme_load_icon() combines
|
||||
* these two steps if all you need is the pixbuf.)
|
||||
*
|
||||
* Return value: (transfer full): a #GtkIconInfo object containing
|
||||
* information about the icon, or %NULL if the icon wasn't found.
|
||||
*
|
||||
* Since: 3.10
|
||||
*/
|
||||
GtkIconInfo *
|
||||
gtk_icon_theme_lookup_icon_for_scale (GtkIconTheme *icon_theme,
|
||||
const gchar *icon_name,
|
||||
gint size,
|
||||
gint scale,
|
||||
GtkIconLookupFlags flags)
|
||||
{
|
||||
GtkIconInfo *info;
|
||||
|
||||
@@ -1783,6 +1840,7 @@ gtk_icon_theme_lookup_icon (GtkIconTheme *icon_theme,
|
||||
g_return_val_if_fail (icon_name != NULL, NULL);
|
||||
g_return_val_if_fail ((flags & GTK_ICON_LOOKUP_NO_SVG) == 0 ||
|
||||
(flags & GTK_ICON_LOOKUP_FORCE_SVG) == 0, NULL);
|
||||
g_return_val_if_fail (scale >= 1, NULL);
|
||||
|
||||
GTK_NOTE (ICONTHEME,
|
||||
g_print ("gtk_icon_theme_lookup_icon %s\n", icon_name));
|
||||
@@ -1808,7 +1866,7 @@ gtk_icon_theme_lookup_icon (GtkIconTheme *icon_theme,
|
||||
}
|
||||
names[dashes + 1] = NULL;
|
||||
|
||||
info = choose_icon (icon_theme, (const gchar **) names, size, flags);
|
||||
info = choose_icon (icon_theme, (const gchar **) names, size, scale, flags);
|
||||
|
||||
g_strfreev (names);
|
||||
}
|
||||
@@ -1819,7 +1877,7 @@ gtk_icon_theme_lookup_icon (GtkIconTheme *icon_theme,
|
||||
names[0] = icon_name;
|
||||
names[1] = NULL;
|
||||
|
||||
info = choose_icon (icon_theme, names, size, flags);
|
||||
info = choose_icon (icon_theme, names, size, scale, flags);
|
||||
}
|
||||
|
||||
return info;
|
||||
@@ -1859,9 +1917,50 @@ gtk_icon_theme_choose_icon (GtkIconTheme *icon_theme,
|
||||
g_return_val_if_fail ((flags & GTK_ICON_LOOKUP_NO_SVG) == 0 ||
|
||||
(flags & GTK_ICON_LOOKUP_FORCE_SVG) == 0, NULL);
|
||||
|
||||
return choose_icon (icon_theme, icon_names, size, flags);
|
||||
return choose_icon (icon_theme, icon_names, size, 1, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_icon_theme_choose_icon_for_scale:
|
||||
* @icon_theme: a #GtkIconTheme
|
||||
* @icon_names: (array zero-terminated=1): %NULL-terminated array of
|
||||
* icon names to lookup
|
||||
* @size: desired icon size
|
||||
* @scale: desired scale
|
||||
* @flags: flags modifying the behavior of the icon lookup
|
||||
*
|
||||
* Looks up a named icon for a particular window scale and returns a
|
||||
* structure containing information such as the filename of the
|
||||
* icon. The icon can then be rendered into a pixbuf using
|
||||
* gtk_icon_info_load_icon(). (gtk_icon_theme_load_icon() combines
|
||||
* these two steps if all you need is the pixbuf.)
|
||||
*
|
||||
* If @icon_names contains more than one name, this function
|
||||
* tries them all in the given order before falling back to
|
||||
* inherited icon themes.
|
||||
*
|
||||
* Return value: (transfer full): a #GtkIconInfo object containing information
|
||||
* about the icon, or %NULL if the icon wasn't found.
|
||||
*
|
||||
* Since: 3.10
|
||||
*/
|
||||
GtkIconInfo *
|
||||
gtk_icon_theme_choose_icon_for_scale (GtkIconTheme *icon_theme,
|
||||
const gchar *icon_names[],
|
||||
gint size,
|
||||
gint scale,
|
||||
GtkIconLookupFlags flags)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_ICON_THEME (icon_theme), NULL);
|
||||
g_return_val_if_fail (icon_names != NULL, NULL);
|
||||
g_return_val_if_fail ((flags & GTK_ICON_LOOKUP_NO_SVG) == 0 ||
|
||||
(flags & GTK_ICON_LOOKUP_FORCE_SVG) == 0, NULL);
|
||||
g_return_val_if_fail (scale >= 1, NULL);
|
||||
|
||||
return choose_icon (icon_theme, icon_names, size, scale, flags);
|
||||
}
|
||||
|
||||
|
||||
/* Error quark */
|
||||
GQuark
|
||||
gtk_icon_theme_error_quark (void)
|
||||
@@ -1905,6 +2004,56 @@ gtk_icon_theme_load_icon (GtkIconTheme *icon_theme,
|
||||
gint size,
|
||||
GtkIconLookupFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_ICON_THEME (icon_theme), NULL);
|
||||
g_return_val_if_fail (icon_name != NULL, NULL);
|
||||
g_return_val_if_fail ((flags & GTK_ICON_LOOKUP_NO_SVG) == 0 ||
|
||||
(flags & GTK_ICON_LOOKUP_FORCE_SVG) == 0, NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
return gtk_icon_theme_load_icon_for_scale (icon_theme, icon_name,
|
||||
size, 1, flags, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_icon_theme_load_icon_for_scale:
|
||||
* @icon_theme: a #GtkIconTheme
|
||||
* @icon_name: the name of the icon to lookup
|
||||
* @size: the desired icon size. The resulting icon may not be
|
||||
* exactly this size; see gtk_icon_info_load_icon().
|
||||
* @scale: desired scale
|
||||
* @flags: flags modifying the behavior of the icon lookup
|
||||
* @error: (allow-none): Location to store error information on failure,
|
||||
* or %NULL.
|
||||
*
|
||||
* Looks up an icon in an icon theme for a particular window scale,
|
||||
* scales it to the given size and renders it into a pixbuf. This is a
|
||||
* convenience function; if more details about the icon are needed,
|
||||
* use gtk_icon_theme_lookup_icon() followed by
|
||||
* gtk_icon_info_load_icon().
|
||||
*
|
||||
* Note that you probably want to listen for icon theme changes and
|
||||
* update the icon. This is usually done by connecting to the
|
||||
* GtkWidget::style-set signal. If for some reason you do not want to
|
||||
* update the icon when the icon theme changes, you should consider
|
||||
* using gdk_pixbuf_copy() to make a private copy of the pixbuf
|
||||
* returned by this function. Otherwise GTK+ may need to keep the old
|
||||
* icon theme loaded, which would be a waste of memory.
|
||||
*
|
||||
* Return value: (transfer full): the rendered icon; this may be a
|
||||
* newly created icon or a new reference to an internal icon, so
|
||||
* you must not modify the icon. Use g_object_unref() to release
|
||||
* your reference to the icon. %NULL if the icon isn't found.
|
||||
*
|
||||
* Since: 3.10
|
||||
**/
|
||||
GdkPixbuf *
|
||||
gtk_icon_theme_load_icon_for_scale (GtkIconTheme *icon_theme,
|
||||
const gchar *icon_name,
|
||||
gint size,
|
||||
gint scale,
|
||||
GtkIconLookupFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
GtkIconInfo *icon_info;
|
||||
GdkPixbuf *pixbuf = NULL;
|
||||
@@ -1914,9 +2063,10 @@ gtk_icon_theme_load_icon (GtkIconTheme *icon_theme,
|
||||
g_return_val_if_fail ((flags & GTK_ICON_LOOKUP_NO_SVG) == 0 ||
|
||||
(flags & GTK_ICON_LOOKUP_FORCE_SVG) == 0, NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
icon_info = gtk_icon_theme_lookup_icon (icon_theme, icon_name, size,
|
||||
flags | GTK_ICON_LOOKUP_USE_BUILTIN);
|
||||
g_return_val_if_fail (scale >= 1, NULL);
|
||||
|
||||
icon_info = gtk_icon_theme_lookup_icon_for_scale (icon_theme, icon_name, size, scale,
|
||||
flags | GTK_ICON_LOOKUP_USE_BUILTIN);
|
||||
if (!icon_info)
|
||||
{
|
||||
g_set_error (error, GTK_ICON_THEME_ERROR, GTK_ICON_THEME_NOT_FOUND,
|
||||
@@ -1930,6 +2080,69 @@ gtk_icon_theme_load_icon (GtkIconTheme *icon_theme,
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_icon_theme_load_surface:
|
||||
* @icon_theme: a #GtkIconTheme
|
||||
* @icon_name: the name of the icon to lookup
|
||||
* @size: the desired icon size. The resulting icon may not be
|
||||
* exactly this size; see gtk_icon_info_load_icon().
|
||||
* @scale: desired scale
|
||||
* @for_window: (allow-none): #GdkWindow to optimize drawing for, or %NULL
|
||||
* @flags: flags modifying the behavior of the icon lookup
|
||||
* @error: (allow-none): Location to store error information on failure,
|
||||
* or %NULL.
|
||||
*
|
||||
* Looks up an icon in an icon theme for a particular window scale,
|
||||
* scales it to the given size and renders it into a cairo surface. This is a
|
||||
* convenience function; if more details about the icon are needed,
|
||||
* use gtk_icon_theme_lookup_icon() followed by
|
||||
* gtk_icon_info_load_surface().
|
||||
*
|
||||
* Note that you probably want to listen for icon theme changes and
|
||||
* update the icon. This is usually done by connecting to the
|
||||
* GtkWidget::style-set signal.
|
||||
*
|
||||
* Return value: (transfer full): the rendered icon; this may be a
|
||||
* newly created icon or a new reference to an internal icon, so
|
||||
* you must not modify the icon. Use cairo_surface_destroy() to release
|
||||
* your reference to the icon. %NULL if the icon isn't found.
|
||||
*
|
||||
* Since: 3.10
|
||||
**/
|
||||
cairo_surface_t *
|
||||
gtk_icon_theme_load_surface (GtkIconTheme *icon_theme,
|
||||
const gchar *icon_name,
|
||||
gint size,
|
||||
gint scale,
|
||||
GdkWindow *for_window,
|
||||
GtkIconLookupFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
GtkIconInfo *icon_info;
|
||||
cairo_surface_t *surface = NULL;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_ICON_THEME (icon_theme), NULL);
|
||||
g_return_val_if_fail (icon_name != NULL, NULL);
|
||||
g_return_val_if_fail ((flags & GTK_ICON_LOOKUP_NO_SVG) == 0 ||
|
||||
(flags & GTK_ICON_LOOKUP_FORCE_SVG) == 0, NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
g_return_val_if_fail (scale >= 1, NULL);
|
||||
|
||||
icon_info = gtk_icon_theme_lookup_icon_for_scale (icon_theme, icon_name, size, scale,
|
||||
flags | GTK_ICON_LOOKUP_USE_BUILTIN);
|
||||
if (!icon_info)
|
||||
{
|
||||
g_set_error (error, GTK_ICON_THEME_ERROR, GTK_ICON_THEME_NOT_FOUND,
|
||||
_("Icon '%s' not present in theme"), icon_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
surface = gtk_icon_info_load_surface (icon_info, for_window, error);
|
||||
g_object_unref (icon_info);
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_icon_theme_has_icon:
|
||||
* @icon_theme: a #GtkIconTheme
|
||||
@@ -2352,31 +2565,35 @@ theme_dir_destroy (IconThemeDir *dir)
|
||||
}
|
||||
|
||||
static int
|
||||
theme_dir_size_difference (IconThemeDir *dir, int size, gboolean *smaller)
|
||||
theme_dir_size_difference (IconThemeDir *dir,
|
||||
int size,
|
||||
gint scale)
|
||||
{
|
||||
int scaled_size, scaled_dir_size;
|
||||
int min, max;
|
||||
|
||||
scaled_size = size * scale;
|
||||
scaled_dir_size = dir->size * dir->scale;
|
||||
|
||||
switch (dir->type)
|
||||
{
|
||||
case ICON_THEME_DIR_FIXED:
|
||||
*smaller = size < dir->size;
|
||||
return abs (size - dir->size);
|
||||
return abs (scaled_size - scaled_dir_size);
|
||||
break;
|
||||
case ICON_THEME_DIR_SCALABLE:
|
||||
*smaller = size < dir->min_size;
|
||||
if (size < dir->min_size)
|
||||
return dir->min_size - size;
|
||||
if (size > dir->max_size)
|
||||
return size - dir->max_size;
|
||||
if (scaled_size < (dir->min_size * dir->scale))
|
||||
return (dir->min_size * dir->scale) - scaled_size;
|
||||
if (size > (dir->max_size * dir->scale))
|
||||
return scaled_size - (dir->max_size * dir->scale);
|
||||
return 0;
|
||||
break;
|
||||
case ICON_THEME_DIR_THRESHOLD:
|
||||
min = dir->size - dir->threshold;
|
||||
max = dir->size + dir->threshold;
|
||||
*smaller = size < min;
|
||||
if (size < min)
|
||||
return min - size;
|
||||
if (size > max)
|
||||
return size - max;
|
||||
min = (dir->size - dir->threshold) * dir->scale;
|
||||
max = (dir->size + dir->threshold) * dir->scale;
|
||||
if (scaled_size < min)
|
||||
return min - scaled_size;
|
||||
if (scaled_size > max)
|
||||
return scaled_size - max;
|
||||
return 0;
|
||||
break;
|
||||
case ICON_THEME_DIR_UNTHEMED:
|
||||
@@ -2463,10 +2680,75 @@ theme_dir_get_icon_suffix (IconThemeDir *dir,
|
||||
return suffix;
|
||||
}
|
||||
|
||||
/* returns TRUE if dir_a is a better match */
|
||||
static gboolean
|
||||
compare_dir_matches (IconThemeDir *dir_a, int difference_a,
|
||||
IconThemeDir *dir_b, int difference_b,
|
||||
int requested_size, int requested_scale)
|
||||
{
|
||||
int diff_a;
|
||||
int diff_b;
|
||||
|
||||
if (difference_a == 0)
|
||||
{
|
||||
if (difference_b != 0)
|
||||
return TRUE;
|
||||
|
||||
/* a and b both exact matches */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If scaling, *always* prefer downscaling */
|
||||
if (dir_a->size >= requested_size &&
|
||||
dir_b->size < requested_size)
|
||||
return TRUE;
|
||||
|
||||
if (dir_a->size < requested_size &&
|
||||
dir_b->size >= requested_size)
|
||||
return FALSE;
|
||||
|
||||
/* Otherwise prefer the closest match */
|
||||
|
||||
if (difference_a < difference_b)
|
||||
return TRUE;
|
||||
|
||||
if (difference_a > difference_b)
|
||||
return FALSE;
|
||||
|
||||
/* same pixel difference */
|
||||
}
|
||||
|
||||
if (dir_a->scale == requested_scale &&
|
||||
dir_b->scale != requested_scale)
|
||||
return TRUE;
|
||||
|
||||
if (dir_a->scale != requested_scale &&
|
||||
dir_b->scale == requested_scale)
|
||||
return FALSE;
|
||||
|
||||
/* a and b both match the scale */
|
||||
|
||||
if (dir_a->type != ICON_THEME_DIR_SCALABLE &&
|
||||
dir_b->type == ICON_THEME_DIR_SCALABLE)
|
||||
return TRUE;
|
||||
|
||||
if (dir_a->type == ICON_THEME_DIR_SCALABLE &&
|
||||
dir_b->type != ICON_THEME_DIR_SCALABLE)
|
||||
return FALSE;
|
||||
|
||||
/* a and b both are scalable */
|
||||
|
||||
diff_a = abs (requested_size * requested_scale - dir_a->size * dir_a->scale);
|
||||
diff_b = abs (requested_size * requested_scale - dir_b->size * dir_b->scale);
|
||||
|
||||
return diff_a <= diff_b;
|
||||
}
|
||||
|
||||
static GtkIconInfo *
|
||||
theme_lookup_icon (IconTheme *theme,
|
||||
const char *icon_name,
|
||||
int size,
|
||||
gint scale,
|
||||
gboolean allow_svg,
|
||||
gboolean use_builtin)
|
||||
{
|
||||
@@ -2475,13 +2757,10 @@ theme_lookup_icon (IconTheme *theme,
|
||||
char *file;
|
||||
int min_difference, difference;
|
||||
BuiltinIcon *closest_builtin = NULL;
|
||||
gboolean smaller, has_larger, match;
|
||||
IconSuffix suffix;
|
||||
|
||||
min_difference = G_MAXINT;
|
||||
min_dir = NULL;
|
||||
has_larger = FALSE;
|
||||
match = FALSE;
|
||||
|
||||
/* Builtin icons are logically part of the default theme and
|
||||
* are searched before other subdirectories of the default theme.
|
||||
@@ -2489,9 +2768,8 @@ theme_lookup_icon (IconTheme *theme,
|
||||
if (use_builtin && strcmp (theme->name, DEFAULT_THEME_NAME) == 0)
|
||||
{
|
||||
closest_builtin = find_builtin_icon (icon_name,
|
||||
size,
|
||||
&min_difference,
|
||||
&has_larger);
|
||||
size, scale,
|
||||
&min_difference);
|
||||
|
||||
if (min_difference == 0)
|
||||
return icon_info_new_builtin (closest_builtin);
|
||||
@@ -2511,57 +2789,14 @@ theme_lookup_icon (IconTheme *theme,
|
||||
suffix = theme_dir_get_icon_suffix (dir, icon_name, NULL);
|
||||
if (best_suffix (suffix, allow_svg) != ICON_SUFFIX_NONE)
|
||||
{
|
||||
difference = theme_dir_size_difference (dir, size, &smaller);
|
||||
|
||||
if (difference == 0)
|
||||
difference = theme_dir_size_difference (dir, size, scale);
|
||||
if (min_dir == NULL ||
|
||||
compare_dir_matches (dir, difference,
|
||||
min_dir, min_difference,
|
||||
size, scale))
|
||||
{
|
||||
if (dir->type == ICON_THEME_DIR_SCALABLE)
|
||||
{
|
||||
/* don't pick scalable if we already found
|
||||
* a matching non-scalable dir
|
||||
*/
|
||||
if (!match)
|
||||
{
|
||||
min_dir = dir;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* for a matching non-scalable dir keep
|
||||
* going and look for a closer match
|
||||
*/
|
||||
difference = abs (size - dir->size);
|
||||
if (!match || difference < min_difference)
|
||||
{
|
||||
match = TRUE;
|
||||
min_difference = difference;
|
||||
min_dir = dir;
|
||||
}
|
||||
if (difference == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!match)
|
||||
{
|
||||
if (!has_larger)
|
||||
{
|
||||
if (difference < min_difference || smaller)
|
||||
{
|
||||
min_difference = difference;
|
||||
min_dir = dir;
|
||||
has_larger = smaller;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (difference < min_difference && smaller)
|
||||
{
|
||||
min_difference = difference;
|
||||
min_dir = dir;
|
||||
}
|
||||
}
|
||||
min_dir = dir;
|
||||
min_difference = difference;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2640,6 +2875,7 @@ theme_lookup_icon (IconTheme *theme,
|
||||
|
||||
icon_info->dir_type = min_dir->type;
|
||||
icon_info->dir_size = min_dir->size;
|
||||
icon_info->dir_scale = min_dir->scale;
|
||||
icon_info->threshold = min_dir->threshold;
|
||||
|
||||
return icon_info;
|
||||
@@ -2858,6 +3094,7 @@ theme_subdir_load (GtkIconTheme *icon_theme,
|
||||
char *full_dir;
|
||||
GError *error = NULL;
|
||||
IconThemeDirMtime *dir_mtime;
|
||||
int scale;
|
||||
|
||||
size = g_key_file_get_integer (theme_file, subdir, "Size", &error);
|
||||
if (error)
|
||||
@@ -2905,6 +3142,11 @@ theme_subdir_load (GtkIconTheme *icon_theme,
|
||||
else
|
||||
threshold = 2;
|
||||
|
||||
if (g_key_file_has_key (theme_file, subdir, "OutputScale", NULL))
|
||||
scale = g_key_file_get_integer (theme_file, subdir, "OutputScale", NULL);
|
||||
else
|
||||
scale = 1;
|
||||
|
||||
for (d = icon_theme->priv->dir_mtimes; d; d = d->next)
|
||||
{
|
||||
dir_mtime = (IconThemeDirMtime *)d->data;
|
||||
@@ -2933,6 +3175,8 @@ theme_subdir_load (GtkIconTheme *icon_theme,
|
||||
dir->dir = full_dir;
|
||||
dir->icon_data = NULL;
|
||||
dir->subdir = g_strdup (subdir);
|
||||
dir->scale = scale;
|
||||
|
||||
if (dir_mtime->cache != NULL)
|
||||
{
|
||||
dir->cache = _gtk_icon_cache_ref (dir_mtime->cache);
|
||||
@@ -3048,8 +3292,10 @@ icon_info_dup (GtkIconInfo *icon_info)
|
||||
dup->data = icon_data_dup (icon_info->data);
|
||||
dup->dir_type = icon_info->dir_type;
|
||||
dup->dir_size = icon_info->dir_size;
|
||||
dup->dir_scale = icon_info->dir_scale;
|
||||
dup->threshold = icon_info->threshold;
|
||||
dup->desired_size = icon_info->desired_size;
|
||||
dup->desired_scale = icon_info->desired_scale;
|
||||
dup->raw_coordinates = icon_info->raw_coordinates;
|
||||
dup->forced_size = icon_info->forced_size;
|
||||
dup->emblems_applied = icon_info->emblems_applied;
|
||||
@@ -3065,6 +3311,7 @@ icon_info_new_builtin (BuiltinIcon *icon)
|
||||
icon_info->cache_pixbuf = g_object_ref (icon->pixbuf);
|
||||
icon_info->dir_type = ICON_THEME_DIR_THRESHOLD;
|
||||
icon_info->dir_size = icon->size;
|
||||
icon_info->dir_scale = 1;
|
||||
icon_info->threshold = 2;
|
||||
|
||||
return icon_info;
|
||||
@@ -3158,7 +3405,10 @@ gtk_icon_info_class_init (GtkIconInfoClass *klass)
|
||||
* to a larger icon. These icons will be given
|
||||
* the same base size as the larger icons to which
|
||||
* they are attached.
|
||||
*
|
||||
*
|
||||
* Note that for scaled icons the base size does
|
||||
* not include the base scale.
|
||||
*
|
||||
* Return value: the base size, or 0, if no base
|
||||
* size is known for the icon.
|
||||
*
|
||||
@@ -3172,6 +3422,27 @@ gtk_icon_info_get_base_size (GtkIconInfo *icon_info)
|
||||
return icon_info->dir_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_icon_info_get_base_scale:
|
||||
* @icon_info: a #GtkIconInfo
|
||||
*
|
||||
* Gets the base scale for the icon. The base scale is a scale for the
|
||||
* icon that was specified by the icon theme creator. For instance an
|
||||
* icon drawn for a high-dpi screen with window-scale 2 for a base
|
||||
* size of 32 will be 64 pixels tall and have a base_scale of 2.
|
||||
*
|
||||
* Return value: the base scale.
|
||||
*
|
||||
* Since: 3.10
|
||||
**/
|
||||
gint
|
||||
gtk_icon_info_get_base_scale (GtkIconInfo *icon_info)
|
||||
{
|
||||
g_return_val_if_fail (icon_info != NULL, 0);
|
||||
|
||||
return icon_info->dir_scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_icon_info_get_filename:
|
||||
* @icon_info: a #GtkIconInfo
|
||||
@@ -3332,6 +3603,7 @@ icon_info_ensure_scale_and_pixbuf (GtkIconInfo *icon_info,
|
||||
gboolean scale_only)
|
||||
{
|
||||
int image_width, image_height;
|
||||
int scaled_desired_size;
|
||||
GdkPixbuf *source_pixbuf;
|
||||
gboolean is_svg;
|
||||
|
||||
@@ -3356,6 +3628,8 @@ icon_info_ensure_scale_and_pixbuf (GtkIconInfo *icon_info,
|
||||
if (icon_info->icon_file && !icon_info->loadable)
|
||||
icon_info->loadable = G_LOADABLE_ICON (g_file_icon_new (icon_info->icon_file));
|
||||
|
||||
scaled_desired_size = icon_info->desired_size * icon_info->desired_scale;
|
||||
|
||||
is_svg = FALSE;
|
||||
if (G_IS_FILE_ICON (icon_info->loadable))
|
||||
{
|
||||
@@ -3383,20 +3657,21 @@ icon_info_ensure_scale_and_pixbuf (GtkIconInfo *icon_info,
|
||||
{
|
||||
GInputStream *stream;
|
||||
|
||||
icon_info->scale = icon_info->desired_size / 1000.;
|
||||
icon_info->scale = scaled_desired_size / 1000.;
|
||||
|
||||
if (scale_only)
|
||||
return TRUE;
|
||||
|
||||
|
||||
/* TODO: We should have a load_at_scale */
|
||||
stream = g_loadable_icon_load (icon_info->loadable,
|
||||
icon_info->desired_size,
|
||||
scaled_desired_size,
|
||||
NULL, NULL,
|
||||
&icon_info->load_error);
|
||||
if (stream)
|
||||
{
|
||||
icon_info->pixbuf = gdk_pixbuf_new_from_stream_at_scale (stream,
|
||||
icon_info->desired_size,
|
||||
icon_info->desired_size,
|
||||
scaled_desired_size,
|
||||
scaled_desired_size,
|
||||
TRUE,
|
||||
NULL,
|
||||
&icon_info->load_error);
|
||||
@@ -3419,19 +3694,19 @@ icon_info_ensure_scale_and_pixbuf (GtkIconInfo *icon_info,
|
||||
if (icon_info->forced_size)
|
||||
icon_info->scale = -1;
|
||||
else if (icon_info->dir_type == ICON_THEME_DIR_FIXED)
|
||||
icon_info->scale = 1.0;
|
||||
icon_info->scale = round((gdouble) scaled_desired_size / (icon_info->dir_size * icon_info->dir_scale));
|
||||
else if (icon_info->dir_type == ICON_THEME_DIR_THRESHOLD)
|
||||
{
|
||||
if (icon_info->desired_size >= icon_info->dir_size - icon_info->threshold &&
|
||||
icon_info->desired_size <= icon_info->dir_size + icon_info->threshold)
|
||||
icon_info->scale = 1.0;
|
||||
if (scaled_desired_size >= (icon_info->dir_size - icon_info->threshold) * icon_info->dir_scale &&
|
||||
scaled_desired_size <= (icon_info->dir_size + icon_info->threshold) * icon_info->dir_scale)
|
||||
icon_info->scale = round((gdouble) scaled_desired_size / (icon_info->dir_size * icon_info->dir_scale));
|
||||
else if (icon_info->dir_size > 0)
|
||||
icon_info->scale =(gdouble) icon_info->desired_size / icon_info->dir_size;
|
||||
icon_info->scale =(gdouble) scaled_desired_size / (icon_info->dir_size * icon_info->dir_scale);
|
||||
}
|
||||
else if (icon_info->dir_type == ICON_THEME_DIR_SCALABLE)
|
||||
{
|
||||
if (icon_info->dir_size > 0)
|
||||
icon_info->scale = (gdouble) icon_info->desired_size / icon_info->dir_size;
|
||||
icon_info->scale = (gdouble) scaled_desired_size / (icon_info->dir_size * icon_info->dir_scale);
|
||||
}
|
||||
|
||||
if (icon_info->scale >= 0. && scale_only)
|
||||
@@ -3447,8 +3722,9 @@ icon_info_ensure_scale_and_pixbuf (GtkIconInfo *icon_info,
|
||||
{
|
||||
GInputStream *stream;
|
||||
|
||||
/* TODO: We should have a load_at_scale */
|
||||
stream = g_loadable_icon_load (icon_info->loadable,
|
||||
icon_info->desired_size,
|
||||
scaled_desired_size,
|
||||
NULL, NULL,
|
||||
&icon_info->load_error);
|
||||
if (stream)
|
||||
@@ -3472,7 +3748,7 @@ icon_info_ensure_scale_and_pixbuf (GtkIconInfo *icon_info,
|
||||
{
|
||||
gint image_size = MAX (image_width, image_height);
|
||||
if (image_size > 0)
|
||||
icon_info->scale = (gdouble)icon_info->desired_size / (gdouble)image_size;
|
||||
icon_info->scale = (gdouble)scaled_desired_size / (gdouble)image_size;
|
||||
else
|
||||
icon_info->scale = 1.0;
|
||||
|
||||
@@ -3589,6 +3865,54 @@ gtk_icon_info_load_icon (GtkIconInfo *icon_info,
|
||||
return icon_info->proxy_pixbuf;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_icon_info_load_surface:
|
||||
* @icon_info: a #GtkIconInfo structure from gtk_icon_theme_lookup_icon()
|
||||
* @for_window: (allow-none): #GdkWindow to optimize drawing for, or %NULL
|
||||
* @error: (allow-none): location to store error information on failure,
|
||||
* or %NULL.
|
||||
*
|
||||
* Renders an icon previously looked up in an icon theme using
|
||||
* gtk_icon_theme_lookup_icon(); the size will be based on the size
|
||||
* passed to gtk_icon_theme_lookup_icon(). Note that the resulting
|
||||
* surface may not be exactly this size; an icon theme may have icons
|
||||
* that differ slightly from their nominal sizes, and in addition GTK+
|
||||
* will avoid scaling icons that it considers sufficiently close to the
|
||||
* requested size or for which the source image would have to be scaled
|
||||
* up too far. (This maintains sharpness.). This behaviour can be changed
|
||||
* by passing the %GTK_ICON_LOOKUP_FORCE_SIZE flag when obtaining
|
||||
* the #GtkIconInfo. If this flag has been specified, the pixbuf
|
||||
* returned by this function will be scaled to the exact size.
|
||||
*
|
||||
* Return value: (transfer full): the rendered icon; this may be a newly
|
||||
* created icon or a new reference to an internal icon, so you must
|
||||
* not modify the icon. Use cairo_surface_destroy() to release your reference
|
||||
* to the icon.
|
||||
*
|
||||
* Since: 3.10
|
||||
**/
|
||||
cairo_surface_t *
|
||||
gtk_icon_info_load_surface (GtkIconInfo *icon_info,
|
||||
GdkWindow *for_window,
|
||||
GError **error)
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
cairo_surface_t *surface;
|
||||
|
||||
g_return_val_if_fail (icon_info != NULL, NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
pixbuf = gtk_icon_info_load_icon (icon_info, error);
|
||||
|
||||
if (pixbuf == NULL)
|
||||
return NULL;
|
||||
|
||||
surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, icon_info->desired_scale, for_window);
|
||||
g_object_unref (pixbuf);
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
static void
|
||||
load_icon_thread (GTask *task,
|
||||
gpointer source_object,
|
||||
@@ -3887,8 +4211,8 @@ _gtk_icon_info_load_symbolic_internal (GtkIconInfo *icon_info,
|
||||
|
||||
stream = g_memory_input_stream_new_from_data (data, -1, g_free);
|
||||
pixbuf = gdk_pixbuf_new_from_stream_at_scale (stream,
|
||||
icon_info->desired_size,
|
||||
icon_info->desired_size,
|
||||
icon_info->desired_size * icon_info->desired_scale,
|
||||
icon_info->desired_size * icon_info->desired_scale,
|
||||
TRUE,
|
||||
NULL,
|
||||
error);
|
||||
@@ -4740,8 +5064,8 @@ gtk_icon_theme_add_builtin_icon (const gchar *icon_name,
|
||||
static BuiltinIcon *
|
||||
find_builtin_icon (const gchar *icon_name,
|
||||
gint size,
|
||||
gint *min_difference_p,
|
||||
gboolean *has_larger_p)
|
||||
gint scale,
|
||||
gint *min_difference_p)
|
||||
{
|
||||
GSList *icons = NULL;
|
||||
gint min_difference = G_MAXINT;
|
||||
@@ -4751,6 +5075,8 @@ find_builtin_icon (const gchar *icon_name,
|
||||
if (!icon_theme_builtin_icons)
|
||||
return NULL;
|
||||
|
||||
size *= scale;
|
||||
|
||||
icons = g_hash_table_lookup (icon_theme_builtin_icons, icon_name);
|
||||
|
||||
while (icons)
|
||||
@@ -4798,8 +5124,6 @@ find_builtin_icon (const gchar *icon_name,
|
||||
|
||||
if (min_difference_p)
|
||||
*min_difference_p = min_difference;
|
||||
if (has_larger_p)
|
||||
*has_larger_p = has_larger;
|
||||
|
||||
return min_icon;
|
||||
}
|
||||
@@ -4827,6 +5151,37 @@ gtk_icon_theme_lookup_by_gicon (GtkIconTheme *icon_theme,
|
||||
GIcon *icon,
|
||||
gint size,
|
||||
GtkIconLookupFlags flags)
|
||||
{
|
||||
return gtk_icon_theme_lookup_by_gicon_for_scale (icon_theme, icon,
|
||||
size, 1, flags);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gtk_icon_theme_lookup_by_gicon_for_scale:
|
||||
* @icon_theme: a #GtkIconTheme
|
||||
* @icon: the #GIcon to look up
|
||||
* @size: desired icon size
|
||||
* @scale: the desired scale
|
||||
* @flags: flags modifying the behavior of the icon lookup
|
||||
*
|
||||
* Looks up an icon and returns a structure containing
|
||||
* information such as the filename of the icon.
|
||||
* The icon can then be rendered into a pixbuf using
|
||||
* gtk_icon_info_load_icon_for_scale ().
|
||||
*
|
||||
* Return value: (transfer full): a #GtkIconInfo structure containing
|
||||
* information about the icon, or %NULL if the icon
|
||||
* wasn't found. Unref with g_object_unref()
|
||||
*
|
||||
* Since: 2.14
|
||||
*/
|
||||
GtkIconInfo *
|
||||
gtk_icon_theme_lookup_by_gicon_for_scale (GtkIconTheme *icon_theme,
|
||||
GIcon *icon,
|
||||
gint size,
|
||||
gint scale,
|
||||
GtkIconLookupFlags flags)
|
||||
{
|
||||
GtkIconInfo *info;
|
||||
|
||||
@@ -4851,6 +5206,7 @@ gtk_icon_theme_lookup_by_gicon (GtkIconTheme *icon_theme,
|
||||
info->dir_type = ICON_THEME_DIR_UNTHEMED;
|
||||
info->dir_size = size;
|
||||
info->desired_size = size;
|
||||
info->desired_scale = scale;
|
||||
info->threshold = 2;
|
||||
info->forced_size = (flags & GTK_ICON_LOOKUP_FORCE_SIZE) != 0;
|
||||
|
||||
@@ -4861,7 +5217,7 @@ gtk_icon_theme_lookup_by_gicon (GtkIconTheme *icon_theme,
|
||||
const gchar **names;
|
||||
|
||||
names = (const gchar **)g_themed_icon_get_names (G_THEMED_ICON (icon));
|
||||
info = gtk_icon_theme_choose_icon (icon_theme, names, size, flags);
|
||||
info = gtk_icon_theme_choose_icon_for_scale (icon_theme, names, size, scale, flags);
|
||||
|
||||
return info;
|
||||
}
|
||||
@@ -4875,7 +5231,7 @@ gtk_icon_theme_lookup_by_gicon (GtkIconTheme *icon_theme,
|
||||
_gtk_numerable_icon_set_background_icon_size (GTK_NUMERABLE_ICON (icon), size / 2);
|
||||
|
||||
base = g_emblemed_icon_get_icon (G_EMBLEMED_ICON (icon));
|
||||
base_info = gtk_icon_theme_lookup_by_gicon (icon_theme, base, size, flags);
|
||||
base_info = gtk_icon_theme_lookup_by_gicon_for_scale (icon_theme, base, size, scale, flags);
|
||||
if (base_info)
|
||||
{
|
||||
info = icon_info_dup (base_info);
|
||||
@@ -4886,7 +5242,7 @@ gtk_icon_theme_lookup_by_gicon (GtkIconTheme *icon_theme,
|
||||
{
|
||||
emblem = g_emblem_get_icon (G_EMBLEM (l->data));
|
||||
/* always force size for emblems */
|
||||
emblem_info = gtk_icon_theme_lookup_by_gicon (icon_theme, emblem, size / 2, flags | GTK_ICON_LOOKUP_FORCE_SIZE);
|
||||
emblem_info = gtk_icon_theme_lookup_by_gicon_for_scale (icon_theme, emblem, size / 2, scale, flags | GTK_ICON_LOOKUP_FORCE_SIZE);
|
||||
if (emblem_info)
|
||||
info->emblem_infos = g_slist_prepend (info->emblem_infos, emblem_info);
|
||||
}
|
||||
@@ -4905,17 +5261,17 @@ gtk_icon_theme_lookup_by_gicon (GtkIconTheme *icon_theme,
|
||||
if ((flags & GTK_ICON_LOOKUP_FORCE_SIZE) != 0)
|
||||
{
|
||||
gint width, height, max;
|
||||
gdouble scale;
|
||||
gdouble pixbuf_scale;
|
||||
GdkPixbuf *scaled;
|
||||
|
||||
width = gdk_pixbuf_get_width (pixbuf);
|
||||
height = gdk_pixbuf_get_height (pixbuf);
|
||||
max = MAX (width, height);
|
||||
scale = (gdouble) size / (gdouble) max;
|
||||
pixbuf_scale = (gdouble) size * scale / (gdouble) max;
|
||||
|
||||
scaled = gdk_pixbuf_scale_simple (pixbuf,
|
||||
0.5 + width * scale,
|
||||
0.5 + height * scale,
|
||||
0.5 + width * pixbuf_scale,
|
||||
0.5 + height * pixbuf_scale,
|
||||
GDK_INTERP_BILINEAR);
|
||||
|
||||
info = gtk_icon_info_new_for_pixbuf (icon_theme, scaled);
|
||||
|
||||
@@ -179,23 +179,57 @@ GtkIconInfo * gtk_icon_theme_lookup_icon (GtkIconTheme
|
||||
const gchar *icon_name,
|
||||
gint size,
|
||||
GtkIconLookupFlags flags);
|
||||
GDK_AVAILABLE_IN_3_10
|
||||
GtkIconInfo * gtk_icon_theme_lookup_icon_for_scale (GtkIconTheme *icon_theme,
|
||||
const gchar *icon_name,
|
||||
gint size,
|
||||
gint scale,
|
||||
GtkIconLookupFlags flags);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkIconInfo * gtk_icon_theme_choose_icon (GtkIconTheme *icon_theme,
|
||||
const gchar *icon_names[],
|
||||
gint size,
|
||||
GtkIconLookupFlags flags);
|
||||
GDK_AVAILABLE_IN_3_10
|
||||
GtkIconInfo * gtk_icon_theme_choose_icon_for_scale (GtkIconTheme *icon_theme,
|
||||
const gchar *icon_names[],
|
||||
gint size,
|
||||
gint scale,
|
||||
GtkIconLookupFlags flags);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkPixbuf * gtk_icon_theme_load_icon (GtkIconTheme *icon_theme,
|
||||
const gchar *icon_name,
|
||||
gint size,
|
||||
GtkIconLookupFlags flags,
|
||||
GError **error);
|
||||
GDK_AVAILABLE_IN_3_10
|
||||
GdkPixbuf * gtk_icon_theme_load_icon_for_scale (GtkIconTheme *icon_theme,
|
||||
const gchar *icon_name,
|
||||
gint size,
|
||||
gint scale,
|
||||
GtkIconLookupFlags flags,
|
||||
GError **error);
|
||||
GDK_AVAILABLE_IN_3_10
|
||||
cairo_surface_t * gtk_icon_theme_load_surface (GtkIconTheme *icon_theme,
|
||||
const gchar *icon_name,
|
||||
gint size,
|
||||
gint scale,
|
||||
GdkWindow *for_window,
|
||||
GtkIconLookupFlags flags,
|
||||
GError **error);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkIconInfo * gtk_icon_theme_lookup_by_gicon (GtkIconTheme *icon_theme,
|
||||
GIcon *icon,
|
||||
gint size,
|
||||
GtkIconLookupFlags flags);
|
||||
GtkIconInfo * gtk_icon_theme_lookup_by_gicon_for_scale (GtkIconTheme *icon_theme,
|
||||
GIcon *icon,
|
||||
gint size,
|
||||
gint scale,
|
||||
GtkIconLookupFlags flags);
|
||||
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GList * gtk_icon_theme_list_icons (GtkIconTheme *icon_theme,
|
||||
@@ -226,6 +260,8 @@ GtkIconInfo * gtk_icon_info_new_for_pixbuf (GtkIconTheme *icon_them
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gint gtk_icon_info_get_base_size (GtkIconInfo *icon_info);
|
||||
GDK_AVAILABLE_IN_3_10
|
||||
gint gtk_icon_info_get_base_scale (GtkIconInfo *icon_info);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
const gchar * gtk_icon_info_get_filename (GtkIconInfo *icon_info);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
@@ -233,6 +269,10 @@ GdkPixbuf * gtk_icon_info_get_builtin_pixbuf (GtkIconInfo *icon_info
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkPixbuf * gtk_icon_info_load_icon (GtkIconInfo *icon_info,
|
||||
GError **error);
|
||||
GDK_AVAILABLE_IN_3_10
|
||||
cairo_surface_t * gtk_icon_info_load_surface (GtkIconInfo *icon_info,
|
||||
GdkWindow *for_window,
|
||||
GError **error);
|
||||
GDK_AVAILABLE_IN_3_8
|
||||
void gtk_icon_info_load_icon_async (GtkIconInfo *icon_info,
|
||||
GCancellable *cancellable,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user