mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-09-19 21:40:22 +00:00
Add support for composited child windows. (#412882, Ryan Lortie)
2007-06-01 Matthias Clasen <mclasen@redhat.com> Add support for composited child windows. (#412882, Ryan Lortie) * gdk/gdk.symbols: * gdk/gdkdisplay.h: * gdk/gdkinternals.h: * gdk/gdkwindow.[hc]: Add gdk_display_supports_composite() and gdk_window_set_composited(). * gdk/x11/gdkevents-x11.c: * gdk/x11/gdkdisplay-x11.[hc]: * gdk/x11/gdkwindow-x11.[hc]: X11 implementation. * gdk/win32/gdkdisplay-win32.c: * gdk/win32/gdkwindow-win32.c: Dummy win32 implementration. * gdk/quartz/gdkdisplay-quartz.c: * gdk/quartz/gdkwindow-quartz.c: Dummy Quartz implementation. * gdk/directfb/gdkdisplay-directfb.c: * gdk/directfb/gdkwindow-directfb.c: Dummy DirectFB implementation. * tests/testgtk.c: Add a "composited window" test. svn path=/trunk/; revision=18004
This commit is contained in:
parent
62c13f0463
commit
885ba04648
25
ChangeLog
25
ChangeLog
@ -1,3 +1,28 @@
|
|||||||
|
2007-06-01 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
|
Add support for composited child windows. (#412882, Ryan Lortie)
|
||||||
|
|
||||||
|
* gdk/gdk.symbols:
|
||||||
|
* gdk/gdkdisplay.h:
|
||||||
|
* gdk/gdkinternals.h:
|
||||||
|
* gdk/gdkwindow.[hc]: Add gdk_display_supports_composite() and
|
||||||
|
gdk_window_set_composited().
|
||||||
|
|
||||||
|
* gdk/x11/gdkevents-x11.c:
|
||||||
|
* gdk/x11/gdkdisplay-x11.[hc]:
|
||||||
|
* gdk/x11/gdkwindow-x11.[hc]: X11 implementation.
|
||||||
|
|
||||||
|
* gdk/win32/gdkdisplay-win32.c:
|
||||||
|
* gdk/win32/gdkwindow-win32.c: Dummy win32 implementration.
|
||||||
|
|
||||||
|
* gdk/quartz/gdkdisplay-quartz.c:
|
||||||
|
* gdk/quartz/gdkwindow-quartz.c: Dummy Quartz implementation.
|
||||||
|
|
||||||
|
* gdk/directfb/gdkdisplay-directfb.c:
|
||||||
|
* gdk/directfb/gdkwindow-directfb.c: Dummy DirectFB implementation.
|
||||||
|
|
||||||
|
* tests/testgtk.c: Add a "composited window" test.
|
||||||
|
|
||||||
2007-06-01 Michael Natterer <mitch@imendio.com>
|
2007-06-01 Michael Natterer <mitch@imendio.com>
|
||||||
|
|
||||||
* gtk/gtkmenuitem.c (gtk_menu_item_position_menu): don't switch
|
* gtk/gtkmenuitem.c (gtk_menu_item_position_menu): don't switch
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
2007-06-01 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
|
* gdk/gdk-sections.txt: Add new composited window api
|
||||||
|
* gdk/tmpl/windows.sgml: Add composited window example
|
||||||
|
|
||||||
2007-05-26 Matthias Clasen <mclasen@redhat.com>
|
2007-05-26 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
* gtk/migrating*.sgml: Some cleanups
|
* gtk/migrating*.sgml: Some cleanups
|
||||||
|
@ -155,6 +155,7 @@ gdk_display_supports_clipboard_persistence
|
|||||||
gdk_display_store_clipboard
|
gdk_display_store_clipboard
|
||||||
gdk_display_supports_shapes
|
gdk_display_supports_shapes
|
||||||
gdk_display_supports_input_shapes
|
gdk_display_supports_input_shapes
|
||||||
|
gdk_display_supports_composite
|
||||||
<SUBSECTION Standard>
|
<SUBSECTION Standard>
|
||||||
GDK_DISPLAY_OBJECT
|
GDK_DISPLAY_OBJECT
|
||||||
GDK_IS_DISPLAY
|
GDK_IS_DISPLAY
|
||||||
@ -651,6 +652,7 @@ gdk_window_unfullscreen
|
|||||||
gdk_window_set_keep_above
|
gdk_window_set_keep_above
|
||||||
gdk_window_set_keep_below
|
gdk_window_set_keep_below
|
||||||
gdk_window_set_opacity
|
gdk_window_set_opacity
|
||||||
|
gdk_window_set_composited
|
||||||
gdk_window_move
|
gdk_window_move
|
||||||
gdk_window_resize
|
gdk_window_resize
|
||||||
gdk_window_move_resize
|
gdk_window_move_resize
|
||||||
|
@ -12,6 +12,164 @@ GTK+ level. A #GtkWindow is a toplevel window, the thing a user might think of
|
|||||||
as a "window" with a titlebar and so on; a #GtkWindow may contain many #GdkWindow.
|
as a "window" with a titlebar and so on; a #GtkWindow may contain many #GdkWindow.
|
||||||
For example, each #GtkButton has a #GdkWindow associated with it.
|
For example, each #GtkButton has a #GdkWindow associated with it.
|
||||||
</para>
|
</para>
|
||||||
|
<example id="composited-window-example"><title>Composited windows</title>
|
||||||
|
<programlisting><![CDATA[
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
/* The expose event handler for the event box.
|
||||||
|
*
|
||||||
|
* This function simply draws a transparency onto a widget on the area
|
||||||
|
* for which it receives expose events. This is intended to give the
|
||||||
|
* event box a "transparent" background.
|
||||||
|
*
|
||||||
|
* In order for this to work properly, the widget must have an RGBA
|
||||||
|
* colourmap. The widget should also be set as app-paintable since it
|
||||||
|
* doesn't make sense for GTK+ to draw a background if we are drawing it
|
||||||
|
* (and because GTK+ might actually replace our transparency with its
|
||||||
|
* default background colour).
|
||||||
|
*/
|
||||||
|
static gboolean
|
||||||
|
transparent_expose (GtkWidget *widget,
|
||||||
|
GdkEventExpose *event)
|
||||||
|
{
|
||||||
|
cairo_t *cr;
|
||||||
|
|
||||||
|
cr = gdk_cairo_create (widget->window);
|
||||||
|
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
|
||||||
|
gdk_cairo_region (cr, event->region);
|
||||||
|
cairo_fill (cr);
|
||||||
|
cairo_destroy (cr);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The expose event handler for the window.
|
||||||
|
*
|
||||||
|
* This function performs the actual compositing of the event box onto
|
||||||
|
* the already-existing background of the window at 50% normal opacity.
|
||||||
|
*
|
||||||
|
* In this case we do not want app-paintable to be set on the widget
|
||||||
|
* since we want it to draw its own (red) background. Because of this,
|
||||||
|
* however, we must ensure that we use g_signal_register_after so that
|
||||||
|
* this handler is called after the red has been drawn. If it was
|
||||||
|
* called before then GTK would just blindly paint over our work.
|
||||||
|
*
|
||||||
|
* Note: if the child window has children, then you need a cairo 1.16
|
||||||
|
* feature to make this work correctly.
|
||||||
|
*/
|
||||||
|
static gboolean
|
||||||
|
window_expose_event (GtkWidget *widget,
|
||||||
|
GdkEventExpose *event)
|
||||||
|
{
|
||||||
|
GdkRegion *region;
|
||||||
|
GtkWidget *child;
|
||||||
|
cairo_t *cr;
|
||||||
|
|
||||||
|
/* get our child (in this case, the event box) */
|
||||||
|
child = gtk_bin_get_child (GTK_BIN (widget));
|
||||||
|
|
||||||
|
/* create a cairo context to draw to the window */
|
||||||
|
cr = gdk_cairo_create (widget->window);
|
||||||
|
|
||||||
|
/* the source data is the (composited) event box */
|
||||||
|
gdk_cairo_set_source_pixmap (cr, child->window,
|
||||||
|
child->allocation.x,
|
||||||
|
child->allocation.y);
|
||||||
|
|
||||||
|
/* draw no more than our expose event intersects our child */
|
||||||
|
region = gdk_region_rectangle (&child->allocation);
|
||||||
|
gdk_region_intersect (region, event->region);
|
||||||
|
gdk_cairo_region (cr, region);
|
||||||
|
cairo_clip (cr);
|
||||||
|
|
||||||
|
/* composite, with a 50% opacity */
|
||||||
|
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
|
||||||
|
cairo_paint_with_alpha (cr, 0.5);
|
||||||
|
|
||||||
|
/* we're done */
|
||||||
|
cairo_destroy (cr);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
GtkWidget *window, *event, *button;
|
||||||
|
GdkScreen *screen;
|
||||||
|
GdkColormap *rgba;
|
||||||
|
GdkColor red;
|
||||||
|
|
||||||
|
gtk_init (&argc, &argv);
|
||||||
|
|
||||||
|
/* Make the widgets */
|
||||||
|
button = gtk_button_new_with_label ("A Button");
|
||||||
|
event = gtk_event_box_new ();
|
||||||
|
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||||
|
|
||||||
|
/* Put a red background on the window */
|
||||||
|
gdk_color_parse ("red", &red);
|
||||||
|
gtk_widget_modify_bg (window, GTK_STATE_NORMAL, &red);
|
||||||
|
|
||||||
|
/* Set the colourmap for the event box.
|
||||||
|
* Must be done before the event box is realised.
|
||||||
|
*/
|
||||||
|
screen = gtk_widget_get_screen (event);
|
||||||
|
rgba = gdk_screen_get_rgba_colormap (screen);
|
||||||
|
gtk_widget_set_colormap (event, rgba);
|
||||||
|
|
||||||
|
/* Set our event box to have a fully-transparent background
|
||||||
|
* drawn on it. Currently there is no way to simply tell GTK+
|
||||||
|
* that "transparency" is the background colour for a widget.
|
||||||
|
*/
|
||||||
|
gtk_widget_set_app_paintable (GTK_WIDGET (event), TRUE);
|
||||||
|
g_signal_connect (event, "expose-event",
|
||||||
|
G_CALLBACK (transparent_expose), NULL);
|
||||||
|
|
||||||
|
/* Put them inside one another */
|
||||||
|
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
|
||||||
|
gtk_container_add (GTK_CONTAINER (window), event);
|
||||||
|
gtk_container_add (GTK_CONTAINER (event), button);
|
||||||
|
|
||||||
|
/* Realise and show everything */
|
||||||
|
gtk_widget_show_all (window);
|
||||||
|
|
||||||
|
/* Set the event box GdkWindow to be composited.
|
||||||
|
* Obviously must be performed after event box is realised.
|
||||||
|
*/
|
||||||
|
gdk_window_set_composited (event->window, TRUE);
|
||||||
|
|
||||||
|
/* Set up the compositing handler.
|
||||||
|
* Note that we do _after_ so that the normal (red) background is drawn
|
||||||
|
* by gtk before our compositing occurs.
|
||||||
|
*/
|
||||||
|
g_signal_connect_after (window, "expose-event",
|
||||||
|
G_CALLBACK (window_expose_event), NULL);
|
||||||
|
|
||||||
|
gtk_main (<!-- -->);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
]]>
|
||||||
|
</programlisting></example>
|
||||||
|
<para>
|
||||||
|
In the example <xref linkend="composited-window-example"/>, a button is
|
||||||
|
placed inside of an event box inside of a window. The event box is
|
||||||
|
set as composited and therefore is no longer automatically drawn to
|
||||||
|
the screen.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
When the contents of the event box change, an expose event is
|
||||||
|
generated on its parent window (which, in this case, belongs to
|
||||||
|
the toplevel #GtkWindow). The expose handler for this widget is
|
||||||
|
responsible for merging the changes back on the screen in the way
|
||||||
|
that it wishes.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
In our case, we merge the contents with a 50% transparency. We
|
||||||
|
also set the background colour of the window to red. The effect is
|
||||||
|
that the background shows through the button.
|
||||||
|
</para>
|
||||||
|
|
||||||
<!-- ##### SECTION See_Also ##### -->
|
<!-- ##### SECTION See_Also ##### -->
|
||||||
<para>
|
<para>
|
||||||
@ -465,6 +623,15 @@ Deprecated equivalent of g_object_unref()
|
|||||||
@opacity:
|
@opacity:
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ##### FUNCTION gdk_window_set_composited ##### -->
|
||||||
|
<para>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
|
@window:
|
||||||
|
@composited:
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION gdk_window_move ##### -->
|
<!-- ##### FUNCTION gdk_window_move ##### -->
|
||||||
<para>
|
<para>
|
||||||
|
|
||||||
|
@ -511,6 +511,13 @@ gdk_notify_startup_complete_with_id (const gchar* startup_id)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gdk_display_supports_composite (GdkDisplay *display)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
#define __GDK_DISPLAY_X11_C__
|
#define __GDK_DISPLAY_X11_C__
|
||||||
#include "gdkaliasdef.c"
|
#include "gdkaliasdef.c"
|
||||||
|
|
||||||
|
@ -3038,6 +3038,14 @@ gdk_window_set_opacity (GdkWindow *window,
|
|||||||
cardinal = opacity * 0xff;
|
cardinal = opacity * 0xff;
|
||||||
gdk_directfb_window_set_opacity(window,cardinal);
|
gdk_directfb_window_set_opacity(window,cardinal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gdk_windowing_window_set_composited (GdkWindow *window,
|
||||||
|
gboolean composited)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define __GDK_WINDOW_X11_C__
|
#define __GDK_WINDOW_X11_C__
|
||||||
#include "gdkaliasdef.c"
|
#include "gdkaliasdef.c"
|
||||||
|
|
||||||
|
@ -466,6 +466,7 @@ gdk_display_supports_clipboard_persistence
|
|||||||
gdk_display_supports_selection_notification
|
gdk_display_supports_selection_notification
|
||||||
gdk_display_supports_shapes
|
gdk_display_supports_shapes
|
||||||
gdk_display_supports_input_shapes
|
gdk_display_supports_input_shapes
|
||||||
|
gdk_display_supports_composite
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -673,6 +674,7 @@ gdk_window_remove_filter
|
|||||||
gdk_window_set_debug_updates
|
gdk_window_set_debug_updates
|
||||||
gdk_window_set_user_data
|
gdk_window_set_user_data
|
||||||
gdk_window_thaw_updates
|
gdk_window_thaw_updates
|
||||||
|
gdk_window_set_composited
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -181,6 +181,7 @@ void gdk_display_store_clipboard (GdkDisplay *display,
|
|||||||
|
|
||||||
gboolean gdk_display_supports_shapes (GdkDisplay *display);
|
gboolean gdk_display_supports_shapes (GdkDisplay *display);
|
||||||
gboolean gdk_display_supports_input_shapes (GdkDisplay *display);
|
gboolean gdk_display_supports_input_shapes (GdkDisplay *display);
|
||||||
|
gboolean gdk_display_supports_composite (GdkDisplay *display);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
@ -337,6 +337,9 @@ void _gdk_windowing_window_destroy_foreign (GdkWindow *window);
|
|||||||
void _gdk_windowing_display_set_sm_client_id (GdkDisplay *display,
|
void _gdk_windowing_display_set_sm_client_id (GdkDisplay *display,
|
||||||
const gchar *sm_client_id);
|
const gchar *sm_client_id);
|
||||||
|
|
||||||
|
void _gdk_windowing_window_set_composited (GdkWindow *window,
|
||||||
|
gboolean composited);
|
||||||
|
|
||||||
#define GDK_TYPE_PAINTABLE (_gdk_paintable_get_type ())
|
#define GDK_TYPE_PAINTABLE (_gdk_paintable_get_type ())
|
||||||
#define GDK_PAINTABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_PAINTABLE, GdkPaintable))
|
#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_IS_PAINTABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_PAINTABLE))
|
||||||
|
@ -1042,6 +1042,7 @@ gdk_window_end_paint (GdkWindow *window)
|
|||||||
{
|
{
|
||||||
#ifdef USE_BACKING_STORE
|
#ifdef USE_BACKING_STORE
|
||||||
GdkWindowObject *private = (GdkWindowObject *)window;
|
GdkWindowObject *private = (GdkWindowObject *)window;
|
||||||
|
GdkWindowObject *composited;
|
||||||
GdkWindowPaint *paint;
|
GdkWindowPaint *paint;
|
||||||
GdkGC *tmp_gc;
|
GdkGC *tmp_gc;
|
||||||
GdkRectangle clip_box;
|
GdkRectangle clip_box;
|
||||||
@ -1094,6 +1095,34 @@ gdk_window_end_paint (GdkWindow *window)
|
|||||||
g_object_unref (paint->pixmap);
|
g_object_unref (paint->pixmap);
|
||||||
gdk_region_destroy (paint->region);
|
gdk_region_destroy (paint->region);
|
||||||
g_free (paint);
|
g_free (paint);
|
||||||
|
|
||||||
|
/* find a composited window in our hierarchy to signal its
|
||||||
|
* parent to redraw, calculating the clip box as we go...
|
||||||
|
*
|
||||||
|
* stop if parent becomes NULL since then we'd have nowhere
|
||||||
|
* to draw (ie: 'composited' will always be non-NULL here).
|
||||||
|
*/
|
||||||
|
for (composited = private;
|
||||||
|
composited->parent;
|
||||||
|
composited = composited->parent)
|
||||||
|
{
|
||||||
|
int width, height;
|
||||||
|
|
||||||
|
gdk_drawable_get_size (GDK_DRAWABLE (composited->parent),
|
||||||
|
&width, &height);
|
||||||
|
|
||||||
|
clip_box.x += composited->x;
|
||||||
|
clip_box.y += composited->y;
|
||||||
|
clip_box.width = MIN (clip_box.width, width - clip_box.x);
|
||||||
|
clip_box.height = MIN (clip_box.height, height - clip_box.y);
|
||||||
|
|
||||||
|
if (composited->composited)
|
||||||
|
{
|
||||||
|
gdk_window_invalidate_rect (GDK_WINDOW (composited->parent),
|
||||||
|
&clip_box, FALSE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif /* USE_BACKING_STORE */
|
#endif /* USE_BACKING_STORE */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2601,7 +2630,8 @@ gdk_window_invalidate_maybe_recurse (GdkWindow *window,
|
|||||||
child_region = gdk_region_rectangle (&child_rect);
|
child_region = gdk_region_rectangle (&child_rect);
|
||||||
|
|
||||||
/* remove child area from the invalid area of the parent */
|
/* remove child area from the invalid area of the parent */
|
||||||
if (GDK_WINDOW_IS_MAPPED (child) && !child->shaped)
|
if (GDK_WINDOW_IS_MAPPED (child) && !child->shaped &&
|
||||||
|
!child->composited)
|
||||||
gdk_region_subtract (visible_region, child_region);
|
gdk_region_subtract (visible_region, child_region);
|
||||||
|
|
||||||
if (child_func && (*child_func) ((GdkWindow *)child, user_data))
|
if (child_func && (*child_func) ((GdkWindow *)child, user_data))
|
||||||
@ -3056,5 +3086,64 @@ gdk_window_foreign_new (GdkNativeWindow anid)
|
|||||||
return gdk_window_foreign_new_for_display (gdk_display_get_default (), anid);
|
return gdk_window_foreign_new_for_display (gdk_display_get_default (), anid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gdk_window_set_composited:
|
||||||
|
* @window: a #GdkWindow
|
||||||
|
*
|
||||||
|
* Sets a #GdkWindow as composited. Composited windows do
|
||||||
|
* not automatically have their contents drawn to the screen.
|
||||||
|
* Drawing is redirected to an offscreen buffer and an expose
|
||||||
|
* event is emitted on the parent of the composited window.
|
||||||
|
* It is the responsibility of the parent's expose handler to
|
||||||
|
* manually merge the off-screen content onto the screen in
|
||||||
|
* whatever way it sees fit. See <xref linkend="composited-window-example"/>
|
||||||
|
* for an example.
|
||||||
|
*
|
||||||
|
* It only makes sense for child windows to be composited; see
|
||||||
|
* gdk_window_set_opacity() if you need translucent toplevel
|
||||||
|
* windows.
|
||||||
|
*
|
||||||
|
* An additional effect of this call is that the area of this
|
||||||
|
* window is no longer clipped from regions marked for
|
||||||
|
* invalidation on its parent. Draws done on the parent
|
||||||
|
* window are also no longer clipped by the child.
|
||||||
|
*
|
||||||
|
* This call is only supported on some systems (currently,
|
||||||
|
* only X11 with new enough Xcomposite and Xdamage extensions).
|
||||||
|
* You must call gdk_display_supports_composite() to check if
|
||||||
|
* setting a window as composited is supported before
|
||||||
|
* attempting to do so.
|
||||||
|
*
|
||||||
|
* Since: 2.12
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
gdk_window_set_composited (GdkWindow *window,
|
||||||
|
gboolean composited)
|
||||||
|
{
|
||||||
|
GdkWindowObject *private = (GdkWindowObject *)window;
|
||||||
|
GdkDisplay *display;
|
||||||
|
|
||||||
|
g_return_if_fail (window != NULL);
|
||||||
|
g_return_if_fail (GDK_IS_WINDOW (window));
|
||||||
|
|
||||||
|
composited = composited != FALSE;
|
||||||
|
|
||||||
|
if (private->composited == composited)
|
||||||
|
return;
|
||||||
|
|
||||||
|
display = gdk_drawable_get_display (GDK_DRAWABLE (window));
|
||||||
|
|
||||||
|
if (!gdk_display_supports_composite (display) && composited)
|
||||||
|
{
|
||||||
|
g_warning ("gdk_window_set_composited called but "
|
||||||
|
"compositing is not supported");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_gdk_windowing_window_set_composited (window, composited);
|
||||||
|
|
||||||
|
private->composited = composited;
|
||||||
|
}
|
||||||
|
|
||||||
#define __GDK_WINDOW_C__
|
#define __GDK_WINDOW_C__
|
||||||
#include "gdkaliasdef.c"
|
#include "gdkaliasdef.c"
|
||||||
|
@ -289,6 +289,7 @@ struct _GdkWindowObject
|
|||||||
guint guffaw_gravity : 1;
|
guint guffaw_gravity : 1;
|
||||||
guint input_only : 1;
|
guint input_only : 1;
|
||||||
guint modal_hint : 1;
|
guint modal_hint : 1;
|
||||||
|
guint composited : 1;
|
||||||
|
|
||||||
guint destroyed : 2;
|
guint destroyed : 2;
|
||||||
|
|
||||||
@ -394,6 +395,9 @@ void gdk_window_shape_combine_region (GdkWindow *window,
|
|||||||
*/
|
*/
|
||||||
void gdk_window_set_child_shapes (GdkWindow *window);
|
void gdk_window_set_child_shapes (GdkWindow *window);
|
||||||
|
|
||||||
|
void gdk_window_set_composited (GdkWindow *window,
|
||||||
|
gboolean composited);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This routine allows you to merge (ie ADD) child shapes to your
|
* This routine allows you to merge (ie ADD) child shapes to your
|
||||||
* own window's shape keeping its current shape and ADDING the child
|
* own window's shape keeping its current shape and ADDING the child
|
||||||
|
@ -169,3 +169,11 @@ gdk_display_store_clipboard (GdkDisplay *display,
|
|||||||
{
|
{
|
||||||
/* FIXME: Implement */
|
/* FIXME: Implement */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gdk_display_supports_composite (GdkDisplay *display)
|
||||||
|
{
|
||||||
|
/* FIXME: Implement */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
@ -2155,3 +2155,8 @@ gdk_window_set_opacity (GdkWindow *window,
|
|||||||
|
|
||||||
[impl->toplevel setAlphaValue: opacity];
|
[impl->toplevel setAlphaValue: opacity];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gdk_windowing_window_set_composited (GdkWindow *window, gboolean composited)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
@ -389,3 +389,9 @@ gdk_display_supports_input_shapes (GdkDisplay *display)
|
|||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gdk_display_supports_composite (GdkDisplay *display)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
@ -3571,3 +3571,8 @@ gdk_window_set_opacity (GdkWindow *window,
|
|||||||
opacity * 0xff,
|
opacity * 0xff,
|
||||||
LWA_ALPHA));
|
LWA_ALPHA));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gdk_windowing_window_set_composited (GdkWindow *window, gboolean composited)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
@ -54,6 +54,14 @@
|
|||||||
#include <X11/extensions/shape.h>
|
#include <X11/extensions/shape.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_XCOMPOSITE
|
||||||
|
#include <X11/extensions/Xcomposite.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_XDAMAGE
|
||||||
|
#include <X11/extensions/Xdamage.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static void gdk_display_x11_dispose (GObject *object);
|
static void gdk_display_x11_dispose (GObject *object);
|
||||||
static void gdk_display_x11_finalize (GObject *object);
|
static void gdk_display_x11_finalize (GObject *object);
|
||||||
@ -206,6 +214,29 @@ gdk_display_open (const gchar *display_name)
|
|||||||
#endif
|
#endif
|
||||||
display_x11->have_xfixes = FALSE;
|
display_x11->have_xfixes = FALSE;
|
||||||
|
|
||||||
|
#ifdef HAVE_XCOMPOSITE
|
||||||
|
if (XCompositeQueryExtension (display_x11->xdisplay,
|
||||||
|
&ignore, &ignore))
|
||||||
|
display_x11->have_xcomposite = TRUE;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
display_x11->have_xcomposite = FALSE;
|
||||||
|
|
||||||
|
#ifdef HAVE_XDAMAGE
|
||||||
|
if (XDamageQueryExtension (display_x11->xdisplay,
|
||||||
|
&display_x11->xdamage_event_base,
|
||||||
|
&ignore))
|
||||||
|
{
|
||||||
|
display_x11->have_xdamage = TRUE;
|
||||||
|
|
||||||
|
gdk_x11_register_standard_event_type (display,
|
||||||
|
display_x11->xdamage_event_base,
|
||||||
|
XDamageNumberEvents);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
display_x11->have_xdamage = FALSE;
|
||||||
|
|
||||||
display_x11->have_shapes = FALSE;
|
display_x11->have_shapes = FALSE;
|
||||||
display_x11->have_input_shapes = FALSE;
|
display_x11->have_input_shapes = FALSE;
|
||||||
#ifdef HAVE_SHAPE_EXT
|
#ifdef HAVE_SHAPE_EXT
|
||||||
@ -1363,5 +1394,30 @@ gdk_x11_display_get_startup_notification_id (GdkDisplay *display)
|
|||||||
return GDK_DISPLAY_X11 (display)->startup_notification_id;
|
return GDK_DISPLAY_X11 (display)->startup_notification_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gdk_display_supports_composite:
|
||||||
|
* @display: a #GdkDisplay
|
||||||
|
*
|
||||||
|
* Returns %TRUE if gdk_window_set_composited() can be used
|
||||||
|
* to redirect drawing on the window using compositing.
|
||||||
|
*
|
||||||
|
* Currently this only works on X11 with XComposite and
|
||||||
|
* XDamage extensions available.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if windows may be composited.
|
||||||
|
*
|
||||||
|
* Since: 2.12
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
gdk_display_supports_composite (GdkDisplay *display)
|
||||||
|
{
|
||||||
|
GdkDisplayX11 *x11_display = GDK_DISPLAY_X11 (display);
|
||||||
|
|
||||||
|
return x11_display->have_xcomposite &&
|
||||||
|
x11_display->have_xdamage &&
|
||||||
|
x11_display->have_xfixes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define __GDK_DISPLAY_X11_C__
|
#define __GDK_DISPLAY_X11_C__
|
||||||
#include "gdkaliasdef.c"
|
#include "gdkaliasdef.c"
|
||||||
|
@ -81,6 +81,10 @@ struct _GdkDisplayX11
|
|||||||
gboolean have_xfixes;
|
gboolean have_xfixes;
|
||||||
gint xfixes_event_base;
|
gint xfixes_event_base;
|
||||||
|
|
||||||
|
gboolean have_xcomposite;
|
||||||
|
gboolean have_xdamage;
|
||||||
|
gint xdamage_event_base;
|
||||||
|
|
||||||
/* If the SECURITY extension is in place, whether this client holds
|
/* If the SECURITY extension is in place, whether this client holds
|
||||||
* a trusted authorization and so is allowed to make various requests
|
* a trusted authorization and so is allowed to make various requests
|
||||||
* (grabs, properties etc.) Otherwise always TRUE. */
|
* (grabs, properties etc.) Otherwise always TRUE. */
|
||||||
|
@ -2101,6 +2101,34 @@ gdk_event_translate (GdkDisplay *display,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(HAVE_XCOMPOSITE) && defined (HAVE_XDAMAGE) && defined (HAVE_XFIXES)
|
||||||
|
if (display_x11->have_xdamage && window_private->composited &&
|
||||||
|
xevent->type == display_x11->xdamage_event_base + XDamageNotify)
|
||||||
|
{
|
||||||
|
XDamageNotifyEvent *damage_event = (XDamageNotifyEvent *) xevent;
|
||||||
|
XserverRegion repair;
|
||||||
|
GdkRectangle rect;
|
||||||
|
|
||||||
|
rect.x = window_private->x + damage_event->area.x;
|
||||||
|
rect.y = window_private->y + damage_event->area.y;
|
||||||
|
rect.width = damage_event->area.width;
|
||||||
|
rect.height = damage_event->area.height;
|
||||||
|
|
||||||
|
repair = XFixesCreateRegion (display_x11->xdisplay,
|
||||||
|
&damage_event->area, 1);
|
||||||
|
XDamageSubtract (display_x11->xdisplay,
|
||||||
|
window_impl->damage,
|
||||||
|
repair, None);
|
||||||
|
XFixesDestroyRegion (display_x11->xdisplay, repair);
|
||||||
|
|
||||||
|
if (window_private->parent != NULL)
|
||||||
|
_gdk_window_process_expose (GDK_WINDOW (window_private->parent),
|
||||||
|
damage_event->serial, &rect);
|
||||||
|
|
||||||
|
return_val = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
/* something else - (e.g., a Xinput event) */
|
/* something else - (e.g., a Xinput event) */
|
||||||
|
|
||||||
|
@ -59,6 +59,18 @@
|
|||||||
#include <X11/extensions/shape.h>
|
#include <X11/extensions/shape.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_XCOMPOSITE
|
||||||
|
#include <X11/extensions/Xcomposite.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_XFIXES
|
||||||
|
#include <X11/extensions/Xfixes.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_XDAMAGE
|
||||||
|
#include <X11/extensions/Xdamage.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
const int _gdk_event_mask_table[21] =
|
const int _gdk_event_mask_table[21] =
|
||||||
{
|
{
|
||||||
ExposureMask,
|
ExposureMask,
|
||||||
@ -185,6 +197,14 @@ gdk_window_impl_x11_finalize (GObject *object)
|
|||||||
|
|
||||||
_gdk_xgrab_check_destroy (GDK_WINDOW (wrapper));
|
_gdk_xgrab_check_destroy (GDK_WINDOW (wrapper));
|
||||||
|
|
||||||
|
#if defined(HAVE_XCOMPOSITE) && defined(HAVE_XDAMAGE) && defined (HAVE_XFIXES)
|
||||||
|
if (window_impl->damage != None)
|
||||||
|
{
|
||||||
|
XDamageDestroy (GDK_WINDOW_XDISPLAY (object), window_impl->damage);
|
||||||
|
window_impl->damage = None;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!GDK_WINDOW_DESTROYED (wrapper))
|
if (!GDK_WINDOW_DESTROYED (wrapper))
|
||||||
{
|
{
|
||||||
GdkDisplay *display = GDK_WINDOW_DISPLAY (wrapper);
|
GdkDisplay *display = GDK_WINDOW_DISPLAY (wrapper);
|
||||||
@ -6413,10 +6433,14 @@ gdk_window_beep (GdkWindow *window)
|
|||||||
*
|
*
|
||||||
* Request the windowing system to make @window partially transparent,
|
* Request the windowing system to make @window partially transparent,
|
||||||
* with opacity 0 being fully transparent and 1 fully opaque. (Values
|
* with opacity 0 being fully transparent and 1 fully opaque. (Values
|
||||||
* of the opacity parameter are clamped to the [0,1] range.) On X11
|
* of the opacity parameter are clamped to the [0,1] range.)
|
||||||
* this works only on X screens with a compositing manager running.
|
*
|
||||||
|
* On X11, this works only on X screens with a compositing manager
|
||||||
|
* running.
|
||||||
*
|
*
|
||||||
* For setting up per-pixel alpha, see gdk_screen_get_rgba_colormap().
|
* For setting up per-pixel alpha, see gdk_screen_get_rgba_colormap().
|
||||||
|
* For making non-toplevel windows translucent, see
|
||||||
|
* gdk_window_set_composited().
|
||||||
*
|
*
|
||||||
* Since: 2.12
|
* Since: 2.12
|
||||||
*/
|
*/
|
||||||
@ -6455,5 +6479,39 @@ gdk_window_set_opacity (GdkWindow *window,
|
|||||||
(guchar *) cardinal, 1);
|
(guchar *) cardinal, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gdk_windowing_window_set_composited (GdkWindow *window,
|
||||||
|
gboolean composited)
|
||||||
|
{
|
||||||
|
#if defined(HAVE_XCOMPOSITE) && defined(HAVE_XDAMAGE) && defined (HAVE_XFIXES)
|
||||||
|
GdkWindowObject *private = (GdkWindowObject *) window;
|
||||||
|
GdkDisplayX11 *x11_display;
|
||||||
|
GdkWindowImplX11 *impl;
|
||||||
|
GdkDisplay *display;
|
||||||
|
Display *dpy;
|
||||||
|
Window xid;
|
||||||
|
|
||||||
|
impl = GDK_WINDOW_IMPL_X11 (private->impl);
|
||||||
|
|
||||||
|
display = gdk_screen_get_display (GDK_DRAWABLE_IMPL_X11 (impl)->screen);
|
||||||
|
x11_display = GDK_DISPLAY_X11 (display);
|
||||||
|
dpy = GDK_DISPLAY_XDISPLAY (display);
|
||||||
|
xid = GDK_WINDOW_XWINDOW (private);
|
||||||
|
|
||||||
|
if (composited)
|
||||||
|
{
|
||||||
|
XCompositeRedirectWindow (dpy, xid, CompositeRedirectManual);
|
||||||
|
impl->damage = XDamageCreate (dpy, xid, XDamageReportBoundingBox);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
XCompositeUnredirectWindow (dpy, xid, CompositeRedirectManual);
|
||||||
|
XDamageDestroy (dpy, impl->damage);
|
||||||
|
impl->damage = None;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define __GDK_WINDOW_X11_C__
|
#define __GDK_WINDOW_X11_C__
|
||||||
#include "gdkaliasdef.c"
|
#include "gdkaliasdef.c"
|
||||||
|
@ -29,6 +29,10 @@
|
|||||||
|
|
||||||
#include <gdk/x11/gdkdrawable-x11.h>
|
#include <gdk/x11/gdkdrawable-x11.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_XDAMAGE
|
||||||
|
#include <X11/extensions/Xdamage.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_XSYNC
|
#ifdef HAVE_XSYNC
|
||||||
#include <X11/extensions/sync.h>
|
#include <X11/extensions/sync.h>
|
||||||
#endif
|
#endif
|
||||||
@ -79,6 +83,10 @@ struct _GdkWindowImplX11
|
|||||||
gint8 toplevel_window_type;
|
gint8 toplevel_window_type;
|
||||||
guint override_redirect : 1;
|
guint override_redirect : 1;
|
||||||
guint use_synchronized_configure : 1;
|
guint use_synchronized_configure : 1;
|
||||||
|
|
||||||
|
#if defined (HAVE_XCOMPOSITE) && defined(HAVE_XDAMAGE) && defined (HAVE_XFIXES)
|
||||||
|
Damage damage;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GdkWindowImplX11Class
|
struct _GdkWindowImplX11Class
|
||||||
|
141
tests/testgtk.c
141
tests/testgtk.c
@ -420,6 +420,146 @@ create_alpha_window (GtkWidget *widget)
|
|||||||
gtk_widget_destroy (window);
|
gtk_widget_destroy (window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Composited non-toplevel window
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* The expose event handler for the event box.
|
||||||
|
*
|
||||||
|
* This function simply draws a transparency onto a widget on the area
|
||||||
|
* for which it receives expose events. This is intended to give the
|
||||||
|
* event box a "transparent" background.
|
||||||
|
*
|
||||||
|
* In order for this to work properly, the widget must have an RGBA
|
||||||
|
* colourmap. The widget should also be set as app-paintable since it
|
||||||
|
* doesn't make sense for GTK to draw a background if we are drawing it
|
||||||
|
* (and because GTK might actually replace our transparency with its
|
||||||
|
* default background colour).
|
||||||
|
*/
|
||||||
|
static gboolean
|
||||||
|
transparent_expose (GtkWidget *widget,
|
||||||
|
GdkEventExpose *event)
|
||||||
|
{
|
||||||
|
cairo_t *cr;
|
||||||
|
|
||||||
|
cr = gdk_cairo_create (widget->window);
|
||||||
|
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
|
||||||
|
gdk_cairo_region (cr, event->region);
|
||||||
|
cairo_fill (cr);
|
||||||
|
cairo_destroy (cr);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The expose event handler for the window.
|
||||||
|
*
|
||||||
|
* This function performs the actual compositing of the event box onto
|
||||||
|
* the already-existing background of the window at 50% normal opacity.
|
||||||
|
*
|
||||||
|
* In this case we do not want app-paintable to be set on the widget
|
||||||
|
* since we want it to draw its own (red) background. Because of this,
|
||||||
|
* however, we must ensure that we use g_signal_register_after so that
|
||||||
|
* this handler is called after the red has been drawn. If it was
|
||||||
|
* called before then GTK would just blindly paint over our work.
|
||||||
|
*/
|
||||||
|
static gboolean
|
||||||
|
window_expose_event (GtkWidget *widget,
|
||||||
|
GdkEventExpose *event)
|
||||||
|
{
|
||||||
|
GdkRegion *region;
|
||||||
|
GtkWidget *child;
|
||||||
|
cairo_t *cr;
|
||||||
|
|
||||||
|
/* get our child (in this case, the event box) */
|
||||||
|
child = gtk_bin_get_child (GTK_BIN (widget));
|
||||||
|
|
||||||
|
/* create a cairo context to draw to the window */
|
||||||
|
cr = gdk_cairo_create (widget->window);
|
||||||
|
|
||||||
|
/* the source data is the (composited) event box */
|
||||||
|
gdk_cairo_set_source_pixmap (cr, child->window,
|
||||||
|
child->allocation.x,
|
||||||
|
child->allocation.y);
|
||||||
|
|
||||||
|
/* draw no more than our expose event intersects our child */
|
||||||
|
region = gdk_region_rectangle (&child->allocation);
|
||||||
|
gdk_region_intersect (region, event->region);
|
||||||
|
gdk_cairo_region (cr, region);
|
||||||
|
cairo_clip (cr);
|
||||||
|
|
||||||
|
/* composite, with a 50% opacity */
|
||||||
|
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
|
||||||
|
cairo_paint_with_alpha (cr, 0.5);
|
||||||
|
|
||||||
|
/* we're done */
|
||||||
|
cairo_destroy (cr);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
create_composited_window (GtkWidget *widget)
|
||||||
|
{
|
||||||
|
static GtkWidget *window;
|
||||||
|
|
||||||
|
if (!window)
|
||||||
|
{
|
||||||
|
GtkWidget *event, *button;
|
||||||
|
GdkScreen *screen;
|
||||||
|
GdkColormap *rgba;
|
||||||
|
GdkColor red;
|
||||||
|
|
||||||
|
/* make the widgets */
|
||||||
|
button = gtk_button_new_with_label ("A Button");
|
||||||
|
event = gtk_event_box_new ();
|
||||||
|
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||||
|
|
||||||
|
/* put a red background on the window */
|
||||||
|
gdk_color_parse ("red", &red);
|
||||||
|
gtk_widget_modify_bg (window, GTK_STATE_NORMAL, &red);
|
||||||
|
|
||||||
|
/* set the colourmap for the event box.
|
||||||
|
* must be done before the event box is realised.
|
||||||
|
*/
|
||||||
|
screen = gtk_widget_get_screen (event);
|
||||||
|
rgba = gdk_screen_get_rgba_colormap (screen);
|
||||||
|
gtk_widget_set_colormap (event, rgba);
|
||||||
|
|
||||||
|
/* set our event box to have a fully-transparent background
|
||||||
|
* drawn on it. currently there is no way to simply tell gtk
|
||||||
|
* that "transparency" is the background colour for a widget.
|
||||||
|
*/
|
||||||
|
gtk_widget_set_app_paintable (GTK_WIDGET (event), TRUE);
|
||||||
|
g_signal_connect (event, "expose-event",
|
||||||
|
G_CALLBACK (transparent_expose), NULL);
|
||||||
|
|
||||||
|
/* put them inside one another */
|
||||||
|
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
|
||||||
|
gtk_container_add (GTK_CONTAINER (window), event);
|
||||||
|
gtk_container_add (GTK_CONTAINER (event), button);
|
||||||
|
|
||||||
|
/* realise and show everything */
|
||||||
|
gtk_widget_realize (button);
|
||||||
|
|
||||||
|
/* set the event box GdkWindow to be composited.
|
||||||
|
* obviously must be performed after event box is realised.
|
||||||
|
*/
|
||||||
|
gdk_window_set_composited (event->window, TRUE);
|
||||||
|
|
||||||
|
/* set up the compositing handler.
|
||||||
|
* note that we do _after so that the normal (red) background is drawn
|
||||||
|
* by gtk before our compositing occurs.
|
||||||
|
*/
|
||||||
|
g_signal_connect_after (window, "expose-event",
|
||||||
|
G_CALLBACK (window_expose_event), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GTK_WIDGET_VISIBLE (window))
|
||||||
|
gtk_widget_show_all (window);
|
||||||
|
else
|
||||||
|
gtk_widget_destroy (window);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Big windows and guffaw scrolling
|
* Big windows and guffaw scrolling
|
||||||
*/
|
*/
|
||||||
@ -13290,6 +13430,7 @@ struct {
|
|||||||
{ "check buttons", create_check_buttons },
|
{ "check buttons", create_check_buttons },
|
||||||
{ "clist", create_clist},
|
{ "clist", create_clist},
|
||||||
{ "color selection", create_color_selection },
|
{ "color selection", create_color_selection },
|
||||||
|
{ "composited window", create_composited_window },
|
||||||
{ "ctree", create_ctree },
|
{ "ctree", create_ctree },
|
||||||
{ "cursors", create_cursors },
|
{ "cursors", create_cursors },
|
||||||
{ "dialog", create_dialog, TRUE },
|
{ "dialog", create_dialog, TRUE },
|
||||||
|
Loading…
Reference in New Issue
Block a user