forked from AuroraMiddleware/gtk
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.
This commit is contained in:
parent
615f91dadd
commit
5a52d2a2f0
@ -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
|
||||
|
239
gdk/gdkwindow.c
239
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*
|
||||
@ -2290,6 +2319,35 @@ gdk_window_get_parent (GdkWindow *window)
|
||||
return (GdkWindow*) ((GdkWindowObject*) window)->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
@ -2321,6 +2384,35 @@ gdk_window_get_toplevel (GdkWindow *window)
|
||||
return GDK_WINDOW (obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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:
|
||||
@ -8969,20 +9184,6 @@ update_cursor (GdkDisplay *display)
|
||||
impl_iface->set_cursor ((GdkWindow *)toplevel, cursor_window->cursor);
|
||||
}
|
||||
|
||||
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,
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user