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.
This commit is contained in:
Owen Taylor 2003-07-05 01:54:05 +00:00 committed by Owen Taylor
parent eaab3748ed
commit 9bedbf662d
23 changed files with 937 additions and 231 deletions

View 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> Fri Jul 4 19:55:49 2003 Soeren Sandmann <sandmann@daimi.au.dk>
* tests/stresstest-toolbar: remove this accidentally committed * tests/stresstest-toolbar: remove this accidentally committed

View 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> Fri Jul 4 19:55:49 2003 Soeren Sandmann <sandmann@daimi.au.dk>
* tests/stresstest-toolbar: remove this accidentally committed * tests/stresstest-toolbar: remove this accidentally committed

View 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> Fri Jul 4 19:55:49 2003 Soeren Sandmann <sandmann@daimi.au.dk>
* tests/stresstest-toolbar: remove this accidentally committed * tests/stresstest-toolbar: remove this accidentally committed

View 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> Fri Jul 4 19:55:49 2003 Soeren Sandmann <sandmann@daimi.au.dk>
* tests/stresstest-toolbar: remove this accidentally committed * tests/stresstest-toolbar: remove this accidentally committed

View 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> Fri Jul 4 19:55:49 2003 Soeren Sandmann <sandmann@daimi.au.dk>
* tests/stresstest-toolbar: remove this accidentally committed * tests/stresstest-toolbar: remove this accidentally committed

View File

@ -161,8 +161,8 @@ AC_ARG_ENABLE(debug,
enable_debug=debug_default) enable_debug=debug_default)
AC_ARG_ENABLE(shm, AC_ARG_ENABLE(shm,
[AC_HELP_STRING([--enable-shm], [AC_HELP_STRING([--enable-shm],
[support shared memory if available [default=yes]])], [support shared memory if available [default=yes]])],,
[echo $enable_shm, enable_shm="yes"]) [enable_shm="yes"])
AC_ARG_ENABLE(ansi, AC_ARG_ENABLE(ansi,
[AC_HELP_STRING([--enable-ansi], [AC_HELP_STRING([--enable-ansi],
[turn on strict ansi [default=no]])],, [turn on strict ansi [default=no]])],,

View File

@ -60,6 +60,7 @@ EXPORTS
gdk_display_add_client_message_filter gdk_display_add_client_message_filter
gdk_display_beep gdk_display_beep
gdk_display_close gdk_display_close
gdk_display_flush
gdk_display_get_core_pointer gdk_display_get_core_pointer
gdk_display_get_default gdk_display_get_default
gdk_display_get_default_screen gdk_display_get_default_screen

View File

@ -113,6 +113,8 @@ void gdk_display_keyboard_ungrab (GdkDisplay *display,
gboolean gdk_display_pointer_is_grabbed (GdkDisplay *display); gboolean gdk_display_pointer_is_grabbed (GdkDisplay *display);
void gdk_display_beep (GdkDisplay *display); void gdk_display_beep (GdkDisplay *display);
void gdk_display_sync (GdkDisplay *display); void gdk_display_sync (GdkDisplay *display);
void gdk_display_flush (GdkDisplay *display);
void gdk_display_close (GdkDisplay *display); void gdk_display_close (GdkDisplay *display);
GList * gdk_display_list_devices (GdkDisplay *display); GList * gdk_display_list_devices (GdkDisplay *display);

View 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: * gdk_window_process_all_updates:
* *
@ -2174,7 +2186,7 @@ gdk_window_process_all_updates (void)
g_slist_free (old_update_windows); g_slist_free (old_update_windows);
gdk_flush(); flush_all_displays ();
} }
static gboolean static gboolean

View File

@ -225,3 +225,8 @@ void
gdk_display_sync (GdkDisplay *display) gdk_display_sync (GdkDisplay *display)
{ {
} }
void
gdk_display_flush (GdkDisplay * display)
{
}

View File

@ -3516,3 +3516,11 @@ gdk_display_sync (GdkDisplay * display)
DispatchMessage (&msg); DispatchMessage (&msg);
} }
} }
void
gdk_display_flush (GdkDisplay * display)
{
g_return_if_fail (display == gdk_display_get_default ());
/* Nothing */
}

View File

@ -20,6 +20,8 @@ noinst_LTLIBRARIES = libgdk-x11.la
libgdk_x11_la_SOURCES = \ libgdk_x11_la_SOURCES = \
MwmUtil.h \ MwmUtil.h \
gdkasync.c \
gdkasync.h \
gdkcolor-x11.c \ gdkcolor-x11.c \
gdkcursor-x11.c \ gdkcursor-x11.c \
gdkdisplay-x11.c \ gdkdisplay-x11.c \

156
gdk/x11/gdkasync.c Normal file
View File

@ -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();
}

36
gdk/x11/gdkasync.h Normal file
View File

@ -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__ */

View File

@ -587,7 +587,7 @@ gdk_display_get_maximal_cursor_size (GdkDisplay *display,
GdkScreen *screen; GdkScreen *screen;
GdkWindow *window; 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); screen = gdk_display_get_default_screen (display);
window = gdk_screen_get_root_window (screen); window = gdk_screen_get_root_window (screen);

View File

@ -57,6 +57,32 @@ static void gdk_internal_connection_watch (Display *display,
static gpointer parent_class = NULL; 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 GType
_gdk_display_x11_get_type (void) _gdk_display_x11_get_type (void)
{ {
@ -117,7 +143,6 @@ gdk_display_open (const gchar *display_name)
const char *sm_client_id; const char *sm_client_id;
XClassHint *class_hint; XClassHint *class_hint;
XKeyboardState keyboard_state;
gulong pid; gulong pid;
gint i; gint i;
@ -162,6 +187,8 @@ gdk_display_open (const gchar *display_name)
if (_gdk_synchronize) if (_gdk_synchronize)
XSynchronize (display_x11->xdisplay, True); XSynchronize (display_x11->xdisplay, True);
_gdk_x11_precache_atoms (display, precache_atoms, G_N_ELEMENTS (precache_atoms));
class_hint = XAllocClassHint(); class_hint = XAllocClassHint();
class_hint->res_name = g_get_prgname (); 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"), gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PID"),
XA_CARDINAL, 32, PropModeReplace, (guchar *) & pid, 1); XA_CARDINAL, 32, PropModeReplace, (guchar *) & pid, 1);
XGetKeyboardControl (display_x11->xdisplay, &keyboard_state);
#ifdef HAVE_XKB #ifdef HAVE_XKB
{ {
gint xkb_major = XkbMajorVersion; gint xkb_major = XkbMajorVersion;
@ -509,6 +534,31 @@ gdk_display_sync (GdkDisplay * display)
XSync (GDK_DISPLAY_XDISPLAY (display), False); 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: * gdk_x11_display_grab:
* @display: a #GdkDisplay * @display: a #GdkDisplay

View File

@ -30,6 +30,7 @@
#include "gdkx.h" #include "gdkx.h"
#include "gdkscreen-x11.h" #include "gdkscreen-x11.h"
#include "gdkdisplay-x11.h" #include "gdkdisplay-x11.h"
#include "gdkasync.h"
#include "gdkkeysyms.h" #include "gdkkeysyms.h"
@ -357,28 +358,122 @@ gdk_add_client_message_filter (GdkAtom message_type,
} }
static void static void
gdk_check_wm_state_changed (GdkWindow *window) do_net_wm_state_changes (GdkWindow *window)
{ {
GdkWindowObject *window_private = (GdkWindowObject *)window;
GdkWindowImplX11 *window_impl = GDK_WINDOW_IMPL_X11 (window_private->impl);
GdkWindowState old_state;
if (GDK_WINDOW_DESTROYED (window) ||
gdk_window_get_window_type (window) != GDK_WINDOW_TOPLEVEL)
return;
old_state = gdk_window_get_state (window);
/* For found_sticky to remain TRUE, we have to also be on desktop
* 0xFFFFFFFF
*/
if (old_state & GDK_WINDOW_STATE_STICKY)
{
if (!(window_impl->have_sticky && window_impl->on_all_desktops))
gdk_synthesize_window_state (window,
GDK_WINDOW_STATE_STICKY,
0);
}
else
{
if (window_impl->have_sticky && window_impl->on_all_desktops)
gdk_synthesize_window_state (window,
0,
GDK_WINDOW_STATE_STICKY);
}
if (old_state & GDK_WINDOW_STATE_FULLSCREEN)
{
if (!window_impl->have_fullscreen)
gdk_synthesize_window_state (window,
GDK_WINDOW_STATE_FULLSCREEN,
0);
}
else
{
if (window_impl->have_fullscreen)
gdk_synthesize_window_state (window,
0,
GDK_WINDOW_STATE_FULLSCREEN);
}
/* Our "maximized" means both vertical and horizontal; if only one,
* we don't expose that via GDK
*/
if (old_state & GDK_WINDOW_STATE_MAXIMIZED)
{
if (!(window_impl->have_maxvert && window_impl->have_maxhorz))
gdk_synthesize_window_state (window,
GDK_WINDOW_STATE_MAXIMIZED,
0);
}
else
{
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; Atom type;
gint format; gint format;
gulong nitems; gulong nitems;
gulong bytes_after; gulong bytes_after;
Atom *atoms = NULL; Atom *atoms = NULL;
gulong i; gulong i;
gboolean found_sticky, found_maxvert, found_maxhorz, found_fullscreen;
GdkWindowState old_state; gboolean had_sticky = window_impl->have_sticky;
GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (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"), gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"),
0, G_MAXLONG, False, XA_ATOM, &type, &format, &nitems, 0, G_MAXLONG, False, XA_ATOM, &type, &format, &nitems,
&bytes_after, (guchar **)&atoms); &bytes_after, (guchar **)&atoms);
@ -394,13 +489,13 @@ gdk_check_wm_state_changed (GdkWindow *window)
while (i < nitems) while (i < nitems)
{ {
if (atoms[i] == sticky_atom) if (atoms[i] == sticky_atom)
found_sticky = TRUE; window_impl->have_sticky = TRUE;
else if (atoms[i] == maxvert_atom) else if (atoms[i] == maxvert_atom)
found_maxvert = TRUE; window_impl->have_maxvert = TRUE;
else if (atoms[i] == maxhorz_atom) else if (atoms[i] == maxhorz_atom)
found_maxhorz = TRUE; window_impl->have_maxhorz = TRUE;
else if (atoms[i] == fullscreen_atom) else if (atoms[i] == fullscreen_atom)
found_fullscreen = TRUE; window_impl->have_fullscreen = TRUE;
++i; ++i;
} }
@ -408,79 +503,13 @@ gdk_check_wm_state_changed (GdkWindow *window)
XFree (atoms); XFree (atoms);
} }
/* For found_sticky to remain TRUE, we have to also be on desktop /* When have_sticky is turned on, we have to check the DESKTOP property
* 0xFFFFFFFF * as well.
*/ */
if (window_impl->have_sticky && !had_sticky)
if (found_sticky) gdk_check_wm_desktop_changed (window);
{
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)
gdk_synthesize_window_state (window,
GDK_WINDOW_STATE_STICKY,
0);
}
else else
{ do_net_wm_state_changes (window);
if (found_sticky)
gdk_synthesize_window_state (window,
0,
GDK_WINDOW_STATE_STICKY);
}
if (old_state & GDK_WINDOW_STATE_FULLSCREEN)
{
if (!found_fullscreen)
gdk_synthesize_window_state (window,
GDK_WINDOW_STATE_FULLSCREEN,
0);
}
else
{
if (found_fullscreen)
gdk_synthesize_window_state (window,
0,
GDK_WINDOW_STATE_FULLSCREEN);
}
/* Our "maximized" means both vertical and horizontal; if only one,
* we don't expose that via GDK
*/
if (old_state & GDK_WINDOW_STATE_MAXIMIZED)
{
if (!(found_maxvert && found_maxhorz))
gdk_synthesize_window_state (window,
GDK_WINDOW_STATE_MAXIMIZED,
0);
}
else
{
if (found_maxvert && found_maxhorz)
gdk_synthesize_window_state (window,
0,
GDK_WINDOW_STATE_MAXIMIZED);
}
} }
#define HAS_FOCUS(window_impl) \ #define HAS_FOCUS(window_impl) \
@ -1590,7 +1619,8 @@ gdk_event_translate (GdkDisplay *display,
event->configure.width = xevent->xconfigure.width; event->configure.width = xevent->xconfigure.width;
event->configure.height = xevent->xconfigure.height; event->configure.height = xevent->xconfigure.height;
if (!xevent->xconfigure.send_event && if (!xevent->xconfigure.send_event &&
!xevent->xconfigure.override_redirect &&
!GDK_WINDOW_DESTROYED (window)) !GDK_WINDOW_DESTROYED (window))
{ {
gint tx = 0; gint tx = 0;
@ -1605,14 +1635,10 @@ gdk_event_translate (GdkDisplay *display,
&tx, &ty, &tx, &ty,
&child_window)) &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 else
{ {
@ -1647,13 +1673,18 @@ gdk_event_translate (GdkDisplay *display,
return_val = FALSE; return_val = FALSE;
break; break;
} }
if (xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE") || /* We compare with the serial of the last time we mapped the
xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP")) * window to avoid refetching properties that we set ourselves
{ */
/* If window state changed, then synthesize those events. */ if (xevent->xproperty.serial >= GDK_WINDOW_IMPL_X11 (window_private->impl)->map_serial)
gdk_check_wm_state_changed (window); {
} 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) 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")) 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; 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 /* There is no way of knowing reliably whether we are viewable;
* to trap errors so we don't cause a BadMatch. * _gdk_x11_set_input_focus_safe() traps errors asynchronously.
*/ */
gdk_error_trap_push (); _gdk_x11_set_input_focus_safe (display, impl->focus_window,
XSetInputFocus (GDK_WINDOW_XDISPLAY (win), RevertToParent,
focus_win, xevent->xclient.data.l[1]);
RevertToParent,
xevent->xclient.data.l[1]);
XSync (GDK_WINDOW_XDISPLAY (win), False);
gdk_error_trap_pop ();
} }
else if ((Atom) xevent->xclient.data.l[0] == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PING") && 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, !_gdk_x11_display_is_root_window (display,
@ -2190,8 +2217,8 @@ timestamp_predicate (Display *display,
if (xevent->type == PropertyNotify && if (xevent->type == PropertyNotify &&
xevent->xproperty.window == xwindow && xevent->xproperty.window == xwindow &&
xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (gdk_display,
(gdk_display, "GDK_TIMESTAMP_PROP")) "GDK_TIMESTAMP_PROP"))
return True; return True;
return False; return False;

View File

@ -205,16 +205,12 @@ static int
gdk_image_check_xshm(Display *display) gdk_image_check_xshm(Display *display)
{ {
#ifdef USE_SHM #ifdef USE_SHM
int major, minor, ignore; int major, minor;
Bool pixmaps; Bool pixmaps;
if (XQueryExtension(display, "MIT-SHM", &ignore, &ignore, &ignore)) if (XShmQueryExtension (display) &&
{ XShmQueryVersion (display, &major, &minor, &pixmaps))
if (XShmQueryVersion(display, &major, &minor, &pixmaps )==True) return pixmaps ? 2 : 1;
{
return (pixmaps==True) ? 2 : 1;
}
}
#endif /* USE_SHM */ #endif /* USE_SHM */
return 0; return 0;
} }

View File

@ -167,6 +167,10 @@ void _gdk_xgrab_check_destroy (GdkWindow *window);
gboolean _gdk_x11_display_is_root_window (GdkDisplay *display, gboolean _gdk_x11_display_is_root_window (GdkDisplay *display,
Window xroot_window); 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_init_screen (GdkScreen *screen);
void _gdk_x11_events_uninit_screen (GdkScreen *screen); void _gdk_x11_events_uninit_screen (GdkScreen *screen);

View File

@ -142,6 +142,23 @@ insert_atom_pair (GdkDisplay *display,
GUINT_TO_POINTER (xatom), GUINT_TO_POINTER (xatom),
GDK_ATOM_TO_POINTER (virtual_atom)); 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: * gdk_x11_atom_to_xatom_for_display:
* @display: A #GdkDisplay * @display: A #GdkDisplay
@ -158,7 +175,6 @@ Atom
gdk_x11_atom_to_xatom_for_display (GdkDisplay *display, gdk_x11_atom_to_xatom_for_display (GdkDisplay *display,
GdkAtom atom) GdkAtom atom)
{ {
GdkDisplayX11 *display_x11;
Atom xatom = None; Atom xatom = None;
g_return_val_if_fail (GDK_IS_DISPLAY (display), 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) if (display->closed)
return None; return None;
display_x11 = GDK_DISPLAY_X11 (display); xatom = lookup_cached_xatom (display, atom);
if (ATOM_TO_INDEX (atom) < G_N_ELEMENTS (XAtomsStrings) - N_CUSTOM_PREDEFINED)
return ATOM_TO_INDEX (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) if (!xatom)
{ {
char *name; char *name;
@ -189,6 +199,45 @@ gdk_x11_atom_to_xatom_for_display (GdkDisplay *display,
return xatom; 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: * gdk_x11_atom_to_xatom:
* @atom: A #GdkAtom * @atom: A #GdkAtom

View File

@ -33,6 +33,7 @@
#include "config.h" #include "config.h"
#include "gdkwindow.h" #include "gdkwindow.h"
#include "gdkasync.h"
#include "gdkinputprivate.h" #include "gdkinputprivate.h"
#include "gdkdisplay-x11.h" #include "gdkdisplay-x11.h"
#include "gdkprivate-x11.h" #include "gdkprivate-x11.h"
@ -283,12 +284,6 @@ _gdk_windowing_window_init (GdkScreen * screen)
GdkWindowImplX11 *impl; GdkWindowImplX11 *impl;
GdkDrawableImplX11 *draw_impl; GdkDrawableImplX11 *draw_impl;
GdkScreenX11 *screen_x11; 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); screen_x11 = GDK_SCREEN_X11 (screen);
@ -297,10 +292,6 @@ _gdk_windowing_window_init (GdkScreen * screen)
gdk_screen_set_default_colormap (screen, gdk_screen_set_default_colormap (screen,
gdk_screen_get_system_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); screen_x11->root_window = g_object_new (GDK_TYPE_WINDOW, NULL);
private = (GdkWindowObject *)screen_x11->root_window; private = (GdkWindowObject *)screen_x11->root_window;
impl = GDK_WINDOW_IMPL_X11 (private->impl); impl = GDK_WINDOW_IMPL_X11 (private->impl);
@ -313,10 +304,10 @@ _gdk_windowing_window_init (GdkScreen * screen)
g_object_ref (draw_impl->colormap); g_object_ref (draw_impl->colormap);
private->window_type = GDK_WINDOW_ROOT; private->window_type = GDK_WINDOW_ROOT;
private->depth = depth; private->depth = DefaultDepthOfScreen (screen_x11->xscreen);
impl->width = width; impl->width = WidthOfScreen (screen_x11->xscreen);
impl->height = height; impl->height = HeightOfScreen (screen_x11->xscreen);
_gdk_window_init_position (GDK_WINDOW (private)); _gdk_window_init_position (GDK_WINDOW (private));
@ -400,7 +391,6 @@ gdk_window_new (GdkWindow *parent,
XSetWindowAttributes xattributes; XSetWindowAttributes xattributes;
long xattributes_mask; long xattributes_mask;
XSizeHints size_hints; XSizeHints size_hints;
XWMHints wm_hints;
XClassHint *class_hint; XClassHint *class_hint;
int x, y, depth; int x, y, depth;
@ -659,19 +649,12 @@ gdk_window_new (GdkWindow *parent,
check_leader_window_title (screen_x11->display); 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 /* FIXME: Is there any point in doing this? Do any WM's pay
* attention to PSize, and even if they do, is this the * attention to PSize, and even if they do, is this the
* correct value??? * correct value???
*/ */
XSetWMNormalHints (xdisplay, xid, &size_hints); XSetWMNormalHints (xdisplay, xid, &size_hints);
XSetWMHints (xdisplay, xid, &wm_hints);
/* This will set WM_CLIENT_MACHINE and WM_LOCALE_NAME */ /* This will set WM_CLIENT_MACHINE and WM_LOCALE_NAME */
XSetWMProperties (xdisplay, xid, NULL, NULL, NULL, 0, NULL, NULL, NULL); XSetWMProperties (xdisplay, xid, NULL, NULL, NULL, 0, NULL, NULL, NULL);
@ -855,14 +838,38 @@ _gdk_windowing_window_destroy (GdkWindow *window,
gboolean foreign_destroy) gboolean foreign_destroy)
{ {
GdkWindowObject *private = (GdkWindowObject *)window; GdkWindowObject *private = (GdkWindowObject *)window;
GdkWindowImplX11 *window_impl;
g_return_if_fail (GDK_IS_WINDOW (window)); g_return_if_fail (GDK_IS_WINDOW (window));
window_impl = GDK_WINDOW_IMPL_X11 (private->impl);
_gdk_selection_window_destroyed (window); _gdk_selection_window_destroyed (window);
if (private->extension_events != 0) if (private->extension_events != 0)
_gdk_input_window_destroy (window); _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 #ifdef HAVE_XFT
{ {
GdkDrawableImplX11 *draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl); GdkDrawableImplX11 *draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
@ -944,6 +951,61 @@ gdk_window_destroy_notify (GdkWindow *window)
g_object_unref (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 static void
set_initial_hints (GdkWindow *window) set_initial_hints (GdkWindow *window)
{ {
@ -957,22 +1019,9 @@ set_initial_hints (GdkWindow *window)
private = (GdkWindowObject*) window; private = (GdkWindowObject*) window;
impl = GDK_WINDOW_IMPL_X11 (private->impl); impl = GDK_WINDOW_IMPL_X11 (private->impl);
update_wm_hints (window, TRUE);
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);
}
/* We set the spec hints regardless of whether the spec is supported, /* 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 * since it can't hurt and it's kind of expensive to check whether
* it's supported. * it's supported.
@ -1068,9 +1117,12 @@ show_window_internal (GdkWindow *window,
private = (GdkWindowObject*) window; private = (GdkWindowObject*) window;
if (!private->destroyed) 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) if (raise)
XRaiseWindow (GDK_WINDOW_XDISPLAY (window), XRaiseWindow (xdisplay, xwindow);
GDK_WINDOW_XID (window));
if (!GDK_WINDOW_IS_MAPPED (window)) if (!GDK_WINDOW_IS_MAPPED (window))
{ {
@ -1079,13 +1131,14 @@ show_window_internal (GdkWindow *window,
gdk_synthesize_window_state (window, gdk_synthesize_window_state (window,
GDK_WINDOW_STATE_WITHDRAWN, GDK_WINDOW_STATE_WITHDRAWN,
0); 0);
impl->map_serial = NextRequest (xdisplay);
} }
g_assert (GDK_WINDOW_IS_MAPPED (window)); g_assert (GDK_WINDOW_IS_MAPPED (window));
if (GDK_WINDOW_IMPL_X11 (private->impl)->position_info.mapped) if (impl->position_info.mapped)
XMapWindow (GDK_WINDOW_XDISPLAY (window), XMapWindow (xdisplay, xwindow);
GDK_WINDOW_XID (window));
} }
} }
@ -1550,11 +1603,15 @@ void
gdk_window_focus (GdkWindow *window, gdk_window_focus (GdkWindow *window,
guint32 timestamp) guint32 timestamp)
{ {
GdkDisplay *display;
g_return_if_fail (GDK_IS_WINDOW (window)); g_return_if_fail (GDK_IS_WINDOW (window));
if (GDK_WINDOW_DESTROYED (window)) if (GDK_WINDOW_DESTROYED (window))
return; return;
display = GDK_WINDOW_DISPLAY (window);
if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window), if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
gdk_atom_intern ("_NET_ACTIVE_WINDOW", FALSE))) gdk_atom_intern ("_NET_ACTIVE_WINDOW", FALSE)))
{ {
@ -1564,7 +1621,7 @@ gdk_window_focus (GdkWindow *window,
xev.xclient.serial = 0; xev.xclient.serial = 0;
xev.xclient.send_event = True; xev.xclient.send_event = True;
xev.xclient.window = GDK_WINDOW_XWINDOW (window); 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"); "_NET_ACTIVE_WINDOW");
xev.xclient.format = 32; xev.xclient.format = 32;
xev.xclient.data.l[0] = 0; 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[3] = 0;
xev.xclient.data.l[4] = 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, SubstructureRedirectMask | SubstructureNotifyMask,
&xev); &xev);
} }
else 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 /* There is no way of knowing reliably whether we are viewable;
* to trap errors so we don't cause a BadMatch. * _gdk_x11_set_input_focus_safe() traps errors asynchronously.
*/ */
gdk_error_trap_push (); _gdk_x11_set_input_focus_safe (display, GDK_WINDOW_XID (window),
XSetInputFocus (GDK_WINDOW_XDISPLAY (window), RevertToParent,
GDK_WINDOW_XWINDOW (window), timestamp);
RevertToParent,
timestamp);
XSync (GDK_WINDOW_XDISPLAY (window), False);
gdk_error_trap_pop ();
} }
} }
@ -3277,40 +3330,40 @@ gdk_window_set_icon (GdkWindow *window,
GdkPixmap *pixmap, GdkPixmap *pixmap,
GdkBitmap *mask) GdkBitmap *mask)
{ {
XWMHints *wm_hints; GdkWindowObject *private;
GdkWindowImplX11 *impl;
g_return_if_fail (window != NULL); g_return_if_fail (window != NULL);
g_return_if_fail (GDK_IS_WINDOW (window)); g_return_if_fail (GDK_IS_WINDOW (window));
if (GDK_WINDOW_DESTROYED (window)) if (GDK_WINDOW_DESTROYED (window))
return; return;
wm_hints = XGetWMHints (GDK_WINDOW_XDISPLAY (window), private = (GdkWindowObject *)window;
GDK_WINDOW_XID (window)); impl = GDK_WINDOW_IMPL_X11 (private->impl);
if (!wm_hints)
wm_hints = XAllocWMHints ();
if (icon_window != NULL) if (impl->icon_window != icon_window)
{ {
wm_hints->flags |= IconWindowHint; if (impl->icon_window)
wm_hints->icon_window = GDK_WINDOW_XID (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; if (impl->icon_pixmap)
wm_hints->icon_pixmap = GDK_PIXMAP_XID (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; if (impl->icon_mask)
wm_hints->icon_mask = GDK_PIXMAP_XID (mask); g_object_unref (impl->icon_mask);
impl->icon_mask = g_object_ref (mask);
} }
XSetWMHints (GDK_WINDOW_XDISPLAY (window), update_wm_hints (window, FALSE);
GDK_WINDOW_XID (window), wm_hints);
XFree (wm_hints);
} }
static gboolean static gboolean
@ -3733,15 +3786,13 @@ gdk_window_unfullscreen (GdkWindow *window)
* allow users to minimize/unminimize all windows belonging to an * allow users to minimize/unminimize all windows belonging to an
* application at once. You should only set a non-default group window * application at once. You should only set a non-default group window
* if your application pretends to be multiple applications. * 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 void
gdk_window_set_group (GdkWindow *window, gdk_window_set_group (GdkWindow *window,
GdkWindow *leader) GdkWindow *leader)
{ {
XWMHints *wm_hints; GdkWindowObject *private;
GdkWindowImplX11 *impl;
g_return_if_fail (window != NULL); g_return_if_fail (window != NULL);
g_return_if_fail (GDK_IS_WINDOW (window)); 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)) if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (leader))
return; return;
wm_hints = XGetWMHints (GDK_WINDOW_XDISPLAY (window), private = (GdkWindowObject *)window;
GDK_WINDOW_XID (window)); impl = GDK_WINDOW_IMPL_X11 (private->impl);
if (!wm_hints)
wm_hints = XAllocWMHints ();
wm_hints->flags |= WindowGroupHint; if (impl->group_leader != leader)
wm_hints->window_group = GDK_WINDOW_XID (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), update_wm_hints (window, FALSE);
GDK_WINDOW_XID (window), wm_hints);
XFree (wm_hints);
} }
static MotifWmHints * static MotifWmHints *

View File

@ -90,7 +90,21 @@ struct _GdkWindowImplX11
/* Set if we are requesting these hints */ /* Set if we are requesting these hints */
guint skip_taskbar_hint : 1; guint skip_taskbar_hint : 1;
guint skip_pager_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() /* We use an extra X window for toplevel windows that we XSetInputFocus()
* to in order to avoid getting keyboard events redirected to subwindows * to in order to avoid getting keyboard events redirected to subwindows
* that might not even be part of this app * that might not even be part of this app

View File

@ -439,7 +439,9 @@ xsettings_client_new (Display *display,
{ {
XSettingsClient *client; XSettingsClient *client;
char buffer[256]; char buffer[256];
char *atom_names[3];
Atom atoms[3];
client = malloc (sizeof *client); client = malloc (sizeof *client);
if (!client) if (!client)
return NULL; return NULL;
@ -454,9 +456,15 @@ xsettings_client_new (Display *display,
client->settings = NULL; client->settings = NULL;
sprintf(buffer, "_XSETTINGS_S%d", screen); sprintf(buffer, "_XSETTINGS_S%d", screen);
client->selection_atom = XInternAtom (display, buffer, False); atom_names[0] = buffer;
client->xsettings_atom = XInternAtom (display, "_XSETTINGS_SETTINGS", False); atom_names[1] = "_XSETTINGS_SETTINGS";
client->manager_atom = XInternAtom (display, "MANAGER", False); 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 /* Select on StructureNotify so we get MANAGER events
*/ */