summaryrefslogtreecommitdiff
path: root/gdk
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2003-07-05 01:54:05 +0000
committerOwen Taylor <otaylor@src.gnome.org>2003-07-05 01:54:05 +0000
commit9bedbf662de936081dcdf1b7baff0c3a3de68811 (patch)
tree29d6dc3c234efb569311fc1d01daf2a1635fe1d5 /gdk
parenteaab3748ed20740f09ec64fd3e814da8e5e25962 (diff)
downloadgdk-pixbuf-9bedbf662de936081dcdf1b7baff0c3a3de68811.tar.gz
Use asynchronously _gdk_x11_set_input_focus_safe to avoid having to trap
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.
Diffstat (limited to 'gdk')
-rw-r--r--gdk/gdk.def1
-rw-r--r--gdk/gdkdisplay.h2
-rw-r--r--gdk/gdkwindow.c14
-rw-r--r--gdk/linux-fb/gdkevents-fb.c5
-rw-r--r--gdk/win32/gdkevents-win32.c8
-rw-r--r--gdk/x11/Makefile.am2
-rw-r--r--gdk/x11/gdkasync.c156
-rw-r--r--gdk/x11/gdkasync.h36
-rw-r--r--gdk/x11/gdkcursor-x11.c2
-rw-r--r--gdk/x11/gdkdisplay-x11.c56
-rw-r--r--gdk/x11/gdkevents-x11.c225
-rw-r--r--gdk/x11/gdkimage-x11.c12
-rw-r--r--gdk/x11/gdkprivate-x11.h4
-rw-r--r--gdk/x11/gdkproperty-x11.c65
-rw-r--r--gdk/x11/gdkwindow-x11.c225
-rw-r--r--gdk/x11/gdkwindow-x11.h14
-rw-r--r--gdk/x11/xsettings-client.c16
17 files changed, 632 insertions, 211 deletions
diff --git a/gdk/gdk.def b/gdk/gdk.def
index 27e2a2055..01ea9db72 100644
--- a/gdk/gdk.def
+++ b/gdk/gdk.def
@@ -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
diff --git a/gdk/gdkdisplay.h b/gdk/gdkdisplay.h
index 831424014..db6df0cd4 100644
--- a/gdk/gdkdisplay.h
+++ b/gdk/gdkdisplay.h
@@ -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);
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index 21310ceb2..00c708c7b 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -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
diff --git a/gdk/linux-fb/gdkevents-fb.c b/gdk/linux-fb/gdkevents-fb.c
index b61377e4d..9001da48e 100644
--- a/gdk/linux-fb/gdkevents-fb.c
+++ b/gdk/linux-fb/gdkevents-fb.c
@@ -225,3 +225,8 @@ void
gdk_display_sync (GdkDisplay *display)
{
}
+
+void
+gdk_display_flush (GdkDisplay * display)
+{
+}
diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c
index 841835bc7..4838d0891 100644
--- a/gdk/win32/gdkevents-win32.c
+++ b/gdk/win32/gdkevents-win32.c
@@ -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 */
+}
diff --git a/gdk/x11/Makefile.am b/gdk/x11/Makefile.am
index 51ca91826..3fb2f2b1d 100644
--- a/gdk/x11/Makefile.am
+++ b/gdk/x11/Makefile.am
@@ -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
index 000000000..5f2672bda
--- /dev/null
+++ b/gdk/x11/gdkasync.c
@@ -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
index 000000000..2da604030
--- /dev/null
+++ b/gdk/x11/gdkasync.h
@@ -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__ */
diff --git a/gdk/x11/gdkcursor-x11.c b/gdk/x11/gdkcursor-x11.c
index 80f4bf9f8..d87270919 100644
--- a/gdk/x11/gdkcursor-x11.c
+++ b/gdk/x11/gdkcursor-x11.c
@@ -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);
diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c
index 66ec5c36e..969ccb71e 100644
--- a/gdk/x11/gdkdisplay-x11.c
+++ b/gdk/x11/gdkdisplay-x11.c
@@ -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;
@@ -510,6 +535,31 @@ gdk_display_sync (GdkDisplay * display)
}
/**
+ * 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
*
diff --git a/gdk/x11/gdkevents-x11.c b/gdk/x11/gdkevents-x11.c
index 7bb9d63d7..4e3db600c 100644
--- a/gdk/x11/gdkevents-x11.c
+++ b/gdk/x11/gdkevents-x11.c
@@ -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;
diff --git a/gdk/x11/gdkimage-x11.c b/gdk/x11/gdkimage-x11.c
index 4db96354b..06bf212bf 100644
--- a/gdk/x11/gdkimage-x11.c
+++ b/gdk/x11/gdkimage-x11.c
@@ -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;
}
diff --git a/gdk/x11/gdkprivate-x11.h b/gdk/x11/gdkprivate-x11.h
index f6f62a3ba..3543d86cc 100644
--- a/gdk/x11/gdkprivate-x11.h
+++ b/gdk/x11/gdkprivate-x11.h
@@ -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);
diff --git a/gdk/x11/gdkproperty-x11.c b/gdk/x11/gdkproperty-x11.c
index 139c5b52c..bedea12d1 100644
--- a/gdk/x11/gdkproperty-x11.c
+++ b/gdk/x11/gdkproperty-x11.c
@@ -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
diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c
index 13799250a..ffd8d583e 100644
--- a/gdk/x11/gdkwindow-x11.c
+++ b/gdk/x11/gdkwindow-x11.c
@@ -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);
@@ -945,6 +952,61 @@ gdk_window_destroy_notify (GdkWindow *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)
{
GdkDisplay *display = GDK_WINDOW_DISPLAY (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 *
diff --git a/gdk/x11/gdkwindow-x11.h b/gdk/x11/gdkwindow-x11.h
index 72246ebf2..105676075 100644
--- a/gdk/x11/gdkwindow-x11.h
+++ b/gdk/x11/gdkwindow-x11.h
@@ -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
diff --git a/gdk/x11/xsettings-client.c b/gdk/x11/xsettings-client.c
index 7be2dd1bb..542e9cfaf 100644
--- a/gdk/x11/xsettings-client.c
+++ b/gdk/x11/xsettings-client.c
@@ -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
*/