[gtk+/saved/mir: 37/47] Draw transient windows onto their parents
- From: Ryan Lortie <desrt src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/saved/mir: 37/47] Draw transient windows onto their parents
- Date: Wed, 22 Oct 2014 16:22:58 +0000 (UTC)
commit 6663895e8194225e270a5528cfbc28e6d80f1f4e
Author: Robert Ancell <robert ancell canonical com>
Date: Thu May 29 17:58:58 2014 +0200
Draw transient windows onto their parents
configure.ac | 2 +-
gdk/mir/gdkmir-private.h | 7 ++
gdk/mir/gdkmir.h | 4 +-
gdk/mir/gdkmirdisplay.c | 5 +-
gdk/mir/gdkmirwindowimpl.c | 142 +++++++++++++++++++++++++++++++++++---------
gtk/gtktooltip.c | 16 +++++
6 files changed, 145 insertions(+), 31 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index f49c870..a7cf66e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1394,7 +1394,7 @@ fi
PKG_CHECK_MODULES(ATK, $ATK_PACKAGES)
GTK_PACKAGES="atk >= atk_required_version cairo >= cairo_required_version cairo-gobject >=
cairo_required_version gdk-pixbuf-2.0 >= gdk_pixbuf_required_version gio-2.0 >= glib_required_version"
-GTK_PRIVATE_PACKAGES="$ATK_PACKAGES"
+GTK_PRIVATE_PACKAGES="$ATK_PACKAGES $WAYLAND_PACKAGES $MIR_PACKAGES"
if test "x$enable_x11_backend" = xyes; then
GTK_PRIVATE_PACKAGES="$GTK_PRIVATE_PACKAGES pangoft2"
fi
diff --git a/gdk/mir/gdkmir-private.h b/gdk/mir/gdkmir-private.h
index 8309edf..d81f62f 100644
--- a/gdk/mir/gdkmir-private.h
+++ b/gdk/mir/gdkmir-private.h
@@ -55,6 +55,13 @@ struct _GdkMirWindowImpl
{
GdkWindowImpl parent_instance;
+ /* Window we are temporary for */
+ GdkWindow *transient_for;
+ GdkRectangle transient_size;
+
+ /* Child windows (e.g. tooltips) */
+ GList *transient_children;
+
/* Desired surface attributes */
MirSurfaceType surface_type; // FIXME
MirSurfaceState surface_state;
diff --git a/gdk/mir/gdkmir.h b/gdk/mir/gdkmir.h
index 8ce99b7..1ab0a28 100644
--- a/gdk/mir/gdkmir.h
+++ b/gdk/mir/gdkmir.h
@@ -27,11 +27,13 @@
#define GDK_TYPE_MIR_WINDOW (gdk_mir_window_get_type ())
#define GDK_IS_WINDOW_MIR(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WINDOW_MIR))
+GDK_AVAILABLE_IN_3_10
GType gdk_mir_display_get_type (void);
-GDK_AVAILABLE_IN_ALL
+GDK_AVAILABLE_IN_3_10
struct MirConnection *gdk_mir_display_get_mir_connection (GdkDisplay *display);
+GDK_AVAILABLE_IN_3_10
GType gdk_mir_window_get_type (void);
#endif /* __GDK_MIR_H__ */
diff --git a/gdk/mir/gdkmirdisplay.c b/gdk/mir/gdkmirdisplay.c
index 67af65d..e705239 100644
--- a/gdk/mir/gdkmirdisplay.c
+++ b/gdk/mir/gdkmirdisplay.c
@@ -405,7 +405,10 @@ gdk_mir_display_create_window_impl (GdkDisplay *display,
GdkWindowAttr *attributes,
gint attributes_mask)
{
- g_printerr ("gdk_mir_display_create_window_impl (%d, %d, %d, %d), events=0x%X\n", window->x, window->y,
window->width, window->height, event_mask);
+ g_printerr ("gdk_mir_display_create_window_impl");
+ g_printerr (" location=(%d, %d)", window->x, window->y);
+ g_printerr (" size=(%d, %d)", window->width, window->height);
+ g_printerr ("\n");
window->impl = _gdk_mir_window_impl_new ();
}
diff --git a/gdk/mir/gdkmirwindowimpl.c b/gdk/mir/gdkmirwindowimpl.c
index ab0bcc7..a3d9425 100644
--- a/gdk/mir/gdkmirwindowimpl.c
+++ b/gdk/mir/gdkmirwindowimpl.c
@@ -41,6 +41,8 @@ struct _GdkMirWindowImplClass
G_DEFINE_TYPE (GdkMirWindowImpl, gdk_mir_window_impl, GDK_TYPE_WINDOW_IMPL)
+static cairo_surface_t *gdk_mir_window_impl_ref_cairo_surface (GdkWindow *window);
+
GdkWindowImpl *
_gdk_mir_window_impl_new (void)
{
@@ -153,6 +155,41 @@ send_buffer (GdkWindow *window)
{
GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
+ /* Transient windows draw onto parent instead */
+ if (impl->transient_for)
+ {
+ gdk_window_invalidate_rect (impl->transient_for, &impl->transient_size, FALSE);
+ return;
+ }
+
+ /* Composite transient windows over this one */
+ if (impl->transient_children)
+ {
+ cairo_surface_t *surface;
+ cairo_t *c;
+ GList *link;
+
+ surface = gdk_mir_window_impl_ref_cairo_surface (window);
+ c = cairo_create (surface);
+
+ for (link = impl->transient_children; link; link = link->next)
+ {
+ GdkWindow *child_window = link->data;
+ GdkMirWindowImpl *child_impl = GDK_MIR_WINDOW_IMPL (child_window->impl);
+
+ /* Skip children not yet drawn to */
+ if (!child_impl->cairo_surface)
+ continue;
+
+ cairo_set_source_surface (c, child_impl->cairo_surface, child_impl->transient_size.x,
child_impl->transient_size.y);
+ cairo_rectangle (c, child_impl->transient_size.x, child_impl->transient_size.y,
child_impl->transient_size.width, child_impl->transient_size.height);
+ cairo_fill (c);
+ }
+
+ cairo_destroy (c);
+ cairo_surface_destroy (surface);
+ }
+
/* Send the completed buffer to Mir */
mir_surface_swap_buffers_sync (impl->surface);
@@ -180,31 +217,40 @@ gdk_mir_window_impl_ref_cairo_surface (GdkWindow *window)
return impl->cairo_surface;
}
- ensure_surface (window);
-
- mir_surface_get_graphics_region (impl->surface, ®ion);
-
- // FIXME: Should calculate this once
- switch (region.pixel_format)
+ /* Transient windows get rendered into a buffer and copied onto their parent */
+ if (impl->transient_for)
{
- case mir_pixel_format_argb_8888:
- pixel_format = CAIRO_FORMAT_ARGB32;
- break;
- default:
- case mir_pixel_format_abgr_8888:
- case mir_pixel_format_xbgr_8888:
- case mir_pixel_format_xrgb_8888:
- case mir_pixel_format_bgr_888:
- // uh-oh...
- g_printerr ("Unsupported pixel format %d\n", region.pixel_format);
- break;
+ cairo_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, impl->transient_size.width,
impl->transient_size.height);
+ }
+ else
+ {
+ ensure_surface (window);
+
+ mir_surface_get_graphics_region (impl->surface, ®ion);
+
+ // FIXME: Should calculate this once
+ switch (region.pixel_format)
+ {
+ case mir_pixel_format_argb_8888:
+ pixel_format = CAIRO_FORMAT_ARGB32;
+ break;
+ default:
+ case mir_pixel_format_abgr_8888:
+ case mir_pixel_format_xbgr_8888:
+ case mir_pixel_format_xrgb_8888:
+ case mir_pixel_format_bgr_888:
+ // uh-oh...
+ g_printerr ("Unsupported pixel format %d\n", region.pixel_format);
+ break;
+ }
+
+ cairo_surface = cairo_image_surface_create_for_data ((unsigned char *) region.vaddr,
+ pixel_format,
+ region.width,
+ region.height,
+ region.stride);
}
- cairo_surface = cairo_image_surface_create_for_data ((unsigned char *) region.vaddr,
- pixel_format,
- region.width,
- region.height,
- region.stride);
impl->cairo_surface = cairo_surface_reference (cairo_surface);
/* Draw background */
@@ -233,6 +279,13 @@ static void
gdk_mir_window_impl_finalize (GObject *object)
{
GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (object);
+ GList *link;
+
+ for (link = impl->transient_children; link; link = link->next)
+ {
+ GdkWindow *window = link->data;
+ gdk_window_destroy (window);
+ }
if (impl->background)
cairo_pattern_destroy (impl->background);
@@ -240,6 +293,7 @@ gdk_mir_window_impl_finalize (GObject *object)
mir_surface_release_sync (impl->surface);
if (impl->cairo_surface)
cairo_surface_destroy (impl->cairo_surface);
+ g_list_free (impl->transient_children);
G_OBJECT_CLASS (gdk_mir_window_impl_parent_class)->finalize (object);
}
@@ -324,16 +378,25 @@ gdk_mir_window_impl_move_resize (GdkWindow *window,
gint height)
{
g_printerr ("gdk_mir_window_impl_move_resize (%d, %d, %d, %d)\n", x, y, width, height);
+ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
- if (with_move)
+ /* Transient windows are always the requested size */
+ if (impl->transient_for)
{
- window->x = x;
- window->y = y;
+ if (with_move)
+ {
+ impl->transient_size.x = x;
+ impl->transient_size.y = y;
+ }
+ if (width >= 0)
+ impl->transient_size.width = width;
+ if (height >= 0)
+ impl->transient_size.height = height;
}
/* If resize requested then destroy surface */
if (width >= 0)
- ensure_no_surface (window);
+ ensure_no_surface (window);
}
static void
@@ -511,6 +574,13 @@ gdk_mir_window_impl_destroy (GdkWindow *window,
impl->visible = FALSE;
ensure_no_surface (window);
+
+ /* Remove from transient list */
+ if (impl->transient_for)
+ {
+ GdkMirWindowImpl *parent_impl = GDK_MIR_WINDOW_IMPL (impl->transient_for->impl);
+ parent_impl->transient_children = g_list_remove (parent_impl->transient_children, window);
+ }
}
static void
@@ -614,8 +684,24 @@ static void
gdk_mir_window_impl_set_transient_for (GdkWindow *window,
GdkWindow *parent)
{
- //g_printerr ("gdk_mir_window_impl_set_transient_for\n");
- //FIXME
+ g_printerr ("gdk_mir_window_impl_set_transient_for\n");
+ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
+
+ if (impl->transient_for == parent)
+ return;
+
+ g_return_if_fail (impl->transient_for == NULL);
+
+ /* Link this window to the parent */
+ impl->transient_for = parent;
+ if (parent)
+ {
+ GdkMirWindowImpl *parent_impl = GDK_MIR_WINDOW_IMPL (parent->impl);
+ parent_impl->transient_children = g_list_append (parent_impl->transient_children, window);
+ }
+
+ /* Remove surface if we had made one before this was set */
+ ensure_no_surface (window);
}
static void
diff --git a/gtk/gtktooltip.c b/gtk/gtktooltip.c
index 8c3f2df..ea76210 100644
--- a/gtk/gtktooltip.c
+++ b/gtk/gtktooltip.c
@@ -40,6 +40,9 @@
#ifdef GDK_WINDOWING_WAYLAND
#include "wayland/gdkwayland.h"
#endif
+#ifdef GDK_WINDOWING_MIR
+#include "mir/gdkmir.h"
+#endif
/**
@@ -1169,6 +1172,19 @@ found:
GTK_WINDOW (toplevel));
}
#endif
+#ifdef GDK_WINDOWING_MIR
+ /* Set the transient parent on the tooltip when running with the Mir
+ * backend to allow correct positioning of the tooltip windows */
+ if (GDK_IS_MIR_DISPLAY (display))
+ {
+ GtkWidget *toplevel;
+
+ toplevel = gtk_widget_get_toplevel (tooltip->tooltip_widget);
+ if (GTK_IS_WINDOW (toplevel))
+ gtk_window_set_transient_for (GTK_WINDOW (tooltip->current_window),
+ GTK_WINDOW (toplevel));
+ }
+#endif
x -= border.left;
y -= border.top;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]