diff options
author | Michael Natterer <mitch@gimp.org> | 2010-04-15 12:59:44 +0200 |
---|---|---|
committer | Michael Natterer <mitch@gimp.org> | 2010-04-15 12:59:44 +0200 |
commit | 5a52d2a2f09c1999488190d935339e75dbe44c48 (patch) | |
tree | 9913442b4e05d8bbfa1815fa2b7c97211bdf3941 /gdk | |
parent | 615f91daddf983307b93092fd5a1b52f41b8cb94 (diff) | |
download | gtk+-5a52d2a2f09c1999488190d935339e75dbe44c48.tar.gz |
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.
Diffstat (limited to 'gdk')
-rw-r--r-- | gdk/gdk.symbols | 4 | ||||
-rw-r--r-- | gdk/gdkwindow.c | 239 | ||||
-rw-r--r-- | gdk/gdkwindow.h | 13 |
3 files changed, 237 insertions, 19 deletions
diff --git a/gdk/gdk.symbols b/gdk/gdk.symbols index 548a06386c..bb6e2b2475 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 5c9219d583..37abea7b63 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 1a42ed5678..2402078214 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); |