Compare commits
36 Commits
css-variab
...
wip/simple
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2ce9c8cff2 | ||
|
|
76add3ec39 | ||
|
|
30b10fe78b | ||
|
|
640ead7656 | ||
|
|
16623aabd1 | ||
|
|
958df1c4bf | ||
|
|
f05fc2dd57 | ||
|
|
7442ca3f63 | ||
|
|
f4006d6eaf | ||
|
|
827295d016 | ||
|
|
770ef2dc83 | ||
|
|
d0e34a0ac9 | ||
|
|
0ec74de37d | ||
|
|
8856966e5b | ||
|
|
18f540a9d4 | ||
|
|
a6bffcfb57 | ||
|
|
cc21fafd20 | ||
|
|
1224011b8a | ||
|
|
5dbd2f200b | ||
|
|
33f33b0e65 | ||
|
|
4c5a5bb6d3 | ||
|
|
08df83daec | ||
|
|
0e71895274 | ||
|
|
5eefd88208 | ||
|
|
ebee0d80fb | ||
|
|
1703c5a87a | ||
|
|
8251523e1d | ||
|
|
b8d3b98416 | ||
|
|
7e4f48e55e | ||
|
|
0770104286 | ||
|
|
f03474a4a0 | ||
|
|
08d0270614 | ||
|
|
4106b75a25 | ||
|
|
7c1d9332e2 | ||
|
|
ce8bd92cb9 | ||
|
|
896a170421 |
@@ -1470,56 +1470,6 @@ _gdk_broadway_window_queue_antiexpose (GdkWindow *window,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
copy_region (cairo_surface_t *surface,
|
|
||||||
cairo_region_t *area,
|
|
||||||
gint dx,
|
|
||||||
gint dy)
|
|
||||||
{
|
|
||||||
cairo_t *cr;
|
|
||||||
|
|
||||||
cr = cairo_create (surface);
|
|
||||||
|
|
||||||
gdk_cairo_region (cr, area);
|
|
||||||
cairo_clip (cr);
|
|
||||||
|
|
||||||
/* NB: This is a self-copy and Cairo doesn't support that yet.
|
|
||||||
* So we do a litle trick.
|
|
||||||
*/
|
|
||||||
cairo_push_group (cr);
|
|
||||||
|
|
||||||
cairo_set_source_surface (cr, surface, dx, dy);
|
|
||||||
cairo_paint (cr);
|
|
||||||
|
|
||||||
cairo_pop_group_to_source (cr);
|
|
||||||
cairo_paint (cr);
|
|
||||||
|
|
||||||
cairo_destroy (cr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
_gdk_broadway_window_translate (GdkWindow *window,
|
|
||||||
cairo_region_t *area,
|
|
||||||
gint dx,
|
|
||||||
gint dy)
|
|
||||||
{
|
|
||||||
GdkWindowImplBroadway *impl;
|
|
||||||
GdkBroadwayDisplay *broadway_display;
|
|
||||||
|
|
||||||
impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
|
|
||||||
|
|
||||||
if (impl->surface)
|
|
||||||
{
|
|
||||||
copy_region (impl->surface, area, dx, dy);
|
|
||||||
broadway_display = GDK_BROADWAY_DISPLAY (gdk_window_get_display (window));
|
|
||||||
|
|
||||||
if (_gdk_broadway_server_window_translate (broadway_display->server,
|
|
||||||
impl->id,
|
|
||||||
area, dx, dy))
|
|
||||||
queue_flush (window);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
guint32
|
guint32
|
||||||
gdk_broadway_get_last_seen_time (GdkWindow *window)
|
gdk_broadway_get_last_seen_time (GdkWindow *window)
|
||||||
{
|
{
|
||||||
@@ -1558,7 +1508,6 @@ gdk_window_impl_broadway_class_init (GdkWindowImplBroadwayClass *klass)
|
|||||||
impl_class->input_shape_combine_region = gdk_window_broadway_input_shape_combine_region;
|
impl_class->input_shape_combine_region = gdk_window_broadway_input_shape_combine_region;
|
||||||
impl_class->set_static_gravities = gdk_window_broadway_set_static_gravities;
|
impl_class->set_static_gravities = gdk_window_broadway_set_static_gravities;
|
||||||
impl_class->queue_antiexpose = _gdk_broadway_window_queue_antiexpose;
|
impl_class->queue_antiexpose = _gdk_broadway_window_queue_antiexpose;
|
||||||
impl_class->translate = _gdk_broadway_window_translate;
|
|
||||||
impl_class->destroy = _gdk_broadway_window_destroy;
|
impl_class->destroy = _gdk_broadway_window_destroy;
|
||||||
impl_class->destroy_foreign = gdk_broadway_window_destroy_foreign;
|
impl_class->destroy_foreign = gdk_broadway_window_destroy_foreign;
|
||||||
impl_class->resize_cairo_surface = gdk_window_broadway_resize_cairo_surface;
|
impl_class->resize_cairo_surface = gdk_window_broadway_resize_cairo_surface;
|
||||||
|
|||||||
@@ -384,6 +384,7 @@ gdk_frame_clock_paint_idle (void *data)
|
|||||||
case GDK_FRAME_CLOCK_PHASE_LAYOUT:
|
case GDK_FRAME_CLOCK_PHASE_LAYOUT:
|
||||||
if (priv->freeze_count == 0)
|
if (priv->freeze_count == 0)
|
||||||
{
|
{
|
||||||
|
int iter;
|
||||||
#ifdef G_ENABLE_DEBUG
|
#ifdef G_ENABLE_DEBUG
|
||||||
if ((_gdk_debug_flags & GDK_DEBUG_FRAMES) != 0)
|
if ((_gdk_debug_flags & GDK_DEBUG_FRAMES) != 0)
|
||||||
{
|
{
|
||||||
@@ -394,11 +395,20 @@ gdk_frame_clock_paint_idle (void *data)
|
|||||||
#endif /* G_ENABLE_DEBUG */
|
#endif /* G_ENABLE_DEBUG */
|
||||||
|
|
||||||
priv->phase = GDK_FRAME_CLOCK_PHASE_LAYOUT;
|
priv->phase = GDK_FRAME_CLOCK_PHASE_LAYOUT;
|
||||||
if (priv->requested & GDK_FRAME_CLOCK_PHASE_LAYOUT)
|
/* We loop in the layout phase, because we don't want to progress
|
||||||
|
* into the paint phase with invalid size allocations. This may
|
||||||
|
* happen in some situation like races between user window
|
||||||
|
* resizes and natural size changes.
|
||||||
|
*/
|
||||||
|
iter = 0;
|
||||||
|
while ((priv->requested & GDK_FRAME_CLOCK_PHASE_LAYOUT) &&
|
||||||
|
priv->freeze_count == 0 && iter++ < 4)
|
||||||
{
|
{
|
||||||
priv->requested &= ~GDK_FRAME_CLOCK_PHASE_LAYOUT;
|
priv->requested &= ~GDK_FRAME_CLOCK_PHASE_LAYOUT;
|
||||||
g_signal_emit_by_name (G_OBJECT (clock), "layout");
|
g_signal_emit_by_name (G_OBJECT (clock), "layout");
|
||||||
}
|
}
|
||||||
|
if (iter == 5)
|
||||||
|
g_warning ("gdk-frame-clock: layout continuously requested, giving up after 4 tries");
|
||||||
}
|
}
|
||||||
case GDK_FRAME_CLOCK_PHASE_PAINT:
|
case GDK_FRAME_CLOCK_PHASE_PAINT:
|
||||||
if (priv->freeze_count == 0)
|
if (priv->freeze_count == 0)
|
||||||
|
|||||||
@@ -224,6 +224,7 @@ struct _GdkWindow
|
|||||||
guint native_visibility : 2; /* the native visibility of a impl windows */
|
guint native_visibility : 2; /* the native visibility of a impl windows */
|
||||||
guint viewable : 1; /* mapped and all parents mapped */
|
guint viewable : 1; /* mapped and all parents mapped */
|
||||||
guint applied_shape : 1;
|
guint applied_shape : 1;
|
||||||
|
guint in_update : 1;
|
||||||
GdkFullscreenMode fullscreen_mode;
|
GdkFullscreenMode fullscreen_mode;
|
||||||
|
|
||||||
/* The GdkWindow that has the impl, ref:ed if another window.
|
/* The GdkWindow that has the impl, ref:ed if another window.
|
||||||
@@ -250,10 +251,6 @@ struct _GdkWindow
|
|||||||
GdkCursor *cursor;
|
GdkCursor *cursor;
|
||||||
GHashTable *device_cursor;
|
GHashTable *device_cursor;
|
||||||
|
|
||||||
GSList *implicit_paint;
|
|
||||||
|
|
||||||
GList *outstanding_moves;
|
|
||||||
|
|
||||||
cairo_region_t *shape;
|
cairo_region_t *shape;
|
||||||
cairo_region_t *input_shape;
|
cairo_region_t *input_shape;
|
||||||
|
|
||||||
@@ -269,6 +266,7 @@ struct _GdkWindow
|
|||||||
guint num_offscreen_children;
|
guint num_offscreen_children;
|
||||||
|
|
||||||
GdkFrameClock *frame_clock; /* NULL to use from parent or default */
|
GdkFrameClock *frame_clock; /* NULL to use from parent or default */
|
||||||
|
GdkWindowInvalidateHandlerFunc invalidate_handler;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GDK_WINDOW_TYPE(d) (((GDK_WINDOW (d)))->window_type)
|
#define GDK_WINDOW_TYPE(d) (((GDK_WINDOW (d)))->window_type)
|
||||||
@@ -354,26 +352,6 @@ void _gdk_windowing_got_event (GdkDisplay *display,
|
|||||||
|
|
||||||
#define GDK_WINDOW_IS_MAPPED(window) (((window)->state & GDK_WINDOW_STATE_WITHDRAWN) == 0)
|
#define GDK_WINDOW_IS_MAPPED(window) (((window)->state & GDK_WINDOW_STATE_WITHDRAWN) == 0)
|
||||||
|
|
||||||
#define GDK_TYPE_PAINTABLE (_gdk_paintable_get_type ())
|
|
||||||
#define GDK_PAINTABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_PAINTABLE, GdkPaintable))
|
|
||||||
#define GDK_IS_PAINTABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_PAINTABLE))
|
|
||||||
#define GDK_PAINTABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GDK_TYPE_PAINTABLE, GdkPaintableIface))
|
|
||||||
|
|
||||||
typedef struct _GdkPaintable GdkPaintable;
|
|
||||||
typedef struct _GdkPaintableIface GdkPaintableIface;
|
|
||||||
|
|
||||||
struct _GdkPaintableIface
|
|
||||||
{
|
|
||||||
GTypeInterface g_iface;
|
|
||||||
|
|
||||||
void (* begin_paint_region) (GdkPaintable *paintable,
|
|
||||||
GdkWindow *window,
|
|
||||||
const cairo_region_t *region);
|
|
||||||
void (* end_paint) (GdkPaintable *paintable);
|
|
||||||
};
|
|
||||||
|
|
||||||
GType _gdk_paintable_get_type (void) G_GNUC_CONST;
|
|
||||||
|
|
||||||
void _gdk_window_invalidate_for_expose (GdkWindow *window,
|
void _gdk_window_invalidate_for_expose (GdkWindow *window,
|
||||||
cairo_region_t *region);
|
cairo_region_t *region);
|
||||||
|
|
||||||
|
|||||||
@@ -555,42 +555,6 @@ gdk_offscreen_window_queue_antiexpose (GdkWindow *window,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gdk_offscreen_window_translate (GdkWindow *window,
|
|
||||||
cairo_region_t *area,
|
|
||||||
gint dx,
|
|
||||||
gint dy)
|
|
||||||
{
|
|
||||||
GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (window->impl);
|
|
||||||
|
|
||||||
if (offscreen->surface)
|
|
||||||
{
|
|
||||||
cairo_t *cr;
|
|
||||||
|
|
||||||
cr = cairo_create (offscreen->surface);
|
|
||||||
|
|
||||||
area = cairo_region_copy (area);
|
|
||||||
|
|
||||||
gdk_cairo_region (cr, area);
|
|
||||||
cairo_clip (cr);
|
|
||||||
|
|
||||||
/* NB: This is a self-copy and Cairo doesn't support that yet.
|
|
||||||
* So we do a litle trick.
|
|
||||||
*/
|
|
||||||
cairo_push_group (cr);
|
|
||||||
|
|
||||||
cairo_set_source_surface (cr, offscreen->surface, dx, dy);
|
|
||||||
cairo_paint (cr);
|
|
||||||
|
|
||||||
cairo_pop_group_to_source (cr);
|
|
||||||
cairo_paint (cr);
|
|
||||||
|
|
||||||
cairo_destroy (cr);
|
|
||||||
}
|
|
||||||
|
|
||||||
_gdk_window_add_damage (window, area);
|
|
||||||
}
|
|
||||||
|
|
||||||
static cairo_surface_t *
|
static cairo_surface_t *
|
||||||
gdk_offscreen_window_resize_cairo_surface (GdkWindow *window,
|
gdk_offscreen_window_resize_cairo_surface (GdkWindow *window,
|
||||||
cairo_surface_t *surface,
|
cairo_surface_t *surface,
|
||||||
@@ -752,7 +716,6 @@ gdk_offscreen_window_class_init (GdkOffscreenWindowClass *klass)
|
|||||||
impl_class->input_shape_combine_region = gdk_offscreen_window_input_shape_combine_region;
|
impl_class->input_shape_combine_region = gdk_offscreen_window_input_shape_combine_region;
|
||||||
impl_class->set_static_gravities = gdk_offscreen_window_set_static_gravities;
|
impl_class->set_static_gravities = gdk_offscreen_window_set_static_gravities;
|
||||||
impl_class->queue_antiexpose = gdk_offscreen_window_queue_antiexpose;
|
impl_class->queue_antiexpose = gdk_offscreen_window_queue_antiexpose;
|
||||||
impl_class->translate = gdk_offscreen_window_translate;
|
|
||||||
impl_class->destroy = gdk_offscreen_window_destroy;
|
impl_class->destroy = gdk_offscreen_window_destroy;
|
||||||
impl_class->destroy_foreign = NULL;
|
impl_class->destroy_foreign = NULL;
|
||||||
impl_class->resize_cairo_surface = gdk_offscreen_window_resize_cairo_surface;
|
impl_class->resize_cairo_surface = gdk_offscreen_window_resize_cairo_surface;
|
||||||
|
|||||||
1791
gdk/gdkwindow.c
1791
gdk/gdkwindow.c
File diff suppressed because it is too large
Load Diff
@@ -634,6 +634,26 @@ gboolean gdk_window_set_static_gravities (GdkWindow *window,
|
|||||||
|
|
||||||
/* GdkWindow */
|
/* GdkWindow */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GdkWindowInvalidateHandlerFunc:
|
||||||
|
* @window: a #GdkWindow
|
||||||
|
* @region: a #cairo_region_t
|
||||||
|
*
|
||||||
|
* Whenever some area of the window is invalidated (directly in the
|
||||||
|
* window or in a child window) this gets called with @region in
|
||||||
|
* the coordinate space of @window. You can use @region to just
|
||||||
|
* keep track of the dirty region, or you can actually change
|
||||||
|
* @region in case you are doing display tricks like showing
|
||||||
|
* a child in multiple places.
|
||||||
|
*
|
||||||
|
* Since: 3.10
|
||||||
|
*/
|
||||||
|
typedef void (*GdkWindowInvalidateHandlerFunc) (GdkWindow *window,
|
||||||
|
cairo_region_t *region);
|
||||||
|
GDK_AVAILABLE_IN_3_10
|
||||||
|
void gdk_window_set_invalidate_handler (GdkWindow *window,
|
||||||
|
GdkWindowInvalidateHandlerFunc handler);
|
||||||
|
|
||||||
gboolean gdk_window_has_native (GdkWindow *window);
|
gboolean gdk_window_has_native (GdkWindow *window);
|
||||||
void gdk_window_set_type_hint (GdkWindow *window,
|
void gdk_window_set_type_hint (GdkWindow *window,
|
||||||
GdkWindowTypeHint hint);
|
GdkWindowTypeHint hint);
|
||||||
|
|||||||
@@ -101,6 +101,9 @@ struct _GdkWindowImplClass
|
|||||||
gint *x,
|
gint *x,
|
||||||
gint *y,
|
gint *y,
|
||||||
GdkModifierType *mask);
|
GdkModifierType *mask);
|
||||||
|
gboolean (* begin_paint_region) (GdkWindow *window,
|
||||||
|
const cairo_region_t *region);
|
||||||
|
void (* end_paint) (GdkWindow *window);
|
||||||
|
|
||||||
cairo_region_t * (* get_shape) (GdkWindow *window);
|
cairo_region_t * (* get_shape) (GdkWindow *window);
|
||||||
cairo_region_t * (* get_input_shape) (GdkWindow *window);
|
cairo_region_t * (* get_input_shape) (GdkWindow *window);
|
||||||
@@ -125,16 +128,6 @@ struct _GdkWindowImplClass
|
|||||||
gboolean (* queue_antiexpose) (GdkWindow *window,
|
gboolean (* queue_antiexpose) (GdkWindow *window,
|
||||||
cairo_region_t *update_area);
|
cairo_region_t *update_area);
|
||||||
|
|
||||||
/* Called to move @area inside @window by @dx x @dy pixels. @area is
|
|
||||||
* guaranteed to be inside @window. If part of @area is not invisible or
|
|
||||||
* invalid, it is this function's job to queue expose events in those
|
|
||||||
* areas.
|
|
||||||
*/
|
|
||||||
void (* translate) (GdkWindow *window,
|
|
||||||
cairo_region_t *area,
|
|
||||||
gint dx,
|
|
||||||
gint dy);
|
|
||||||
|
|
||||||
/* Called to do the windowing system specific part of gdk_window_destroy(),
|
/* Called to do the windowing system specific part of gdk_window_destroy(),
|
||||||
*
|
*
|
||||||
* window: The window being destroyed
|
* window: The window being destroyed
|
||||||
|
|||||||
@@ -364,19 +364,18 @@ gdk_window_impl_quartz_init (GdkWindowImplQuartz *impl)
|
|||||||
impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
|
impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static gboolean
|
||||||
gdk_window_impl_quartz_begin_paint_region (GdkPaintable *paintable,
|
gdk_window_impl_quartz_begin_paint_region (GdkWindow *window,
|
||||||
GdkWindow *window,
|
|
||||||
const cairo_region_t *region)
|
const cairo_region_t *region)
|
||||||
{
|
{
|
||||||
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (paintable);
|
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->imp);
|
||||||
cairo_region_t *clipped_and_offset_region;
|
cairo_region_t *clipped_and_offset_region;
|
||||||
cairo_t *cr;
|
cairo_t *cr;
|
||||||
|
|
||||||
clipped_and_offset_region = cairo_region_copy (region);
|
clipped_and_offset_region = cairo_region_copy (region);
|
||||||
|
|
||||||
cairo_region_intersect (clipped_and_offset_region,
|
cairo_region_intersect (clipped_and_offset_region,
|
||||||
window->clip_region_with_children);
|
window->clip_region);
|
||||||
cairo_region_translate (clipped_and_offset_region,
|
cairo_region_translate (clipped_and_offset_region,
|
||||||
window->abs_x, window->abs_y);
|
window->abs_x, window->abs_y);
|
||||||
|
|
||||||
@@ -415,12 +414,14 @@ gdk_window_impl_quartz_begin_paint_region (GdkPaintable *paintable,
|
|||||||
|
|
||||||
done:
|
done:
|
||||||
cairo_region_destroy (clipped_and_offset_region);
|
cairo_region_destroy (clipped_and_offset_region);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gdk_window_impl_quartz_end_paint (GdkPaintable *paintable)
|
gdk_window_impl_quartz_end_paint (GdkWindow *window)
|
||||||
{
|
{
|
||||||
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (paintable);
|
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
|
||||||
|
|
||||||
impl->begin_paint_count--;
|
impl->begin_paint_count--;
|
||||||
|
|
||||||
@@ -536,13 +537,6 @@ _gdk_quartz_display_after_process_all_updates (GdkDisplay *display)
|
|||||||
NSEnableScreenUpdates ();
|
NSEnableScreenUpdates ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gdk_window_impl_quartz_paintable_init (GdkPaintableIface *iface)
|
|
||||||
{
|
|
||||||
iface->begin_paint_region = gdk_window_impl_quartz_begin_paint_region;
|
|
||||||
iface->end_paint = gdk_window_impl_quartz_end_paint;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const gchar *
|
static const gchar *
|
||||||
get_default_title (void)
|
get_default_title (void)
|
||||||
{
|
{
|
||||||
@@ -2237,49 +2231,6 @@ gdk_quartz_window_queue_antiexpose (GdkWindow *window,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gdk_quartz_window_translate (GdkWindow *window,
|
|
||||||
cairo_region_t *area,
|
|
||||||
gint dx,
|
|
||||||
gint dy)
|
|
||||||
{
|
|
||||||
cairo_region_t *invalidate, *scrolled;
|
|
||||||
GdkWindowImplQuartz *impl = (GdkWindowImplQuartz *)window->impl;
|
|
||||||
GdkRectangle extents;
|
|
||||||
|
|
||||||
cairo_region_get_extents (area, &extents);
|
|
||||||
|
|
||||||
[impl->view scrollRect:NSMakeRect (extents.x - dx, extents.y - dy,
|
|
||||||
extents.width, extents.height)
|
|
||||||
by:NSMakeSize (dx, dy)];
|
|
||||||
|
|
||||||
if (impl->needs_display_region)
|
|
||||||
{
|
|
||||||
cairo_region_t *intersection;
|
|
||||||
|
|
||||||
/* Invalidate already invalidated area that was moved at new
|
|
||||||
* location.
|
|
||||||
*/
|
|
||||||
intersection = cairo_region_copy (impl->needs_display_region);
|
|
||||||
cairo_region_intersect (intersection, area);
|
|
||||||
cairo_region_translate (intersection, dx, dy);
|
|
||||||
|
|
||||||
gdk_quartz_window_set_needs_display_in_region (window, intersection);
|
|
||||||
cairo_region_destroy (intersection);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Calculate newly exposed area that needs invalidation */
|
|
||||||
scrolled = cairo_region_copy (area);
|
|
||||||
cairo_region_translate (scrolled, dx, dy);
|
|
||||||
|
|
||||||
invalidate = cairo_region_copy (area);
|
|
||||||
cairo_region_subtract (invalidate, scrolled);
|
|
||||||
cairo_region_destroy (scrolled);
|
|
||||||
|
|
||||||
gdk_quartz_window_set_needs_display_in_region (window, invalidate);
|
|
||||||
cairo_region_destroy (invalidate);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gdk_quartz_window_set_focus_on_map (GdkWindow *window,
|
gdk_quartz_window_set_focus_on_map (GdkWindow *window,
|
||||||
gboolean focus_on_map)
|
gboolean focus_on_map)
|
||||||
@@ -3078,12 +3029,13 @@ gdk_window_impl_quartz_class_init (GdkWindowImplQuartzClass *klass)
|
|||||||
impl_class->input_shape_combine_region = gdk_window_quartz_input_shape_combine_region;
|
impl_class->input_shape_combine_region = gdk_window_quartz_input_shape_combine_region;
|
||||||
impl_class->set_static_gravities = gdk_window_quartz_set_static_gravities;
|
impl_class->set_static_gravities = gdk_window_quartz_set_static_gravities;
|
||||||
impl_class->queue_antiexpose = gdk_quartz_window_queue_antiexpose;
|
impl_class->queue_antiexpose = gdk_quartz_window_queue_antiexpose;
|
||||||
impl_class->translate = gdk_quartz_window_translate;
|
|
||||||
impl_class->destroy = gdk_quartz_window_destroy;
|
impl_class->destroy = gdk_quartz_window_destroy;
|
||||||
impl_class->destroy_foreign = gdk_quartz_window_destroy_foreign;
|
impl_class->destroy_foreign = gdk_quartz_window_destroy_foreign;
|
||||||
impl_class->resize_cairo_surface = gdk_window_quartz_resize_cairo_surface;
|
impl_class->resize_cairo_surface = gdk_window_quartz_resize_cairo_surface;
|
||||||
impl_class->get_shape = gdk_quartz_window_get_shape;
|
impl_class->get_shape = gdk_quartz_window_get_shape;
|
||||||
impl_class->get_input_shape = gdk_quartz_window_get_input_shape;
|
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->focus = gdk_quartz_window_focus;
|
impl_class->focus = gdk_quartz_window_focus;
|
||||||
impl_class->set_type_hint = gdk_quartz_window_set_type_hint;
|
impl_class->set_type_hint = gdk_quartz_window_set_type_hint;
|
||||||
@@ -3159,19 +3111,9 @@ _gdk_window_impl_quartz_get_type (void)
|
|||||||
(GInstanceInitFunc) gdk_window_impl_quartz_init,
|
(GInstanceInitFunc) gdk_window_impl_quartz_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
const GInterfaceInfo paintable_info =
|
|
||||||
{
|
|
||||||
(GInterfaceInitFunc) gdk_window_impl_quartz_paintable_init,
|
|
||||||
NULL,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
object_type = g_type_register_static (GDK_TYPE_WINDOW_IMPL,
|
object_type = g_type_register_static (GDK_TYPE_WINDOW_IMPL,
|
||||||
"GdkWindowImplQuartz",
|
"GdkWindowImplQuartz",
|
||||||
&object_info, 0);
|
&object_info, 0);
|
||||||
g_type_add_interface_static (object_type,
|
|
||||||
GDK_TYPE_PAINTABLE,
|
|
||||||
&paintable_info);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return object_type;
|
return object_type;
|
||||||
|
|||||||
@@ -382,11 +382,24 @@ on_frame_clock_before_paint (GdkFrameClock *clock,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const cairo_user_data_key_t gdk_wayland_cairo_key;
|
||||||
|
|
||||||
|
typedef struct _GdkWaylandCairoSurfaceData {
|
||||||
|
gpointer buf;
|
||||||
|
size_t buf_length;
|
||||||
|
struct wl_shm_pool *pool;
|
||||||
|
struct wl_buffer *buffer;
|
||||||
|
GdkWaylandDisplay *display;
|
||||||
|
int32_t width, height;
|
||||||
|
gboolean busy;
|
||||||
|
} GdkWaylandCairoSurfaceData;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_frame_clock_after_paint (GdkFrameClock *clock,
|
on_frame_clock_after_paint (GdkFrameClock *clock,
|
||||||
GdkWindow *window)
|
GdkWindow *window)
|
||||||
{
|
{
|
||||||
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
||||||
|
GdkWaylandCairoSurfaceData *data;
|
||||||
struct wl_callback *callback;
|
struct wl_callback *callback;
|
||||||
|
|
||||||
if (!impl->pending_commit)
|
if (!impl->pending_commit)
|
||||||
@@ -400,6 +413,10 @@ on_frame_clock_after_paint (GdkFrameClock *clock,
|
|||||||
_gdk_frame_clock_freeze (clock);
|
_gdk_frame_clock_freeze (clock);
|
||||||
|
|
||||||
wl_surface_commit (impl->surface);
|
wl_surface_commit (impl->surface);
|
||||||
|
|
||||||
|
data = cairo_surface_get_user_data (impl->cairo_surface,
|
||||||
|
&gdk_wayland_cairo_key);
|
||||||
|
data->busy = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -462,17 +479,6 @@ _gdk_wayland_display_create_window_impl (GdkDisplay *display,
|
|||||||
G_CALLBACK (on_frame_clock_after_paint), window);
|
G_CALLBACK (on_frame_clock_after_paint), window);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const cairo_user_data_key_t gdk_wayland_cairo_key;
|
|
||||||
|
|
||||||
typedef struct _GdkWaylandCairoSurfaceData {
|
|
||||||
gpointer buf;
|
|
||||||
size_t buf_length;
|
|
||||||
struct wl_shm_pool *pool;
|
|
||||||
struct wl_buffer *buffer;
|
|
||||||
GdkWaylandDisplay *display;
|
|
||||||
int32_t width, height;
|
|
||||||
} GdkWaylandCairoSurfaceData;
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gdk_wayland_window_attach_image (GdkWindow *window)
|
gdk_wayland_window_attach_image (GdkWindow *window)
|
||||||
{
|
{
|
||||||
@@ -588,6 +594,19 @@ _create_shm_pool (struct wl_shm *shm,
|
|||||||
return pool;
|
return pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
buffer_release_callback (void *_data, struct wl_buffer *wl_buffer)
|
||||||
|
{
|
||||||
|
GdkWaylandCairoSurfaceData *data = _data;
|
||||||
|
|
||||||
|
data->busy = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wl_buffer_listener buffer_listener = {
|
||||||
|
buffer_release_callback
|
||||||
|
};
|
||||||
|
|
||||||
static cairo_surface_t *
|
static cairo_surface_t *
|
||||||
gdk_wayland_create_cairo_surface (GdkWaylandDisplay *display,
|
gdk_wayland_create_cairo_surface (GdkWaylandDisplay *display,
|
||||||
int width, int height)
|
int width, int height)
|
||||||
@@ -602,6 +621,7 @@ gdk_wayland_create_cairo_surface (GdkWaylandDisplay *display,
|
|||||||
data->buffer = NULL;
|
data->buffer = NULL;
|
||||||
data->width = width;
|
data->width = width;
|
||||||
data->height = height;
|
data->height = height;
|
||||||
|
data->busy = FALSE;
|
||||||
|
|
||||||
stride = width * 4;
|
stride = width * 4;
|
||||||
|
|
||||||
@@ -613,6 +633,7 @@ gdk_wayland_create_cairo_surface (GdkWaylandDisplay *display,
|
|||||||
data->buffer = wl_shm_pool_create_buffer (data->pool, 0,
|
data->buffer = wl_shm_pool_create_buffer (data->pool, 0,
|
||||||
width, height,
|
width, height,
|
||||||
stride, WL_SHM_FORMAT_ARGB8888);
|
stride, WL_SHM_FORMAT_ARGB8888);
|
||||||
|
wl_buffer_add_listener (data->buffer, &buffer_listener, data);
|
||||||
|
|
||||||
surface = cairo_image_surface_create_for_data (data->buf,
|
surface = cairo_image_surface_create_for_data (data->buf,
|
||||||
CAIRO_FORMAT_ARGB32,
|
CAIRO_FORMAT_ARGB32,
|
||||||
@@ -668,6 +689,20 @@ gdk_wayland_window_ref_cairo_surface (GdkWindow *window)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gdk_window_impl_wayland_begin_paint_region (GdkWindow *window,
|
||||||
|
const cairo_region_t *region)
|
||||||
|
{
|
||||||
|
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
||||||
|
GdkWaylandCairoSurfaceData *data;
|
||||||
|
|
||||||
|
gdk_wayland_window_ensure_cairo_surface (window);
|
||||||
|
data = cairo_surface_get_user_data (impl->cairo_surface,
|
||||||
|
&gdk_wayland_cairo_key);
|
||||||
|
|
||||||
|
return data->busy;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gdk_window_impl_wayland_finalize (GObject *object)
|
gdk_window_impl_wayland_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
@@ -1193,15 +1228,6 @@ gdk_wayland_window_queue_antiexpose (GdkWindow *window,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gdk_wayland_window_translate (GdkWindow *window,
|
|
||||||
cairo_region_t *area,
|
|
||||||
gint dx,
|
|
||||||
gint dy)
|
|
||||||
{
|
|
||||||
_gdk_window_invalidate_for_expose (window, area);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gdk_wayland_window_destroy (GdkWindow *window,
|
gdk_wayland_window_destroy (GdkWindow *window,
|
||||||
gboolean recursing,
|
gboolean recursing,
|
||||||
@@ -1908,12 +1934,12 @@ _gdk_window_impl_wayland_class_init (GdkWindowImplWaylandClass *klass)
|
|||||||
impl_class->input_shape_combine_region = gdk_window_wayland_input_shape_combine_region;
|
impl_class->input_shape_combine_region = gdk_window_wayland_input_shape_combine_region;
|
||||||
impl_class->set_static_gravities = gdk_window_wayland_set_static_gravities;
|
impl_class->set_static_gravities = gdk_window_wayland_set_static_gravities;
|
||||||
impl_class->queue_antiexpose = gdk_wayland_window_queue_antiexpose;
|
impl_class->queue_antiexpose = gdk_wayland_window_queue_antiexpose;
|
||||||
impl_class->translate = gdk_wayland_window_translate;
|
|
||||||
impl_class->destroy = gdk_wayland_window_destroy;
|
impl_class->destroy = gdk_wayland_window_destroy;
|
||||||
impl_class->destroy_foreign = gdk_window_wayland_destroy_foreign;
|
impl_class->destroy_foreign = gdk_window_wayland_destroy_foreign;
|
||||||
impl_class->resize_cairo_surface = gdk_window_wayland_resize_cairo_surface;
|
impl_class->resize_cairo_surface = gdk_window_wayland_resize_cairo_surface;
|
||||||
impl_class->get_shape = gdk_wayland_window_get_shape;
|
impl_class->get_shape = gdk_wayland_window_get_shape;
|
||||||
impl_class->get_input_shape = gdk_wayland_window_get_input_shape;
|
impl_class->get_input_shape = gdk_wayland_window_get_input_shape;
|
||||||
|
impl_class->begin_paint_region = gdk_window_impl_wayland_begin_paint_region;
|
||||||
/* impl_class->beep */
|
/* impl_class->beep */
|
||||||
|
|
||||||
impl_class->focus = gdk_wayland_window_focus;
|
impl_class->focus = gdk_wayland_window_focus;
|
||||||
|
|||||||
@@ -3319,77 +3319,6 @@ _gdk_win32_window_queue_antiexpose (GdkWindow *window,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Gets called from gdwindow.c(do_move_region_bits_on_impl)
|
|
||||||
* and got tested with testgtk::big_window. Given the previous,
|
|
||||||
* untested implementation this one looks much too simple ;)
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
_gdk_win32_window_translate (GdkWindow *window,
|
|
||||||
cairo_region_t *area, /* In impl window coords */
|
|
||||||
gint dx,
|
|
||||||
gint dy)
|
|
||||||
{
|
|
||||||
GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
|
|
||||||
HRGN hrgn, area_hrgn;
|
|
||||||
cairo_region_t *update_region;
|
|
||||||
HDC hdc;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* Note: This is the destination area, not the source, and
|
|
||||||
it has been moved by dx, dy from the source area */
|
|
||||||
area_hrgn = cairo_region_to_hrgn (area, 0, 0);
|
|
||||||
|
|
||||||
/* First we copy any outstanding invalid areas in the
|
|
||||||
source area to the new position in the destination area */
|
|
||||||
hrgn = CreateRectRgn (0, 0, 0, 0);
|
|
||||||
ret = GetUpdateRgn (GDK_WINDOW_HWND (window), hrgn, FALSE);
|
|
||||||
if (ret == ERROR)
|
|
||||||
WIN32_API_FAILED ("GetUpdateRgn");
|
|
||||||
else if (ret != NULLREGION)
|
|
||||||
{
|
|
||||||
/* Convert the source invalid region as it would be copied */
|
|
||||||
OffsetRgn (hrgn, dx, dy);
|
|
||||||
/* Keep what intersects the copy destination area */
|
|
||||||
ret = CombineRgn (hrgn, hrgn, area_hrgn, RGN_AND);
|
|
||||||
/* And invalidate it */
|
|
||||||
if (ret == ERROR)
|
|
||||||
WIN32_API_FAILED ("CombineRgn");
|
|
||||||
else if (ret != NULLREGION)
|
|
||||||
API_CALL (InvalidateRgn, (GDK_WINDOW_HWND (window), hrgn, TRUE));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Then we copy the bits, invalidating whatever is copied from
|
|
||||||
otherwise invisible areas */
|
|
||||||
|
|
||||||
hdc = _gdk_win32_impl_acquire_dc (impl);
|
|
||||||
|
|
||||||
/* Clip hdc to target region */
|
|
||||||
API_CALL (SelectClipRgn, (hdc, area_hrgn));
|
|
||||||
|
|
||||||
SetRectRgn (hrgn, 0, 0, 0, 0);
|
|
||||||
|
|
||||||
if (!ScrollDC (hdc, dx, dy, NULL, NULL, hrgn, NULL))
|
|
||||||
WIN32_GDI_FAILED ("ScrollDC");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
update_region = _gdk_win32_hrgn_to_region (hrgn);
|
|
||||||
if (!cairo_region_is_empty (update_region))
|
|
||||||
_gdk_window_invalidate_for_expose (window, update_region);
|
|
||||||
cairo_region_destroy (update_region);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Unset hdc clip region */
|
|
||||||
API_CALL (SelectClipRgn, (hdc, NULL));
|
|
||||||
|
|
||||||
_gdk_win32_impl_release_dc (impl);
|
|
||||||
|
|
||||||
if (!DeleteObject (hrgn))
|
|
||||||
WIN32_GDI_FAILED ("DeleteObject");
|
|
||||||
|
|
||||||
if (!DeleteObject (area_hrgn))
|
|
||||||
WIN32_GDI_FAILED ("DeleteObject");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gdk_win32_input_shape_combine_region (GdkWindow *window,
|
gdk_win32_input_shape_combine_region (GdkWindow *window,
|
||||||
const cairo_region_t *shape_region,
|
const cairo_region_t *shape_region,
|
||||||
@@ -3556,7 +3485,6 @@ gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass)
|
|||||||
impl_class->input_shape_combine_region = gdk_win32_input_shape_combine_region;
|
impl_class->input_shape_combine_region = gdk_win32_input_shape_combine_region;
|
||||||
impl_class->set_static_gravities = gdk_win32_window_set_static_gravities;
|
impl_class->set_static_gravities = gdk_win32_window_set_static_gravities;
|
||||||
impl_class->queue_antiexpose = _gdk_win32_window_queue_antiexpose;
|
impl_class->queue_antiexpose = _gdk_win32_window_queue_antiexpose;
|
||||||
impl_class->translate = _gdk_win32_window_translate;
|
|
||||||
impl_class->destroy = gdk_win32_window_destroy;
|
impl_class->destroy = gdk_win32_window_destroy;
|
||||||
impl_class->destroy_foreign = gdk_win32_window_destroy_foreign;
|
impl_class->destroy_foreign = gdk_win32_window_destroy_foreign;
|
||||||
impl_class->resize_cairo_surface = gdk_win32_window_resize_cairo_surface;
|
impl_class->resize_cairo_surface = gdk_win32_window_resize_cairo_surface;
|
||||||
|
|||||||
@@ -28,26 +28,11 @@
|
|||||||
typedef struct _GdkWindowQueueItem GdkWindowQueueItem;
|
typedef struct _GdkWindowQueueItem GdkWindowQueueItem;
|
||||||
typedef struct _GdkWindowParentPos GdkWindowParentPos;
|
typedef struct _GdkWindowParentPos GdkWindowParentPos;
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
GDK_WINDOW_QUEUE_TRANSLATE,
|
|
||||||
GDK_WINDOW_QUEUE_ANTIEXPOSE
|
|
||||||
} GdkWindowQueueType;
|
|
||||||
|
|
||||||
struct _GdkWindowQueueItem
|
struct _GdkWindowQueueItem
|
||||||
{
|
{
|
||||||
GdkWindow *window;
|
GdkWindow *window;
|
||||||
gulong serial;
|
gulong serial;
|
||||||
GdkWindowQueueType type;
|
cairo_region_t *antiexpose_area;
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
cairo_region_t *area;
|
|
||||||
gint dx;
|
|
||||||
gint dy;
|
|
||||||
} translate;
|
|
||||||
struct {
|
|
||||||
cairo_region_t *area;
|
|
||||||
} antiexpose;
|
|
||||||
} u;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -140,14 +125,7 @@ queue_item_free (GdkWindowQueueItem *item)
|
|||||||
(gpointer *)&(item->window));
|
(gpointer *)&(item->window));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item->type == GDK_WINDOW_QUEUE_ANTIEXPOSE)
|
cairo_region_destroy (item->antiexpose_area);
|
||||||
cairo_region_destroy (item->u.antiexpose.area);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (item->u.translate.area)
|
|
||||||
cairo_region_destroy (item->u.translate.area);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free (item);
|
g_free (item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,11 +191,8 @@ gdk_window_queue (GdkWindow *window,
|
|||||||
GdkWindowQueueItem *item = tmp_list->data;
|
GdkWindowQueueItem *item = tmp_list->data;
|
||||||
GList *next = tmp_list->next;
|
GList *next = tmp_list->next;
|
||||||
|
|
||||||
if (item->type == GDK_WINDOW_QUEUE_ANTIEXPOSE)
|
queue_delete_link (display_x11->translate_queue, tmp_list);
|
||||||
{
|
queue_item_free (item);
|
||||||
queue_delete_link (display_x11->translate_queue, tmp_list);
|
|
||||||
queue_item_free (item);
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp_list = next;
|
tmp_list = next;
|
||||||
}
|
}
|
||||||
@@ -232,86 +207,12 @@ gdk_window_queue (GdkWindow *window,
|
|||||||
g_queue_push_tail (display_x11->translate_queue, item);
|
g_queue_push_tail (display_x11->translate_queue, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GC
|
|
||||||
_get_scratch_gc (GdkWindow *window, cairo_region_t *clip_region)
|
|
||||||
{
|
|
||||||
GdkX11Screen *screen;
|
|
||||||
XRectangle *rectangles;
|
|
||||||
gint n_rects;
|
|
||||||
gint depth;
|
|
||||||
|
|
||||||
screen = GDK_X11_SCREEN (gdk_window_get_screen (window));
|
|
||||||
depth = gdk_visual_get_depth (gdk_window_get_visual (window)) - 1;
|
|
||||||
|
|
||||||
if (!screen->subwindow_gcs[depth])
|
|
||||||
{
|
|
||||||
XGCValues values;
|
|
||||||
|
|
||||||
values.graphics_exposures = True;
|
|
||||||
values.subwindow_mode = IncludeInferiors;
|
|
||||||
|
|
||||||
screen->subwindow_gcs[depth] = XCreateGC (screen->xdisplay,
|
|
||||||
GDK_WINDOW_XID (window),
|
|
||||||
GCSubwindowMode | GCGraphicsExposures,
|
|
||||||
&values);
|
|
||||||
}
|
|
||||||
|
|
||||||
_gdk_x11_region_get_xrectangles (clip_region,
|
|
||||||
0, 0,
|
|
||||||
&rectangles,
|
|
||||||
&n_rects);
|
|
||||||
|
|
||||||
XSetClipRectangles (screen->xdisplay,
|
|
||||||
screen->subwindow_gcs[depth],
|
|
||||||
0, 0,
|
|
||||||
rectangles, n_rects,
|
|
||||||
YXBanded);
|
|
||||||
|
|
||||||
g_free (rectangles);
|
|
||||||
return screen->subwindow_gcs[depth];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
_gdk_x11_window_translate (GdkWindow *window,
|
|
||||||
cairo_region_t *area,
|
|
||||||
gint dx,
|
|
||||||
gint dy)
|
|
||||||
{
|
|
||||||
GdkWindowQueueItem *item;
|
|
||||||
GC xgc;
|
|
||||||
GdkRectangle extents;
|
|
||||||
|
|
||||||
cairo_region_get_extents (area, &extents);
|
|
||||||
|
|
||||||
xgc = _get_scratch_gc (window, area);
|
|
||||||
|
|
||||||
cairo_region_translate (area, -dx, -dy); /* Move to source region */
|
|
||||||
|
|
||||||
item = g_new (GdkWindowQueueItem, 1);
|
|
||||||
item->type = GDK_WINDOW_QUEUE_TRANSLATE;
|
|
||||||
item->u.translate.area = cairo_region_copy (area);
|
|
||||||
item->u.translate.dx = dx;
|
|
||||||
item->u.translate.dy = dy;
|
|
||||||
gdk_window_queue (window, item);
|
|
||||||
|
|
||||||
XCopyArea (GDK_WINDOW_XDISPLAY (window),
|
|
||||||
GDK_WINDOW_XID (window),
|
|
||||||
GDK_WINDOW_XID (window),
|
|
||||||
xgc,
|
|
||||||
extents.x - dx, extents.y - dy,
|
|
||||||
extents.width, extents.height,
|
|
||||||
extents.x, extents.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
_gdk_x11_window_queue_antiexpose (GdkWindow *window,
|
_gdk_x11_window_queue_antiexpose (GdkWindow *window,
|
||||||
cairo_region_t *area)
|
cairo_region_t *area)
|
||||||
{
|
{
|
||||||
GdkWindowQueueItem *item = g_new (GdkWindowQueueItem, 1);
|
GdkWindowQueueItem *item = g_new (GdkWindowQueueItem, 1);
|
||||||
item->type = GDK_WINDOW_QUEUE_ANTIEXPOSE;
|
item->antiexpose_area = area;
|
||||||
item->u.antiexpose.area = area;
|
|
||||||
|
|
||||||
gdk_window_queue (window, item);
|
gdk_window_queue (window, item);
|
||||||
|
|
||||||
@@ -339,28 +240,7 @@ _gdk_x11_window_process_expose (GdkWindow *window,
|
|||||||
if (serial - item->serial > (gulong) G_MAXLONG)
|
if (serial - item->serial > (gulong) G_MAXLONG)
|
||||||
{
|
{
|
||||||
if (item->window == window)
|
if (item->window == window)
|
||||||
{
|
cairo_region_subtract (invalidate_region, item->antiexpose_area);
|
||||||
if (item->type == GDK_WINDOW_QUEUE_TRANSLATE)
|
|
||||||
{
|
|
||||||
if (item->u.translate.area)
|
|
||||||
{
|
|
||||||
cairo_region_t *intersection;
|
|
||||||
|
|
||||||
intersection = cairo_region_copy (invalidate_region);
|
|
||||||
cairo_region_intersect (intersection, item->u.translate.area);
|
|
||||||
cairo_region_subtract (invalidate_region, intersection);
|
|
||||||
cairo_region_translate (intersection, item->u.translate.dx, item->u.translate.dy);
|
|
||||||
cairo_region_union (invalidate_region, intersection);
|
|
||||||
cairo_region_destroy (intersection);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
cairo_region_translate (invalidate_region, item->u.translate.dx, item->u.translate.dy);
|
|
||||||
}
|
|
||||||
else /* anti-expose */
|
|
||||||
{
|
|
||||||
cairo_region_subtract (invalidate_region, item->u.antiexpose.area);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5334,7 +5334,6 @@ gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass)
|
|||||||
impl_class->input_shape_combine_region = gdk_window_x11_input_shape_combine_region;
|
impl_class->input_shape_combine_region = gdk_window_x11_input_shape_combine_region;
|
||||||
impl_class->set_static_gravities = gdk_window_x11_set_static_gravities;
|
impl_class->set_static_gravities = gdk_window_x11_set_static_gravities;
|
||||||
impl_class->queue_antiexpose = _gdk_x11_window_queue_antiexpose;
|
impl_class->queue_antiexpose = _gdk_x11_window_queue_antiexpose;
|
||||||
impl_class->translate = _gdk_x11_window_translate;
|
|
||||||
impl_class->destroy = gdk_x11_window_destroy;
|
impl_class->destroy = gdk_x11_window_destroy;
|
||||||
impl_class->destroy_foreign = gdk_x11_window_destroy_foreign;
|
impl_class->destroy_foreign = gdk_x11_window_destroy_foreign;
|
||||||
impl_class->resize_cairo_surface = gdk_window_x11_resize_cairo_surface;
|
impl_class->resize_cairo_surface = gdk_window_x11_resize_cairo_surface;
|
||||||
|
|||||||
@@ -519,6 +519,7 @@ gtk_private_h_sources = \
|
|||||||
gtkprintoperation-private.h \
|
gtkprintoperation-private.h \
|
||||||
gtkprintutils.h \
|
gtkprintutils.h \
|
||||||
gtkprivate.h \
|
gtkprivate.h \
|
||||||
|
gtkpixelcacheprivate.h \
|
||||||
gtkquery.h \
|
gtkquery.h \
|
||||||
gtkrbtree.h \
|
gtkrbtree.h \
|
||||||
gtkrecentchooserdefault.h \
|
gtkrecentchooserdefault.h \
|
||||||
@@ -800,6 +801,7 @@ gtk_base_c_sources = \
|
|||||||
gtkprivate.c \
|
gtkprivate.c \
|
||||||
gtkprivatetypebuiltins.c \
|
gtkprivatetypebuiltins.c \
|
||||||
gtkprogressbar.c \
|
gtkprogressbar.c \
|
||||||
|
gtkpixelcache.c \
|
||||||
gtkradioaction.c \
|
gtkradioaction.c \
|
||||||
gtkradiobutton.c \
|
gtkradiobutton.c \
|
||||||
gtkradiomenuitem.c \
|
gtkradiomenuitem.c \
|
||||||
|
|||||||
@@ -3365,7 +3365,7 @@ gtk_container_propagate_draw (GtkContainer *container,
|
|||||||
{
|
{
|
||||||
GdkEventExpose *event;
|
GdkEventExpose *event;
|
||||||
GtkAllocation allocation;
|
GtkAllocation allocation;
|
||||||
GdkWindow *window, *w;
|
GdkWindow *window, *w, *event_window, *child_in_window;
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
g_return_if_fail (GTK_IS_CONTAINER (container));
|
g_return_if_fail (GTK_IS_CONTAINER (container));
|
||||||
@@ -3374,13 +3374,26 @@ gtk_container_propagate_draw (GtkContainer *container,
|
|||||||
|
|
||||||
g_assert (gtk_widget_get_parent (child) == GTK_WIDGET (container));
|
g_assert (gtk_widget_get_parent (child) == GTK_WIDGET (container));
|
||||||
|
|
||||||
|
if (!gtk_widget_is_drawable (child))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Only propagate to native child window if we're not handling
|
||||||
|
an expose (i.e. in a pure gtk_widget_draw() call */
|
||||||
event = _gtk_cairo_get_event (cr);
|
event = _gtk_cairo_get_event (cr);
|
||||||
if (event)
|
if (event &&
|
||||||
{
|
(gtk_widget_get_has_window (child) &&
|
||||||
if (gtk_widget_get_has_window (child) ||
|
gdk_window_has_native (gtk_widget_get_window (child))))
|
||||||
gtk_widget_get_window (child) != event->window)
|
return;
|
||||||
return;
|
|
||||||
}
|
/* Never propagate to a child window when exposing a window
|
||||||
|
that is not the one the child widget is in. */
|
||||||
|
event_window = _gtk_cairo_get_event_window (cr);
|
||||||
|
if (gtk_widget_get_has_window (child))
|
||||||
|
child_in_window = gdk_window_get_parent (gtk_widget_get_window (child));
|
||||||
|
else
|
||||||
|
child_in_window = gtk_widget_get_window (child);
|
||||||
|
if (event_window != NULL && child_in_window != event_window)
|
||||||
|
return;
|
||||||
|
|
||||||
cairo_save (cr);
|
cairo_save (cr);
|
||||||
|
|
||||||
@@ -3422,7 +3435,7 @@ gtk_container_propagate_draw (GtkContainer *container,
|
|||||||
|
|
||||||
cairo_translate (cr, x, y);
|
cairo_translate (cr, x, y);
|
||||||
|
|
||||||
_gtk_widget_draw_internal (child, cr, TRUE);
|
_gtk_widget_draw (child, cr);
|
||||||
|
|
||||||
cairo_restore (cr);
|
cairo_restore (cr);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,8 @@ typedef enum {
|
|||||||
GTK_DEBUG_BUILDER = 1 << 11,
|
GTK_DEBUG_BUILDER = 1 << 11,
|
||||||
GTK_DEBUG_SIZE_REQUEST = 1 << 12,
|
GTK_DEBUG_SIZE_REQUEST = 1 << 12,
|
||||||
GTK_DEBUG_NO_CSS_CACHE = 1 << 13,
|
GTK_DEBUG_NO_CSS_CACHE = 1 << 13,
|
||||||
GTK_DEBUG_BASELINES = 1 << 14
|
GTK_DEBUG_BASELINES = 1 << 14,
|
||||||
|
GTK_DEBUG_PIXEL_CACHE = 1 << 15
|
||||||
} GtkDebugFlag;
|
} GtkDebugFlag;
|
||||||
|
|
||||||
#ifdef G_ENABLE_DEBUG
|
#ifdef G_ENABLE_DEBUG
|
||||||
|
|||||||
@@ -172,7 +172,8 @@ static const GDebugKey gtk_debug_keys[] = {
|
|||||||
{"builder", GTK_DEBUG_BUILDER},
|
{"builder", GTK_DEBUG_BUILDER},
|
||||||
{"size-request", GTK_DEBUG_SIZE_REQUEST},
|
{"size-request", GTK_DEBUG_SIZE_REQUEST},
|
||||||
{"no-css-cache", GTK_DEBUG_NO_CSS_CACHE},
|
{"no-css-cache", GTK_DEBUG_NO_CSS_CACHE},
|
||||||
{"baselines", GTK_DEBUG_BASELINES}
|
{"baselines", GTK_DEBUG_BASELINES},
|
||||||
|
{"pixel-cache", GTK_DEBUG_PIXEL_CACHE}
|
||||||
};
|
};
|
||||||
#endif /* G_ENABLE_DEBUG */
|
#endif /* G_ENABLE_DEBUG */
|
||||||
|
|
||||||
@@ -1615,9 +1616,17 @@ gtk_main_do_event (GdkEvent *event)
|
|||||||
case GDK_EXPOSE:
|
case GDK_EXPOSE:
|
||||||
if (event->any.window && gtk_widget_get_double_buffered (event_widget))
|
if (event->any.window && gtk_widget_get_double_buffered (event_widget))
|
||||||
{
|
{
|
||||||
gdk_window_begin_paint_region (event->any.window, event->expose.region);
|
/* We handle exposes only on native windows, relying on the
|
||||||
gtk_widget_send_expose (event_widget, event);
|
* draw() handler to propagate down to non-native windows.
|
||||||
gdk_window_end_paint (event->any.window);
|
* This is ok now that we child windows always are considered
|
||||||
|
* (semi)transparent.
|
||||||
|
*/
|
||||||
|
if (gdk_window_has_native (event->expose.window))
|
||||||
|
{
|
||||||
|
gdk_window_begin_paint_region (event->any.window, event->expose.region);
|
||||||
|
gtk_widget_send_expose (event_widget, event);
|
||||||
|
gdk_window_end_paint (event->any.window);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
362
gtk/gtkpixelcache.c
Normal file
362
gtk/gtkpixelcache.c
Normal file
@@ -0,0 +1,362 @@
|
|||||||
|
/* GTK - The GIMP Toolkit
|
||||||
|
* Copyright (C) 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 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "gtkdebug.h"
|
||||||
|
#include "gtkpixelcacheprivate.h"
|
||||||
|
|
||||||
|
/* The extra size of the offscreen surface we allocate
|
||||||
|
to make scrolling more efficient */
|
||||||
|
#define EXTRA_SIZE 64
|
||||||
|
|
||||||
|
/* When resizing viewport to smaller we allow this extra
|
||||||
|
size to avoid constantly reallocating when resizing */
|
||||||
|
#define ALLOW_LARGER_SIZE 32
|
||||||
|
|
||||||
|
struct _GtkPixelCache {
|
||||||
|
cairo_surface_t *surface;
|
||||||
|
|
||||||
|
/* Valid if surface != NULL */
|
||||||
|
int surface_x;
|
||||||
|
int surface_y;
|
||||||
|
int surface_w;
|
||||||
|
int surface_h;
|
||||||
|
|
||||||
|
/* may be null if not dirty */
|
||||||
|
cairo_region_t *surface_dirty;
|
||||||
|
};
|
||||||
|
|
||||||
|
GtkPixelCache *
|
||||||
|
_gtk_pixel_cache_new ()
|
||||||
|
{
|
||||||
|
GtkPixelCache *cache;
|
||||||
|
|
||||||
|
cache = g_new0 (GtkPixelCache, 1);
|
||||||
|
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gtk_pixel_cache_free (GtkPixelCache *cache)
|
||||||
|
{
|
||||||
|
if (cache == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (cache->surface != NULL)
|
||||||
|
cairo_surface_destroy (cache->surface);
|
||||||
|
|
||||||
|
if (cache->surface_dirty != NULL)
|
||||||
|
cairo_region_destroy (cache->surface_dirty);
|
||||||
|
|
||||||
|
g_free (cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Region is in canvas coordinates */
|
||||||
|
void
|
||||||
|
_gtk_pixel_cache_invalidate (GtkPixelCache *cache,
|
||||||
|
cairo_region_t *region)
|
||||||
|
{
|
||||||
|
cairo_rectangle_int_t r;
|
||||||
|
cairo_region_t *free_region = NULL;
|
||||||
|
|
||||||
|
if (cache->surface == NULL ||
|
||||||
|
(region != NULL && cairo_region_is_empty (region)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (region == NULL)
|
||||||
|
{
|
||||||
|
r.x = cache->surface_x;
|
||||||
|
r.y = cache->surface_y;
|
||||||
|
r.width = cache->surface_w;
|
||||||
|
r.height = cache->surface_h;
|
||||||
|
|
||||||
|
free_region = region =
|
||||||
|
cairo_region_create_rectangle (&r);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cache->surface_dirty == NULL)
|
||||||
|
{
|
||||||
|
cache->surface_dirty = cairo_region_copy (region);
|
||||||
|
cairo_region_translate (cache->surface_dirty,
|
||||||
|
-cache->surface_x,
|
||||||
|
-cache->surface_y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cairo_region_translate (region,
|
||||||
|
-cache->surface_x,
|
||||||
|
-cache->surface_y);
|
||||||
|
cairo_region_union (cache->surface_dirty, region);
|
||||||
|
cairo_region_translate (region,
|
||||||
|
cache->surface_x,
|
||||||
|
cache->surface_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (free_region)
|
||||||
|
cairo_region_destroy (free_region);
|
||||||
|
|
||||||
|
r.x = 0;
|
||||||
|
r.y = 0;
|
||||||
|
r.width = cache->surface_w;
|
||||||
|
r.height = cache->surface_h;
|
||||||
|
|
||||||
|
cairo_region_intersect_rectangle (cache->surface_dirty, &r);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_gtk_pixel_cache_create_surface_if_needed (GtkPixelCache *cache,
|
||||||
|
GdkWindow *window,
|
||||||
|
cairo_rectangle_int_t *view_rect,
|
||||||
|
cairo_rectangle_int_t *canvas_rect)
|
||||||
|
{
|
||||||
|
cairo_rectangle_int_t rect;
|
||||||
|
int surface_w, surface_h;
|
||||||
|
cairo_content_t content;
|
||||||
|
cairo_pattern_t *bg;
|
||||||
|
double red, green, blue, alpha;
|
||||||
|
|
||||||
|
content = CAIRO_CONTENT_COLOR_ALPHA;
|
||||||
|
bg = gdk_window_get_background_pattern (window);
|
||||||
|
if (bg != NULL &&
|
||||||
|
cairo_pattern_get_type (bg) == CAIRO_PATTERN_TYPE_SOLID &&
|
||||||
|
cairo_pattern_get_rgba (bg, &red, &green, &blue, &alpha) == CAIRO_STATUS_SUCCESS &&
|
||||||
|
alpha == 1.0)
|
||||||
|
content = CAIRO_CONTENT_COLOR;
|
||||||
|
|
||||||
|
surface_w = view_rect->width;
|
||||||
|
if (canvas_rect->width > surface_w)
|
||||||
|
surface_w = MIN (surface_w + EXTRA_SIZE, canvas_rect->width);
|
||||||
|
|
||||||
|
surface_h = view_rect->height;
|
||||||
|
if (canvas_rect->height > surface_h)
|
||||||
|
surface_h = MIN (surface_h + EXTRA_SIZE, canvas_rect->height);
|
||||||
|
|
||||||
|
/* If current surface can't fit view_rect or is too large, kill it */
|
||||||
|
if (cache->surface != NULL &&
|
||||||
|
(cairo_surface_get_content (cache->surface) != content ||
|
||||||
|
cache->surface_w < view_rect->width ||
|
||||||
|
cache->surface_w > surface_w + ALLOW_LARGER_SIZE ||
|
||||||
|
cache->surface_h < view_rect->height ||
|
||||||
|
cache->surface_h > surface_h + ALLOW_LARGER_SIZE))
|
||||||
|
{
|
||||||
|
cairo_surface_destroy (cache->surface);
|
||||||
|
cache->surface = NULL;
|
||||||
|
if (cache->surface_dirty)
|
||||||
|
cairo_region_destroy (cache->surface_dirty);
|
||||||
|
cache->surface_dirty = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Don't allocate a surface if view >= canvas, as we won't
|
||||||
|
be scrolling then anyway */
|
||||||
|
if (cache->surface == NULL &&
|
||||||
|
(view_rect->width < canvas_rect->width ||
|
||||||
|
view_rect->height < canvas_rect->height))
|
||||||
|
{
|
||||||
|
cache->surface_x = -canvas_rect->x;
|
||||||
|
cache->surface_y = -canvas_rect->y;
|
||||||
|
cache->surface_w = surface_w;
|
||||||
|
cache->surface_h = surface_h;
|
||||||
|
|
||||||
|
cache->surface =
|
||||||
|
gdk_window_create_similar_surface (window, content,
|
||||||
|
surface_w, surface_h);
|
||||||
|
rect.x = 0;
|
||||||
|
rect.y = 0;
|
||||||
|
rect.width = surface_w;
|
||||||
|
rect.height = surface_h;
|
||||||
|
cache->surface_dirty =
|
||||||
|
cairo_region_create_rectangle (&rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gtk_pixel_cache_set_position (GtkPixelCache *cache,
|
||||||
|
cairo_rectangle_int_t *view_rect,
|
||||||
|
cairo_rectangle_int_t *canvas_rect)
|
||||||
|
{
|
||||||
|
cairo_rectangle_int_t r, view_pos;
|
||||||
|
cairo_region_t *copy_region;
|
||||||
|
int new_surf_x, new_surf_y;
|
||||||
|
cairo_t *backing_cr;
|
||||||
|
|
||||||
|
if (cache->surface == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Position of view inside canvas */
|
||||||
|
view_pos.x = -canvas_rect->x;
|
||||||
|
view_pos.y = -canvas_rect->y;
|
||||||
|
view_pos.width = view_rect->width;
|
||||||
|
view_pos.height = view_rect->height;
|
||||||
|
|
||||||
|
/* Reposition so all is visible */
|
||||||
|
if (view_pos.x < cache->surface_x ||
|
||||||
|
view_pos.x + view_pos.width >
|
||||||
|
cache->surface_x + cache->surface_w ||
|
||||||
|
view_pos.y < cache->surface_y ||
|
||||||
|
view_pos.y + view_pos.height >
|
||||||
|
cache->surface_y + cache->surface_h)
|
||||||
|
{
|
||||||
|
new_surf_x = cache->surface_x;
|
||||||
|
if (view_pos.x < cache->surface_x)
|
||||||
|
new_surf_x = MAX (view_pos.x + view_pos.width - cache->surface_w, 0);
|
||||||
|
else if (view_pos.x + view_pos.width >
|
||||||
|
cache->surface_x + cache->surface_w)
|
||||||
|
new_surf_x = MIN (view_pos.x, canvas_rect->width - cache->surface_w);
|
||||||
|
|
||||||
|
new_surf_y = cache->surface_y;
|
||||||
|
if (view_pos.y < cache->surface_y)
|
||||||
|
new_surf_y = MAX (view_pos.y + view_pos.height - cache->surface_h, 0);
|
||||||
|
else if (view_pos.y + view_pos.height >
|
||||||
|
cache->surface_y + cache->surface_h)
|
||||||
|
new_surf_y = MIN (view_pos.y, canvas_rect->height - cache->surface_h);
|
||||||
|
|
||||||
|
r.x = 0;
|
||||||
|
r.y = 0;
|
||||||
|
r.width = cache->surface_w;
|
||||||
|
r.height = cache->surface_h;
|
||||||
|
copy_region = cairo_region_create_rectangle (&r);
|
||||||
|
|
||||||
|
if (cache->surface_dirty)
|
||||||
|
{
|
||||||
|
cairo_region_subtract (copy_region, cache->surface_dirty);
|
||||||
|
cairo_region_destroy (cache->surface_dirty);
|
||||||
|
cache->surface_dirty = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_region_translate (copy_region,
|
||||||
|
cache->surface_x - new_surf_x,
|
||||||
|
cache->surface_y - new_surf_y);
|
||||||
|
cairo_region_intersect_rectangle (copy_region, &r);
|
||||||
|
|
||||||
|
backing_cr = cairo_create (cache->surface);
|
||||||
|
gdk_cairo_region (backing_cr, copy_region);
|
||||||
|
cairo_set_operator (backing_cr, CAIRO_OPERATOR_SOURCE);
|
||||||
|
cairo_clip (backing_cr);
|
||||||
|
cairo_push_group (backing_cr);
|
||||||
|
cairo_set_source_surface (backing_cr, cache->surface,
|
||||||
|
cache->surface_x - new_surf_x,
|
||||||
|
cache->surface_y - new_surf_y);
|
||||||
|
cairo_paint (backing_cr);
|
||||||
|
cairo_pop_group_to_source (backing_cr);
|
||||||
|
cairo_paint (backing_cr);
|
||||||
|
cairo_destroy (backing_cr);
|
||||||
|
|
||||||
|
cache->surface_x = new_surf_x;
|
||||||
|
cache->surface_y = new_surf_y;
|
||||||
|
|
||||||
|
cairo_region_xor_rectangle (copy_region, &r);
|
||||||
|
cache->surface_dirty = copy_region;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gtk_pixel_cache_repaint (GtkPixelCache *cache,
|
||||||
|
GtkPixelCacheDrawFunc draw,
|
||||||
|
cairo_rectangle_int_t *view_rect,
|
||||||
|
cairo_rectangle_int_t *canvas_rect,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
cairo_t *backing_cr;
|
||||||
|
|
||||||
|
if (cache->surface &&
|
||||||
|
cache->surface_dirty &&
|
||||||
|
!cairo_region_is_empty (cache->surface_dirty))
|
||||||
|
{
|
||||||
|
backing_cr = cairo_create (cache->surface);
|
||||||
|
gdk_cairo_region (backing_cr, cache->surface_dirty);
|
||||||
|
cairo_clip (backing_cr);
|
||||||
|
cairo_translate (backing_cr,
|
||||||
|
-cache->surface_x - canvas_rect->x - view_rect->x,
|
||||||
|
-cache->surface_y - canvas_rect->y - view_rect->y);
|
||||||
|
cairo_set_source_rgba (backing_cr,
|
||||||
|
0.0, 0, 0, 0.0);
|
||||||
|
cairo_set_operator (backing_cr, CAIRO_OPERATOR_SOURCE);
|
||||||
|
cairo_paint (backing_cr);
|
||||||
|
|
||||||
|
cairo_set_operator (backing_cr, CAIRO_OPERATOR_OVER);
|
||||||
|
|
||||||
|
cairo_save (backing_cr);
|
||||||
|
draw (backing_cr, user_data);
|
||||||
|
cairo_restore (backing_cr);
|
||||||
|
|
||||||
|
#ifdef G_ENABLE_DEBUG
|
||||||
|
if (gtk_get_debug_flags () & GTK_DEBUG_PIXEL_CACHE)
|
||||||
|
{
|
||||||
|
GdkRGBA colors[] = {
|
||||||
|
{ 1, 0, 0, 0.08},
|
||||||
|
{ 0, 1, 0, 0.08},
|
||||||
|
{ 0, 0, 1, 0.08},
|
||||||
|
{ 1, 0, 1, 0.08},
|
||||||
|
{ 1, 1, 0, 0.08},
|
||||||
|
{ 0, 1, 1, 0.08},
|
||||||
|
};
|
||||||
|
static int current_color = 0;
|
||||||
|
|
||||||
|
gdk_cairo_set_source_rgba (backing_cr, &colors[(current_color++) % G_N_ELEMENTS (colors)]);
|
||||||
|
cairo_paint (backing_cr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
cairo_destroy (backing_cr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cache->surface_dirty)
|
||||||
|
{
|
||||||
|
cairo_region_destroy (cache->surface_dirty);
|
||||||
|
cache->surface_dirty = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gtk_pixel_cache_draw (GtkPixelCache *cache,
|
||||||
|
cairo_t *cr,
|
||||||
|
GdkWindow *window,
|
||||||
|
/* View position in widget coords */
|
||||||
|
cairo_rectangle_int_t *view_rect,
|
||||||
|
/* Size and position of canvas in view coords */
|
||||||
|
cairo_rectangle_int_t *canvas_rect,
|
||||||
|
GtkPixelCacheDrawFunc draw,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
_gtk_pixel_cache_create_surface_if_needed (cache, window,
|
||||||
|
view_rect, canvas_rect);
|
||||||
|
_gtk_pixel_cache_set_position (cache, view_rect, canvas_rect);
|
||||||
|
_gtk_pixel_cache_repaint (cache, draw, view_rect, canvas_rect, user_data);
|
||||||
|
|
||||||
|
if (cache->surface &&
|
||||||
|
/* Don't use backing surface if rendering elsewhere */
|
||||||
|
cairo_surface_get_type (cache->surface) == cairo_surface_get_type (cairo_get_target (cr)))
|
||||||
|
{
|
||||||
|
cairo_save (cr);
|
||||||
|
cairo_set_source_surface (cr, cache->surface,
|
||||||
|
cache->surface_x + view_rect->x + canvas_rect->x,
|
||||||
|
cache->surface_y + view_rect->y + canvas_rect->y);
|
||||||
|
cairo_rectangle (cr, view_rect->x, view_rect->y,
|
||||||
|
view_rect->width, view_rect->height);
|
||||||
|
cairo_fill (cr);
|
||||||
|
cairo_restore (cr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cairo_rectangle (cr,
|
||||||
|
view_rect->x, view_rect->y,
|
||||||
|
view_rect->width, view_rect->height);
|
||||||
|
cairo_clip (cr);
|
||||||
|
draw (cr, user_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
48
gtk/gtkpixelcacheprivate.h
Normal file
48
gtk/gtkpixelcacheprivate.h
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* 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_PIXEL_CACHE_PRIVATE_H__
|
||||||
|
#define __GTK_PIXEL_CACHE_PRIVATE_H__
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <gtkwidget.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
typedef struct _GtkPixelCache GtkPixelCache;
|
||||||
|
|
||||||
|
typedef void (*GtkPixelCacheDrawFunc) (cairo_t *cr,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
|
GtkPixelCache *_gtk_pixel_cache_new (void);
|
||||||
|
void _gtk_pixel_cache_free (GtkPixelCache *cache);
|
||||||
|
void _gtk_pixel_cache_invalidate (GtkPixelCache *cache,
|
||||||
|
cairo_region_t *region);
|
||||||
|
void _gtk_pixel_cache_draw (GtkPixelCache *cache,
|
||||||
|
cairo_t *cr,
|
||||||
|
GdkWindow *window,
|
||||||
|
cairo_rectangle_int_t *view_rect,
|
||||||
|
cairo_rectangle_int_t *canvas_rect,
|
||||||
|
GtkPixelCacheDrawFunc draw,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GTK_PIXEL_CACHE_PRIVATE_H__ */
|
||||||
@@ -53,6 +53,7 @@
|
|||||||
#include "gtkmain.h"
|
#include "gtkmain.h"
|
||||||
#include "gtksettings.h"
|
#include "gtksettings.h"
|
||||||
#include "gtkwidgetpath.h"
|
#include "gtkwidgetpath.h"
|
||||||
|
#include "gtkpixelcacheprivate.h"
|
||||||
#include "a11y/gtktreeviewaccessibleprivate.h"
|
#include "a11y/gtktreeviewaccessibleprivate.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -304,6 +305,8 @@ struct _GtkTreeViewPrivate
|
|||||||
GdkWindow *bin_window;
|
GdkWindow *bin_window;
|
||||||
GdkWindow *header_window;
|
GdkWindow *header_window;
|
||||||
|
|
||||||
|
GtkPixelCache *pixel_cache;
|
||||||
|
|
||||||
/* Scroll position state keeping */
|
/* Scroll position state keeping */
|
||||||
GtkTreeRowReference *top_row;
|
GtkTreeRowReference *top_row;
|
||||||
gint top_row_dy;
|
gint top_row_dy;
|
||||||
@@ -492,6 +495,8 @@ struct _GtkTreeViewPrivate
|
|||||||
|
|
||||||
guint in_grab : 1;
|
guint in_grab : 1;
|
||||||
|
|
||||||
|
guint in_scroll : 1;
|
||||||
|
|
||||||
/* Whether our key press handler is to avoid sending an unhandled binding to the search entry */
|
/* Whether our key press handler is to avoid sending an unhandled binding to the search entry */
|
||||||
guint search_entry_avoid_unhandled_binding : 1;
|
guint search_entry_avoid_unhandled_binding : 1;
|
||||||
|
|
||||||
@@ -794,6 +799,8 @@ static void gtk_tree_view_stop_rubber_band (GtkTreeView
|
|||||||
static void update_prelight (GtkTreeView *tree_view,
|
static void update_prelight (GtkTreeView *tree_view,
|
||||||
int x,
|
int x,
|
||||||
int y);
|
int y);
|
||||||
|
static void gtk_tree_view_queue_draw_region (GtkWidget *widget,
|
||||||
|
const cairo_region_t *region);
|
||||||
|
|
||||||
static inline gint gtk_tree_view_get_effective_header_height (GtkTreeView *tree_view);
|
static inline gint gtk_tree_view_get_effective_header_height (GtkTreeView *tree_view);
|
||||||
|
|
||||||
@@ -960,6 +967,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
|
|||||||
widget_class->style_updated = gtk_tree_view_style_updated;
|
widget_class->style_updated = gtk_tree_view_style_updated;
|
||||||
widget_class->grab_notify = gtk_tree_view_grab_notify;
|
widget_class->grab_notify = gtk_tree_view_grab_notify;
|
||||||
widget_class->state_flags_changed = gtk_tree_view_state_flags_changed;
|
widget_class->state_flags_changed = gtk_tree_view_state_flags_changed;
|
||||||
|
widget_class->queue_draw_region = gtk_tree_view_queue_draw_region;
|
||||||
|
|
||||||
/* GtkContainer signals */
|
/* GtkContainer signals */
|
||||||
container_class->remove = gtk_tree_view_remove;
|
container_class->remove = gtk_tree_view_remove;
|
||||||
@@ -1730,6 +1738,8 @@ gtk_tree_view_init (GtkTreeView *tree_view)
|
|||||||
tree_view->priv->headers_visible = TRUE;
|
tree_view->priv->headers_visible = TRUE;
|
||||||
tree_view->priv->activate_on_single_click = FALSE;
|
tree_view->priv->activate_on_single_click = FALSE;
|
||||||
|
|
||||||
|
tree_view->priv->pixel_cache = _gtk_pixel_cache_new ();
|
||||||
|
|
||||||
/* We need some padding */
|
/* We need some padding */
|
||||||
tree_view->priv->dy = 0;
|
tree_view->priv->dy = 0;
|
||||||
tree_view->priv->cursor_offset = 0;
|
tree_view->priv->cursor_offset = 0;
|
||||||
@@ -2130,6 +2140,10 @@ gtk_tree_view_destroy (GtkWidget *widget)
|
|||||||
tree_view->priv->vadjustment = NULL;
|
tree_view->priv->vadjustment = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tree_view->priv->pixel_cache)
|
||||||
|
_gtk_pixel_cache_free (tree_view->priv->pixel_cache);
|
||||||
|
tree_view->priv->pixel_cache = NULL;
|
||||||
|
|
||||||
GTK_WIDGET_CLASS (gtk_tree_view_parent_class)->destroy (widget);
|
GTK_WIDGET_CLASS (gtk_tree_view_parent_class)->destroy (widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2217,6 +2231,47 @@ gtk_tree_view_ensure_background (GtkTreeView *tree_view)
|
|||||||
gtk_style_context_set_background (context, tree_view->priv->header_window);
|
gtk_style_context_set_background (context, tree_view->priv->header_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_tree_view_bin_window_invalidate_handler (GdkWindow *window,
|
||||||
|
cairo_region_t *region)
|
||||||
|
{
|
||||||
|
gpointer widget;
|
||||||
|
GtkTreeView *tree_view;
|
||||||
|
int y;
|
||||||
|
|
||||||
|
gdk_window_get_user_data (window, &widget);
|
||||||
|
tree_view = GTK_TREE_VIEW (widget);
|
||||||
|
|
||||||
|
/* Scrolling will invalidate everything in the bin window,
|
||||||
|
but we already have it in the cache, so we can ignore that */
|
||||||
|
if (tree_view->priv->in_scroll)
|
||||||
|
return;
|
||||||
|
|
||||||
|
y = gtk_adjustment_get_value (tree_view->priv->vadjustment);
|
||||||
|
cairo_region_translate (region,
|
||||||
|
0, y);
|
||||||
|
_gtk_pixel_cache_invalidate (tree_view->priv->pixel_cache, region);
|
||||||
|
cairo_region_translate (region,
|
||||||
|
0, -y);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_tree_view_queue_draw_region (GtkWidget *widget,
|
||||||
|
const cairo_region_t *region)
|
||||||
|
{
|
||||||
|
GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
|
||||||
|
|
||||||
|
/* There is no way we can know if a region targets the
|
||||||
|
not-currently-visible but in pixel cache region, so we
|
||||||
|
always just invalidate the whole thing whenever the
|
||||||
|
tree view gets a queue draw. This doesn't normally happen
|
||||||
|
in normal scrolling cases anyway. */
|
||||||
|
_gtk_pixel_cache_invalidate (tree_view->priv->pixel_cache, NULL);
|
||||||
|
|
||||||
|
GTK_WIDGET_CLASS (gtk_tree_view_parent_class)->queue_draw_region (widget,
|
||||||
|
region);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_tree_view_realize (GtkWidget *widget)
|
gtk_tree_view_realize (GtkWidget *widget)
|
||||||
{
|
{
|
||||||
@@ -2268,6 +2323,8 @@ gtk_tree_view_realize (GtkWidget *widget)
|
|||||||
tree_view->priv->bin_window = gdk_window_new (window,
|
tree_view->priv->bin_window = gdk_window_new (window,
|
||||||
&attributes, attributes_mask);
|
&attributes, attributes_mask);
|
||||||
gtk_widget_register_window (widget, tree_view->priv->bin_window);
|
gtk_widget_register_window (widget, tree_view->priv->bin_window);
|
||||||
|
gdk_window_set_invalidate_handler (tree_view->priv->bin_window,
|
||||||
|
gtk_tree_view_bin_window_invalidate_handler);
|
||||||
|
|
||||||
gtk_widget_get_allocation (widget, &allocation);
|
gtk_widget_get_allocation (widget, &allocation);
|
||||||
|
|
||||||
@@ -4769,8 +4826,6 @@ gtk_tree_view_bin_draw (GtkWidget *widget,
|
|||||||
|
|
||||||
bin_window_width = gdk_window_get_width (tree_view->priv->bin_window);
|
bin_window_width = gdk_window_get_width (tree_view->priv->bin_window);
|
||||||
bin_window_height = gdk_window_get_height (tree_view->priv->bin_window);
|
bin_window_height = gdk_window_get_height (tree_view->priv->bin_window);
|
||||||
cairo_rectangle (cr, 0, 0, bin_window_width, bin_window_height);
|
|
||||||
cairo_clip (cr);
|
|
||||||
if (!gdk_cairo_get_clip_rectangle (cr, &clip))
|
if (!gdk_cairo_get_clip_rectangle (cr, &clip))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
@@ -5368,6 +5423,35 @@ done:
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
draw_bin (cairo_t *cr,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GtkWidget *widget = GTK_WIDGET (user_data);
|
||||||
|
GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
|
||||||
|
GList *tmp_list;
|
||||||
|
|
||||||
|
cairo_save (cr);
|
||||||
|
|
||||||
|
gtk_cairo_transform_to_window (cr, widget, tree_view->priv->bin_window);
|
||||||
|
gtk_tree_view_bin_draw (widget, cr);
|
||||||
|
|
||||||
|
cairo_restore (cr);
|
||||||
|
|
||||||
|
/* We can't just chain up to Container::draw as it will try to send the
|
||||||
|
* event to the headers, so we handle propagating it to our children
|
||||||
|
* (eg. widgets being edited) ourselves.
|
||||||
|
*/
|
||||||
|
tmp_list = tree_view->priv->children;
|
||||||
|
while (tmp_list)
|
||||||
|
{
|
||||||
|
GtkTreeViewChild *child = tmp_list->data;
|
||||||
|
tmp_list = tmp_list->next;
|
||||||
|
|
||||||
|
gtk_container_propagate_draw (GTK_CONTAINER (tree_view), child->widget, cr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gtk_tree_view_draw (GtkWidget *widget,
|
gtk_tree_view_draw (GtkWidget *widget,
|
||||||
cairo_t *cr)
|
cairo_t *cr)
|
||||||
@@ -5384,27 +5468,22 @@ gtk_tree_view_draw (GtkWidget *widget,
|
|||||||
|
|
||||||
if (gtk_cairo_should_draw_window (cr, tree_view->priv->bin_window))
|
if (gtk_cairo_should_draw_window (cr, tree_view->priv->bin_window))
|
||||||
{
|
{
|
||||||
GList *tmp_list;
|
cairo_rectangle_int_t view_rect;
|
||||||
|
cairo_rectangle_int_t canvas_rect;
|
||||||
|
|
||||||
cairo_save (cr);
|
view_rect.x = 0;
|
||||||
|
view_rect.y = gtk_tree_view_get_effective_header_height (tree_view);
|
||||||
|
view_rect.width = gdk_window_get_width (tree_view->priv->bin_window);
|
||||||
|
view_rect.height = gdk_window_get_height (tree_view->priv->bin_window);
|
||||||
|
|
||||||
gtk_cairo_transform_to_window (cr, widget, tree_view->priv->bin_window);
|
gdk_window_get_position (tree_view->priv->bin_window, &canvas_rect.x, &canvas_rect.y);
|
||||||
gtk_tree_view_bin_draw (widget, cr);
|
canvas_rect.y = -gtk_adjustment_get_value (tree_view->priv->vadjustment);
|
||||||
|
canvas_rect.width = gdk_window_get_width (tree_view->priv->bin_window);
|
||||||
|
canvas_rect.height = tree_view->priv->height;
|
||||||
|
|
||||||
cairo_restore (cr);
|
_gtk_pixel_cache_draw (tree_view->priv->pixel_cache, cr, tree_view->priv->bin_window,
|
||||||
|
&view_rect, &canvas_rect,
|
||||||
/* We can't just chain up to Container::draw as it will try to send the
|
draw_bin, widget);
|
||||||
* event to the headers, so we handle propagating it to our children
|
|
||||||
* (eg. widgets being edited) ourselves.
|
|
||||||
*/
|
|
||||||
tmp_list = tree_view->priv->children;
|
|
||||||
while (tmp_list)
|
|
||||||
{
|
|
||||||
GtkTreeViewChild *child = tmp_list->data;
|
|
||||||
tmp_list = tmp_list->next;
|
|
||||||
|
|
||||||
gtk_container_propagate_draw (GTK_CONTAINER (tree_view), child->widget, cr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_style_context_save (context);
|
gtk_style_context_save (context);
|
||||||
@@ -5974,18 +6053,17 @@ gtk_tree_view_node_queue_redraw (GtkTreeView *tree_view,
|
|||||||
GtkRBTree *tree,
|
GtkRBTree *tree,
|
||||||
GtkRBNode *node)
|
GtkRBNode *node)
|
||||||
{
|
{
|
||||||
GtkAllocation allocation;
|
GdkRectangle rect;
|
||||||
gint y;
|
|
||||||
|
|
||||||
y = _gtk_rbtree_node_find_offset (tree, node)
|
rect.x = 0;
|
||||||
- gtk_adjustment_get_value (tree_view->priv->vadjustment)
|
rect.y =
|
||||||
+ gtk_tree_view_get_effective_header_height (tree_view);
|
_gtk_rbtree_node_find_offset (tree, node)
|
||||||
|
- gtk_adjustment_get_value (tree_view->priv->vadjustment);
|
||||||
|
rect.width = gtk_widget_get_allocated_width (GTK_WIDGET (tree_view));
|
||||||
|
rect.height = GTK_RBNODE_GET_HEIGHT (node);
|
||||||
|
|
||||||
gtk_widget_get_allocation (GTK_WIDGET (tree_view), &allocation);
|
gdk_window_invalidate_rect (tree_view->priv->bin_window,
|
||||||
gtk_widget_queue_draw_area (GTK_WIDGET (tree_view),
|
&rect, TRUE);
|
||||||
0, y,
|
|
||||||
allocation.width,
|
|
||||||
GTK_RBNODE_GET_HEIGHT (node));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@@ -11236,7 +11314,9 @@ gtk_tree_view_adjustment_changed (GtkAdjustment *adjustment,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
tree_view->priv->in_scroll = TRUE;
|
||||||
gdk_window_scroll (tree_view->priv->bin_window, 0, dy);
|
gdk_window_scroll (tree_view->priv->bin_window, 0, dy);
|
||||||
|
tree_view->priv->in_scroll = FALSE;
|
||||||
|
|
||||||
if (tree_view->priv->dy != (int) gtk_adjustment_get_value (tree_view->priv->vadjustment))
|
if (tree_view->priv->dy != (int) gtk_adjustment_get_value (tree_view->priv->vadjustment))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
#include "gtkprivate.h"
|
#include "gtkprivate.h"
|
||||||
#include "gtkscrollable.h"
|
#include "gtkscrollable.h"
|
||||||
#include "gtktypebuiltins.h"
|
#include "gtktypebuiltins.h"
|
||||||
|
#include "gtkpixelcacheprivate.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -66,6 +67,8 @@ struct _GtkViewportPrivate
|
|||||||
GdkWindow *bin_window;
|
GdkWindow *bin_window;
|
||||||
GdkWindow *view_window;
|
GdkWindow *view_window;
|
||||||
|
|
||||||
|
GtkPixelCache *pixel_cache;
|
||||||
|
|
||||||
/* GtkScrollablePolicy needs to be checked when
|
/* GtkScrollablePolicy needs to be checked when
|
||||||
* driving the scrollable adjustment values */
|
* driving the scrollable adjustment values */
|
||||||
guint hscroll_policy : 1;
|
guint hscroll_policy : 1;
|
||||||
@@ -249,6 +252,8 @@ gtk_viewport_init (GtkViewport *viewport)
|
|||||||
priv->hadjustment = NULL;
|
priv->hadjustment = NULL;
|
||||||
priv->vadjustment = NULL;
|
priv->vadjustment = NULL;
|
||||||
|
|
||||||
|
priv->pixel_cache = _gtk_pixel_cache_new ();
|
||||||
|
|
||||||
viewport_set_adjustment (viewport, GTK_ORIENTATION_HORIZONTAL, NULL);
|
viewport_set_adjustment (viewport, GTK_ORIENTATION_HORIZONTAL, NULL);
|
||||||
viewport_set_adjustment (viewport, GTK_ORIENTATION_VERTICAL, NULL);
|
viewport_set_adjustment (viewport, GTK_ORIENTATION_VERTICAL, NULL);
|
||||||
}
|
}
|
||||||
@@ -301,10 +306,15 @@ static void
|
|||||||
gtk_viewport_destroy (GtkWidget *widget)
|
gtk_viewport_destroy (GtkWidget *widget)
|
||||||
{
|
{
|
||||||
GtkViewport *viewport = GTK_VIEWPORT (widget);
|
GtkViewport *viewport = GTK_VIEWPORT (widget);
|
||||||
|
GtkViewportPrivate *priv = viewport->priv;
|
||||||
|
|
||||||
viewport_disconnect_adjustment (viewport, GTK_ORIENTATION_HORIZONTAL);
|
viewport_disconnect_adjustment (viewport, GTK_ORIENTATION_HORIZONTAL);
|
||||||
viewport_disconnect_adjustment (viewport, GTK_ORIENTATION_VERTICAL);
|
viewport_disconnect_adjustment (viewport, GTK_ORIENTATION_VERTICAL);
|
||||||
|
|
||||||
|
if (priv->pixel_cache)
|
||||||
|
_gtk_pixel_cache_free (priv->pixel_cache);
|
||||||
|
priv->pixel_cache = NULL;
|
||||||
|
|
||||||
GTK_WIDGET_CLASS (gtk_viewport_parent_class)->destroy (widget);
|
GTK_WIDGET_CLASS (gtk_viewport_parent_class)->destroy (widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -649,6 +659,21 @@ gtk_viewport_get_view_window (GtkViewport *viewport)
|
|||||||
return viewport->priv->view_window;
|
return viewport->priv->view_window;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_viewport_bin_window_invalidate_handler (GdkWindow *window,
|
||||||
|
cairo_region_t *region)
|
||||||
|
{
|
||||||
|
gpointer widget;
|
||||||
|
GtkViewport *viewport;
|
||||||
|
GtkViewportPrivate *priv;
|
||||||
|
|
||||||
|
gdk_window_get_user_data (window, &widget);
|
||||||
|
viewport = GTK_VIEWPORT (widget);
|
||||||
|
priv = viewport->priv;
|
||||||
|
|
||||||
|
_gtk_pixel_cache_invalidate (priv->pixel_cache, region);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_viewport_realize (GtkWidget *widget)
|
gtk_viewport_realize (GtkWidget *widget)
|
||||||
{
|
{
|
||||||
@@ -713,6 +738,8 @@ gtk_viewport_realize (GtkWidget *widget)
|
|||||||
|
|
||||||
priv->bin_window = gdk_window_new (priv->view_window, &attributes, attributes_mask);
|
priv->bin_window = gdk_window_new (priv->view_window, &attributes, attributes_mask);
|
||||||
gtk_widget_register_window (widget, priv->bin_window);
|
gtk_widget_register_window (widget, priv->bin_window);
|
||||||
|
gdk_window_set_invalidate_handler (priv->bin_window,
|
||||||
|
gtk_viewport_bin_window_invalidate_handler);
|
||||||
|
|
||||||
child = gtk_bin_get_child (bin);
|
child = gtk_bin_get_child (bin);
|
||||||
if (child)
|
if (child)
|
||||||
@@ -743,6 +770,25 @@ gtk_viewport_unrealize (GtkWidget *widget)
|
|||||||
GTK_WIDGET_CLASS (gtk_viewport_parent_class)->unrealize (widget);
|
GTK_WIDGET_CLASS (gtk_viewport_parent_class)->unrealize (widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
draw_bin (cairo_t *cr,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GtkWidget *widget = GTK_WIDGET (user_data);
|
||||||
|
GtkViewport *viewport = GTK_VIEWPORT (widget);
|
||||||
|
GtkViewportPrivate *priv = viewport->priv;
|
||||||
|
GtkStyleContext *context;
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
context = gtk_widget_get_style_context (widget);
|
||||||
|
|
||||||
|
gdk_window_get_position (priv->bin_window, &x, &y);
|
||||||
|
gtk_render_background (context, cr, x, y,
|
||||||
|
gdk_window_get_width (priv->bin_window),
|
||||||
|
gdk_window_get_height (priv->bin_window));
|
||||||
|
GTK_WIDGET_CLASS (gtk_viewport_parent_class)->draw (widget, cr);
|
||||||
|
}
|
||||||
|
|
||||||
static gint
|
static gint
|
||||||
gtk_viewport_draw (GtkWidget *widget,
|
gtk_viewport_draw (GtkWidget *widget,
|
||||||
cairo_t *cr)
|
cairo_t *cr)
|
||||||
@@ -750,7 +796,6 @@ gtk_viewport_draw (GtkWidget *widget,
|
|||||||
GtkViewport *viewport = GTK_VIEWPORT (widget);
|
GtkViewport *viewport = GTK_VIEWPORT (widget);
|
||||||
GtkViewportPrivate *priv = viewport->priv;
|
GtkViewportPrivate *priv = viewport->priv;
|
||||||
GtkStyleContext *context;
|
GtkStyleContext *context;
|
||||||
int x, y;
|
|
||||||
|
|
||||||
context = gtk_widget_get_style_context (widget);
|
context = gtk_widget_get_style_context (widget);
|
||||||
|
|
||||||
@@ -767,29 +812,22 @@ gtk_viewport_draw (GtkWidget *widget,
|
|||||||
gtk_style_context_restore (context);
|
gtk_style_context_restore (context);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gtk_cairo_should_draw_window (cr, priv->view_window))
|
|
||||||
{
|
|
||||||
/* This is a cute hack to ensure the contents of bin_window are
|
|
||||||
* restricted to where they are visible. We only need to do this
|
|
||||||
* clipping when called via gtk_widget_draw() and not in expose
|
|
||||||
* events. And when that happens every window (including this one)
|
|
||||||
* should be drawn.
|
|
||||||
*/
|
|
||||||
gdk_window_get_position (priv->view_window, &x, &y);
|
|
||||||
cairo_rectangle (cr, x, y,
|
|
||||||
gdk_window_get_width (priv->view_window),
|
|
||||||
gdk_window_get_height (priv->view_window));
|
|
||||||
cairo_clip (cr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gtk_cairo_should_draw_window (cr, priv->bin_window))
|
if (gtk_cairo_should_draw_window (cr, priv->bin_window))
|
||||||
{
|
{
|
||||||
gdk_window_get_position (priv->bin_window, &x, &y);
|
cairo_rectangle_int_t view_rect;
|
||||||
gtk_render_background (context, cr, x, y,
|
cairo_rectangle_int_t canvas_rect;
|
||||||
gdk_window_get_width (priv->bin_window),
|
|
||||||
gdk_window_get_height (priv->bin_window));
|
|
||||||
|
|
||||||
GTK_WIDGET_CLASS (gtk_viewport_parent_class)->draw (widget, cr);
|
gdk_window_get_position (priv->view_window, &view_rect.x, &view_rect.y);
|
||||||
|
view_rect.width = gdk_window_get_width (priv->view_window);
|
||||||
|
view_rect.height = gdk_window_get_height (priv->view_window);
|
||||||
|
|
||||||
|
gdk_window_get_position (priv->bin_window, &canvas_rect.x, &canvas_rect.y);
|
||||||
|
canvas_rect.width = gdk_window_get_width (priv->bin_window);
|
||||||
|
canvas_rect.height = gdk_window_get_height (priv->bin_window);
|
||||||
|
|
||||||
|
_gtk_pixel_cache_draw (priv->pixel_cache, cr, priv->bin_window,
|
||||||
|
&view_rect, &canvas_rect,
|
||||||
|
draw_bin, widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|||||||
471
gtk/gtkwidget.c
471
gtk/gtkwidget.c
@@ -751,6 +751,8 @@ static void gtk_widget_real_get_width_for_height (GtkWidget
|
|||||||
gint *natural_width);
|
gint *natural_width);
|
||||||
static void gtk_widget_real_state_flags_changed (GtkWidget *widget,
|
static void gtk_widget_real_state_flags_changed (GtkWidget *widget,
|
||||||
GtkStateFlags old_state);
|
GtkStateFlags old_state);
|
||||||
|
static void gtk_widget_real_queue_draw_region (GtkWidget *widget,
|
||||||
|
const cairo_region_t *region);
|
||||||
static const GtkWidgetAuxInfo* _gtk_widget_get_aux_info_or_defaults (GtkWidget *widget);
|
static const GtkWidgetAuxInfo* _gtk_widget_get_aux_info_or_defaults (GtkWidget *widget);
|
||||||
static GtkWidgetAuxInfo* gtk_widget_get_aux_info (GtkWidget *widget,
|
static GtkWidgetAuxInfo* gtk_widget_get_aux_info (GtkWidget *widget,
|
||||||
gboolean create);
|
gboolean create);
|
||||||
@@ -854,9 +856,10 @@ static void gtk_widget_on_frame_clock_update (GdkFrameClock *frame_clock,
|
|||||||
GtkWidget *widget);
|
GtkWidget *widget);
|
||||||
|
|
||||||
static gboolean event_window_is_still_viewable (GdkEvent *event);
|
static gboolean event_window_is_still_viewable (GdkEvent *event);
|
||||||
|
static void gtk_cairo_set_event_window (cairo_t *cr,
|
||||||
|
GdkWindow *window);
|
||||||
static void gtk_cairo_set_event (cairo_t *cr,
|
static void gtk_cairo_set_event (cairo_t *cr,
|
||||||
GdkEventExpose *event);
|
GdkEventExpose *event);
|
||||||
static void gtk_widget_propagate_alpha (GtkWidget *widget);
|
|
||||||
|
|
||||||
/* --- variables --- */
|
/* --- variables --- */
|
||||||
static gpointer gtk_widget_parent_class = NULL;
|
static gpointer gtk_widget_parent_class = NULL;
|
||||||
@@ -955,110 +958,6 @@ child_property_notify_dispatcher (GObject *object,
|
|||||||
GTK_WIDGET_GET_CLASS (object)->dispatch_child_properties_changed (GTK_WIDGET (object), n_pspecs, pspecs);
|
GTK_WIDGET_GET_CLASS (object)->dispatch_child_properties_changed (GTK_WIDGET (object), n_pspecs, pspecs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We guard against the draw signal callbacks modifying the state of the
|
|
||||||
* cairo context by surounding it with save/restore.
|
|
||||||
* Maybe we should also cairo_new_path() just to be sure?
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
gtk_widget_draw_marshaller (GClosure *closure,
|
|
||||||
GValue *return_value,
|
|
||||||
guint n_param_values,
|
|
||||||
const GValue *param_values,
|
|
||||||
gpointer invocation_hint,
|
|
||||||
gpointer marshal_data)
|
|
||||||
{
|
|
||||||
GtkWidget *widget = g_value_get_object (¶m_values[0]);
|
|
||||||
GdkEventExpose *tmp_event;
|
|
||||||
gboolean push_group;
|
|
||||||
cairo_t *cr = g_value_get_boxed (¶m_values[1]);
|
|
||||||
|
|
||||||
cairo_save (cr);
|
|
||||||
tmp_event = _gtk_cairo_get_event (cr);
|
|
||||||
|
|
||||||
push_group =
|
|
||||||
widget->priv->opacity_group ||
|
|
||||||
(widget->priv->alpha != 255 &&
|
|
||||||
(!gtk_widget_get_has_window (widget) || tmp_event == NULL));
|
|
||||||
|
|
||||||
if (push_group)
|
|
||||||
{
|
|
||||||
cairo_push_group (cr);
|
|
||||||
gtk_cairo_set_event (cr, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
_gtk_marshal_BOOLEAN__BOXED (closure,
|
|
||||||
return_value,
|
|
||||||
n_param_values,
|
|
||||||
param_values,
|
|
||||||
invocation_hint,
|
|
||||||
marshal_data);
|
|
||||||
|
|
||||||
|
|
||||||
if (push_group)
|
|
||||||
{
|
|
||||||
cairo_pop_group_to_source (cr);
|
|
||||||
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
|
|
||||||
cairo_paint_with_alpha (cr, widget->priv->alpha / 255.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk_cairo_set_event (cr, tmp_event);
|
|
||||||
cairo_restore (cr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gtk_widget_draw_marshallerv (GClosure *closure,
|
|
||||||
GValue *return_value,
|
|
||||||
gpointer instance,
|
|
||||||
va_list args,
|
|
||||||
gpointer marshal_data,
|
|
||||||
int n_params,
|
|
||||||
GType *param_types)
|
|
||||||
{
|
|
||||||
GtkWidget *widget = GTK_WIDGET (instance);
|
|
||||||
GdkEventExpose *tmp_event;
|
|
||||||
gboolean push_group;
|
|
||||||
cairo_t *cr;
|
|
||||||
va_list args_copy;
|
|
||||||
|
|
||||||
G_VA_COPY (args_copy, args);
|
|
||||||
cr = va_arg (args_copy, gpointer);
|
|
||||||
|
|
||||||
cairo_save (cr);
|
|
||||||
tmp_event = _gtk_cairo_get_event (cr);
|
|
||||||
|
|
||||||
push_group =
|
|
||||||
widget->priv->opacity_group ||
|
|
||||||
(widget->priv->alpha != 255 &&
|
|
||||||
(!gtk_widget_get_has_window (widget) || tmp_event == NULL));
|
|
||||||
|
|
||||||
if (push_group)
|
|
||||||
{
|
|
||||||
cairo_push_group (cr);
|
|
||||||
gtk_cairo_set_event (cr, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
_gtk_marshal_BOOLEAN__BOXEDv (closure,
|
|
||||||
return_value,
|
|
||||||
instance,
|
|
||||||
args,
|
|
||||||
marshal_data,
|
|
||||||
n_params,
|
|
||||||
param_types);
|
|
||||||
|
|
||||||
|
|
||||||
if (push_group)
|
|
||||||
{
|
|
||||||
cairo_pop_group_to_source (cr);
|
|
||||||
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
|
|
||||||
cairo_paint_with_alpha (cr, widget->priv->alpha / 255.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk_cairo_set_event (cr, tmp_event);
|
|
||||||
cairo_restore (cr);
|
|
||||||
|
|
||||||
va_end (args_copy);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_widget_class_init (GtkWidgetClass *klass)
|
gtk_widget_class_init (GtkWidgetClass *klass)
|
||||||
{
|
{
|
||||||
@@ -1181,6 +1080,7 @@ gtk_widget_class_init (GtkWidgetClass *klass)
|
|||||||
klass->adjust_baseline_request = gtk_widget_real_adjust_baseline_request;
|
klass->adjust_baseline_request = gtk_widget_real_adjust_baseline_request;
|
||||||
klass->adjust_size_allocation = gtk_widget_real_adjust_size_allocation;
|
klass->adjust_size_allocation = gtk_widget_real_adjust_size_allocation;
|
||||||
klass->adjust_baseline_allocation = gtk_widget_real_adjust_baseline_allocation;
|
klass->adjust_baseline_allocation = gtk_widget_real_adjust_baseline_allocation;
|
||||||
|
klass->queue_draw_region = gtk_widget_real_queue_draw_region;
|
||||||
|
|
||||||
g_object_class_install_property (gobject_class,
|
g_object_class_install_property (gobject_class,
|
||||||
PROP_NAME,
|
PROP_NAME,
|
||||||
@@ -1994,12 +1894,12 @@ gtk_widget_class_init (GtkWidgetClass *klass)
|
|||||||
G_TYPE_FROM_CLASS (gobject_class),
|
G_TYPE_FROM_CLASS (gobject_class),
|
||||||
G_SIGNAL_RUN_LAST,
|
G_SIGNAL_RUN_LAST,
|
||||||
G_STRUCT_OFFSET (GtkWidgetClass, draw),
|
G_STRUCT_OFFSET (GtkWidgetClass, draw),
|
||||||
_gtk_boolean_handled_accumulator, NULL,
|
_gtk_boolean_handled_accumulator, NULL,
|
||||||
gtk_widget_draw_marshaller,
|
_gtk_marshal_BOOLEAN__BOXED,
|
||||||
G_TYPE_BOOLEAN, 1,
|
G_TYPE_BOOLEAN, 1,
|
||||||
CAIRO_GOBJECT_TYPE_CONTEXT);
|
CAIRO_GOBJECT_TYPE_CONTEXT | G_SIGNAL_TYPE_STATIC_SCOPE);
|
||||||
g_signal_set_va_marshaller (widget_signals[DRAW], G_TYPE_FROM_CLASS (klass),
|
g_signal_set_va_marshaller (widget_signals[DRAW], G_TYPE_FROM_CLASS (klass),
|
||||||
gtk_widget_draw_marshallerv);
|
_gtk_marshal_BOOLEAN__BOXEDv);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GtkWidget::mnemonic-activate:
|
* GtkWidget::mnemonic-activate:
|
||||||
@@ -4235,8 +4135,6 @@ gtk_widget_unparent (GtkWidget *widget)
|
|||||||
g_object_notify_queue_clear (G_OBJECT (widget), nqueue);
|
g_object_notify_queue_clear (G_OBJECT (widget), nqueue);
|
||||||
g_object_notify_queue_thaw (G_OBJECT (widget), nqueue);
|
g_object_notify_queue_thaw (G_OBJECT (widget), nqueue);
|
||||||
|
|
||||||
gtk_widget_propagate_alpha (widget);
|
|
||||||
|
|
||||||
gtk_widget_pop_verify_invariants (widget);
|
gtk_widget_pop_verify_invariants (widget);
|
||||||
g_object_unref (widget);
|
g_object_unref (widget);
|
||||||
}
|
}
|
||||||
@@ -5066,6 +4964,15 @@ gtk_widget_unrealize (GtkWidget *widget)
|
|||||||
* Draw queueing.
|
* Draw queueing.
|
||||||
*****************************************/
|
*****************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_widget_real_queue_draw_region (GtkWidget *widget,
|
||||||
|
const cairo_region_t *region)
|
||||||
|
{
|
||||||
|
GtkWidgetPrivate *priv = widget->priv;
|
||||||
|
|
||||||
|
gdk_window_invalidate_region (priv->window, region, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gtk_widget_queue_draw_region:
|
* gtk_widget_queue_draw_region:
|
||||||
* @widget: a #GtkWidget
|
* @widget: a #GtkWidget
|
||||||
@@ -5103,7 +5010,7 @@ gtk_widget_queue_draw_region (GtkWidget *widget,
|
|||||||
if (!gtk_widget_get_mapped (w))
|
if (!gtk_widget_get_mapped (w))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gdk_window_invalidate_region (priv->window, region, TRUE);
|
WIDGET_CLASS (widget)->queue_draw_region (widget, region);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -6314,6 +6221,23 @@ gtk_widget_real_mnemonic_activate (GtkWidget *widget,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const cairo_user_data_key_t event_window_key;
|
||||||
|
|
||||||
|
GdkWindow *
|
||||||
|
_gtk_cairo_get_event_window (cairo_t *cr)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (cr != NULL, NULL);
|
||||||
|
|
||||||
|
return cairo_get_user_data (cr, &event_window_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_cairo_set_event_window (cairo_t *cr,
|
||||||
|
GdkWindow *event_window)
|
||||||
|
{
|
||||||
|
cairo_set_user_data (cr, &event_window_key, event_window, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static const cairo_user_data_key_t event_key;
|
static const cairo_user_data_key_t event_key;
|
||||||
|
|
||||||
GdkEventExpose *
|
GdkEventExpose *
|
||||||
@@ -6326,7 +6250,7 @@ _gtk_cairo_get_event (cairo_t *cr)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_cairo_set_event (cairo_t *cr,
|
gtk_cairo_set_event (cairo_t *cr,
|
||||||
GdkEventExpose *event)
|
GdkEventExpose *event)
|
||||||
{
|
{
|
||||||
cairo_set_user_data (cr, &event_key, event, NULL);
|
cairo_set_user_data (cr, &event_key, event, NULL);
|
||||||
}
|
}
|
||||||
@@ -6355,15 +6279,15 @@ gboolean
|
|||||||
gtk_cairo_should_draw_window (cairo_t *cr,
|
gtk_cairo_should_draw_window (cairo_t *cr,
|
||||||
GdkWindow *window)
|
GdkWindow *window)
|
||||||
{
|
{
|
||||||
GdkEventExpose *event;
|
GdkWindow *event_window;
|
||||||
|
|
||||||
g_return_val_if_fail (cr != NULL, FALSE);
|
g_return_val_if_fail (cr != NULL, FALSE);
|
||||||
g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
|
g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
|
||||||
|
|
||||||
event = _gtk_cairo_get_event (cr);
|
event_window = _gtk_cairo_get_event_window (cr);
|
||||||
|
|
||||||
return event == NULL ||
|
return event_window == NULL ||
|
||||||
event->window == window;
|
event_window == window;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@@ -6380,17 +6304,20 @@ gtk_widget_get_clip_draw (GtkWidget *widget)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* code shared by gtk_container_propagate_draw() and
|
static void
|
||||||
* gtk_widget_draw()
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
_gtk_widget_draw_internal (GtkWidget *widget,
|
_gtk_widget_draw_internal (GtkWidget *widget,
|
||||||
cairo_t *cr,
|
cairo_t *cr,
|
||||||
gboolean clip_to_size)
|
gboolean clip_to_size,
|
||||||
|
GdkWindow *window)
|
||||||
{
|
{
|
||||||
|
GdkWindow *tmp_event_window;
|
||||||
|
|
||||||
if (!gtk_widget_is_drawable (widget))
|
if (!gtk_widget_is_drawable (widget))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
tmp_event_window = _gtk_cairo_get_event_window (cr);
|
||||||
|
gtk_cairo_set_event_window (cr, window);
|
||||||
|
|
||||||
clip_to_size &= gtk_widget_get_clip_draw (widget);
|
clip_to_size &= gtk_widget_get_clip_draw (widget);
|
||||||
|
|
||||||
if (clip_to_size)
|
if (clip_to_size)
|
||||||
@@ -6406,10 +6333,14 @@ _gtk_widget_draw_internal (GtkWidget *widget,
|
|||||||
{
|
{
|
||||||
gboolean result;
|
gboolean result;
|
||||||
|
|
||||||
|
cairo_save (cr);
|
||||||
|
|
||||||
g_signal_emit (widget, widget_signals[DRAW],
|
g_signal_emit (widget, widget_signals[DRAW],
|
||||||
0, cr,
|
0, cr,
|
||||||
&result);
|
&result);
|
||||||
|
|
||||||
|
cairo_restore (cr);
|
||||||
|
|
||||||
#ifdef G_ENABLE_DEBUG
|
#ifdef G_ENABLE_DEBUG
|
||||||
if (G_UNLIKELY (gtk_get_debug_flags () & GTK_DEBUG_BASELINES))
|
if (G_UNLIKELY (gtk_get_debug_flags () & GTK_DEBUG_BASELINES))
|
||||||
{
|
{
|
||||||
@@ -6431,7 +6362,7 @@ _gtk_widget_draw_internal (GtkWidget *widget,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (cairo_status (cr) &&
|
if (cairo_status (cr) &&
|
||||||
_gtk_cairo_get_event (cr))
|
_gtk_cairo_get_event_window (cr))
|
||||||
{
|
{
|
||||||
/* We check the event so we only warn about internal GTK calls.
|
/* We check the event so we only warn about internal GTK calls.
|
||||||
* Errors might come from PDF streams having write failures and
|
* Errors might come from PDF streams having write failures and
|
||||||
@@ -6443,8 +6374,174 @@ _gtk_widget_draw_internal (GtkWidget *widget,
|
|||||||
cairo_status_to_string (cairo_status (cr)));
|
cairo_status_to_string (cairo_status (cr)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gtk_cairo_set_event_window (cr, tmp_event_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Emit draw() on the widget that owns window,
|
||||||
|
and on any child windows that also belong
|
||||||
|
to the widget. */
|
||||||
|
static void
|
||||||
|
_gtk_widget_draw_windows (GdkWindow *window,
|
||||||
|
cairo_t *cr,
|
||||||
|
int window_x,
|
||||||
|
int window_y)
|
||||||
|
{
|
||||||
|
cairo_pattern_t *pattern;
|
||||||
|
gboolean do_clip;
|
||||||
|
GtkWidget *widget = NULL;
|
||||||
|
GList *l;
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
if (!gdk_window_is_viewable (window))
|
||||||
|
return;
|
||||||
|
|
||||||
|
cairo_save (cr);
|
||||||
|
cairo_translate (cr, window_x, window_y);
|
||||||
|
cairo_rectangle (cr, 0, 0,
|
||||||
|
gdk_window_get_width (window),
|
||||||
|
gdk_window_get_height (window));
|
||||||
|
cairo_clip (cr);
|
||||||
|
|
||||||
|
if (gdk_cairo_get_clip_rectangle (cr, NULL))
|
||||||
|
{
|
||||||
|
gdk_window_get_user_data (window, (gpointer *) &widget);
|
||||||
|
|
||||||
|
/* Only clear bg if double bufferer. This is what we used
|
||||||
|
to do before, where begin_paint() did the clearing. */
|
||||||
|
pattern = gdk_window_get_background_pattern (window);
|
||||||
|
if (pattern != NULL &&
|
||||||
|
widget->priv->double_buffered)
|
||||||
|
{
|
||||||
|
cairo_save (cr);
|
||||||
|
cairo_set_source (cr, pattern);
|
||||||
|
cairo_paint (cr);
|
||||||
|
cairo_restore (cr);
|
||||||
|
}
|
||||||
|
|
||||||
|
do_clip = _gtk_widget_get_translation_to_window (widget, window,
|
||||||
|
&x, &y);
|
||||||
|
cairo_save (cr);
|
||||||
|
cairo_translate (cr, -x, -y);
|
||||||
|
_gtk_widget_draw_internal (widget, cr, do_clip, window);
|
||||||
|
cairo_restore (cr);
|
||||||
|
|
||||||
|
for (l = g_list_last (gdk_window_peek_children (window));
|
||||||
|
l != NULL;
|
||||||
|
l = l->prev)
|
||||||
|
{
|
||||||
|
GdkWindow *child_window = l->data;
|
||||||
|
gpointer child_data;
|
||||||
|
GdkWindowType type;
|
||||||
|
int wx, wy;
|
||||||
|
|
||||||
|
type = gdk_window_get_window_type (child_window);
|
||||||
|
if (!gdk_window_is_visible (child_window) ||
|
||||||
|
gdk_window_is_input_only (child_window) ||
|
||||||
|
type == GDK_WINDOW_OFFSCREEN ||
|
||||||
|
type == GDK_WINDOW_FOREIGN)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
gdk_window_get_user_data (child_window, &child_data);
|
||||||
|
if (child_data == (gpointer)widget)
|
||||||
|
{
|
||||||
|
gdk_window_get_position (child_window, &wx, &wy);
|
||||||
|
_gtk_widget_draw_windows (child_window, cr, wx,wy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_restore (cr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gtk_widget_draw (GtkWidget *widget,
|
||||||
|
cairo_t *cr)
|
||||||
|
{
|
||||||
|
GdkWindow *window, *child_window;
|
||||||
|
gpointer child_data;
|
||||||
|
GList *l;
|
||||||
|
int wx, wy;
|
||||||
|
gboolean push_group;
|
||||||
|
GdkWindowType type;
|
||||||
|
|
||||||
|
/* We get expose events only on native windows, so the draw
|
||||||
|
* implementation has to walk the entire widget hierarchy, except
|
||||||
|
* that it stops at native subwindows while we're in an expose
|
||||||
|
* event (_gtk_cairo_get_event () != NULL).
|
||||||
|
*
|
||||||
|
* However, we need to properly clip drawing into child windows
|
||||||
|
* to avoid drawing outside if widgets use e.g. cairo_paint(), so
|
||||||
|
* we traverse over GdkWindows as well as GtkWidgets.
|
||||||
|
*
|
||||||
|
* In order to be able to have opacity groups for entire widgets
|
||||||
|
* that consists of multiple windows we collect all the windows
|
||||||
|
* that belongs to a widget and draw them in one go. This means
|
||||||
|
* we may somewhat reorder GdkWindows when we paint them, but
|
||||||
|
* thats not generally a problem, as if you want a guaranteed
|
||||||
|
* order you generally use a windowed widget where you control
|
||||||
|
* the window hierarchy.
|
||||||
|
*/
|
||||||
|
|
||||||
|
cairo_save (cr);
|
||||||
|
|
||||||
|
push_group =
|
||||||
|
widget->priv->opacity_group ||
|
||||||
|
(widget->priv->alpha != 255 &&
|
||||||
|
!gtk_widget_is_toplevel (widget));
|
||||||
|
|
||||||
|
if (push_group)
|
||||||
|
cairo_push_group (cr);
|
||||||
|
|
||||||
|
window = gtk_widget_get_window (widget);
|
||||||
|
if (gtk_widget_get_has_window (widget))
|
||||||
|
{
|
||||||
|
/* The widget will be completely contained in its window, so just
|
||||||
|
* expose that (and any child window belonging to the widget) */
|
||||||
|
_gtk_widget_draw_windows (window, cr, 0, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The widget draws in its parent window, so we send a draw() for
|
||||||
|
* that. */
|
||||||
|
_gtk_widget_draw_internal (widget, cr, TRUE, window);
|
||||||
|
|
||||||
|
/* But, it may also have child windows in the parent which we should
|
||||||
|
* draw (after having drawn on the parent) */
|
||||||
|
for (l = g_list_last (gdk_window_peek_children (window));
|
||||||
|
l != NULL;
|
||||||
|
l = l->prev)
|
||||||
|
{
|
||||||
|
child_window = l->data;
|
||||||
|
type = gdk_window_get_window_type (child_window);
|
||||||
|
if (!gdk_window_is_visible (child_window) ||
|
||||||
|
gdk_window_is_input_only (child_window) ||
|
||||||
|
type == GDK_WINDOW_OFFSCREEN ||
|
||||||
|
type == GDK_WINDOW_FOREIGN)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
gdk_window_get_user_data (child_window, &child_data);
|
||||||
|
if (child_data == (gpointer)widget)
|
||||||
|
{
|
||||||
|
gdk_window_get_position (child_window, &wx, &wy);
|
||||||
|
_gtk_widget_draw_windows (child_window, cr,
|
||||||
|
wx - widget->priv->allocation.x,
|
||||||
|
wy - widget->priv->allocation.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (push_group)
|
||||||
|
{
|
||||||
|
cairo_pop_group_to_source (cr);
|
||||||
|
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
|
||||||
|
cairo_paint_with_alpha (cr, widget->priv->alpha / 255.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_restore (cr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gtk_widget_draw:
|
* gtk_widget_draw:
|
||||||
* @widget: the widget to draw. It must be drawable (see
|
* @widget: the widget to draw. It must be drawable (see
|
||||||
@@ -6475,24 +6572,11 @@ void
|
|||||||
gtk_widget_draw (GtkWidget *widget,
|
gtk_widget_draw (GtkWidget *widget,
|
||||||
cairo_t *cr)
|
cairo_t *cr)
|
||||||
{
|
{
|
||||||
GdkEventExpose *tmp_event;
|
|
||||||
|
|
||||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||||
g_return_if_fail (!widget->priv->alloc_needed);
|
g_return_if_fail (!widget->priv->alloc_needed);
|
||||||
g_return_if_fail (cr != NULL);
|
g_return_if_fail (cr != NULL);
|
||||||
|
|
||||||
cairo_save (cr);
|
_gtk_widget_draw (widget, cr);
|
||||||
/* We have to reset the event here so that draw functions can call
|
|
||||||
* gtk_widget_draw() on random other widgets and get the desired
|
|
||||||
* effect: Drawing all contents, not just the current window.
|
|
||||||
*/
|
|
||||||
tmp_event = _gtk_cairo_get_event (cr);
|
|
||||||
gtk_cairo_set_event (cr, NULL);
|
|
||||||
|
|
||||||
_gtk_widget_draw_internal (widget, cr, TRUE);
|
|
||||||
|
|
||||||
gtk_cairo_set_event (cr, tmp_event);
|
|
||||||
cairo_restore (cr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@@ -6787,8 +6871,6 @@ gtk_widget_send_expose (GtkWidget *widget,
|
|||||||
{
|
{
|
||||||
gboolean result = FALSE;
|
gboolean result = FALSE;
|
||||||
cairo_t *cr;
|
cairo_t *cr;
|
||||||
int x, y;
|
|
||||||
gboolean do_clip;
|
|
||||||
|
|
||||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), TRUE);
|
g_return_val_if_fail (GTK_IS_WIDGET (widget), TRUE);
|
||||||
g_return_val_if_fail (gtk_widget_get_realized (widget), TRUE);
|
g_return_val_if_fail (gtk_widget_get_realized (widget), TRUE);
|
||||||
@@ -6796,21 +6878,18 @@ gtk_widget_send_expose (GtkWidget *widget,
|
|||||||
g_return_val_if_fail (event->type == GDK_EXPOSE, TRUE);
|
g_return_val_if_fail (event->type == GDK_EXPOSE, TRUE);
|
||||||
|
|
||||||
cr = gdk_cairo_create (event->expose.window);
|
cr = gdk_cairo_create (event->expose.window);
|
||||||
gtk_cairo_set_event (cr, &event->expose);
|
|
||||||
|
|
||||||
gdk_cairo_region (cr, event->expose.region);
|
gdk_cairo_region (cr, event->expose.region);
|
||||||
cairo_clip (cr);
|
cairo_clip (cr);
|
||||||
|
|
||||||
do_clip = _gtk_widget_get_translation_to_window (widget,
|
gtk_cairo_set_event (cr, &event->expose);
|
||||||
event->expose.window,
|
|
||||||
&x, &y);
|
|
||||||
cairo_translate (cr, -x, -y);
|
|
||||||
|
|
||||||
_gtk_widget_draw_internal (widget, cr, do_clip);
|
if (event->expose.window == widget->priv->window)
|
||||||
|
_gtk_widget_draw (widget, cr);
|
||||||
|
else
|
||||||
|
_gtk_widget_draw_windows (event->expose.window, cr, 0, 0);
|
||||||
|
|
||||||
/* unset here, so if someone keeps a reference to cr we
|
|
||||||
* don't leak the window. */
|
|
||||||
gtk_cairo_set_event (cr, NULL);
|
gtk_cairo_set_event (cr, NULL);
|
||||||
|
|
||||||
cairo_destroy (cr);
|
cairo_destroy (cr);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -8492,6 +8571,9 @@ gtk_widget_get_app_paintable (GtkWidget *widget)
|
|||||||
* expose events, since even the clearing to the background color or
|
* expose events, since even the clearing to the background color or
|
||||||
* pixmap will not happen automatically (as it is done in
|
* pixmap will not happen automatically (as it is done in
|
||||||
* gdk_window_begin_paint_region()).
|
* gdk_window_begin_paint_region()).
|
||||||
|
*
|
||||||
|
* Since 3.10 this function only works for widgets with native
|
||||||
|
* windows.
|
||||||
**/
|
**/
|
||||||
void
|
void
|
||||||
gtk_widget_set_double_buffered (GtkWidget *widget,
|
gtk_widget_set_double_buffered (GtkWidget *widget,
|
||||||
@@ -8750,8 +8832,6 @@ gtk_widget_set_parent (GtkWidget *widget,
|
|||||||
gtk_widget_queue_compute_expand (parent);
|
gtk_widget_queue_compute_expand (parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_widget_propagate_alpha (widget);
|
|
||||||
|
|
||||||
gtk_widget_pop_verify_invariants (widget);
|
gtk_widget_pop_verify_invariants (widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -14588,10 +14668,6 @@ gtk_widget_set_window (GtkWidget *widget,
|
|||||||
{
|
{
|
||||||
priv->window = window;
|
priv->window = window;
|
||||||
|
|
||||||
if (gtk_widget_get_has_window (widget) && window != NULL && !gdk_window_has_native (window))
|
|
||||||
gdk_window_set_opacity (window,
|
|
||||||
priv->norender ? 0 : priv->alpha / 255.0);
|
|
||||||
|
|
||||||
g_object_notify (G_OBJECT (widget), "window");
|
g_object_notify (G_OBJECT (widget), "window");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -14730,86 +14806,8 @@ gtk_widget_set_support_multidevice (GtkWidget *widget,
|
|||||||
* in gtk_widget_set_opacity, secondly we can get it from the css opacity. These two
|
* in gtk_widget_set_opacity, secondly we can get it from the css opacity. These two
|
||||||
* are multiplied together to form the total alpha. Secondly, the user can specify
|
* are multiplied together to form the total alpha. Secondly, the user can specify
|
||||||
* an opacity group for a widget, which means we must essentially handle it as having alpha.
|
* an opacity group for a widget, which means we must essentially handle it as having alpha.
|
||||||
*
|
|
||||||
* We handle opacity in two ways. For a windowed widget, with opacity set but no opacity
|
|
||||||
* group we directly set the opacity of widget->window. This will cause gdk to properly
|
|
||||||
* redirect drawing inside the window to a buffer and do OVER paint_with_alpha.
|
|
||||||
*
|
|
||||||
* However, if the widget is not windowed, or the user specified an opacity group for the
|
|
||||||
* widget we do the opacity handling in the ::draw marshaller for the widget. A naive
|
|
||||||
* implementation of this would break for windowed widgets or descendant widgets with
|
|
||||||
* windows, as these would not be handled by the ::draw signal. To handle this we set
|
|
||||||
* all such gdkwindows as fully transparent and then override gtk_cairo_should_draw_window()
|
|
||||||
* to make the draw signal propagate to *all* child widgets/windows.
|
|
||||||
*
|
|
||||||
* Note: We don't make all child windows fully transparent, we stop at the first one
|
|
||||||
* in each branch when propagating down the hierarchy.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* This is called when priv->alpha or priv->opacity_group group changes, and should
|
|
||||||
* update priv->norender and GdkWindow opacity for this widget and any children that
|
|
||||||
* needs changing. It is also called whenver the parent changes, the parents
|
|
||||||
* norender_children state changes, or the has_window state of the widget changes.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
gtk_widget_propagate_alpha (GtkWidget *widget)
|
|
||||||
{
|
|
||||||
GtkWidgetPrivate *priv = widget->priv;
|
|
||||||
GtkWidget *parent;
|
|
||||||
gboolean norender, norender_children;
|
|
||||||
GList *l;
|
|
||||||
|
|
||||||
parent = priv->parent;
|
|
||||||
|
|
||||||
/* Norender affects only windowed widget and means don't render widget->window in the
|
|
||||||
normal fashion.
|
|
||||||
We only set this if the parent has norender_children, because:
|
|
||||||
a) For an opacity group (that does not have a norender_children parent) we still
|
|
||||||
need to render the window or we will never get an expose event.
|
|
||||||
b) For alpha we set the opacity of window->widget directly, so no other
|
|
||||||
work is needed.
|
|
||||||
*/
|
|
||||||
norender = (parent != NULL && parent->priv->norender_children);
|
|
||||||
|
|
||||||
/* windows under this widget should not render if:
|
|
||||||
a) This widget has an opacity group
|
|
||||||
b) This widget has alpha and is no-windowed (otherwise we'd set alpha on widget->window)
|
|
||||||
c) This widget has norender but is no-windowed (a windowed widget would "swallow" the norender)
|
|
||||||
*/
|
|
||||||
norender_children =
|
|
||||||
priv->opacity_group ||
|
|
||||||
(!gtk_widget_get_has_window (widget) &&
|
|
||||||
( norender || priv->alpha != 255));
|
|
||||||
|
|
||||||
if (gtk_widget_get_has_window (widget))
|
|
||||||
{
|
|
||||||
if (priv->window != NULL &&
|
|
||||||
(!gdk_window_has_native (priv->window) || gtk_widget_is_toplevel (widget)))
|
|
||||||
gdk_window_set_opacity (priv->window,
|
|
||||||
norender ? 0 : priv->alpha / 255.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (l = priv->registered_windows; l != NULL; l = l->next)
|
|
||||||
{
|
|
||||||
GdkWindow *w = l->data;
|
|
||||||
if (w != priv->window && !gdk_window_has_native (w))
|
|
||||||
gdk_window_set_opacity (w, norender_children ? 0.0 : 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
priv->norender = norender;
|
|
||||||
if (priv->norender_children != norender_children)
|
|
||||||
{
|
|
||||||
priv->norender_children = norender_children;
|
|
||||||
|
|
||||||
if (GTK_IS_CONTAINER (widget))
|
|
||||||
gtk_container_forall (GTK_CONTAINER (widget), (GtkCallback)gtk_widget_propagate_alpha, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gtk_widget_get_realized (widget))
|
|
||||||
gtk_widget_queue_draw (widget);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_widget_update_alpha (GtkWidget *widget)
|
gtk_widget_update_alpha (GtkWidget *widget)
|
||||||
{
|
{
|
||||||
@@ -14836,8 +14834,12 @@ gtk_widget_update_alpha (GtkWidget *widget)
|
|||||||
|
|
||||||
priv->alpha = alpha;
|
priv->alpha = alpha;
|
||||||
|
|
||||||
gtk_widget_propagate_alpha (widget);
|
if (gtk_widget_is_toplevel (widget))
|
||||||
|
gdk_window_set_opacity (priv->window,
|
||||||
|
priv->alpha / 255.0);
|
||||||
|
|
||||||
|
if (gtk_widget_get_realized (widget))
|
||||||
|
gtk_widget_queue_draw (widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -14857,7 +14859,8 @@ gtk_widget_set_has_opacity_group (GtkWidget *widget,
|
|||||||
|
|
||||||
priv->opacity_group = has_opacity_group;
|
priv->opacity_group = has_opacity_group;
|
||||||
|
|
||||||
gtk_widget_propagate_alpha (widget);
|
if (gtk_widget_get_realized (widget))
|
||||||
|
gtk_widget_queue_draw (widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -444,13 +444,14 @@ struct _GtkWidgetClass
|
|||||||
gint *natural_baseline);
|
gint *natural_baseline);
|
||||||
void (* adjust_baseline_allocation) (GtkWidget *widget,
|
void (* adjust_baseline_allocation) (GtkWidget *widget,
|
||||||
gint *baseline);
|
gint *baseline);
|
||||||
|
void (*queue_draw_region) (GtkWidget *widget,
|
||||||
|
const cairo_region_t *region);
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
|
|
||||||
GtkWidgetClassPrivate *priv;
|
GtkWidgetClassPrivate *priv;
|
||||||
|
|
||||||
/* Padding for future expansion */
|
/* Padding for future expansion */
|
||||||
void (*_gtk_reserved5) (void);
|
|
||||||
void (*_gtk_reserved6) (void);
|
void (*_gtk_reserved6) (void);
|
||||||
void (*_gtk_reserved7) (void);
|
void (*_gtk_reserved7) (void);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ void _gtk_widget_set_shadowed (GtkWidget *widget,
|
|||||||
gboolean _gtk_widget_get_alloc_needed (GtkWidget *widget);
|
gboolean _gtk_widget_get_alloc_needed (GtkWidget *widget);
|
||||||
void _gtk_widget_set_alloc_needed (GtkWidget *widget,
|
void _gtk_widget_set_alloc_needed (GtkWidget *widget,
|
||||||
gboolean alloc_needed);
|
gboolean alloc_needed);
|
||||||
|
void _gtk_widget_draw (GtkWidget *widget,
|
||||||
|
cairo_t *cr);
|
||||||
|
|
||||||
void _gtk_widget_add_sizegroup (GtkWidget *widget,
|
void _gtk_widget_add_sizegroup (GtkWidget *widget,
|
||||||
gpointer group);
|
gpointer group);
|
||||||
@@ -89,11 +91,9 @@ const gchar* _gtk_widget_get_accel_path (GtkWidget *widget,
|
|||||||
|
|
||||||
AtkObject * _gtk_widget_peek_accessible (GtkWidget *widget);
|
AtkObject * _gtk_widget_peek_accessible (GtkWidget *widget);
|
||||||
|
|
||||||
|
GdkWindow * _gtk_cairo_get_event_window (cairo_t *cr);
|
||||||
GdkEventExpose * _gtk_cairo_get_event (cairo_t *cr);
|
GdkEventExpose * _gtk_cairo_get_event (cairo_t *cr);
|
||||||
|
|
||||||
void _gtk_widget_draw_internal (GtkWidget *widget,
|
|
||||||
cairo_t *cr,
|
|
||||||
gboolean clip_to_size);
|
|
||||||
void _gtk_widget_set_has_default (GtkWidget *widget,
|
void _gtk_widget_set_has_default (GtkWidget *widget,
|
||||||
gboolean has_default);
|
gboolean has_default);
|
||||||
void _gtk_widget_set_has_grab (GtkWidget *widget,
|
void _gtk_widget_set_has_grab (GtkWidget *widget,
|
||||||
|
|||||||
Reference in New Issue
Block a user