diff options
author | Owen Taylor <otaylor@redhat.com> | 2003-07-05 15:02:35 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 2003-07-05 15:02:35 +0000 |
commit | ba999da1d8528afdb7cf810e626bd1ab3946ff17 (patch) | |
tree | 150cdacc2eaa93c606eb702fbdccf7cc077d7282 /gdk/x11/gdkasync.c | |
parent | e5561940f2a3720d1c514afdff92cf327236f550 (diff) | |
download | gtk+-ba999da1d8528afdb7cf810e626bd1ab3946ff17.tar.gz |
Lookup all the atoms in the target list at once.
Sat Jul 5 09:55:38 2003 Owen Taylor <otaylor@redhat.com>
* gdk/x11/gdkdnd-x11.c (precache_target_list): Lookup
all the atoms in the target list at once.
* gdk/x11/gdkdnd-x11.c (gdk_drag_get_protocol_for_display):
Local drag short-circuit.
* gdk/x11/gdkdnd-x11.c (gdk_drag_motion): For the
local case, poke the actions in directly instead of
going through xdnd_set_actions.
* gdk/x11/gdkdnd-x11.c (xdnd_read_actions): Short-circuit
the local case.
* gdk/x11/gdkdnd-x11.c (xdnd_manage_source_filter): Don't
XSelectInput()/add a filter if the drag is local.
* gdk/x11/gdkdnd-x11.c (gdk_drag_get_selection):
Simplify handling of "XdndSelection".
* gdk/x11/gdkevents-x11.c (gdk_event_send_client_message_to_all_recurse): Somehow,
a WM_STATE => _NET_WM_STATE change hand been made here.
* gdk/x11/gdkproperty-x11.c (_gdk_x11_precache_atoms): Free
xatom_names, not atom_names.
* tests/testdnd.c (target_drag_motion): Make the trashcan
open again. (Got lost in deprecation cleanup.)
Diffstat (limited to 'gdk/x11/gdkasync.c')
-rw-r--r-- | gdk/x11/gdkasync.c | 147 |
1 files changed, 142 insertions, 5 deletions
diff --git a/gdk/x11/gdkasync.c b/gdk/x11/gdkasync.c index 06dc6d8ca7..06784cd6d3 100644 --- a/gdk/x11/gdkasync.c +++ b/gdk/x11/gdkasync.c @@ -49,6 +49,7 @@ in this Software without prior written authorization from The Open Group. typedef struct _ChildInfoChildState ChildInfoChildState; typedef struct _ChildInfoState ChildInfoState; +typedef struct _ListChildrenState ListChildrenState; typedef struct _SendEventState SendEventState; typedef struct _SetInputFocusState SetInputFocusState; @@ -78,6 +79,14 @@ struct _ChildInfoState gboolean child_has_error; }; +struct _ListChildrenState +{ + Display *dpy; + gulong get_property_req; + gboolean have_error; + gboolean has_wm_state; +}; + struct _SendEventState { Display *dpy; @@ -316,6 +325,116 @@ _gdk_x11_set_input_focus_safe (GdkDisplay *display, SyncHandle(); } +static Bool +list_children_handler (Display *dpy, + xReply *rep, + char *buf, + int len, + XPointer data) +{ + ListChildrenState *state = (ListChildrenState *)data; + + if (dpy->last_request_read != state->get_property_req) + return False; + + if (rep->generic.type == X_Error) + { + state->have_error = TRUE; + return False; + } + else + { + xGetPropertyReply replbuf; + xGetPropertyReply *repl; + + repl = (xGetPropertyReply *) + _XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len, + (sizeof(xGetPropertyReply) - sizeof(xReply)) >> 2, + True); + + state->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 + */ + + return True; + } +} + +static gboolean +list_children_and_wm_state (Display *dpy, + Window w, + Atom wm_state_atom, + gboolean *has_wm_state, + Window **children, + unsigned int *nchildren) +{ + ListChildrenState state; + _XAsyncHandler async; + long nbytes; + xQueryTreeReply rep; + register xResourceReq *req; + xGetPropertyReq *prop_req; + + LockDisplay(dpy); + + *children = NULL; + *nchildren = 0; + *has_wm_state = FALSE; + + state.have_error = FALSE; + state.has_wm_state = FALSE; + + if (wm_state_atom) + { + async.next = dpy->async_handlers; + async.handler = list_children_handler; + async.data = (XPointer) &state; + dpy->async_handlers = &async; + + GetReq (GetProperty, prop_req); + prop_req->window = w; + prop_req->property = wm_state_atom; + prop_req->type = AnyPropertyType; + prop_req->delete = False; + prop_req->longOffset = 0; + prop_req->longLength = 0; + + state.get_property_req = dpy->request; + } + + GetResReq(QueryTree, w, req); + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) + { + state.have_error = TRUE; + goto out; + } + + if (rep.nChildren != 0) + { + nbytes = rep.nChildren << 2; + if (state.have_error) + { + _XEatData(dpy, (unsigned long) nbytes); + goto out; + } + *children = g_new (Window, rep.nChildren); + _XRead32 (dpy, (long *) *children, nbytes); + } + + *nchildren = rep.nChildren; + *has_wm_state = state.has_wm_state; + + out: + if (wm_state_atom) + DeqAsyncHandler(dpy, &async); + UnlockDisplay(dpy); + SyncHandle(); + + return !state.have_error; +} + static void handle_get_wa_reply (Display *dpy, ChildInfoState *state, @@ -454,14 +573,15 @@ gboolean _gdk_x11_get_window_child_info (GdkDisplay *display, Window window, gboolean get_wm_state, + gboolean *win_has_wm_state, GdkChildInfoX11 **children, guint *nchildren) { Display *dpy; _XAsyncHandler async; ChildInfoState state; - Window root, parent; Atom wm_state_atom; + gboolean has_wm_state; Bool result; guint i; @@ -469,15 +589,32 @@ _gdk_x11_get_window_child_info (GdkDisplay *display, *nchildren = 0; dpy = GDK_DISPLAY_XDISPLAY (display); - wm_state_atom = gdk_x11_get_xatom_by_name_for_display (display, "WM_STATE"); + if (get_wm_state) + wm_state_atom = gdk_x11_get_xatom_by_name_for_display (display, "WM_STATE"); + else + wm_state_atom = None; gdk_error_trap_push (); - result = XQueryTree (dpy, window, &root, &parent, - &state.children, &state.nchildren); + result = list_children_and_wm_state (dpy, window, + win_has_wm_state ? wm_state_atom : None, + &has_wm_state, + &state.children, &state.nchildren); gdk_error_trap_pop (); if (!result) return FALSE; + if (has_wm_state) + { + if (win_has_wm_state) + *win_has_wm_state = TRUE; + return TRUE; + } + else + { + if (win_has_wm_state) + *win_has_wm_state = FALSE; + } + state.get_wm_state = get_wm_state; state.child_info = g_new (GdkChildInfoX11, state.nchildren); state.child_states = g_new (ChildInfoChildState, state.nchildren); @@ -547,7 +684,7 @@ _gdk_x11_get_window_child_info (GdkDisplay *display, g_free (state.child_info); } - XFree (state.children); + g_free (state.children); g_free (state.child_states); DeqAsyncHandler(dpy, &async); |