Function to get a range of information about all the children of a window
Fri Jul 4 23:49:22 2003 Owen Taylor <otaylor@redhat.com> * gdk/x11/gdkasync.[ch] (_gdk_x11_get_window_child_info): Function to get a range of information about all the children of a window in a single pass. * gdk/x11/gdkdnd-x11.c (get_client_window_at_coords_recurse) gdk/x11/gdkdnd-x11.c (gdk_window_cache_new): Use _gdk_x11_get_window_child_info() to greatly reduce the number of roundtrips.
This commit is contained in:
11
ChangeLog
11
ChangeLog
@ -1,3 +1,14 @@
|
|||||||
|
Fri Jul 4 23:49:22 2003 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
|
* gdk/x11/gdkasync.[ch] (_gdk_x11_get_window_child_info):
|
||||||
|
Function to get a range of information about all the
|
||||||
|
children of a window in a single pass.
|
||||||
|
|
||||||
|
* gdk/x11/gdkdnd-x11.c (get_client_window_at_coords_recurse)
|
||||||
|
gdk/x11/gdkdnd-x11.c (gdk_window_cache_new): Use
|
||||||
|
_gdk_x11_get_window_child_info() to greatly reduce
|
||||||
|
the number of roundtrips.
|
||||||
|
|
||||||
Fri Jul 4 22:57:18 2003 Owen Taylor <otaylor@redhat.com>
|
Fri Jul 4 22:57:18 2003 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
* gdk/x11/gdkasync.[ch] (_gdk_send_xevent_async): Add
|
* gdk/x11/gdkasync.[ch] (_gdk_send_xevent_async): Add
|
||||||
|
@ -1,3 +1,14 @@
|
|||||||
|
Fri Jul 4 23:49:22 2003 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
|
* gdk/x11/gdkasync.[ch] (_gdk_x11_get_window_child_info):
|
||||||
|
Function to get a range of information about all the
|
||||||
|
children of a window in a single pass.
|
||||||
|
|
||||||
|
* gdk/x11/gdkdnd-x11.c (get_client_window_at_coords_recurse)
|
||||||
|
gdk/x11/gdkdnd-x11.c (gdk_window_cache_new): Use
|
||||||
|
_gdk_x11_get_window_child_info() to greatly reduce
|
||||||
|
the number of roundtrips.
|
||||||
|
|
||||||
Fri Jul 4 22:57:18 2003 Owen Taylor <otaylor@redhat.com>
|
Fri Jul 4 22:57:18 2003 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
* gdk/x11/gdkasync.[ch] (_gdk_send_xevent_async): Add
|
* gdk/x11/gdkasync.[ch] (_gdk_send_xevent_async): Add
|
||||||
|
@ -1,3 +1,14 @@
|
|||||||
|
Fri Jul 4 23:49:22 2003 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
|
* gdk/x11/gdkasync.[ch] (_gdk_x11_get_window_child_info):
|
||||||
|
Function to get a range of information about all the
|
||||||
|
children of a window in a single pass.
|
||||||
|
|
||||||
|
* gdk/x11/gdkdnd-x11.c (get_client_window_at_coords_recurse)
|
||||||
|
gdk/x11/gdkdnd-x11.c (gdk_window_cache_new): Use
|
||||||
|
_gdk_x11_get_window_child_info() to greatly reduce
|
||||||
|
the number of roundtrips.
|
||||||
|
|
||||||
Fri Jul 4 22:57:18 2003 Owen Taylor <otaylor@redhat.com>
|
Fri Jul 4 22:57:18 2003 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
* gdk/x11/gdkasync.[ch] (_gdk_send_xevent_async): Add
|
* gdk/x11/gdkasync.[ch] (_gdk_send_xevent_async): Add
|
||||||
|
@ -1,3 +1,14 @@
|
|||||||
|
Fri Jul 4 23:49:22 2003 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
|
* gdk/x11/gdkasync.[ch] (_gdk_x11_get_window_child_info):
|
||||||
|
Function to get a range of information about all the
|
||||||
|
children of a window in a single pass.
|
||||||
|
|
||||||
|
* gdk/x11/gdkdnd-x11.c (get_client_window_at_coords_recurse)
|
||||||
|
gdk/x11/gdkdnd-x11.c (gdk_window_cache_new): Use
|
||||||
|
_gdk_x11_get_window_child_info() to greatly reduce
|
||||||
|
the number of roundtrips.
|
||||||
|
|
||||||
Fri Jul 4 22:57:18 2003 Owen Taylor <otaylor@redhat.com>
|
Fri Jul 4 22:57:18 2003 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
* gdk/x11/gdkasync.[ch] (_gdk_send_xevent_async): Add
|
* gdk/x11/gdkasync.[ch] (_gdk_send_xevent_async): Add
|
||||||
|
@ -1,3 +1,14 @@
|
|||||||
|
Fri Jul 4 23:49:22 2003 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
|
* gdk/x11/gdkasync.[ch] (_gdk_x11_get_window_child_info):
|
||||||
|
Function to get a range of information about all the
|
||||||
|
children of a window in a single pass.
|
||||||
|
|
||||||
|
* gdk/x11/gdkdnd-x11.c (get_client_window_at_coords_recurse)
|
||||||
|
gdk/x11/gdkdnd-x11.c (gdk_window_cache_new): Use
|
||||||
|
_gdk_x11_get_window_child_info() to greatly reduce
|
||||||
|
the number of roundtrips.
|
||||||
|
|
||||||
Fri Jul 4 22:57:18 2003 Owen Taylor <otaylor@redhat.com>
|
Fri Jul 4 22:57:18 2003 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
* gdk/x11/gdkasync.[ch] (_gdk_send_xevent_async): Add
|
* gdk/x11/gdkasync.[ch] (_gdk_send_xevent_async): Add
|
||||||
|
@ -47,9 +47,37 @@ in this Software without prior written authorization from The Open Group.
|
|||||||
#include "gdkasync.h"
|
#include "gdkasync.h"
|
||||||
#include "gdkx.h"
|
#include "gdkx.h"
|
||||||
|
|
||||||
|
typedef struct _ChildInfoChildState ChildInfoChildState;
|
||||||
|
typedef struct _ChildInfoState ChildInfoState;
|
||||||
typedef struct _SendEventState SendEventState;
|
typedef struct _SendEventState SendEventState;
|
||||||
typedef struct _SetInputFocusState SetInputFocusState;
|
typedef struct _SetInputFocusState SetInputFocusState;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
CHILD_INFO_GET_PROPERTY,
|
||||||
|
CHILD_INFO_GET_WA,
|
||||||
|
CHILD_INFO_GET_GEOMETRY
|
||||||
|
} ChildInfoReq;
|
||||||
|
|
||||||
|
struct _ChildInfoChildState
|
||||||
|
{
|
||||||
|
gulong seq[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _ChildInfoState
|
||||||
|
{
|
||||||
|
gboolean get_wm_state;
|
||||||
|
Window *children;
|
||||||
|
guint nchildren;
|
||||||
|
GdkChildInfoX11 *child_info;
|
||||||
|
ChildInfoChildState *child_states;
|
||||||
|
|
||||||
|
guint current_child;
|
||||||
|
guint n_children_found;
|
||||||
|
gint current_request;
|
||||||
|
gboolean have_error;
|
||||||
|
gboolean child_has_error;
|
||||||
|
};
|
||||||
|
|
||||||
struct _SendEventState
|
struct _SendEventState
|
||||||
{
|
{
|
||||||
Display *dpy;
|
Display *dpy;
|
||||||
@ -81,13 +109,11 @@ send_event_handler (Display *dpy,
|
|||||||
|
|
||||||
if (dpy->last_request_read == state->send_event_req)
|
if (dpy->last_request_read == state->send_event_req)
|
||||||
{
|
{
|
||||||
if (rep->generic.type == X_Error)
|
if (rep->generic.type == X_Error &&
|
||||||
|
rep->error.errorCode == BadWindow)
|
||||||
{
|
{
|
||||||
if (rep->error.errorCode == BadWindow)
|
state->have_error = TRUE;
|
||||||
{
|
return True;
|
||||||
state->have_error = TRUE;
|
|
||||||
return True;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (dpy->last_request_read == state->get_input_focus_req)
|
else if (dpy->last_request_read == state->get_input_focus_req)
|
||||||
@ -97,6 +123,9 @@ send_event_handler (Display *dpy,
|
|||||||
|
|
||||||
if (rep->generic.type != X_Error)
|
if (rep->generic.type != X_Error)
|
||||||
{
|
{
|
||||||
|
/* Actually does nothing, since there are no additional bytes
|
||||||
|
* to read, but maintain good form.
|
||||||
|
*/
|
||||||
repl = (xGetInputFocusReply *)
|
repl = (xGetInputFocusReply *)
|
||||||
_XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len,
|
_XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len,
|
||||||
(sizeof(xGetInputFocusReply) - sizeof(xReply)) >> 2,
|
(sizeof(xGetInputFocusReply) - sizeof(xReply)) >> 2,
|
||||||
@ -108,22 +137,20 @@ send_event_handler (Display *dpy,
|
|||||||
|
|
||||||
DeqAsyncHandler(state->dpy, &state->async);
|
DeqAsyncHandler(state->dpy, &state->async);
|
||||||
|
|
||||||
g_free (state);
|
return (rep->generic.type != X_Error);
|
||||||
|
|
||||||
return True;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_gdk_send_xevent_async (GdkDisplay *display,
|
_gdk_x11_send_xevent_async (GdkDisplay *display,
|
||||||
Window window,
|
Window window,
|
||||||
gboolean propagate,
|
gboolean propagate,
|
||||||
glong event_mask,
|
glong event_mask,
|
||||||
XEvent *event_send,
|
XEvent *event_send,
|
||||||
GdkSendXEventCallback callback,
|
GdkSendXEventCallback callback,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
Display *dpy;
|
Display *dpy;
|
||||||
SendEventState *state;
|
SendEventState *state;
|
||||||
@ -288,3 +315,245 @@ _gdk_x11_set_input_focus_safe (GdkDisplay *display,
|
|||||||
UnlockDisplay(dpy);
|
UnlockDisplay(dpy);
|
||||||
SyncHandle();
|
SyncHandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_get_wa_reply (Display *dpy,
|
||||||
|
ChildInfoState *state,
|
||||||
|
xGetWindowAttributesReply *repl)
|
||||||
|
{
|
||||||
|
GdkChildInfoX11 *child = &state->child_info[state->n_children_found];
|
||||||
|
child->is_mapped = repl->mapState != IsUnmapped;
|
||||||
|
child->window_class = repl->class;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_get_geometry_reply (Display *dpy,
|
||||||
|
ChildInfoState *state,
|
||||||
|
xGetGeometryReply *repl)
|
||||||
|
{
|
||||||
|
GdkChildInfoX11 *child = &state->child_info[state->n_children_found];
|
||||||
|
|
||||||
|
child->x = cvtINT16toInt (repl->x);
|
||||||
|
child->y = cvtINT16toInt (repl->y);
|
||||||
|
child->width = repl->width;
|
||||||
|
child->height = repl->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_get_property_reply (Display *dpy,
|
||||||
|
ChildInfoState *state,
|
||||||
|
xGetPropertyReply *repl)
|
||||||
|
{
|
||||||
|
GdkChildInfoX11 *child = &state->child_info[state->n_children_found];
|
||||||
|
child->has_wm_state = repl->propertyType != None;
|
||||||
|
|
||||||
|
/* Since we called GetProperty with longLength of 0, we don't
|
||||||
|
* have to worry about consuming the property data that would
|
||||||
|
* normally follow after the reply
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
next_child (ChildInfoState *state)
|
||||||
|
{
|
||||||
|
if (state->current_request == CHILD_INFO_GET_GEOMETRY)
|
||||||
|
{
|
||||||
|
if (!state->have_error && !state->child_has_error)
|
||||||
|
{
|
||||||
|
state->child_info[state->n_children_found].window = state->children[state->current_child];
|
||||||
|
state->n_children_found++;
|
||||||
|
}
|
||||||
|
state->current_child++;
|
||||||
|
if (state->get_wm_state)
|
||||||
|
state->current_request = CHILD_INFO_GET_PROPERTY;
|
||||||
|
else
|
||||||
|
state->current_request = CHILD_INFO_GET_WA;
|
||||||
|
state->child_has_error = FALSE;
|
||||||
|
state->have_error = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
state->current_request++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
get_child_info_handler (Display *dpy,
|
||||||
|
xReply *rep,
|
||||||
|
char *buf,
|
||||||
|
int len,
|
||||||
|
XPointer data)
|
||||||
|
{
|
||||||
|
Bool result = True;
|
||||||
|
|
||||||
|
ChildInfoState *state = (ChildInfoState *)data;
|
||||||
|
|
||||||
|
if (dpy->last_request_read != state->child_states[state->current_child].seq[state->current_request])
|
||||||
|
return False;
|
||||||
|
|
||||||
|
if (rep->generic.type == X_Error)
|
||||||
|
{
|
||||||
|
state->child_has_error = TRUE;
|
||||||
|
if (rep->error.errorCode != BadDrawable ||
|
||||||
|
rep->error.errorCode != BadWindow)
|
||||||
|
{
|
||||||
|
state->have_error = TRUE;
|
||||||
|
result = False;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (state->current_request)
|
||||||
|
{
|
||||||
|
case CHILD_INFO_GET_PROPERTY:
|
||||||
|
{
|
||||||
|
xGetPropertyReply replbuf;
|
||||||
|
xGetPropertyReply *repl;
|
||||||
|
|
||||||
|
repl = (xGetPropertyReply *)
|
||||||
|
_XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len,
|
||||||
|
(sizeof(xGetPropertyReply) - sizeof(xReply)) >> 2,
|
||||||
|
True);
|
||||||
|
|
||||||
|
handle_get_property_reply (dpy, state, repl);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CHILD_INFO_GET_WA:
|
||||||
|
{
|
||||||
|
xGetWindowAttributesReply replbuf;
|
||||||
|
xGetWindowAttributesReply *repl;
|
||||||
|
|
||||||
|
repl = (xGetWindowAttributesReply *)
|
||||||
|
_XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len,
|
||||||
|
(sizeof(xGetWindowAttributesReply) - sizeof(xReply)) >> 2,
|
||||||
|
True);
|
||||||
|
|
||||||
|
handle_get_wa_reply (dpy, state, repl);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CHILD_INFO_GET_GEOMETRY:
|
||||||
|
{
|
||||||
|
xGetGeometryReply replbuf;
|
||||||
|
xGetGeometryReply *repl;
|
||||||
|
|
||||||
|
repl = (xGetGeometryReply *)
|
||||||
|
_XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len,
|
||||||
|
(sizeof(xGetGeometryReply) - sizeof(xReply)) >> 2,
|
||||||
|
True);
|
||||||
|
|
||||||
|
handle_get_geometry_reply (dpy, state, repl);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
next_child (state);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_gdk_x11_get_window_child_info (GdkDisplay *display,
|
||||||
|
Window window,
|
||||||
|
gboolean get_wm_state,
|
||||||
|
GdkChildInfoX11 **children,
|
||||||
|
guint *nchildren)
|
||||||
|
{
|
||||||
|
Display *dpy;
|
||||||
|
_XAsyncHandler async;
|
||||||
|
ChildInfoState state;
|
||||||
|
Window root, parent;
|
||||||
|
Atom wm_state_atom;
|
||||||
|
Bool result;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
*children = NULL;
|
||||||
|
*nchildren = 0;
|
||||||
|
|
||||||
|
dpy = GDK_DISPLAY_XDISPLAY (display);
|
||||||
|
wm_state_atom = gdk_x11_get_xatom_by_name_for_display (display, "WM_STATE");
|
||||||
|
|
||||||
|
gdk_error_trap_push ();
|
||||||
|
result = XQueryTree (dpy, window, &root, &parent,
|
||||||
|
&state.children, &state.nchildren);
|
||||||
|
gdk_error_trap_pop ();
|
||||||
|
if (!result)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
state.get_wm_state = get_wm_state;
|
||||||
|
state.child_info = g_new (GdkChildInfoX11, state.nchildren);
|
||||||
|
state.child_states = g_new (ChildInfoChildState, state.nchildren);
|
||||||
|
state.current_child = 0;
|
||||||
|
state.n_children_found = 0;
|
||||||
|
if (get_wm_state)
|
||||||
|
state.current_request = CHILD_INFO_GET_PROPERTY;
|
||||||
|
else
|
||||||
|
state.current_request = CHILD_INFO_GET_WA;
|
||||||
|
state.have_error = FALSE;
|
||||||
|
state.child_has_error = FALSE;
|
||||||
|
|
||||||
|
LockDisplay(dpy);
|
||||||
|
|
||||||
|
async.next = dpy->async_handlers;
|
||||||
|
async.handler = get_child_info_handler;
|
||||||
|
async.data = (XPointer) &state;
|
||||||
|
dpy->async_handlers = &async;
|
||||||
|
|
||||||
|
for (i = 0; i < state.nchildren; i++)
|
||||||
|
{
|
||||||
|
xResourceReq *resource_req;
|
||||||
|
xGetPropertyReq *prop_req;
|
||||||
|
Window window = state.children[i];
|
||||||
|
|
||||||
|
if (get_wm_state)
|
||||||
|
{
|
||||||
|
GetReq (GetProperty, prop_req);
|
||||||
|
prop_req->window = window;
|
||||||
|
prop_req->property = wm_state_atom;
|
||||||
|
prop_req->type = AnyPropertyType;
|
||||||
|
prop_req->delete = False;
|
||||||
|
prop_req->longOffset = 0;
|
||||||
|
prop_req->longLength = 0;
|
||||||
|
|
||||||
|
state.child_states[i].seq[CHILD_INFO_GET_PROPERTY] = dpy->request;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetResReq(GetWindowAttributes, window, resource_req);
|
||||||
|
state.child_states[i].seq[CHILD_INFO_GET_WA] = dpy->request;
|
||||||
|
|
||||||
|
GetResReq(GetGeometry, window, resource_req);
|
||||||
|
state.child_states[i].seq[CHILD_INFO_GET_GEOMETRY] = dpy->request;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i != 0)
|
||||||
|
{
|
||||||
|
/* Wait for the last reply
|
||||||
|
*/
|
||||||
|
xGetGeometryReply rep;
|
||||||
|
|
||||||
|
/* On error, our async handler will get called
|
||||||
|
*/
|
||||||
|
if (_XReply (dpy, (xReply *)&rep, 0, xTrue))
|
||||||
|
handle_get_geometry_reply (dpy, &state, &rep);
|
||||||
|
|
||||||
|
next_child (&state);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!state.have_error)
|
||||||
|
{
|
||||||
|
*children = state.child_info;
|
||||||
|
*nchildren = state.n_children_found;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_free (state.child_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
XFree (state.children);
|
||||||
|
g_free (state.child_states);
|
||||||
|
|
||||||
|
DeqAsyncHandler(dpy, &async);
|
||||||
|
UnlockDisplay(dpy);
|
||||||
|
SyncHandle();
|
||||||
|
|
||||||
|
return !state.have_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -26,11 +26,25 @@
|
|||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
typedef struct _GdkChildInfoX11 GdkChildInfoX11;
|
||||||
|
|
||||||
typedef void (*GdkSendXEventCallback) (Window window,
|
typedef void (*GdkSendXEventCallback) (Window window,
|
||||||
gboolean success,
|
gboolean success,
|
||||||
gpointer data);
|
gpointer data);
|
||||||
|
|
||||||
void _gdk_send_xevent_async (GdkDisplay *display,
|
struct _GdkChildInfoX11
|
||||||
|
{
|
||||||
|
Window window;
|
||||||
|
gint x;
|
||||||
|
gint y;
|
||||||
|
gint width;
|
||||||
|
gint height;
|
||||||
|
guint is_mapped : 1;
|
||||||
|
guint has_wm_state : 1;
|
||||||
|
guint window_class : 2;
|
||||||
|
};
|
||||||
|
|
||||||
|
void _gdk_x11_send_xevent_async (GdkDisplay *display,
|
||||||
Window window,
|
Window window,
|
||||||
gboolean propagate,
|
gboolean propagate,
|
||||||
glong event_mask,
|
glong event_mask,
|
||||||
@ -42,6 +56,12 @@ void _gdk_x11_set_input_focus_safe (GdkDisplay *display,
|
|||||||
int revert_to,
|
int revert_to,
|
||||||
Time time);
|
Time time);
|
||||||
|
|
||||||
|
gboolean _gdk_x11_get_window_child_info (GdkDisplay *display,
|
||||||
|
Window window,
|
||||||
|
gboolean get_wm_state,
|
||||||
|
GdkChildInfoX11 **children,
|
||||||
|
guint *nchildren);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GDK_ASYNC_H__ */
|
#endif /* __GDK_ASYNC_H__ */
|
||||||
|
@ -449,11 +449,10 @@ static GdkWindowCache *
|
|||||||
gdk_window_cache_new (GdkScreen *screen)
|
gdk_window_cache_new (GdkScreen *screen)
|
||||||
{
|
{
|
||||||
XWindowAttributes xwa;
|
XWindowAttributes xwa;
|
||||||
Window root, parent, *children;
|
|
||||||
unsigned int nchildren;
|
|
||||||
int i;
|
|
||||||
Display *xdisplay = GDK_SCREEN_XDISPLAY (screen);
|
Display *xdisplay = GDK_SCREEN_XDISPLAY (screen);
|
||||||
GdkWindow *root_window = gdk_screen_get_root_window (screen);
|
GdkWindow *root_window = gdk_screen_get_root_window (screen);
|
||||||
|
GdkChildInfoX11 *children;
|
||||||
|
guint nchildren, i;
|
||||||
|
|
||||||
GdkWindowCache *result = g_new (GdkWindowCache, 1);
|
GdkWindowCache *result = g_new (GdkWindowCache, 1);
|
||||||
|
|
||||||
@ -467,25 +466,19 @@ gdk_window_cache_new (GdkScreen *screen)
|
|||||||
result->old_event_mask | SubstructureNotifyMask);
|
result->old_event_mask | SubstructureNotifyMask);
|
||||||
gdk_window_add_filter (root_window, gdk_window_cache_filter, result);
|
gdk_window_add_filter (root_window, gdk_window_cache_filter, result);
|
||||||
|
|
||||||
gdk_error_trap_push ();
|
if (!_gdk_x11_get_window_child_info (gdk_screen_get_display (screen),
|
||||||
|
GDK_WINDOW_XWINDOW (root_window),
|
||||||
|
FALSE, &children, &nchildren))
|
||||||
|
return result;
|
||||||
|
|
||||||
if (!XQueryTree(xdisplay, GDK_WINDOW_XWINDOW (root_window),
|
|
||||||
&root, &parent, &children, &nchildren))
|
|
||||||
{
|
|
||||||
gdk_error_trap_pop ();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < nchildren ; i++)
|
for (i = 0; i < nchildren ; i++)
|
||||||
{
|
{
|
||||||
if (XGetWindowAttributes (xdisplay, children[i], &xwa))
|
gdk_window_cache_add (result, children[i].window,
|
||||||
gdk_window_cache_add (result, children[i],
|
children[i].x, children[i].y, children[i].width, children[i].height,
|
||||||
xwa.x, xwa.y, xwa.width, xwa.height,
|
children[i].is_mapped);
|
||||||
xwa.map_state != IsUnmapped);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XFree (children);
|
g_free (children);
|
||||||
gdk_error_trap_pop ();
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -507,67 +500,70 @@ gdk_window_cache_destroy (GdkWindowCache *cache)
|
|||||||
g_free (cache);
|
g_free (cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
window_has_wm_state (GdkDisplay *display,
|
||||||
|
Window win)
|
||||||
|
{
|
||||||
|
Atom type = None;
|
||||||
|
int format;
|
||||||
|
unsigned long nitems, after;
|
||||||
|
unsigned char *data;
|
||||||
|
|
||||||
|
if (XGetWindowProperty (GDK_DISPLAY_XDISPLAY(display), win,
|
||||||
|
gdk_x11_get_xatom_by_name_for_display (display, "WM_STATE"),
|
||||||
|
0, 0, False, AnyPropertyType,
|
||||||
|
&type, &format, &nitems, &after, &data) != Success)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (type != None)
|
||||||
|
{
|
||||||
|
XFree (data);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static Window
|
static Window
|
||||||
get_client_window_at_coords_recurse (GdkDisplay *display,
|
get_client_window_at_coords_recurse (GdkDisplay *display,
|
||||||
Window win,
|
Window win,
|
||||||
gint x,
|
gint x,
|
||||||
gint y)
|
gint y)
|
||||||
{
|
{
|
||||||
Window root, tmp_parent, *children;
|
GdkChildInfoX11 *children;
|
||||||
unsigned int nchildren;
|
unsigned int nchildren;
|
||||||
int i;
|
int i;
|
||||||
Window child = None;
|
gboolean found_child = FALSE;
|
||||||
Atom type = None;
|
GdkChildInfoX11 child;
|
||||||
int format;
|
|
||||||
unsigned long nitems, after;
|
if (!_gdk_x11_get_window_child_info (display, win, TRUE,
|
||||||
unsigned char *data;
|
&children, &nchildren))
|
||||||
|
|
||||||
if (XGetWindowProperty (GDK_DISPLAY_XDISPLAY(display), win,
|
|
||||||
gdk_x11_get_xatom_by_name_for_display (display, "WM_STATE"),
|
|
||||||
0, 0, False, AnyPropertyType,
|
|
||||||
&type, &format, &nitems, &after, &data) != Success)
|
|
||||||
return None;
|
return None;
|
||||||
|
|
||||||
if (type != None)
|
for (i = nchildren - 1; (i >= 0) && !found_child; i--)
|
||||||
{
|
{
|
||||||
XFree (data);
|
GdkChildInfoX11 *cur_child = &children[i];
|
||||||
return win;
|
|
||||||
|
if ((cur_child->is_mapped) && (cur_child->window_class == InputOutput) &&
|
||||||
|
(x >= cur_child->x) && (x < cur_child->x + cur_child->width) &&
|
||||||
|
(y >= cur_child->y) && (y < cur_child->y + cur_child->height))
|
||||||
|
{
|
||||||
|
x -= cur_child->x;
|
||||||
|
y -= cur_child->y;
|
||||||
|
child = *cur_child;
|
||||||
|
found_child = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
g_free (children);
|
||||||
/* This is beautiful! Damn Enlightenment and click-to-focus */
|
|
||||||
if (!XTranslateCoordinates (gdk_display, _gdk_root_window, win,
|
if (found_child)
|
||||||
x_root, y_root, &dest_x, &dest_y, &child))
|
|
||||||
return None;
|
|
||||||
|
|
||||||
#else
|
|
||||||
if (!XQueryTree (GDK_DISPLAY_XDISPLAY (display), win,
|
|
||||||
&root, &tmp_parent, &children, &nchildren))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (i = nchildren - 1; (i >= 0) && (child == None); i--)
|
|
||||||
{
|
{
|
||||||
XWindowAttributes xwa;
|
if (child.has_wm_state)
|
||||||
|
return child.window;
|
||||||
if (XGetWindowAttributes (GDK_DISPLAY_XDISPLAY (display),
|
else
|
||||||
children[i], &xwa))
|
return get_client_window_at_coords_recurse (display, child.window, x, y);
|
||||||
{
|
|
||||||
if ((xwa.map_state == IsViewable) && (xwa.class == InputOutput) &&
|
|
||||||
(x >= xwa.x) && (x < xwa.x + (gint)xwa.width) &&
|
|
||||||
(y >= xwa.y) && (y < xwa.y + (gint)xwa.height))
|
|
||||||
{
|
|
||||||
x -= xwa.x;
|
|
||||||
y -= xwa.y;
|
|
||||||
child = children[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XFree (children);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (child)
|
|
||||||
return get_client_window_at_coords_recurse (display, child, x, y);
|
|
||||||
else
|
else
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@ -594,10 +590,13 @@ get_client_window_at_coords (GdkWindowCache *cache,
|
|||||||
if ((x_root >= child->x) && (x_root < child->x + child->width) &&
|
if ((x_root >= child->x) && (x_root < child->x + child->width) &&
|
||||||
(y_root >= child->y) && (y_root < child->y + child->height))
|
(y_root >= child->y) && (y_root < child->y + child->height))
|
||||||
{
|
{
|
||||||
retval = get_client_window_at_coords_recurse (gdk_screen_get_display (cache->screen),
|
if (window_has_wm_state (gdk_screen_get_display (cache->screen), child->xid))
|
||||||
child->xid,
|
retval = child->xid;
|
||||||
x_root - child->x,
|
else
|
||||||
y_root - child->y);
|
retval = get_client_window_at_coords_recurse (gdk_screen_get_display (cache->screen),
|
||||||
|
child->xid,
|
||||||
|
x_root - child->x,
|
||||||
|
y_root - child->y);
|
||||||
if (!retval)
|
if (!retval)
|
||||||
retval = child->xid;
|
retval = child->xid;
|
||||||
}
|
}
|
||||||
@ -2160,8 +2159,9 @@ send_xevent_async (GdkDragContext *context,
|
|||||||
|
|
||||||
g_object_ref (context);
|
g_object_ref (context);
|
||||||
|
|
||||||
_gdk_send_xevent_async (display, window, propagate, event_mask, event_send,
|
_gdk_x11_send_xevent_async (display, window,
|
||||||
send_xevent_async_cb, context);
|
propagate, event_mask, event_send,
|
||||||
|
send_xevent_async_cb, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
Reference in New Issue
Block a user