[gtk+] gdk: add API to convert coords between parent and child windows
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] gdk: add API to convert coords between parent and child windows
- Date: Thu, 15 Apr 2010 11:04:47 +0000 (UTC)
commit 5a52d2a2f09c1999488190d935339e75dbe44c48
Author: Michael Natterer <mitch gimp org>
Date: Thu Apr 15 12:59:44 2010 +0200
gdk: add API to convert coords between parent and child windows
which also works for offscreen windows and their embedder.
Also add gdk_window_get_effective_parent() and
gdk_window_get_effective_toplevel() which are offscreen aware.
gdk/gdk.symbols | 4 +
gdk/gdkwindow.c | 239 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
gdk/gdkwindow.h | 13 +++
3 files changed, 237 insertions(+), 19 deletions(-)
---
diff --git a/gdk/gdk.symbols b/gdk/gdk.symbols
index 548a063..bb6e2b2 100644
--- a/gdk/gdk.symbols
+++ b/gdk/gdk.symbols
@@ -685,6 +685,8 @@ gdk_window_clear
gdk_window_clear_area
gdk_window_clear_area_e
gdk_window_constrain_size
+gdk_window_coords_from_parent
+gdk_window_coords_to_parent
gdk_window_destroy
gdk_window_end_paint
gdk_window_flush
@@ -694,10 +696,12 @@ gdk_window_freeze_updates
gdk_window_get_children
gdk_window_get_internal_paint_info
gdk_window_get_parent
+gdk_window_get_effective_parent
gdk_window_get_pointer
gdk_window_get_position
gdk_window_get_state
gdk_window_get_toplevel
+gdk_window_get_effective_toplevel
#ifndef GDK_DISABLE_DEPRECATED
gdk_window_get_toplevels
#endif
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index 5c9219d..37abea7 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -2237,6 +2237,30 @@ gdk_window_is_destroyed (GdkWindow *window)
return GDK_WINDOW_DESTROYED (window);
}
+static void
+to_embedder (GdkWindowObject *window,
+ gdouble offscreen_x,
+ gdouble offscreen_y,
+ gdouble *embedder_x,
+ gdouble *embedder_y)
+{
+ g_signal_emit (window, signals[TO_EMBEDDER], 0,
+ offscreen_x, offscreen_y,
+ embedder_x, embedder_y);
+}
+
+static void
+from_embedder (GdkWindowObject *window,
+ gdouble embedder_x,
+ gdouble embedder_y,
+ gdouble *offscreen_x,
+ gdouble *offscreen_y)
+{
+ g_signal_emit (window, signals[FROM_EMBEDDER], 0,
+ embedder_x, embedder_y,
+ offscreen_x, offscreen_y);
+}
+
/**
* gdk_window_get_position:
* @window: a #GdkWindow
@@ -2280,6 +2304,11 @@ gdk_window_get_position (GdkWindow *window,
* matter for toplevel windows, because the window manager may choose
* to reparent them.
*
+ * Note that you should use gdk_window_get_effective_parent() when
+ * writing generic code that walks up a window hierarchy, because
+ * gdk_window_get_parent() will most likely not do what you expect if
+ * there are offscreen windows in the hierarchy.
+ *
* Return value: parent of @window
**/
GdkWindow*
@@ -2291,6 +2320,35 @@ gdk_window_get_parent (GdkWindow *window)
}
/**
+ * gdk_window_get_effective_parent:
+ * @window: a #GdkWindow
+ *
+ * Obtains the parent of @window, as known to GDK. Works like
+ * gdk_window_get_parent() for normal windows, but returns the
+ * window's embedder for offscreen windows.
+ *
+ * See also: gdk_offscreen_window_get_embedder()
+ *
+ * Return value: effective parent of @window
+ *
+ * Since: 2.22
+ **/
+GdkWindow *
+gdk_window_get_effective_parent (GdkWindow *window)
+{
+ GdkWindowObject *obj;
+
+ g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
+
+ obj = (GdkWindowObject *)window;
+
+ if (obj->window_type == GDK_WINDOW_OFFSCREEN)
+ return gdk_offscreen_window_get_embedder (window);
+ else
+ return (GdkWindow *) obj->parent;
+}
+
+/**
* gdk_window_get_toplevel:
* @window: a #GdkWindow
*
@@ -2300,9 +2358,14 @@ gdk_window_get_parent (GdkWindow *window)
* toplevel window, as is a %GDK_WINDOW_CHILD window that
* has a root window as parent.
*
+ * Note that you should use gdk_window_get_effective_toplevel() when
+ * you want to get to a window's toplevel as seen on screen, because
+ * gdk_window_get_toplevel() will most likely not do what you expect
+ * if there are offscreen windows in the hierarchy.
+ *
* Return value: the toplevel window containing @window
**/
-GdkWindow*
+GdkWindow *
gdk_window_get_toplevel (GdkWindow *window)
{
GdkWindowObject *obj;
@@ -2322,6 +2385,35 @@ gdk_window_get_toplevel (GdkWindow *window)
}
/**
+ * gdk_window_get_effective_toplevel:
+ * @window: a #GdkWindow
+ *
+ * Gets the toplevel window that's an ancestor of @window.
+ *
+ * Works like gdk_window_get_toplevel(), but treats an offscreen window's
+ * embedder as its parent, using gdk_window_get_effective_parent().
+ *
+ * See also: gdk_offscreen_window_get_embedder()
+ *
+ * Return value: the effective toplevel window containing @window
+ *
+ * Since: 2.22
+ **/
+GdkWindow *
+gdk_window_get_effective_toplevel (GdkWindow *window)
+{
+ GdkWindow *parent;
+
+ g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
+
+ while ((parent = gdk_window_get_effective_parent (window)) != NULL &&
+ (gdk_window_get_window_type (parent) != GDK_WINDOW_ROOT))
+ window = parent;
+
+ return window;
+}
+
+/**
* gdk_window_get_children:
* @window: a #GdkWindow
*
@@ -7977,10 +8069,10 @@ gdk_window_get_geometry (GdkWindow *window,
}
else
{
- if (x)
- *x = private->x;
- if (y)
- *y = private->y;
+ if (x)
+ *x = private->x;
+ if (y)
+ *y = private->y;
if (width)
*width = private->width;
if (height)
@@ -8079,6 +8171,129 @@ gdk_window_get_root_coords (GdkWindow *window,
root_x, root_y);
}
+/**
+ * gdk_window_coords_to_parent:
+ * @window: a child window
+ * @x: X coordinate in child's coordinate system
+ * @y: Y coordinate in child's coordinate system
+ * @parent_x: return location for X coordinate in parent's coordinate system
+ * @parent_y: return location for Y coordinate in parent's coordinate system
+ *
+ * Transforms window coordinates from a child window to its parent
+ * window, where the parent window is the normal parent as returned by
+ * gdk_window_get_parent() for normal windows, and the window's
+ * embedder as returned by gdk_offscreen_window_get_embedder() for
+ * offscreen windows.
+ *
+ * For normal windows, calling this function is equivalent to adding
+ * the return values of gdk_window_get_position() to the child coordinates.
+ * For offscreen windows however (which can be arbitrarily transformed),
+ * this function calls the GdkWindow::to-embedder: signal to translate
+ * the coordinates.
+ *
+ * You should always use this function when writing generic code that
+ * walks up a window hierarchy.
+ *
+ * See also: gdk_window_coords_from_parent()
+ *
+ * Since: 2.22
+ **/
+void
+gdk_window_coords_to_parent (GdkWindow *window,
+ gdouble x,
+ gdouble y,
+ gdouble *parent_x,
+ gdouble *parent_y)
+{
+ GdkWindowObject *obj;
+
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ obj = (GdkWindowObject *) window;
+
+ if (obj->window_type == GDK_WINDOW_OFFSCREEN)
+ {
+ gdouble px, py;
+
+ to_embedder (obj, x, y, &px, &py);
+
+ if (parent_x)
+ *parent_x = px;
+
+ if (parent_y)
+ *parent_y = py;
+ }
+ else
+ {
+ if (parent_x)
+ *parent_x = x + obj->x;
+
+ if (parent_y)
+ *parent_y = y + obj->y;
+ }
+}
+
+/**
+ * gdk_window_coords_from_parent:
+ * @window: a child window
+ * @parent_x: X coordinate in parent's coordinate system
+ * @parent_y: Y coordinate in parent's coordinate system
+ * @x: return location for X coordinate in child's coordinate system
+ * @y: return location for Y coordinate in child's coordinate system
+ *
+ * Transforms window coordinates from a parent window to a child
+ * window, where the parent window is the normal parent as returned by
+ * gdk_window_get_parent() for normal windows, and the window's
+ * embedder as returned by gdk_offscreen_window_get_embedder() for
+ * offscreen windows.
+ *
+ * For normal windows, calling this function is equivalent to subtracting
+ * the return values of gdk_window_get_position() from the parent coordinates.
+ * For offscreen windows however (which can be arbitrarily transformed),
+ * this function calls the GdkWindow::from-embedder: signal to translate
+ * the coordinates.
+ *
+ * You should always use this function when writing generic code that
+ * walks down a window hierarchy.
+ *
+ * See also: gdk_window_coords_to_parent()
+ *
+ * Since: 2.22
+ **/
+void
+gdk_window_coords_from_parent (GdkWindow *window,
+ gdouble parent_x,
+ gdouble parent_y,
+ gdouble *x,
+ gdouble *y)
+{
+ GdkWindowObject *obj;
+
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ obj = (GdkWindowObject *) window;
+
+ if (obj->window_type == GDK_WINDOW_OFFSCREEN)
+ {
+ gdouble cx, cy;
+
+ from_embedder (obj, parent_x, parent_y, &cx, &cy);
+
+ if (x)
+ *x = cx;
+
+ if (y)
+ *y = cy;
+ }
+ else
+ {
+ if (x)
+ *x = parent_x - obj->x;
+
+ if (y)
+ *y = parent_y - obj->y;
+ }
+}
/**
* gdk_window_get_deskrelative_origin:
@@ -8970,20 +9185,6 @@ update_cursor (GdkDisplay *display)
}
static void
-from_embedder (GdkWindowObject *window,
- gdouble embedder_x,
- gdouble embedder_y,
- gdouble *offscreen_x,
- gdouble *offscreen_y)
-{
- g_signal_emit (window,
- signals[FROM_EMBEDDER], 0,
- embedder_x, embedder_y,
- offscreen_x, offscreen_y,
- NULL);
-}
-
-static void
convert_coords_to_child (GdkWindowObject *child,
gdouble x,
gdouble y,
diff --git a/gdk/gdkwindow.h b/gdk/gdkwindow.h
index 1a42ed5..2402078 100644
--- a/gdk/gdkwindow.h
+++ b/gdk/gdkwindow.h
@@ -546,6 +546,16 @@ void gdk_window_get_root_coords (GdkWindow *window,
gint y,
gint *root_x,
gint *root_y);
+void gdk_window_coords_to_parent (GdkWindow *window,
+ gdouble x,
+ gdouble y,
+ gdouble *parent_x,
+ gdouble *parent_y);
+void gdk_window_coords_from_parent (GdkWindow *window,
+ gdouble parent_x,
+ gdouble parent_y,
+ gdouble *x,
+ gdouble *y);
#if !defined (GDK_DISABLE_DEPRECATED) || defined (GTK_COMPILATION) || defined (GDK_COMPILATION)
/* Used by gtk_handle_box_button_changed () */
@@ -566,6 +576,9 @@ GdkWindow* gdk_window_get_pointer (GdkWindow *window,
GdkWindow * gdk_window_get_parent (GdkWindow *window);
GdkWindow * gdk_window_get_toplevel (GdkWindow *window);
+GdkWindow * gdk_window_get_effective_parent (GdkWindow *window);
+GdkWindow * gdk_window_get_effective_toplevel (GdkWindow *window);
+
GList * gdk_window_get_children (GdkWindow *window);
GList * gdk_window_peek_children (GdkWindow *window);
GdkEventMask gdk_window_get_events (GdkWindow *window);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]