]> Pileus Git - ~andy/gtk/commitdiff
Lookup all the atoms in the target list at once.
authorOwen Taylor <otaylor@redhat.com>
Sat, 5 Jul 2003 15:02:35 +0000 (15:02 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Sat, 5 Jul 2003 15:02:35 +0000 (15:02 +0000)
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.)

12 files changed:
ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gdk/x11/gdkasync.c
gdk/x11/gdkasync.h
gdk/x11/gdkdisplay-x11.h
gdk/x11/gdkdnd-x11.c
gdk/x11/gdkevents-x11.c
gdk/x11/gdkproperty-x11.c
tests/testdnd.c

index 9bb7584a22d34b28b15a1c898ab58bca87f83b6e..0e0a1803edb24e43ac1140d852b37f13305e7645 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,51 @@
+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.)
+
+Sat Jul  5 00:49:32 2003  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkdnd.c (gtk_drag_begin): Move the grabs up
+       earlier, so we don't get a big pile of uncompressed
+       motion events before the grab takes effect.
+
+       * gtk/gtkdnd.c (gtk_drag_update_icon): Call 
+       gdk_window_process_all_updates() so that the area
+       we are dragging over gets a change to redraw.
+
+       * gtk/gtkdnd.c (_gtk_drag_dest_handle_event): Use 
+       gdk_window_get_position(), not gdk_window_get_origin().
+
+       * gdk/x11/gdkwindow-x11.[ch] (gdk_window_have_shape_ext)
+       gdkdisplay-x11.h: use XShapeQueryExtension to 
+       avoid duplicate XQueryExtension when we actually
+       use it. Remove unnecessary caching in GdkDisplayX11.
+
 Fri Jul  4 23:49:22 2003  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/x11/gdkasync.[ch] (_gdk_x11_get_window_child_info): 
index 9bb7584a22d34b28b15a1c898ab58bca87f83b6e..0e0a1803edb24e43ac1140d852b37f13305e7645 100644 (file)
@@ -1,3 +1,51 @@
+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.)
+
+Sat Jul  5 00:49:32 2003  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkdnd.c (gtk_drag_begin): Move the grabs up
+       earlier, so we don't get a big pile of uncompressed
+       motion events before the grab takes effect.
+
+       * gtk/gtkdnd.c (gtk_drag_update_icon): Call 
+       gdk_window_process_all_updates() so that the area
+       we are dragging over gets a change to redraw.
+
+       * gtk/gtkdnd.c (_gtk_drag_dest_handle_event): Use 
+       gdk_window_get_position(), not gdk_window_get_origin().
+
+       * gdk/x11/gdkwindow-x11.[ch] (gdk_window_have_shape_ext)
+       gdkdisplay-x11.h: use XShapeQueryExtension to 
+       avoid duplicate XQueryExtension when we actually
+       use it. Remove unnecessary caching in GdkDisplayX11.
+
 Fri Jul  4 23:49:22 2003  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/x11/gdkasync.[ch] (_gdk_x11_get_window_child_info): 
index 9bb7584a22d34b28b15a1c898ab58bca87f83b6e..0e0a1803edb24e43ac1140d852b37f13305e7645 100644 (file)
@@ -1,3 +1,51 @@
+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.)
+
+Sat Jul  5 00:49:32 2003  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkdnd.c (gtk_drag_begin): Move the grabs up
+       earlier, so we don't get a big pile of uncompressed
+       motion events before the grab takes effect.
+
+       * gtk/gtkdnd.c (gtk_drag_update_icon): Call 
+       gdk_window_process_all_updates() so that the area
+       we are dragging over gets a change to redraw.
+
+       * gtk/gtkdnd.c (_gtk_drag_dest_handle_event): Use 
+       gdk_window_get_position(), not gdk_window_get_origin().
+
+       * gdk/x11/gdkwindow-x11.[ch] (gdk_window_have_shape_ext)
+       gdkdisplay-x11.h: use XShapeQueryExtension to 
+       avoid duplicate XQueryExtension when we actually
+       use it. Remove unnecessary caching in GdkDisplayX11.
+
 Fri Jul  4 23:49:22 2003  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/x11/gdkasync.[ch] (_gdk_x11_get_window_child_info): 
index 9bb7584a22d34b28b15a1c898ab58bca87f83b6e..0e0a1803edb24e43ac1140d852b37f13305e7645 100644 (file)
@@ -1,3 +1,51 @@
+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.)
+
+Sat Jul  5 00:49:32 2003  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkdnd.c (gtk_drag_begin): Move the grabs up
+       earlier, so we don't get a big pile of uncompressed
+       motion events before the grab takes effect.
+
+       * gtk/gtkdnd.c (gtk_drag_update_icon): Call 
+       gdk_window_process_all_updates() so that the area
+       we are dragging over gets a change to redraw.
+
+       * gtk/gtkdnd.c (_gtk_drag_dest_handle_event): Use 
+       gdk_window_get_position(), not gdk_window_get_origin().
+
+       * gdk/x11/gdkwindow-x11.[ch] (gdk_window_have_shape_ext)
+       gdkdisplay-x11.h: use XShapeQueryExtension to 
+       avoid duplicate XQueryExtension when we actually
+       use it. Remove unnecessary caching in GdkDisplayX11.
+
 Fri Jul  4 23:49:22 2003  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/x11/gdkasync.[ch] (_gdk_x11_get_window_child_info): 
index 9bb7584a22d34b28b15a1c898ab58bca87f83b6e..0e0a1803edb24e43ac1140d852b37f13305e7645 100644 (file)
@@ -1,3 +1,51 @@
+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.)
+
+Sat Jul  5 00:49:32 2003  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkdnd.c (gtk_drag_begin): Move the grabs up
+       earlier, so we don't get a big pile of uncompressed
+       motion events before the grab takes effect.
+
+       * gtk/gtkdnd.c (gtk_drag_update_icon): Call 
+       gdk_window_process_all_updates() so that the area
+       we are dragging over gets a change to redraw.
+
+       * gtk/gtkdnd.c (_gtk_drag_dest_handle_event): Use 
+       gdk_window_get_position(), not gdk_window_get_origin().
+
+       * gdk/x11/gdkwindow-x11.[ch] (gdk_window_have_shape_ext)
+       gdkdisplay-x11.h: use XShapeQueryExtension to 
+       avoid duplicate XQueryExtension when we actually
+       use it. Remove unnecessary caching in GdkDisplayX11.
+
 Fri Jul  4 23:49:22 2003  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/x11/gdkasync.[ch] (_gdk_x11_get_window_child_info): 
index 06dc6d8ca79e30bf6ec1b8b533005d47331ba3c2..06784cd6d3599a2e279cae9b9315b18931dab0b4 100644 (file)
@@ -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);
index 36f76997f762dd58df2579f6975c53c5372b6604..146ea538f59ed70f5d3bb2f4cf3a5433c12e370d 100644 (file)
@@ -59,6 +59,7 @@ void _gdk_x11_set_input_focus_safe (GdkDisplay            *display,
 gboolean _gdk_x11_get_window_child_info (GdkDisplay       *display,
                                         Window            window,
                                         gboolean          get_wm_state,
+                                        gboolean         *win_has_wm_state,
                                         GdkChildInfoX11 **children,
                                         guint            *nchildren);
 
index 7e0692d589bc45945fd754d4cac83654d51e051d..1acfe457a508eef4b12f3d8a367c573a962a89bc 100644 (file)
@@ -136,6 +136,11 @@ struct _GdkDisplayX11
 
   /* Startup notification */
   gchar *startup_notification_id;
+
+  /* Sets of atoms for DND */
+  guint base_dnd_atoms_precached : 1;
+  guint xdnd_atoms_precached : 1;
+  guint motif_atoms_precached : 1;
 };
 
 struct _GdkDisplayX11Class
index 5b06b6371ae22f293a69bc2d2c2abf260ea58d24..e6d75c6018f3196998f598306ef9767b2f63283b 100644 (file)
@@ -67,7 +67,6 @@ struct _GdkDragContextPrivateX11 {
   GdkDragContext context;
 
   Atom motif_selection;
-  Atom xdnd_selection;
   guint   ref_count;
 
   guint16 last_x;              /* Coordinates from last event */
@@ -304,6 +303,29 @@ gdk_drag_context_find (GdkDisplay *display,
   return NULL;
 }
 
+static void
+precache_target_list (GdkDragContext *context)
+{
+  if (context->targets)
+    {
+      GPtrArray *targets = g_ptr_array_new ();
+      GList *tmp_list;
+      int i;
+
+      for (tmp_list = context->targets; tmp_list; tmp_list = tmp_list->next)
+       g_ptr_array_add (targets, gdk_atom_name (GDK_POINTER_TO_ATOM (tmp_list->data)));
+
+      _gdk_x11_precache_atoms (GDK_WINDOW_DISPLAY (context->source_window),
+                              (const gchar **)targets->pdata,
+                              targets->len);
+
+      for (i =0; i < targets->len; i++)
+       g_free (targets->pdata[i]);
+
+      g_ptr_array_free (targets, TRUE);
+    }
+}
+
 /* Utility functions */
 
 static void
@@ -468,7 +490,8 @@ gdk_window_cache_new (GdkScreen *screen)
 
   if (!_gdk_x11_get_window_child_info (gdk_screen_get_display (screen),
                                       GDK_WINDOW_XWINDOW (root_window),
-                                      FALSE, &children, &nchildren))
+                                      FALSE, NULL,
+                                      &children, &nchildren))
     return result;
 
   for (i = 0; i < nchildren ; i++)
@@ -500,33 +523,10 @@ gdk_window_cache_destroy (GdkWindowCache *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
 get_client_window_at_coords_recurse (GdkDisplay *display,
                                     Window      win,
+                                    gboolean    is_toplevel,
                                     gint        x,
                                     gint        y)
 {
@@ -535,11 +535,16 @@ get_client_window_at_coords_recurse (GdkDisplay *display,
   int i;
   gboolean found_child = FALSE;
   GdkChildInfoX11 child;
+  gboolean has_wm_state = FALSE;
 
   if (!_gdk_x11_get_window_child_info (display, win, TRUE,
+                                      is_toplevel? &has_wm_state : NULL,
                                       &children, &nchildren))
     return None;
 
+  if (has_wm_state)
+    return win;
+
   for (i = nchildren - 1; (i >= 0) && !found_child; i--)
     {
       GdkChildInfoX11 *cur_child = &children[i];
@@ -562,7 +567,7 @@ get_client_window_at_coords_recurse (GdkDisplay *display,
       if (child.has_wm_state)
        return child.window;
       else
-       return get_client_window_at_coords_recurse (display, child.window, x, y);
+       return get_client_window_at_coords_recurse (display, child.window, FALSE, x, y);
     }
   else
     return None;
@@ -590,13 +595,10 @@ get_client_window_at_coords (GdkWindowCache *cache,
          if ((x_root >= child->x) && (x_root < child->x + child->width) &&
              (y_root >= child->y) && (y_root < child->y + child->height))
            {
-             if (window_has_wm_state (gdk_screen_get_display (cache->screen), child->xid))
-               retval = child->xid;
-             else
-               retval = get_client_window_at_coords_recurse (gdk_screen_get_display (cache->screen),
-                                                             child->xid,
-                                                             x_root - child->x,
-                                                             y_root - child->y);
+             retval = get_client_window_at_coords_recurse (gdk_screen_get_display (cache->screen),
+                                                           child->xid, TRUE,
+                                                           x_root - child->x,
+                                                           y_root - child->y);
              if (!retval)
                retval = child->xid;
            }
@@ -2093,7 +2095,7 @@ xdnd_set_actions (GdkDragContext *context)
 
   g_free (atomlist);
 
-  private->xdnd_actions_set = 1;
+  private->xdnd_actions_set = TRUE;
   private->xdnd_actions = context->actions;
 }
 
@@ -2227,9 +2229,6 @@ xdnd_send_enter (GdkDragContext *context)
   xev.xclient.data.l[3] = 0;
   xev.xclient.data.l[4] = 0;
 
-  if (!private->xdnd_selection)
-    private->xdnd_selection = gdk_x11_get_xatom_by_name_for_display (display, "XdndSelection");
-
   if (g_list_length (context->targets) > 3)
     {
       if (!private->xdnd_targets_set)
@@ -2432,48 +2431,69 @@ xdnd_read_actions (GdkDragContext *context)
   Atom *data;
 
   gint i;
-
-  /* Get the XdndActionList, if set */
-
-  gdk_error_trap_push ();
   
-  if (XGetWindowProperty (GDK_DRAWABLE_XDISPLAY (context->source_window),
-                         GDK_DRAWABLE_XID (context->source_window),
-                         gdk_x11_get_xatom_by_name_for_display (display, "XdndActionList"),
-                         0, 65536,
-                         False, XA_ATOM, &type, &format, &nitems,
-                         &after, (guchar **)&data) == Success &&
-      type == XA_ATOM)
-    {
-      context->actions = 0;
-
-      for (i=0; i<nitems; i++)
-       context->actions |= xdnd_action_from_atom (display, data[i]);
-
-      (PRIVATE_DATA (context))->xdnd_have_actions = TRUE;
+  PRIVATE_DATA (context)->xdnd_have_actions = FALSE;
 
-#ifdef G_ENABLE_DEBUG
-      if (_gdk_debug_flags & GDK_DEBUG_DND)
+  if (gdk_window_get_window_type (context->source_window) == GDK_WINDOW_FOREIGN)
+    {
+      /* Get the XdndActionList, if set */
+      
+      gdk_error_trap_push ();
+      
+      if (XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display),
+                             GDK_DRAWABLE_XID (context->source_window),
+                             gdk_x11_get_xatom_by_name_for_display (display, "XdndActionList"),
+                             0, 65536,
+                             False, XA_ATOM, &type, &format, &nitems,
+                             &after, (guchar **)&data) == Success &&
+         type == XA_ATOM)
        {
-         GString *action_str = g_string_new (NULL);
-         if (context->actions & GDK_ACTION_MOVE)
-           g_string_append(action_str, "MOVE ");
-         if (context->actions & GDK_ACTION_COPY)
-           g_string_append(action_str, "COPY ");
-         if (context->actions & GDK_ACTION_LINK)
-           g_string_append(action_str, "LINK ");
-         if (context->actions & GDK_ACTION_ASK)
-           g_string_append(action_str, "ASK ");
+         context->actions = 0;
          
-         g_message("Xdnd actions = %s", action_str->str);
-         g_string_free (action_str, TRUE);
-       }
+         for (i=0; i<nitems; i++)
+           context->actions |= xdnd_action_from_atom (display, data[i]);
+         
+         PRIVATE_DATA (context)->xdnd_have_actions = TRUE;
+         
+#ifdef G_ENABLE_DEBUG
+         if (_gdk_debug_flags & GDK_DEBUG_DND)
+           {
+             GString *action_str = g_string_new (NULL);
+             if (context->actions & GDK_ACTION_MOVE)
+               g_string_append(action_str, "MOVE ");
+             if (context->actions & GDK_ACTION_COPY)
+               g_string_append(action_str, "COPY ");
+             if (context->actions & GDK_ACTION_LINK)
+               g_string_append(action_str, "LINK ");
+             if (context->actions & GDK_ACTION_ASK)
+               g_string_append(action_str, "ASK ");
+             
+             g_message("Xdnd actions = %s", action_str->str);
+             g_string_free (action_str, TRUE);
+           }
 #endif /* G_ENABLE_DEBUG */
-
-      XFree(data);
+         
+         XFree(data);
+       }
+      
+      gdk_error_trap_pop ();
     }
+  else
+    {
+      /* Local drag
+       */
+      GdkDragContext *source_context;
 
-  gdk_error_trap_pop ();
+      source_context = gdk_drag_context_find (display, TRUE,
+                                             GDK_DRAWABLE_XID (context->source_window),
+                                             GDK_DRAWABLE_XID (context->dest_window));
+
+      if (source_context)
+       {
+         context->actions = source_context->actions;
+         PRIVATE_DATA (context)->xdnd_have_actions = TRUE;
+       }
+    }
 }
 
 /* We have to make sure that the XdndActionList we keep internally
@@ -2507,17 +2527,17 @@ xdnd_manage_source_filter (GdkDragContext *context,
                           GdkWindow      *window,
                           gboolean        add_filter)
 {
-  gdk_error_trap_push ();
-
-  if (!GDK_WINDOW_DESTROYED (window))
+  if (!GDK_WINDOW_DESTROYED (window) &&
+      gdk_window_get_window_type (window) == GDK_WINDOW_FOREIGN)
     {
+      gdk_error_trap_push ();
+
       if (add_filter)
        {
          gdk_window_set_events (window,
                                 gdk_window_get_events (window) |
                                 GDK_PROPERTY_CHANGE_MASK);
          gdk_window_add_filter (window, xdnd_source_window_filter, context);
-
        }
       else
        {
@@ -2529,10 +2549,63 @@ xdnd_manage_source_filter (GdkDragContext *context,
           * INCR selection transactions).
           */
        }
+      
+      gdk_display_sync (gdk_drawable_get_display (window));
+      gdk_error_trap_pop ();  
+    }
+}
+
+static void
+base_precache_atoms (GdkDisplay *display)
+{
+  GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
+
+  if (!display_x11->base_dnd_atoms_precached)
+    {
+      static const char *const precache_atoms[] = {
+       "ENLIGHTENMENT_DESKTOP",
+       "WM_STATE",
+       "XdndAware",
+       "XdndProxy",
+       "_MOTIF_DRAG_RECEIVER_INFO"
+      };
+
+      _gdk_x11_precache_atoms (display,
+                              precache_atoms, G_N_ELEMENTS (precache_atoms));
+
+      display_x11->base_dnd_atoms_precached = TRUE;
     }
+}
+
+static void
+xdnd_precache_atoms (GdkDisplay *display)
+{
+  GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
+
+  if (!display_x11->xdnd_atoms_precached)
+    {
+      static const char *const precache_atoms[] = {
+       "XdndActionAsk",
+       "XdndActionCopy",
+       "XdndActionLink",
+       "XdndActionList",
+       "XdndActionMove",
+       "XdndActionPrivate",
+       "XdndDrop",
+       "XdndEnter",
+       "XdndFinished",
+       "XdndLeave",
+       "XdndPosition",
+       "XdndSelection",
+       "XdndStatus",
+       "XdndTypeList"
+      };
+
+      _gdk_x11_precache_atoms (display,
+                              precache_atoms, G_N_ELEMENTS (precache_atoms));
 
-  gdk_display_sync (gdk_drawable_get_display (window));
-  gdk_error_trap_pop ();  
+      display_x11->xdnd_atoms_precached = TRUE;
+    }
 }
 
 static GdkFilterReturn 
@@ -2566,6 +2639,8 @@ xdnd_enter_filter (GdkXEvent *xev,
   display = GDK_DRAWABLE_DISPLAY (event->any.window);
   display_x11 = GDK_DISPLAY_X11 (display);
 
+  xdnd_precache_atoms (display);
+
   GDK_NOTE (DND, 
            g_message ("XdndEnter: source_window: %#x, version: %#x",
                       source_window, version));
@@ -2651,8 +2726,6 @@ xdnd_enter_filter (GdkXEvent *xev,
 
   display_x11->current_dest_drag = new_context;
 
-  (PRIVATE_DATA (new_context))->xdnd_selection = 
-    gdk_x11_get_xatom_by_name_for_display (display, "XdndSelection");
   return GDK_FILTER_TRANSLATE;
 }
 
@@ -2663,6 +2736,7 @@ xdnd_leave_filter (GdkXEvent *xev,
 {
   XEvent *xevent = (XEvent *)xev;
   guint32 source_window = xevent->xclient.data.l[0];
+  GdkDisplay *display;
   GdkDisplayX11 *display_x11;
 
   if (!event->any.window ||
@@ -2673,7 +2747,10 @@ xdnd_leave_filter (GdkXEvent *xev,
            g_message ("XdndLeave: source_window: %#x",
                       source_window));
 
-  display_x11 = GDK_DISPLAY_X11 (GDK_DRAWABLE_DISPLAY (event->any.window));
+  display = GDK_DRAWABLE_DISPLAY (event->any.window);
+  display_x11 = GDK_DISPLAY_X11 (display);
+
+  xdnd_precache_atoms (display);
 
   if ((display_x11->current_dest_drag != NULL) &&
       (display_x11->current_dest_drag->protocol == GDK_DRAG_PROTO_XDND) &&
@@ -2717,6 +2794,8 @@ xdnd_position_filter (GdkXEvent *xev,
   display = GDK_DRAWABLE_DISPLAY (event->any.window);
   display_x11 = GDK_DISPLAY_X11 (display);
   
+  xdnd_precache_atoms (display);
+
   if ((display_x11->current_dest_drag != NULL) &&
       (display_x11->current_dest_drag->protocol == GDK_DRAG_PROTO_XDND) &&
       (GDK_DRAWABLE_XID (display_x11->current_dest_drag->source_window) == source_window))
@@ -2752,6 +2831,7 @@ xdnd_drop_filter (GdkXEvent *xev,
   XEvent *xevent = (XEvent *)xev;
   guint32 source_window = xevent->xclient.data.l[0];
   guint32 time = xevent->xclient.data.l[2];
+  GdkDisplay *display;
   GdkDisplayX11 *display_x11;
   
   if (!event->any.window ||
@@ -2762,7 +2842,10 @@ xdnd_drop_filter (GdkXEvent *xev,
            g_message ("XdndDrop: source_window: %#x  time: %d",
                       source_window, time));
 
-  display_x11 = GDK_DISPLAY_X11 (GDK_DRAWABLE_DISPLAY (event->any.window));
+  display = GDK_DRAWABLE_DISPLAY (event->any.window);
+  display_x11 = GDK_DISPLAY_X11 (display);
+
+  xdnd_precache_atoms (display);
 
   if ((display_x11->current_dest_drag != NULL) &&
       (display_x11->current_dest_drag->protocol == GDK_DRAG_PROTO_XDND) &&
@@ -2860,6 +2943,8 @@ gdk_drag_begin (GdkWindow     *window,
   g_object_ref (window);
 
   new_context->targets = g_list_copy (targets);
+  precache_target_list (new_context);
+  
   new_context->actions = 0;
 
   return new_context;
@@ -2883,13 +2968,34 @@ gdk_drag_get_protocol_for_display (GdkDisplay      *display,
                                   guint32          xid,
                                   GdkDragProtocol *protocol)
 {
+  GdkWindow *window;
   guint32 retval;
   g_return_val_if_fail (GDK_IS_DISPLAY (display), None);
+
+  base_precache_atoms (display);
+
+  /* Check for a local drag
+   */
+  window = gdk_window_lookup_for_display (display, xid);
+  if (window &&
+      gdk_window_get_window_type (window) != GDK_WINDOW_FOREIGN)
+    {
+      if (g_object_get_data (G_OBJECT (window), "gdk-dnd-registered") != NULL)
+       {
+         *protocol = GDK_DRAG_PROTO_XDND;
+         xdnd_precache_atoms (display);
+         GDK_NOTE (DND, g_message ("Entering local Xdnd window %#x\n", xid));
+         return xid;
+       }
+      else
+       return None;
+    }
   
   if ((retval = xdnd_check_dest (display, xid)))
     {
       *protocol = GDK_DRAG_PROTO_XDND;
-      GDK_NOTE (DND, g_message ("Entering dnd window %#x\n", xid));
+      xdnd_precache_atoms (display);
+      GDK_NOTE (DND, g_message ("Entering Xdnd window %#x\n", xid));
       return retval;
     }
   else if ((retval = motif_check_dest (display, xid)))
@@ -3086,16 +3192,38 @@ gdk_drag_motion (GdkDragContext *context,
 
   g_return_val_if_fail (context != NULL, FALSE);
 
-  /* When we have a Xdnd target, make sure our XdndActionList
-   * matches the current actions;
-   */
   private->old_actions = context->actions;
   context->actions = possible_actions;
   
-  if ((protocol == GDK_DRAG_PROTO_XDND) &&
-      (!private->xdnd_actions_set ||
-       private->xdnd_actions != possible_actions))
-    xdnd_set_actions (context);
+  if (private->old_actions != possible_actions)
+    private->xdnd_actions_set = FALSE;
+      
+  /* When we have a Xdnd target, make sure our XdndActionList
+   * matches the current actions;
+   */
+  if (protocol == GDK_DRAG_PROTO_XDND && !private->xdnd_actions_set)
+    {
+      if (dest_window)
+       {
+         if (gdk_window_get_window_type (dest_window) == GDK_WINDOW_FOREIGN)
+           xdnd_set_actions (context);
+         else if (context->dest_window == dest_window)
+           {
+             GdkDisplay *display = GDK_WINDOW_DISPLAY (dest_window);
+             GdkDragContext *dest_context;
+                   
+             dest_context = gdk_drag_context_find (display, FALSE,
+                                                   GDK_DRAWABLE_XID (context->source_window),
+                                                   GDK_DRAWABLE_XID (dest_window));
+
+             if (dest_context)
+               {
+                 dest_context->actions = context->actions;
+                 PRIVATE_DATA (dest_context)->xdnd_have_actions = TRUE;
+               }
+           }
+       }
+    }
 
   if (context->dest_window != dest_window)
     {
@@ -3516,7 +3644,9 @@ gdk_window_register_dnd (GdkWindow      *window)
 
   g_return_if_fail (window != NULL);
 
-  if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "gdk-dnd-registered")))
+  base_precache_atoms (display);
+
+  if (g_object_get_data (G_OBJECT (window), "gdk-dnd-registered") != NULL)
     return;
   else
     g_object_set_data (G_OBJECT (window), "gdk-dnd-registered", GINT_TO_POINTER (TRUE));
@@ -3566,8 +3696,7 @@ gdk_drag_get_selection (GdkDragContext *context)
     return gdk_x11_xatom_to_atom_for_display (GDK_DRAWABLE_DISPLAY (context->source_window),
                                              (PRIVATE_DATA (context))->motif_selection);
   else if (context->protocol == GDK_DRAG_PROTO_XDND)
-    return gdk_x11_xatom_to_atom_for_display (GDK_DRAWABLE_DISPLAY (context->source_window),
-                                             (PRIVATE_DATA (context))->xdnd_selection);
+    return gdk_atom_intern ("XdndSelection", FALSE);
   else
     return GDK_NONE;
 }
index f9dadd37b369fc057a4d26353218828360340a58..f4be985a48dab1b6d79ccb0396e29ecf8365cbab 100644 (file)
@@ -2095,7 +2095,7 @@ gdk_event_send_client_message_to_all_recurse (GdkDisplay *display,
   gdk_error_trap_push ();
   
   if (XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), xid, 
-                         gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"),
+                         gdk_x11_get_xatom_by_name_for_display (display, "WM_STATE"),
                          0, 0, False, AnyPropertyType,
                          &type, &format, &nitems, &after, &data) != Success)
     goto out;
index bedea12d123ab16fe7c451357d5acb36c35135eb..96cb6317db335af34dfa1081880ec23dd0ba1337 100644 (file)
@@ -234,8 +234,8 @@ _gdk_x11_precache_atoms (GdkDisplay          *display,
     insert_atom_pair (display, atoms[i], xatoms[i]);
 
   g_free (xatoms);
+  g_free (xatom_names);
   g_free (atoms);
-  g_free (atom_names);
 }
 
 /**
index f424c070c5fc0865fbe4e6102d03faccf0bf2dac..600811235f57abb278ffe3fa208d4f55cce998b5 100644 (file)
@@ -311,7 +311,7 @@ target_drag_motion     (GtkWidget          *widget,
     {
       have_drag = TRUE;
       gtk_image_set_from_pixmap (GTK_IMAGE (widget),
-                                trashcan_closed, trashcan_closed_mask);
+                                trashcan_open, trashcan_open_mask);
     }
 
   source_widget = gtk_drag_get_source_widget (context);