]> Pileus Git - ~andy/gtk/commitdiff
Use asynchronously _gdk_x11_set_input_focus_safe to avoid having to trap
authorOwen Taylor <otaylor@redhat.com>
Sat, 5 Jul 2003 01:54:05 +0000 (01:54 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Sat, 5 Jul 2003 01:54:05 +0000 (01:54 +0000)
Fri Jul  4 15:57:52 2003  Owen Taylor  <otaylor@redhat.com>

* gdk/x11/gdkevents-x11.c (gdk_wm_protocols_filter):
Use asynchronously _gdk_x11_set_input_focus_safe
to avoid having to trap errors and XSync().

* gdk/x11/gdkwindow-x11.c (gdk_window_focus): Use
_gdk_x11_set_input_focus_safe() here as well.

* gdk/x11/gdkevents-x11.c (gdk_check_wm_state_changed):
Rework handling of property notifies on _NET_WM_STATE
so that we ignore _NET_WM_DESKTOP notifies unless we
really care.

* gdk/x11/gdkimage-x11.c (gdk_image_check_xshm): Use
XShmQueryExtension() rather than XQueryExtension() to
avoid extra rountrip.

* gdk/x11/gdkwindow-x11.c (_gdk_windowing_window_init):
Remove unused call to XGetWindowAttributes()

* gdk/x11/gdkdisplay-x11.c (gdk_display_open): Remove
unused call to XGetKeyboardControl().

* gdk/x11/gdkdisplay-x11.c gdk/gdk.def (gdk_display_flush):
Add (#99571)

* gdk/win32/gdkevents-win32.c gdk/linux-fb/gdkevents-fb.c
No-op implementations of gdk_display_flush().

* gdk/gdkwindow.c (gdk_window_process_all_updates): Use
gdk_display_flush() rather than gdk_flush() to avoid
XSync().

* gdk/x11/gdkwindow-x11.c (update_wm_hints)
gdk/x11/gdkwindow-x11.h: Centralize all handling of WM_HINTS here
so that we don't have to get the property back from the server.

* gdk/x11/gdkwindow-x11.c (show_window_internal): Store
the serial of when we map a toplevel to allow optimizing
out notifies on _NET_WM_STATE/_NET_WM_DESKTOP.

* gdk/x11/gdkevents-x11.c (gdk_event_translate): Don't
XTranslateCoordinates() for override-redirect windows.

Fri Jul  4 15:59:27 2003  Owen Taylor  <otaylor@redhat.com>

* gdk/x11/gdkwindow-x11.c (gdk_window_set_group): Remove comment
about setting window group after the window is mapped from docs
- nothing the ICCCM forbids that.

* gdk/x11/gdkcursor-x11.c (gdk_display_get_maximal_cursor_size):
Fix g_return_val_if_fail() in void return function.

* configure.in: Fix misplaced comma that was resulting
in XShm always being disabled.

23 files changed:
ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
configure.in
gdk/gdk.def
gdk/gdkdisplay.h
gdk/gdkwindow.c
gdk/linux-fb/gdkevents-fb.c
gdk/win32/gdkevents-win32.c
gdk/x11/Makefile.am
gdk/x11/gdkasync.c [new file with mode: 0644]
gdk/x11/gdkasync.h [new file with mode: 0644]
gdk/x11/gdkcursor-x11.c
gdk/x11/gdkdisplay-x11.c
gdk/x11/gdkevents-x11.c
gdk/x11/gdkimage-x11.c
gdk/x11/gdkprivate-x11.h
gdk/x11/gdkproperty-x11.c
gdk/x11/gdkwindow-x11.c
gdk/x11/gdkwindow-x11.h
gdk/x11/xsettings-client.c

index a468f0cd7abb4cab3124f9bbe498fb57a202a3db..602d64da14ba977c7d313cc542a60bbf01eaa602 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,60 @@
+Fri Jul  4 15:57:52 2003  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/x11/gdkevents-x11.c (gdk_wm_protocols_filter):
+       Use asynchronously _gdk_x11_set_input_focus_safe
+       to avoid having to trap errors and XSync().
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_focus): Use
+       _gdk_x11_set_input_focus_safe() here as well.
+
+       * gdk/x11/gdkevents-x11.c (gdk_check_wm_state_changed):
+       Rework handling of property notifies on _NET_WM_STATE
+       so that we ignore _NET_WM_DESKTOP notifies unless we
+       really care.
+
+       * gdk/x11/gdkimage-x11.c (gdk_image_check_xshm): Use
+       XShmQueryExtension() rather than XQueryExtension() to
+       avoid extra rountrip.
+
+       * gdk/x11/gdkwindow-x11.c (_gdk_windowing_window_init):
+       Remove unused call to XGetWindowAttributes()
+       
+       * gdk/x11/gdkdisplay-x11.c (gdk_display_open): Remove
+       unused call to XGetKeyboardControl().
+
+       * gdk/x11/gdkdisplay-x11.c gdk/gdk.def (gdk_display_flush):
+       Add (#99571)
+
+       * gdk/win32/gdkevents-win32.c gdk/linux-fb/gdkevents-fb.c 
+       No-op implementations of gdk_display_flush().
+
+       * gdk/gdkwindow.c (gdk_window_process_all_updates): Use
+       gdk_display_flush() rather than gdk_flush() to avoid
+       XSync().
+       
+       * gdk/x11/gdkwindow-x11.c (update_wm_hints)
+       gdk/x11/gdkwindow-x11.h: Centralize all handling of WM_HINTS here
+       so that we don't have to get the property back from the server.
+
+       * gdk/x11/gdkwindow-x11.c (show_window_internal): Store
+       the serial of when we map a toplevel to allow optimizing
+       out notifies on _NET_WM_STATE/_NET_WM_DESKTOP.
+
+       * gdk/x11/gdkevents-x11.c (gdk_event_translate): Don't
+       XTranslateCoordinates() for override-redirect windows.
+
+Fri Jul  4 15:59:27 2003  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_set_group): Remove comment
+       about setting window group after the window is mapped from docs
+       - nothing the ICCCM forbids that.
+
+       * gdk/x11/gdkcursor-x11.c (gdk_display_get_maximal_cursor_size):
+       Fix g_return_val_if_fail() in void return function.
+
+       * configure.in: Fix misplaced comma that was resulting
+       in XShm always being disabled.
+
 Fri Jul  4 19:55:49 2003  Soeren Sandmann  <sandmann@daimi.au.dk>
 
        * tests/stresstest-toolbar: remove this accidentally committed
index a468f0cd7abb4cab3124f9bbe498fb57a202a3db..602d64da14ba977c7d313cc542a60bbf01eaa602 100644 (file)
@@ -1,3 +1,60 @@
+Fri Jul  4 15:57:52 2003  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/x11/gdkevents-x11.c (gdk_wm_protocols_filter):
+       Use asynchronously _gdk_x11_set_input_focus_safe
+       to avoid having to trap errors and XSync().
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_focus): Use
+       _gdk_x11_set_input_focus_safe() here as well.
+
+       * gdk/x11/gdkevents-x11.c (gdk_check_wm_state_changed):
+       Rework handling of property notifies on _NET_WM_STATE
+       so that we ignore _NET_WM_DESKTOP notifies unless we
+       really care.
+
+       * gdk/x11/gdkimage-x11.c (gdk_image_check_xshm): Use
+       XShmQueryExtension() rather than XQueryExtension() to
+       avoid extra rountrip.
+
+       * gdk/x11/gdkwindow-x11.c (_gdk_windowing_window_init):
+       Remove unused call to XGetWindowAttributes()
+       
+       * gdk/x11/gdkdisplay-x11.c (gdk_display_open): Remove
+       unused call to XGetKeyboardControl().
+
+       * gdk/x11/gdkdisplay-x11.c gdk/gdk.def (gdk_display_flush):
+       Add (#99571)
+
+       * gdk/win32/gdkevents-win32.c gdk/linux-fb/gdkevents-fb.c 
+       No-op implementations of gdk_display_flush().
+
+       * gdk/gdkwindow.c (gdk_window_process_all_updates): Use
+       gdk_display_flush() rather than gdk_flush() to avoid
+       XSync().
+       
+       * gdk/x11/gdkwindow-x11.c (update_wm_hints)
+       gdk/x11/gdkwindow-x11.h: Centralize all handling of WM_HINTS here
+       so that we don't have to get the property back from the server.
+
+       * gdk/x11/gdkwindow-x11.c (show_window_internal): Store
+       the serial of when we map a toplevel to allow optimizing
+       out notifies on _NET_WM_STATE/_NET_WM_DESKTOP.
+
+       * gdk/x11/gdkevents-x11.c (gdk_event_translate): Don't
+       XTranslateCoordinates() for override-redirect windows.
+
+Fri Jul  4 15:59:27 2003  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_set_group): Remove comment
+       about setting window group after the window is mapped from docs
+       - nothing the ICCCM forbids that.
+
+       * gdk/x11/gdkcursor-x11.c (gdk_display_get_maximal_cursor_size):
+       Fix g_return_val_if_fail() in void return function.
+
+       * configure.in: Fix misplaced comma that was resulting
+       in XShm always being disabled.
+
 Fri Jul  4 19:55:49 2003  Soeren Sandmann  <sandmann@daimi.au.dk>
 
        * tests/stresstest-toolbar: remove this accidentally committed
index a468f0cd7abb4cab3124f9bbe498fb57a202a3db..602d64da14ba977c7d313cc542a60bbf01eaa602 100644 (file)
@@ -1,3 +1,60 @@
+Fri Jul  4 15:57:52 2003  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/x11/gdkevents-x11.c (gdk_wm_protocols_filter):
+       Use asynchronously _gdk_x11_set_input_focus_safe
+       to avoid having to trap errors and XSync().
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_focus): Use
+       _gdk_x11_set_input_focus_safe() here as well.
+
+       * gdk/x11/gdkevents-x11.c (gdk_check_wm_state_changed):
+       Rework handling of property notifies on _NET_WM_STATE
+       so that we ignore _NET_WM_DESKTOP notifies unless we
+       really care.
+
+       * gdk/x11/gdkimage-x11.c (gdk_image_check_xshm): Use
+       XShmQueryExtension() rather than XQueryExtension() to
+       avoid extra rountrip.
+
+       * gdk/x11/gdkwindow-x11.c (_gdk_windowing_window_init):
+       Remove unused call to XGetWindowAttributes()
+       
+       * gdk/x11/gdkdisplay-x11.c (gdk_display_open): Remove
+       unused call to XGetKeyboardControl().
+
+       * gdk/x11/gdkdisplay-x11.c gdk/gdk.def (gdk_display_flush):
+       Add (#99571)
+
+       * gdk/win32/gdkevents-win32.c gdk/linux-fb/gdkevents-fb.c 
+       No-op implementations of gdk_display_flush().
+
+       * gdk/gdkwindow.c (gdk_window_process_all_updates): Use
+       gdk_display_flush() rather than gdk_flush() to avoid
+       XSync().
+       
+       * gdk/x11/gdkwindow-x11.c (update_wm_hints)
+       gdk/x11/gdkwindow-x11.h: Centralize all handling of WM_HINTS here
+       so that we don't have to get the property back from the server.
+
+       * gdk/x11/gdkwindow-x11.c (show_window_internal): Store
+       the serial of when we map a toplevel to allow optimizing
+       out notifies on _NET_WM_STATE/_NET_WM_DESKTOP.
+
+       * gdk/x11/gdkevents-x11.c (gdk_event_translate): Don't
+       XTranslateCoordinates() for override-redirect windows.
+
+Fri Jul  4 15:59:27 2003  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_set_group): Remove comment
+       about setting window group after the window is mapped from docs
+       - nothing the ICCCM forbids that.
+
+       * gdk/x11/gdkcursor-x11.c (gdk_display_get_maximal_cursor_size):
+       Fix g_return_val_if_fail() in void return function.
+
+       * configure.in: Fix misplaced comma that was resulting
+       in XShm always being disabled.
+
 Fri Jul  4 19:55:49 2003  Soeren Sandmann  <sandmann@daimi.au.dk>
 
        * tests/stresstest-toolbar: remove this accidentally committed
index a468f0cd7abb4cab3124f9bbe498fb57a202a3db..602d64da14ba977c7d313cc542a60bbf01eaa602 100644 (file)
@@ -1,3 +1,60 @@
+Fri Jul  4 15:57:52 2003  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/x11/gdkevents-x11.c (gdk_wm_protocols_filter):
+       Use asynchronously _gdk_x11_set_input_focus_safe
+       to avoid having to trap errors and XSync().
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_focus): Use
+       _gdk_x11_set_input_focus_safe() here as well.
+
+       * gdk/x11/gdkevents-x11.c (gdk_check_wm_state_changed):
+       Rework handling of property notifies on _NET_WM_STATE
+       so that we ignore _NET_WM_DESKTOP notifies unless we
+       really care.
+
+       * gdk/x11/gdkimage-x11.c (gdk_image_check_xshm): Use
+       XShmQueryExtension() rather than XQueryExtension() to
+       avoid extra rountrip.
+
+       * gdk/x11/gdkwindow-x11.c (_gdk_windowing_window_init):
+       Remove unused call to XGetWindowAttributes()
+       
+       * gdk/x11/gdkdisplay-x11.c (gdk_display_open): Remove
+       unused call to XGetKeyboardControl().
+
+       * gdk/x11/gdkdisplay-x11.c gdk/gdk.def (gdk_display_flush):
+       Add (#99571)
+
+       * gdk/win32/gdkevents-win32.c gdk/linux-fb/gdkevents-fb.c 
+       No-op implementations of gdk_display_flush().
+
+       * gdk/gdkwindow.c (gdk_window_process_all_updates): Use
+       gdk_display_flush() rather than gdk_flush() to avoid
+       XSync().
+       
+       * gdk/x11/gdkwindow-x11.c (update_wm_hints)
+       gdk/x11/gdkwindow-x11.h: Centralize all handling of WM_HINTS here
+       so that we don't have to get the property back from the server.
+
+       * gdk/x11/gdkwindow-x11.c (show_window_internal): Store
+       the serial of when we map a toplevel to allow optimizing
+       out notifies on _NET_WM_STATE/_NET_WM_DESKTOP.
+
+       * gdk/x11/gdkevents-x11.c (gdk_event_translate): Don't
+       XTranslateCoordinates() for override-redirect windows.
+
+Fri Jul  4 15:59:27 2003  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_set_group): Remove comment
+       about setting window group after the window is mapped from docs
+       - nothing the ICCCM forbids that.
+
+       * gdk/x11/gdkcursor-x11.c (gdk_display_get_maximal_cursor_size):
+       Fix g_return_val_if_fail() in void return function.
+
+       * configure.in: Fix misplaced comma that was resulting
+       in XShm always being disabled.
+
 Fri Jul  4 19:55:49 2003  Soeren Sandmann  <sandmann@daimi.au.dk>
 
        * tests/stresstest-toolbar: remove this accidentally committed
index a468f0cd7abb4cab3124f9bbe498fb57a202a3db..602d64da14ba977c7d313cc542a60bbf01eaa602 100644 (file)
@@ -1,3 +1,60 @@
+Fri Jul  4 15:57:52 2003  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/x11/gdkevents-x11.c (gdk_wm_protocols_filter):
+       Use asynchronously _gdk_x11_set_input_focus_safe
+       to avoid having to trap errors and XSync().
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_focus): Use
+       _gdk_x11_set_input_focus_safe() here as well.
+
+       * gdk/x11/gdkevents-x11.c (gdk_check_wm_state_changed):
+       Rework handling of property notifies on _NET_WM_STATE
+       so that we ignore _NET_WM_DESKTOP notifies unless we
+       really care.
+
+       * gdk/x11/gdkimage-x11.c (gdk_image_check_xshm): Use
+       XShmQueryExtension() rather than XQueryExtension() to
+       avoid extra rountrip.
+
+       * gdk/x11/gdkwindow-x11.c (_gdk_windowing_window_init):
+       Remove unused call to XGetWindowAttributes()
+       
+       * gdk/x11/gdkdisplay-x11.c (gdk_display_open): Remove
+       unused call to XGetKeyboardControl().
+
+       * gdk/x11/gdkdisplay-x11.c gdk/gdk.def (gdk_display_flush):
+       Add (#99571)
+
+       * gdk/win32/gdkevents-win32.c gdk/linux-fb/gdkevents-fb.c 
+       No-op implementations of gdk_display_flush().
+
+       * gdk/gdkwindow.c (gdk_window_process_all_updates): Use
+       gdk_display_flush() rather than gdk_flush() to avoid
+       XSync().
+       
+       * gdk/x11/gdkwindow-x11.c (update_wm_hints)
+       gdk/x11/gdkwindow-x11.h: Centralize all handling of WM_HINTS here
+       so that we don't have to get the property back from the server.
+
+       * gdk/x11/gdkwindow-x11.c (show_window_internal): Store
+       the serial of when we map a toplevel to allow optimizing
+       out notifies on _NET_WM_STATE/_NET_WM_DESKTOP.
+
+       * gdk/x11/gdkevents-x11.c (gdk_event_translate): Don't
+       XTranslateCoordinates() for override-redirect windows.
+
+Fri Jul  4 15:59:27 2003  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_set_group): Remove comment
+       about setting window group after the window is mapped from docs
+       - nothing the ICCCM forbids that.
+
+       * gdk/x11/gdkcursor-x11.c (gdk_display_get_maximal_cursor_size):
+       Fix g_return_val_if_fail() in void return function.
+
+       * configure.in: Fix misplaced comma that was resulting
+       in XShm always being disabled.
+
 Fri Jul  4 19:55:49 2003  Soeren Sandmann  <sandmann@daimi.au.dk>
 
        * tests/stresstest-toolbar: remove this accidentally committed
index 76b7dffc9c50510ff2ba58d33776b1cb1ea2ec96..c37defee6bdbebd1099c02d62ca202689239b13f 100644 (file)
@@ -161,8 +161,8 @@ AC_ARG_ENABLE(debug,
               enable_debug=debug_default)
 AC_ARG_ENABLE(shm,
               [AC_HELP_STRING([--enable-shm],
-                              [support shared memory if available [default=yes]])],
-              [echo $enable_shm, enable_shm="yes"])
+                              [support shared memory if available [default=yes]])],,
+              [enable_shm="yes"])
 AC_ARG_ENABLE(ansi,
               [AC_HELP_STRING([--enable-ansi],
                               [turn on strict ansi [default=no]])],,
index 27e2a20557c94e13499db6407a9f17bd7d0f6996..01ea9db72d4ca4243cbea00f6edfbd907276b416 100644 (file)
@@ -60,6 +60,7 @@ EXPORTS
        gdk_display_add_client_message_filter
        gdk_display_beep
        gdk_display_close
+       gdk_display_flush
        gdk_display_get_core_pointer
        gdk_display_get_default
        gdk_display_get_default_screen
index 8314240143ab3b7713224b18cda66d6fa3f39ebc..db6df0cd4fc99190351f0b3941f06deb1e4721cf 100644 (file)
@@ -113,6 +113,8 @@ void        gdk_display_keyboard_ungrab    (GdkDisplay  *display,
 gboolean    gdk_display_pointer_is_grabbed (GdkDisplay  *display);
 void        gdk_display_beep               (GdkDisplay  *display);
 void        gdk_display_sync               (GdkDisplay  *display);
+void        gdk_display_flush              (GdkDisplay  *display);
+
 void       gdk_display_close              (GdkDisplay  *display);
 
 GList *     gdk_display_list_devices       (GdkDisplay  *display);
index 21310ceb2bd748281a505a39e7d7c9b7f3349586..00c708c7bbb7435a881137a70f640d10f22756bc 100644 (file)
@@ -2144,6 +2144,18 @@ gdk_window_process_updates_internal (GdkWindow *window)
     }
 }
 
+static void
+flush_all_displays (void)
+{
+  GSList *displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
+  GSList *tmp_list;
+
+  for (tmp_list = displays; tmp_list; tmp_list = tmp_list->next)
+    gdk_display_flush (tmp_list->data);
+
+  g_slist_free (displays);
+}
+
 /**
  * gdk_window_process_all_updates:
  *
@@ -2174,7 +2186,7 @@ gdk_window_process_all_updates (void)
 
   g_slist_free (old_update_windows);
 
-  gdk_flush();
+  flush_all_displays ();
 }
 
 static gboolean
index b61377e4dbbdddabcc5159371c04e430158d83a1..9001da48edf3a1efbcea79628947149a191840a3 100644 (file)
@@ -225,3 +225,8 @@ void
 gdk_display_sync (GdkDisplay *display)
 {
 }
+
+void
+gdk_display_flush (GdkDisplay * display)
+{
+}
index 841835bc79340e1f7a1ec82dc4f9dcb32a4d884b..4838d0891b9aa85fe6f5ef9ec1df0378d0eb9c3c 100644 (file)
@@ -3516,3 +3516,11 @@ gdk_display_sync (GdkDisplay * display)
       DispatchMessage (&msg);
     }
 }
+
+void
+gdk_display_flush (GdkDisplay * display)
+{
+  g_return_if_fail (display == gdk_display_get_default ());
+
+  /* Nothing */
+}
index 51ca918265912205d79c4a8d454dbfb836614667..3fb2f2b1d42650add07b5dfd5ea79a5eb2b71437 100644 (file)
@@ -20,6 +20,8 @@ noinst_LTLIBRARIES = libgdk-x11.la
 
 libgdk_x11_la_SOURCES =        \
        MwmUtil.h               \
+       gdkasync.c              \
+       gdkasync.h              \
        gdkcolor-x11.c          \
        gdkcursor-x11.c         \
        gdkdisplay-x11.c        \
diff --git a/gdk/x11/gdkasync.c b/gdk/x11/gdkasync.c
new file mode 100644 (file)
index 0000000..5f2672b
--- /dev/null
@@ -0,0 +1,156 @@
+/* GTK - The GIMP Toolkit
+ * gdkasync.c: Utility functions using the Xlib asynchronous interfaces
+ * Copyright (C) 2003, Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/* Portions of code in this file are based on code from Xlib
+ */
+/*
+Copyright 1986, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+#include <X11/Xlibint.h>
+#include "gdkasync.h"
+#include "gdkx.h"
+
+typedef struct _SetInputFocusState SetInputFocusState;
+
+struct _SetInputFocusState
+{
+  Display *dpy;
+  Window window;
+  _XAsyncHandler async;
+  gulong set_input_focus_req;
+  gulong get_input_focus_req;
+  gboolean have_error;
+  GdkSendXEventCallback callback;
+  gpointer data;
+};
+
+static Bool
+set_input_focus_handler (Display *dpy,
+                        xReply  *rep,
+                        char    *buf,
+                        int      len,
+                        XPointer data)
+{
+  SetInputFocusState *state = (SetInputFocusState *)data;  
+
+  if (dpy->last_request_read == state->set_input_focus_req)
+    {
+      if (rep->generic.type == X_Error &&
+         rep->error.errorCode == BadMatch)
+       {
+         /* Consume BadMatch errors, since we have no control
+          * over them.
+          */
+         return True;
+       }
+    }
+  
+  if (dpy->last_request_read == state->get_input_focus_req)
+    {
+      xGetInputFocusReply replbuf;
+      xGetInputFocusReply *repl;
+      
+      if (rep->generic.type != X_Error)
+       {
+         /* Actually does nothing, since there are no additional bytes
+          * to read, but maintain good form.
+          */
+         repl = (xGetInputFocusReply *)
+           _XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len,
+                           (sizeof(xGetInputFocusReply) - sizeof(xReply)) >> 2,
+                           True);
+       }
+
+      DeqAsyncHandler(state->dpy, &state->async);
+
+      g_free (state);
+      
+      return (rep->generic.type != X_Error);
+    }
+
+  return False;
+}
+
+void
+_gdk_x11_set_input_focus_safe (GdkDisplay             *display,
+                              Window                  window,
+                              int                     revert_to,
+                              Time                    time)
+{
+  Display *dpy;
+  SetInputFocusState *state;
+  
+  dpy = GDK_DISPLAY_XDISPLAY (display);
+
+  state = g_new (SetInputFocusState, 1);
+
+  state->dpy = dpy;
+  state->window = window;
+  
+  LockDisplay(dpy);
+
+  state->async.next = dpy->async_handlers;
+  state->async.handler = set_input_focus_handler;
+  state->async.data = (XPointer) state;
+  dpy->async_handlers = &state->async;
+
+  {
+    xSetInputFocusReq *req;
+    
+    GetReq(SetInputFocus, req);
+    req->focus = window;
+    req->revertTo = revert_to;
+    req->time = time;
+    state->set_input_focus_req = dpy->request;
+  }
+
+  /*
+   * XSync (dpy, 0)
+   */
+  {
+    xReq *req;
+    
+    GetEmptyReq(GetInputFocus, req);
+    state->get_input_focus_req = dpy->request;
+  }
+  
+  UnlockDisplay(dpy);
+  SyncHandle();
+}
diff --git a/gdk/x11/gdkasync.h b/gdk/x11/gdkasync.h
new file mode 100644 (file)
index 0000000..2da6040
--- /dev/null
@@ -0,0 +1,36 @@
+/* GTK - The GIMP Toolkit
+ * gdkasync.h: Utility functions using the Xlib asynchronous interfaces
+ * Copyright (C) 2003, Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GDK_ASYNC_H__
+#define __GDK_ASYNC_H__
+
+#include <X11/Xlib.h>
+#include "gdk.h"
+
+G_BEGIN_DECLS
+
+void _gdk_x11_set_input_focus_safe (GdkDisplay             *display,
+                                   Window                  window,
+                                   int                     revert_to,
+                                   Time                    time);
+
+G_END_DECLS
+
+#endif /* __GDK_ASYNC_H__ */
index 80f4bf9f849bea29a2910cc4427318ca79259043..d8727091912e1db634680bd877e70e4d76f6df3f 100644 (file)
@@ -587,7 +587,7 @@ gdk_display_get_maximal_cursor_size (GdkDisplay *display,
   GdkScreen *screen;
   GdkWindow *window;
 
-  g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
+  g_return_if_fail (GDK_IS_DISPLAY (display));
   
   screen = gdk_display_get_default_screen (display);
   window = gdk_screen_get_root_window (screen);
index 66ec5c36e7e6112c78f2430b059cf091f43d31b3..969ccb71ed4d89ad48f56d51328defefa0cfe43a 100644 (file)
@@ -57,6 +57,32 @@ static void gdk_internal_connection_watch (Display  *display,
 
 static gpointer parent_class = NULL;
 
+/* Note that we never *directly* use WM_LOCALE_NAME, WM_PROTOCOLS,
+ * but including them here has the side-effect of getting them
+ * into the internal Xlib cache
+ */
+static const char *const precache_atoms[] = {
+  "UTF8_STRING",
+  "WM_CLIENT_LEADER",
+  "WM_DELETE_WINDOW",
+  "WM_LOCALE_NAME",
+  "WM_PROTOCOLS",
+  "WM_TAKE_FOCUS",
+  "_NET_WM_DESKTOP",
+  "_NET_WM_ICON",
+  "_NET_WM_ICON_NAME",
+  "_NET_WM_NAME",
+  "_NET_WM_PID",
+  "_NET_WM_PING",
+  "_NET_WM_STATE",
+  "_NET_WM_STATE_STICKY",
+  "_NET_WM_STATE_MAXIMIZED_VERT",
+  "_NET_WM_STATE_MAXIMIZED_HORZ",
+  "_NET_WM_STATE_FULLSCREEN",
+  "_NET_WM_WINDOW_TYPE",
+  "_NET_WM_WINDOW_TYPE_NORMAL",
+};
+
 GType
 _gdk_display_x11_get_type (void)
 {
@@ -117,7 +143,6 @@ gdk_display_open (const gchar *display_name)
   const char *sm_client_id;
   
   XClassHint *class_hint;
-  XKeyboardState keyboard_state;
   gulong pid;
   gint i;
 
@@ -162,6 +187,8 @@ gdk_display_open (const gchar *display_name)
   if (_gdk_synchronize)
     XSynchronize (display_x11->xdisplay, True);
   
+  _gdk_x11_precache_atoms (display, precache_atoms, G_N_ELEMENTS (precache_atoms));
+
   class_hint = XAllocClassHint();
   class_hint->res_name = g_get_prgname ();
   
@@ -183,8 +210,6 @@ gdk_display_open (const gchar *display_name)
                   gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PID"),
                   XA_CARDINAL, 32, PropModeReplace, (guchar *) & pid, 1);
   
-  XGetKeyboardControl (display_x11->xdisplay, &keyboard_state);
-
 #ifdef HAVE_XKB
   {
     gint xkb_major = XkbMajorVersion;
@@ -509,6 +534,31 @@ gdk_display_sync (GdkDisplay * display)
   XSync (GDK_DISPLAY_XDISPLAY (display), False);
 }
 
+/**
+ * gdk_display_flush:
+ * @display: a #GdkDisplay
+ *
+ * Flushes any requests queued for the windowing system; this happens automatically
+ * when the main loop blocks waiting for new events, but if your application
+ * is drawing without returning control to the main loop, you may need
+ * to call this function explicitely. A common case where this function
+ * needs to be called is when an application is executing drawing commands
+ * from a thread other than the thread where the main loop is running.
+ *
+ * This is most useful for X11. On windowing systems where requests are
+ * handled synchronously, this function will do nothing.
+ *
+ * Since: 2.4
+ */
+void 
+gdk_display_flush (GdkDisplay *display)
+{
+  g_return_if_fail (GDK_IS_DISPLAY (display));
+
+  if (!display->closed)
+    XFlush (GDK_DISPLAY_XDISPLAY (display));
+}
+
 /**
  * gdk_x11_display_grab:
  * @display: a #GdkDisplay 
index 7bb9d63d7c4bf75f52d5e9db177edd4dbd3a8234..4e3db600cb1d6a86e6408cbe0fe4751145a071d6 100644 (file)
@@ -30,6 +30,7 @@
 #include "gdkx.h"
 #include "gdkscreen-x11.h"
 #include "gdkdisplay-x11.h"
+#include "gdkasync.h"
 
 #include "gdkkeysyms.h"
 
@@ -357,93 +358,31 @@ gdk_add_client_message_filter (GdkAtom       message_type,
 }
 
 static void
-gdk_check_wm_state_changed (GdkWindow *window)
+do_net_wm_state_changes (GdkWindow *window)
 {  
-  Atom type;
-  gint format;
-  gulong nitems;
-  gulong bytes_after;
-  Atom *atoms = NULL;
-  gulong i;
-  gboolean found_sticky, found_maxvert, found_maxhorz, found_fullscreen;
+  GdkWindowObject *window_private = (GdkWindowObject *)window;
+  GdkWindowImplX11 *window_impl = GDK_WINDOW_IMPL_X11 (window_private->impl);
   GdkWindowState old_state;
-  GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
   
   if (GDK_WINDOW_DESTROYED (window) ||
       gdk_window_get_window_type (window) != GDK_WINDOW_TOPLEVEL)
     return;
   
-  found_sticky = FALSE;
-  found_maxvert = FALSE;
-  found_maxhorz = FALSE;
-  found_fullscreen = FALSE;
-  
-  XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
-                     gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"),
-                     0, G_MAXLONG, False, XA_ATOM, &type, &format, &nitems,
-                     &bytes_after, (guchar **)&atoms);
-
-  if (type != None)
-    {
-      Atom sticky_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_STICKY");
-      Atom maxvert_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_MAXIMIZED_VERT");
-      Atom maxhorz_atom        = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_MAXIMIZED_HORZ");
-      Atom fullscreen_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_FULLSCREEN");
-      
-      i = 0;
-      while (i < nitems)
-        {
-          if (atoms[i] == sticky_atom)
-            found_sticky = TRUE;
-          else if (atoms[i] == maxvert_atom)
-            found_maxvert = TRUE;
-          else if (atoms[i] == maxhorz_atom)
-            found_maxhorz = TRUE;
-          else if (atoms[i] == fullscreen_atom)
-            found_fullscreen = TRUE;
-          
-          ++i;
-        }
-
-      XFree (atoms);
-    }
+  old_state = gdk_window_get_state (window);
 
   /* For found_sticky to remain TRUE, we have to also be on desktop
    * 0xFFFFFFFF
    */
-
-  if (found_sticky)
-    {
-      gulong *desktop;
-      
-      XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), 
-                         GDK_WINDOW_XID (window),
-                          gdk_x11_get_xatom_by_name_for_display 
-                         (display, "_NET_WM_DESKTOP"),
-                         0, G_MAXLONG, False, XA_CARDINAL, &type, 
-                         &format, &nitems,
-                          &bytes_after, (guchar **)&desktop);
-
-      if (type != None)
-        {
-          if (*desktop != 0xFFFFFFFF)
-            found_sticky = FALSE;
-          XFree (desktop);
-        }
-    }
-          
-  old_state = gdk_window_get_state (window);
-
   if (old_state & GDK_WINDOW_STATE_STICKY)
     {
-      if (!found_sticky)
+      if (!(window_impl->have_sticky && window_impl->on_all_desktops))
         gdk_synthesize_window_state (window,
                                      GDK_WINDOW_STATE_STICKY,
                                      0);
     }
   else
     {
-      if (found_sticky)
+      if (window_impl->have_sticky && window_impl->on_all_desktops)
         gdk_synthesize_window_state (window,
                                      0,
                                      GDK_WINDOW_STATE_STICKY);
@@ -451,14 +390,14 @@ gdk_check_wm_state_changed (GdkWindow *window)
 
   if (old_state & GDK_WINDOW_STATE_FULLSCREEN)
     {
-      if (!found_fullscreen)
+      if (!window_impl->have_fullscreen)
         gdk_synthesize_window_state (window,
                                      GDK_WINDOW_STATE_FULLSCREEN,
                                      0);
     }
   else
     {
-      if (found_fullscreen)
+      if (window_impl->have_fullscreen)
         gdk_synthesize_window_state (window,
                                      0,
                                      GDK_WINDOW_STATE_FULLSCREEN);
@@ -469,20 +408,110 @@ gdk_check_wm_state_changed (GdkWindow *window)
    */
   if (old_state & GDK_WINDOW_STATE_MAXIMIZED)
     {
-      if (!(found_maxvert && found_maxhorz))
+      if (!(window_impl->have_maxvert && window_impl->have_maxhorz))
         gdk_synthesize_window_state (window,
                                      GDK_WINDOW_STATE_MAXIMIZED,
                                      0);
     }
   else
     {
-      if (found_maxvert && found_maxhorz)
+      if (window_impl->have_maxvert && window_impl->have_maxhorz)
         gdk_synthesize_window_state (window,
                                      0,
                                      GDK_WINDOW_STATE_MAXIMIZED);
     }
 }
 
+static void
+gdk_check_wm_desktop_changed (GdkWindow *window)
+{
+  GdkWindowObject *window_private = (GdkWindowObject *)window;
+  GdkWindowImplX11 *window_impl = GDK_WINDOW_IMPL_X11 (window_private->impl);
+  GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
+
+  Atom type;
+  gint format;
+  gulong nitems;
+  gulong bytes_after;
+
+  if (window_impl->have_sticky)
+    {
+      gulong *desktop;
+      
+      XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), 
+                         GDK_WINDOW_XID (window),
+                          gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"),
+                         0, G_MAXLONG, False, XA_CARDINAL, &type, 
+                         &format, &nitems,
+                          &bytes_after, (guchar **)&desktop);
+
+      if (type != None)
+        {
+          window_impl->on_all_desktops = (*desktop == 0xFFFFFFFF);
+          XFree (desktop);
+        }
+      else
+       window_impl->on_all_desktops = FALSE;
+      
+      do_net_wm_state_changes (window);
+    }
+}
+
+static void
+gdk_check_wm_state_changed (GdkWindow *window)
+{
+  GdkWindowObject *window_private = (GdkWindowObject *)window;
+  GdkWindowImplX11 *window_impl = GDK_WINDOW_IMPL_X11 (window_private->impl);
+  GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
+  
+  Atom type;
+  gint format;
+  gulong nitems;
+  gulong bytes_after;
+  Atom *atoms = NULL;
+  gulong i;
+
+  gboolean had_sticky = window_impl->have_sticky;
+
+  XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
+                     gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"),
+                     0, G_MAXLONG, False, XA_ATOM, &type, &format, &nitems,
+                     &bytes_after, (guchar **)&atoms);
+
+  if (type != None)
+    {
+      Atom sticky_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_STICKY");
+      Atom maxvert_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_MAXIMIZED_VERT");
+      Atom maxhorz_atom        = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_MAXIMIZED_HORZ");
+      Atom fullscreen_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_FULLSCREEN");
+      
+      i = 0;
+      while (i < nitems)
+        {
+          if (atoms[i] == sticky_atom)
+            window_impl->have_sticky = TRUE;
+          else if (atoms[i] == maxvert_atom)
+            window_impl->have_maxvert = TRUE;
+          else if (atoms[i] == maxhorz_atom)
+            window_impl->have_maxhorz = TRUE;
+          else if (atoms[i] == fullscreen_atom)
+            window_impl->have_fullscreen = TRUE;
+          
+          ++i;
+        }
+
+      XFree (atoms);
+    }
+
+  /* When have_sticky is turned on, we have to check the DESKTOP property
+   * as well.
+   */
+  if (window_impl->have_sticky && !had_sticky)
+    gdk_check_wm_desktop_changed (window);
+  else
+    do_net_wm_state_changes (window);
+}
+
 #define HAS_FOCUS(window_impl)                           \
   ((window_impl)->has_focus || (window_impl)->has_pointer_focus)
 
@@ -1590,7 +1619,8 @@ gdk_event_translate (GdkDisplay *display,
          event->configure.width = xevent->xconfigure.width;
          event->configure.height = xevent->xconfigure.height;
          
-         if (!xevent->xconfigure.send_event && 
+         if (!xevent->xconfigure.send_event &&
+             !xevent->xconfigure.override_redirect &&
              !GDK_WINDOW_DESTROYED (window))
            {
              gint tx = 0;
@@ -1605,14 +1635,10 @@ gdk_event_translate (GdkDisplay *display,
                                         &tx, &ty,
                                         &child_window))
                {
-                 if (!gdk_error_trap_pop ())
-                   {
-                     event->configure.x = tx;
-                     event->configure.y = ty;
-                   }
+                 event->configure.x = tx;
+                 event->configure.y = ty;
                }
-             else
-               gdk_error_trap_pop ();
+             gdk_error_trap_pop ();
            }
          else
            {
@@ -1647,13 +1673,18 @@ gdk_event_translate (GdkDisplay *display,
          return_val = FALSE;
           break;
         }
-      
-      if (xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE") ||
-         xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"))
-        {
-          /* If window state changed, then synthesize those events. */
-          gdk_check_wm_state_changed (window);
-        }
+
+      /* We compare with the serial of the last time we mapped the
+       * window to avoid refetching properties that we set ourselves
+       */
+      if (xevent->xproperty.serial >= GDK_WINDOW_IMPL_X11 (window_private->impl)->map_serial)
+       {
+         if (xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"))
+           gdk_check_wm_state_changed (window);
+         
+         if (xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"))
+           gdk_check_wm_desktop_changed (window);
+       }
       
       if (window_private->event_mask & GDK_PROPERTY_CHANGE_MASK) 
        {
@@ -1876,18 +1907,14 @@ gdk_wm_protocols_filter (GdkXEvent *xev,
   else if ((Atom) xevent->xclient.data.l[0] == gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS"))
     {
       GdkWindow *win = event->any.window;
-      Window focus_win = GDK_WINDOW_IMPL_X11(((GdkWindowObject *)win)->impl)->focus_window;
+      GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (((GdkWindowObject *)win)->impl);
 
-      /* There is no way of knowing reliably whether we are viewable so we need
-       * to trap errors so we don't cause a BadMatch.
+      /* There is no way of knowing reliably whether we are viewable;
+       * _gdk_x11_set_input_focus_safe() traps errors asynchronously.
        */
-      gdk_error_trap_push ();
-      XSetInputFocus (GDK_WINDOW_XDISPLAY (win),
-                     focus_win,
-                     RevertToParent,
-                     xevent->xclient.data.l[1]);
-      XSync (GDK_WINDOW_XDISPLAY (win), False);
-      gdk_error_trap_pop ();
+      _gdk_x11_set_input_focus_safe (display, impl->focus_window,
+                                    RevertToParent,
+                                    xevent->xclient.data.l[1]);
     }
   else if ((Atom) xevent->xclient.data.l[0] == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PING") &&
           !_gdk_x11_display_is_root_window (display,
@@ -2190,8 +2217,8 @@ timestamp_predicate (Display *display,
 
   if (xevent->type == PropertyNotify &&
       xevent->xproperty.window == xwindow &&
-      xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display 
-      (gdk_display, "GDK_TIMESTAMP_PROP"))
+      xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (gdk_display,
+                                                                      "GDK_TIMESTAMP_PROP"))
     return True;
 
   return False;
index 4db96354bfa28236d93bab839da236265b5b0be7..06bf212bf9161b99b0bfc82621da562b9ad3f8ad 100644 (file)
@@ -205,16 +205,12 @@ static int
 gdk_image_check_xshm(Display *display)
 {
 #ifdef USE_SHM
-  int major, minor, ignore;
+  int major, minor;
   Bool pixmaps;
   
-  if (XQueryExtension(display, "MIT-SHM", &ignore, &ignore, &ignore)) 
-    {
-      if (XShmQueryVersion(display, &major, &minor, &pixmaps )==True) 
-       {
-         return (pixmaps==True) ? 2 : 1;
-       }
-    }
+  if (XShmQueryExtension (display) &&
+      XShmQueryVersion (display, &major, &minor, &pixmaps))
+    return pixmaps ? 2 : 1;
 #endif /* USE_SHM */
   return 0;
 }
index f6f62a3bab4877bd984dfbcaa1fb03bb42882185..3543d86cc68d8f46cae3f1d5af7361d5a59fce7a 100644 (file)
@@ -167,6 +167,10 @@ void _gdk_xgrab_check_destroy (GdkWindow *window);
 gboolean _gdk_x11_display_is_root_window (GdkDisplay *display,
                                          Window      xroot_window);
 
+void _gdk_x11_precache_atoms (GdkDisplay          *display,
+                             const gchar * const *atom_names,
+                             gint                 n_atoms);
+
 void _gdk_x11_events_init_screen   (GdkScreen *screen);
 void _gdk_x11_events_uninit_screen (GdkScreen *screen);
 
index 139c5b52c8bd5ef8a68399dced6841615aa303ba..bedea12d123ab16fe7c451357d5acb36c35135eb 100644 (file)
@@ -142,6 +142,23 @@ insert_atom_pair (GdkDisplay *display,
                       GUINT_TO_POINTER (xatom), 
                       GDK_ATOM_TO_POINTER (virtual_atom));
 }
+
+static Atom
+lookup_cached_xatom (GdkDisplay *display,
+                    GdkAtom     atom)
+{
+  GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
+
+  if (ATOM_TO_INDEX (atom) < G_N_ELEMENTS (XAtomsStrings) - N_CUSTOM_PREDEFINED)
+    return ATOM_TO_INDEX (atom);
+  
+  if (display_x11->atom_from_virtual)
+    return GPOINTER_TO_UINT (g_hash_table_lookup (display_x11->atom_from_virtual,
+                                                 GDK_ATOM_TO_POINTER (atom)));
+
+  return None;
+}
+
 /**
  * gdk_x11_atom_to_xatom_for_display:
  * @display: A #GdkDisplay
@@ -158,7 +175,6 @@ Atom
 gdk_x11_atom_to_xatom_for_display (GdkDisplay *display, 
                                   GdkAtom atom)
 {
-  GdkDisplayX11 *display_x11;
   Atom xatom = None;
   
   g_return_val_if_fail (GDK_IS_DISPLAY (display), None);
@@ -166,14 +182,8 @@ gdk_x11_atom_to_xatom_for_display (GdkDisplay *display,
   if (display->closed)
     return None;
   
-  display_x11 = GDK_DISPLAY_X11 (display); 
-  
-  if (ATOM_TO_INDEX (atom) < G_N_ELEMENTS (XAtomsStrings) - N_CUSTOM_PREDEFINED)
-    return ATOM_TO_INDEX (atom);
+  xatom = lookup_cached_xatom (display, atom);
   
-  if (display_x11->atom_from_virtual)
-    xatom = GPOINTER_TO_UINT (g_hash_table_lookup (display_x11->atom_from_virtual,
-                                                  GDK_ATOM_TO_POINTER (atom)));
   if (!xatom)
     {
       char *name;
@@ -189,6 +199,45 @@ gdk_x11_atom_to_xatom_for_display (GdkDisplay *display,
   return xatom;
 }
 
+void
+_gdk_x11_precache_atoms (GdkDisplay          *display,
+                        const gchar * const *atom_names,
+                        gint                 n_atoms)
+{
+  Atom *xatoms;
+  GdkAtom *atoms;
+  const gchar **xatom_names;
+  gint n_xatoms;
+  gint i;
+
+  xatoms = g_new (Atom, n_atoms);
+  xatom_names = g_new (const gchar *, n_atoms);
+  atoms = g_new (GdkAtom, n_atoms);
+
+  n_xatoms = 0;
+  for (i = 0; i < n_atoms; i++)
+    {
+      GdkAtom atom = gdk_atom_intern (atom_names[i], FALSE);
+      if (lookup_cached_xatom (display, atom) == None)
+       {
+         atoms[n_xatoms] = atom;
+         xatom_names[n_xatoms] = atom_names[i];
+         n_xatoms++;
+       }
+    }
+
+  if (n_xatoms)
+    XInternAtoms (GDK_DISPLAY_XDISPLAY (display),
+                 (char **)xatom_names, n_xatoms, False, xatoms);
+
+  for (i = 0; i < n_xatoms; i++)
+    insert_atom_pair (display, atoms[i], xatoms[i]);
+
+  g_free (xatoms);
+  g_free (atoms);
+  g_free (atom_names);
+}
+
 /**
  * gdk_x11_atom_to_xatom:
  * @atom: A #GdkAtom 
index 13799250aac6fb2b371bb3a38ff3d052889f35fc..ffd8d583e5a3420fbfcecce229177e1156177d7c 100644 (file)
@@ -33,6 +33,7 @@
 #include "config.h"
 
 #include "gdkwindow.h"
+#include "gdkasync.h"
 #include "gdkinputprivate.h"
 #include "gdkdisplay-x11.h"
 #include "gdkprivate-x11.h"
@@ -283,12 +284,6 @@ _gdk_windowing_window_init (GdkScreen * screen)
   GdkWindowImplX11 *impl;
   GdkDrawableImplX11 *draw_impl;
   GdkScreenX11 *screen_x11;
-  XWindowAttributes xattributes;
-  unsigned int width;
-  unsigned int height;
-  unsigned int border_width;
-  unsigned int depth;
-  int x, y;
 
   screen_x11 = GDK_SCREEN_X11 (screen);
 
@@ -297,10 +292,6 @@ _gdk_windowing_window_init (GdkScreen * screen)
   gdk_screen_set_default_colormap (screen,
                                   gdk_screen_get_system_colormap (screen));
 
-  XGetGeometry (screen_x11->xdisplay, screen_x11->xroot_window,
-               &screen_x11->xroot_window, &x, &y, &width, &height, &border_width, &depth);
-  XGetWindowAttributes (screen_x11->xdisplay, screen_x11->xroot_window, &xattributes);
-
   screen_x11->root_window = g_object_new (GDK_TYPE_WINDOW, NULL);
   private = (GdkWindowObject *)screen_x11->root_window;
   impl = GDK_WINDOW_IMPL_X11 (private->impl);
@@ -313,10 +304,10 @@ _gdk_windowing_window_init (GdkScreen * screen)
   g_object_ref (draw_impl->colormap);
   
   private->window_type = GDK_WINDOW_ROOT;
-  private->depth = depth;
+  private->depth = DefaultDepthOfScreen (screen_x11->xscreen);
   
-  impl->width = width;
-  impl->height = height;
+  impl->width = WidthOfScreen (screen_x11->xscreen);
+  impl->height = HeightOfScreen (screen_x11->xscreen);
   
   _gdk_window_init_position (GDK_WINDOW (private));
 
@@ -400,7 +391,6 @@ gdk_window_new (GdkWindow     *parent,
   XSetWindowAttributes xattributes;
   long xattributes_mask;
   XSizeHints size_hints;
-  XWMHints wm_hints;
   XClassHint *class_hint;
   int x, y, depth;
   
@@ -659,19 +649,12 @@ gdk_window_new (GdkWindow     *parent,
 
   check_leader_window_title (screen_x11->display);
   
-  wm_hints.flags = StateHint | WindowGroupHint;
-  wm_hints.window_group = GDK_DISPLAY_X11 (screen_x11->display)->leader_window;
-  wm_hints.input = True;
-  wm_hints.initial_state = NormalState;
-  
   /* FIXME: Is there any point in doing this? Do any WM's pay
    * attention to PSize, and even if they do, is this the
    * correct value???
    */
   XSetWMNormalHints (xdisplay, xid, &size_hints);
   
-  XSetWMHints (xdisplay, xid, &wm_hints);
-  
   /* This will set WM_CLIENT_MACHINE and WM_LOCALE_NAME */
   XSetWMProperties (xdisplay, xid, NULL, NULL, NULL, 0, NULL, NULL, NULL);
 
@@ -855,14 +838,38 @@ _gdk_windowing_window_destroy (GdkWindow *window,
                               gboolean   foreign_destroy)
 {
   GdkWindowObject *private = (GdkWindowObject *)window;
-
+  GdkWindowImplX11 *window_impl;
+  
   g_return_if_fail (GDK_IS_WINDOW (window));
 
+  window_impl = GDK_WINDOW_IMPL_X11 (private->impl);
+
   _gdk_selection_window_destroyed (window);
   
   if (private->extension_events != 0)
     _gdk_input_window_destroy (window);
 
+  if (window_impl->icon_window)
+    {
+      g_object_unref (window_impl->icon_window);
+      window_impl->icon_window = NULL;
+    }
+  if (window_impl->icon_pixmap)
+    {
+      g_object_unref (window_impl->icon_pixmap);
+      window_impl->icon_pixmap = NULL;
+    }
+  if (window_impl->icon_mask)
+    {
+      g_object_unref (window_impl->icon_mask);
+      window_impl->icon_mask = NULL;
+    }
+  if (window_impl->group_leader)
+    {
+      g_object_unref (window_impl->group_leader);
+      window_impl->group_leader = NULL;
+    }
+
 #ifdef HAVE_XFT  
   {
     GdkDrawableImplX11 *draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
@@ -944,6 +951,61 @@ gdk_window_destroy_notify (GdkWindow *window)
   g_object_unref (window);
 }
 
+static void
+update_wm_hints (GdkWindow *window,
+                gboolean   force)
+{
+  GdkWindowObject *private = (GdkWindowObject *)window;
+  GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl);
+  GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
+  XWMHints wm_hints;
+
+  if (!force &&
+      private->state & GDK_WINDOW_STATE_WITHDRAWN)
+    return;
+
+  wm_hints.flags = StateHint;
+  wm_hints.input = True;
+  wm_hints.initial_state = NormalState;
+  
+  if (private->state & GDK_WINDOW_STATE_ICONIFIED)
+    {
+      wm_hints.flags |= StateHint;
+      wm_hints.initial_state = IconicState;
+    }
+
+  if (impl->icon_window && !GDK_WINDOW_DESTROYED (impl->icon_window))
+    {
+      wm_hints.flags |= IconWindowHint;
+      wm_hints.icon_window = GDK_WINDOW_XID (impl->icon_window);
+    }
+
+  if (impl->icon_pixmap)
+    {
+      wm_hints.flags |= IconPixmapHint;
+      wm_hints.icon_pixmap = GDK_PIXMAP_XID (impl->icon_pixmap);
+    }
+
+  if (impl->icon_mask)
+    {
+      wm_hints.flags |= IconMaskHint;
+      wm_hints.icon_mask = GDK_PIXMAP_XID (impl->icon_mask);
+    }
+  
+  wm_hints.flags |= WindowGroupHint;
+  if (impl->group_leader && !GDK_WINDOW_DESTROYED (impl->group_leader))
+    {
+      wm_hints.flags |= WindowGroupHint;
+      wm_hints.window_group = GDK_WINDOW_XID (impl->group_leader);
+    }
+  else
+    wm_hints.window_group = GDK_DISPLAY_X11 (display)->leader_window;
+  
+  XSetWMHints (GDK_WINDOW_XDISPLAY (window),
+              GDK_WINDOW_XID (window),
+              &wm_hints);
+}
+
 static void
 set_initial_hints (GdkWindow *window)
 {
@@ -957,22 +1019,9 @@ set_initial_hints (GdkWindow *window)
 
   private = (GdkWindowObject*) window;
   impl = GDK_WINDOW_IMPL_X11 (private->impl);
-  
-  if (private->state & GDK_WINDOW_STATE_ICONIFIED)
-    {
-      XWMHints *wm_hints;
-      
-      wm_hints = XGetWMHints (xdisplay, xwindow);
-      if (!wm_hints)
-        wm_hints = XAllocWMHints ();
-
-      wm_hints->flags |= StateHint;
-      wm_hints->initial_state = IconicState;
-      
-      XSetWMHints (xdisplay, xwindow, wm_hints);
-      XFree (wm_hints);
-    }
 
+  update_wm_hints (window, TRUE);
+  
   /* We set the spec hints regardless of whether the spec is supported,
    * since it can't hurt and it's kind of expensive to check whether
    * it's supported.
@@ -1068,9 +1117,12 @@ show_window_internal (GdkWindow *window,
   private = (GdkWindowObject*) window;
   if (!private->destroyed)
     {
+      GdkWindowImplX11 *impl =GDK_WINDOW_IMPL_X11 (private->impl);
+      Display *xdisplay = GDK_WINDOW_XDISPLAY (window);
+      Window xwindow = GDK_WINDOW_XID (window);
+      
       if (raise)
-        XRaiseWindow (GDK_WINDOW_XDISPLAY (window),
-                      GDK_WINDOW_XID (window));
+        XRaiseWindow (xdisplay, xwindow);
 
       if (!GDK_WINDOW_IS_MAPPED (window))
         {
@@ -1079,13 +1131,14 @@ show_window_internal (GdkWindow *window,
           gdk_synthesize_window_state (window,
                                        GDK_WINDOW_STATE_WITHDRAWN,
                                        0);
+
+         impl->map_serial = NextRequest (xdisplay);
         }
       
       g_assert (GDK_WINDOW_IS_MAPPED (window));
-      
-      if (GDK_WINDOW_IMPL_X11 (private->impl)->position_info.mapped)
-        XMapWindow (GDK_WINDOW_XDISPLAY (window),
-                    GDK_WINDOW_XID (window));
+
+      if (impl->position_info.mapped)
+        XMapWindow (xdisplay, xwindow);
     }
 }
 
@@ -1550,11 +1603,15 @@ void
 gdk_window_focus (GdkWindow *window,
                   guint32    timestamp)
 {
+  GdkDisplay *display;
+  
   g_return_if_fail (GDK_IS_WINDOW (window));
 
   if (GDK_WINDOW_DESTROYED (window))
     return;
 
+  display = GDK_WINDOW_DISPLAY (window);
+
   if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
                                           gdk_atom_intern ("_NET_ACTIVE_WINDOW", FALSE)))
     {
@@ -1564,7 +1621,7 @@ gdk_window_focus (GdkWindow *window,
       xev.xclient.serial = 0;
       xev.xclient.send_event = True;
       xev.xclient.window = GDK_WINDOW_XWINDOW (window);
-      xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
+      xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display,
                                                                        "_NET_ACTIVE_WINDOW");
       xev.xclient.format = 32;
       xev.xclient.data.l[0] = 0;
@@ -1573,24 +1630,20 @@ gdk_window_focus (GdkWindow *window,
       xev.xclient.data.l[3] = 0;
       xev.xclient.data.l[4] = 0;
       
-      XSendEvent (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XROOTWIN (window), False,
+      XSendEvent (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XROOTWIN (window), False,
                   SubstructureRedirectMask | SubstructureNotifyMask,
                   &xev);
     }
   else
     {
-      XRaiseWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
+      XRaiseWindow (GDK_DISPLAY_XDISPLAY (window), GDK_WINDOW_XID (window));
 
-      /* There is no way of knowing reliably whether we are viewable so we need
-       * to trap errors so we don't cause a BadMatch.
+      /* There is no way of knowing reliably whether we are viewable;
+       * _gdk_x11_set_input_focus_safe() traps errors asynchronously.
        */
-      gdk_error_trap_push ();
-      XSetInputFocus (GDK_WINDOW_XDISPLAY (window),
-                      GDK_WINDOW_XWINDOW (window),
-                      RevertToParent,
-                      timestamp);
-      XSync (GDK_WINDOW_XDISPLAY (window), False);
-      gdk_error_trap_pop ();
+      _gdk_x11_set_input_focus_safe (display, GDK_WINDOW_XID (window),
+                                    RevertToParent,
+                                    timestamp);
     }
 }
 
@@ -3277,40 +3330,40 @@ gdk_window_set_icon (GdkWindow *window,
                     GdkPixmap *pixmap,
                     GdkBitmap *mask)
 {
-  XWMHints *wm_hints;
-  
+  GdkWindowObject *private;
+  GdkWindowImplX11 *impl;
+
   g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
 
   if (GDK_WINDOW_DESTROYED (window))
     return;
 
-  wm_hints = XGetWMHints (GDK_WINDOW_XDISPLAY (window),
-                         GDK_WINDOW_XID (window));
-  if (!wm_hints)
-    wm_hints = XAllocWMHints ();
+  private = (GdkWindowObject *)window;
+  impl = GDK_WINDOW_IMPL_X11 (private->impl);
 
-  if (icon_window != NULL)
+  if (impl->icon_window != icon_window)
     {
-      wm_hints->flags |= IconWindowHint;
-      wm_hints->icon_window = GDK_WINDOW_XID (icon_window);
+      if (impl->icon_window)
+       g_object_unref (impl->icon_window);
+      impl->icon_window = g_object_ref (icon_window);
     }
   
-  if (pixmap != NULL)
+  if (impl->icon_pixmap != pixmap)
     {
-      wm_hints->flags |= IconPixmapHint;
-      wm_hints->icon_pixmap = GDK_PIXMAP_XID (pixmap);
+      if (impl->icon_pixmap)
+       g_object_unref (impl->icon_pixmap);
+      impl->icon_pixmap = g_object_ref (pixmap);
     }
   
-  if (mask != NULL)
+  if (impl->icon_mask != mask)
     {
-      wm_hints->flags |= IconMaskHint;
-      wm_hints->icon_mask = GDK_PIXMAP_XID (mask);
+      if (impl->icon_mask)
+       g_object_unref (impl->icon_mask);
+      impl->icon_mask = g_object_ref (mask);
     }
-
-  XSetWMHints (GDK_WINDOW_XDISPLAY (window),
-              GDK_WINDOW_XID (window), wm_hints);
-  XFree (wm_hints);
+  
+  update_wm_hints (window, FALSE);
 }
 
 static gboolean
@@ -3733,15 +3786,13 @@ gdk_window_unfullscreen (GdkWindow *window)
  * allow users to minimize/unminimize all windows belonging to an
  * application at once. You should only set a non-default group window
  * if your application pretends to be multiple applications.
- * The group leader window may not be changed after a window has been
- * mapped (with gdk_window_show() for example).
- * 
  **/
 void          
 gdk_window_set_group (GdkWindow *window, 
                      GdkWindow *leader)
 {
-  XWMHints *wm_hints;
+  GdkWindowObject *private;
+  GdkWindowImplX11 *impl;
   
   g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
@@ -3751,17 +3802,17 @@ gdk_window_set_group (GdkWindow *window,
   if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (leader))
     return;
   
-  wm_hints = XGetWMHints (GDK_WINDOW_XDISPLAY (window),
-                         GDK_WINDOW_XID (window));
-  if (!wm_hints)
-    wm_hints = XAllocWMHints ();
+  private = (GdkWindowObject *)window;
+  impl = GDK_WINDOW_IMPL_X11 (private->impl);
 
-  wm_hints->flags |= WindowGroupHint;
-  wm_hints->window_group = GDK_WINDOW_XID (leader);
+  if (impl->group_leader != leader)
+    {
+      if (impl->group_leader)
+       g_object_unref (impl->group_leader);
+      impl->group_leader = g_object_ref (impl->group_leader);
+    }
 
-  XSetWMHints (GDK_WINDOW_XDISPLAY (window),
-              GDK_WINDOW_XID (window), wm_hints);
-  XFree (wm_hints);
+  update_wm_hints (window, FALSE);
 }
 
 static MotifWmHints *
index 72246ebf23839f999ea617fbd96827b843b5fda5..105676075e5e9b02dc9c92c98924cfa37ca31971 100644 (file)
@@ -90,7 +90,21 @@ struct _GdkWindowImplX11
   /* Set if we are requesting these hints */
   guint skip_taskbar_hint : 1;
   guint skip_pager_hint : 1;
+
+  guint on_all_desktops : 1;   /* _NET_WM_STICKY == 0xFFFFFFFF */
+
+  guint have_sticky : 1;       /* _NET_WM_STATE_STICKY */
+  guint have_maxvert : 1;       /* _NET_WM_STATE_MAXIMIZED_VERT */
+  guint have_maxhorz : 1;       /* _NET_WM_STATE_MAXIMIZED_HORZ */
+  guint have_fullscreen : 1;    /* _NET_WM_STATE_FULLSCREEN */
+
+  gulong map_serial;   /* Serial of last transition from unmapped */
   
+  GdkPixmap *icon_pixmap;
+  GdkPixmap *icon_mask;
+  GdkPixmap *icon_window;
+  GdkWindow *group_leader;
+
   /* We use an extra X window for toplevel windows that we XSetInputFocus()
    * to in order to avoid getting keyboard events redirected to subwindows
    * that might not even be part of this app
index 7be2dd1bb4764b159a581e7941ffb169b5ac1f40..542e9cfaf45ff2156380c14a3c14cae1b7960d2d 100644 (file)
@@ -439,7 +439,9 @@ xsettings_client_new (Display             *display,
 {
   XSettingsClient *client;
   char buffer[256];
-
+  char *atom_names[3];
+  Atom atoms[3];
+  
   client = malloc (sizeof *client);
   if (!client)
     return NULL;
@@ -454,9 +456,15 @@ xsettings_client_new (Display             *display,
   client->settings = NULL;
 
   sprintf(buffer, "_XSETTINGS_S%d", screen);
-  client->selection_atom = XInternAtom (display, buffer, False);
-  client->xsettings_atom = XInternAtom (display, "_XSETTINGS_SETTINGS", False);
-  client->manager_atom = XInternAtom (display, "MANAGER", False);
+  atom_names[0] = buffer;
+  atom_names[1] = "_XSETTINGS_SETTINGS";
+  atom_names[2] = "MANAGER";
+
+  XInternAtoms (display, atom_names, 3, False, atoms);
+  
+  client->selection_atom = atoms[0];
+  client->xsettings_atom = atoms[1];
+  client->manager_atom = atoms[2];
 
   /* Select on StructureNotify so we get MANAGER events
    */