Set the right properties when the window becomes a toplevel. When a window

Sun Dec 21 17:34:22 2003  Soeren Sandmann  <sandmann@daimi.au.dk>

	* gdk/x11/gdkwindow-x11.c (gdk_window_reparent): Set the right
	properties when the window becomes a toplevel. When a window that
	was previously a toplevel becomes a toplevel again, restore its
	window type. Also make sure the focus window is removed from the
	XID hash when it is destroyed. (#117579, reported by Morten
	Welinder, patch reviewed by Owen Taylor).
This commit is contained in:
Soeren Sandmann 2003-12-21 16:37:43 +00:00 committed by Søren Sandmann Pedersen
parent b21fe1745c
commit d2e744ca52
7 changed files with 166 additions and 84 deletions

View File

@ -1,3 +1,12 @@
Sun Dec 21 17:34:22 2003 Soeren Sandmann <sandmann@daimi.au.dk>
* gdk/x11/gdkwindow-x11.c (gdk_window_reparent): Set the right
properties when the window becomes a toplevel. When a window that
was previously a toplevel becomes a toplevel again, restore its
window type. Also make sure the focus window is removed from the
XID hash when it is destroyed. (#117579, reported by Morten
Welinder, patch reviewed by Owen Taylor).
Sun Dec 21 01:54:40 2003 Matthias Clasen <maclas@gmx.de>
* gtk/gtkmenushell.h:

View File

@ -1,3 +1,12 @@
Sun Dec 21 17:34:22 2003 Soeren Sandmann <sandmann@daimi.au.dk>
* gdk/x11/gdkwindow-x11.c (gdk_window_reparent): Set the right
properties when the window becomes a toplevel. When a window that
was previously a toplevel becomes a toplevel again, restore its
window type. Also make sure the focus window is removed from the
XID hash when it is destroyed. (#117579, reported by Morten
Welinder, patch reviewed by Owen Taylor).
Sun Dec 21 01:54:40 2003 Matthias Clasen <maclas@gmx.de>
* gtk/gtkmenushell.h:

View File

@ -1,3 +1,12 @@
Sun Dec 21 17:34:22 2003 Soeren Sandmann <sandmann@daimi.au.dk>
* gdk/x11/gdkwindow-x11.c (gdk_window_reparent): Set the right
properties when the window becomes a toplevel. When a window that
was previously a toplevel becomes a toplevel again, restore its
window type. Also make sure the focus window is removed from the
XID hash when it is destroyed. (#117579, reported by Morten
Welinder, patch reviewed by Owen Taylor).
Sun Dec 21 01:54:40 2003 Matthias Clasen <maclas@gmx.de>
* gtk/gtkmenushell.h:

View File

@ -1,3 +1,12 @@
Sun Dec 21 17:34:22 2003 Soeren Sandmann <sandmann@daimi.au.dk>
* gdk/x11/gdkwindow-x11.c (gdk_window_reparent): Set the right
properties when the window becomes a toplevel. When a window that
was previously a toplevel becomes a toplevel again, restore its
window type. Also make sure the focus window is removed from the
XID hash when it is destroyed. (#117579, reported by Morten
Welinder, patch reviewed by Owen Taylor).
Sun Dec 21 01:54:40 2003 Matthias Clasen <maclas@gmx.de>
* gtk/gtkmenushell.h:

View File

@ -1,3 +1,12 @@
Sun Dec 21 17:34:22 2003 Soeren Sandmann <sandmann@daimi.au.dk>
* gdk/x11/gdkwindow-x11.c (gdk_window_reparent): Set the right
properties when the window becomes a toplevel. When a window that
was previously a toplevel becomes a toplevel again, restore its
window type. Also make sure the focus window is removed from the
XID hash when it is destroyed. (#117579, reported by Morten
Welinder, patch reviewed by Owen Taylor).
Sun Dec 21 01:54:40 2003 Matthias Clasen <maclas@gmx.de>
* gtk/gtkmenushell.h:

View File

@ -1,4 +1,3 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
@ -102,6 +101,10 @@ static void gdk_window_impl_x11_finalize (GObject *object);
static gpointer parent_class = NULL;
#define WINDOW_IS_TOPLEVEL(window) \
(GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
GDK_WINDOW_TYPE (window) != GDK_WINDOW_TOPLEVEL)
GType
gdk_window_impl_x11_get_type (void)
{
@ -141,6 +144,7 @@ gdk_window_impl_x11_init (GdkWindowImplX11 *impl)
{
impl->width = 1;
impl->height = 1;
impl->toplevel_window_type = -1;
}
GdkToplevelX11 *
@ -343,7 +347,6 @@ _gdk_windowing_window_init (GdkScreen * screen)
static void
set_wm_protocols (GdkWindow *window)
{
GdkWindowObject *private = (GdkWindowObject *)window;
GdkDisplay *display = gdk_drawable_get_display (window);
Atom protocols[3];
@ -381,6 +384,79 @@ check_leader_window_title (GdkDisplay *display)
}
}
static Window
create_focus_window (Display *xdisplay,
XID parent)
{
Window focus_window = XCreateSimpleWindow (xdisplay, parent,
-1, -1, 1, 1, 0,
0, 0);
/* FIXME: probably better to actually track the requested event mask for the toplevel
*/
XSelectInput (xdisplay, focus_window,
KeyPressMask | KeyReleaseMask | FocusChangeMask);
XMapWindow (xdisplay, focus_window);
return focus_window;
}
static void
setup_toplevel_window (GdkWindow *window, GdkWindow *parent)
{
GdkWindowObject *obj = (GdkWindowObject *)window;
GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
GdkWindowImplX11 *impl = (GdkWindowImplX11 *)obj->impl;
Display *xdisplay = GDK_WINDOW_XDISPLAY (window);
XID xid = GDK_WINDOW_XID (window);
XID xparent = GDK_WINDOW_XID (parent);
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (GDK_WINDOW_SCREEN (parent));
XSizeHints size_hints;
long pid;
if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_DIALOG)
XSetTransientForHint (xdisplay, xid, xparent);
set_wm_protocols (window);
if (!obj->input_only)
{
/* The focus window is off the visible area, and serves to receive key
* press events so they don't get sent to child windows.
*/
toplevel->focus_window = create_focus_window (xdisplay, xid);
_gdk_xid_table_insert (screen_x11->display, &toplevel->focus_window, window);
}
check_leader_window_title (screen_x11->display);
/* 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???
*/
size_hints.flags = PSize;
size_hints.width = impl->width;
size_hints.height = impl->height;
XSetWMNormalHints (xdisplay, xid, &size_hints);
/* This will set WM_CLIENT_MACHINE and WM_LOCALE_NAME */
XSetWMProperties (xdisplay, xid, NULL, NULL, NULL, 0, NULL, NULL, NULL);
pid = getpid ();
XChangeProperty (xdisplay, xid,
gdk_x11_get_xatom_by_name_for_display (screen_x11->display, "_NET_WM_PID"),
XA_CARDINAL, 32,
PropModeReplace,
(guchar *)&pid, 1);
XChangeProperty (xdisplay, xid,
gdk_x11_get_xatom_by_name_for_display (screen_x11->display, "WM_CLIENT_LEADER"),
XA_WINDOW, 32, PropModeReplace,
(guchar *) &GDK_DISPLAY_X11 (screen_x11->display)->leader_window, 1);
}
/**
* gdk_window_new:
* @parent: a #GdkWindow, or %NULL to create the window as a child of
@ -404,7 +480,6 @@ gdk_window_new (GdkWindow *parent,
GdkWindowObject *private;
GdkWindowImplX11 *impl;
GdkDrawableImplX11 *draw_impl;
GdkToplevelX11 *toplevel;
GdkScreenX11 *screen_x11;
GdkScreen *screen;
@ -416,14 +491,12 @@ gdk_window_new (GdkWindow *parent,
XSetWindowAttributes xattributes;
long xattributes_mask;
XSizeHints size_hints;
XClassHint *class_hint;
int x, y, depth;
unsigned int class;
const char *title;
int i;
long pid;
g_return_val_if_fail (attributes != NULL, NULL);
@ -633,11 +706,27 @@ gdk_window_new (GdkWindow *parent,
switch (GDK_WINDOW_TYPE (private))
{
case GDK_WINDOW_DIALOG:
XSetTransientForHint (xdisplay, xid, xparent);
case GDK_WINDOW_TOPLEVEL:
case GDK_WINDOW_TEMP:
set_wm_protocols (window);
if (attributes_mask & GDK_WA_TITLE)
title = attributes->title;
else
title = get_default_title ();
gdk_window_set_title (window, title);
if (attributes_mask & GDK_WA_WMCLASS)
{
class_hint = XAllocClassHint ();
class_hint->res_name = attributes->wmclass_name;
class_hint->res_class = attributes->wmclass_class;
XSetClassHint (xdisplay, xid, class_hint);
XFree (class_hint);
}
setup_toplevel_window (window, parent);
break;
case GDK_WINDOW_CHILD:
if ((attributes->wclass == GDK_INPUT_OUTPUT) &&
(draw_impl->colormap != gdk_screen_get_system_colormap (screen)) &&
@ -646,76 +735,12 @@ gdk_window_new (GdkWindow *parent,
GDK_NOTE (MISC, g_message ("adding colormap window\n"));
gdk_window_add_colormap_windows (window);
}
break;
return window;
default:
return window;
break;
}
toplevel = _gdk_x11_window_get_toplevel (window);
if (class != InputOnly)
{
/* The focus window is off the visible area, and serves to receive key
* press events so they don't get sent to child windows.
*/
toplevel->focus_window = XCreateSimpleWindow (xdisplay, xid,
-1, -1, 1, 1, 0,
xattributes.background_pixel,
xattributes.background_pixel);
/* FIXME: probably better to actually track the requested event mask for the toplevel
*/
XSelectInput (xdisplay, toplevel->focus_window,
KeyPressMask | KeyReleaseMask | FocusChangeMask);
XMapWindow (xdisplay, toplevel->focus_window);
_gdk_xid_table_insert (screen_x11->display, &toplevel->focus_window, window);
}
size_hints.flags = PSize;
size_hints.width = impl->width;
size_hints.height = impl->height;
check_leader_window_title (screen_x11->display);
/* 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);
/* This will set WM_CLIENT_MACHINE and WM_LOCALE_NAME */
XSetWMProperties (xdisplay, xid, NULL, NULL, NULL, 0, NULL, NULL, NULL);
pid = getpid ();
XChangeProperty (xdisplay, xid,
gdk_x11_get_xatom_by_name_for_display (screen_x11->display, "_NET_WM_PID"),
XA_CARDINAL, 32,
PropModeReplace,
(guchar *)&pid, 1);
XChangeProperty (xdisplay, xid,
gdk_x11_get_xatom_by_name_for_display (screen_x11->display, "WM_CLIENT_LEADER"),
XA_WINDOW, 32, PropModeReplace,
(guchar *) &GDK_DISPLAY_X11 (screen_x11->display)->leader_window, 1);
if (attributes_mask & GDK_WA_TITLE)
title = attributes->title;
else
title = get_default_title ();
gdk_window_set_title (window, title);
if (attributes_mask & GDK_WA_WMCLASS)
{
class_hint = XAllocClassHint ();
class_hint->res_name = attributes->wmclass_name;
class_hint->res_class = attributes->wmclass_class;
XSetClassHint (xdisplay, xid, class_hint);
XFree (class_hint);
}
return window;
}
@ -1470,6 +1495,8 @@ gdk_window_reparent (GdkWindow *window,
GdkWindowObject *window_private;
GdkWindowObject *parent_private;
GdkWindowObject *old_parent_private;
GdkWindowImplX11 *impl;
gboolean was_toplevel;
g_return_if_fail (window != NULL);
g_return_if_fail (GDK_IS_WINDOW (window));
@ -1484,6 +1511,7 @@ gdk_window_reparent (GdkWindow *window,
window_private = (GdkWindowObject*) window;
old_parent_private = (GdkWindowObject*)window_private->parent;
parent_private = (GdkWindowObject*) new_parent;
impl = GDK_WINDOW_IMPL_X11 (window_private->impl);
if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (new_parent))
XReparentWindow (GDK_WINDOW_XDISPLAY (window),
@ -1508,27 +1536,35 @@ gdk_window_reparent (GdkWindow *window,
{
case GDK_WINDOW_ROOT:
case GDK_WINDOW_FOREIGN:
/* Now a toplevel */
if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
set_wm_protocols (window);
was_toplevel = WINDOW_IS_TOPLEVEL (window);
if (impl->toplevel_window_type != -1)
GDK_WINDOW_TYPE (window) = impl->toplevel_window_type;
else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL;
if (WINDOW_IS_TOPLEVEL (window) && !was_toplevel)
setup_toplevel_window (window, new_parent);
break;
case GDK_WINDOW_TOPLEVEL:
case GDK_WINDOW_CHILD:
case GDK_WINDOW_DIALOG:
case GDK_WINDOW_TEMP:
if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD &&
GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
if (WINDOW_IS_TOPLEVEL (window))
{
GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (window_private->impl);
/* If we were being sophisticated, we'd save the old window type
* here, and restore it if we were reparented back to the
* toplevel. However, the difference between different types
* of toplevels only really matters on creation anyways.
/* Save the original window type so we can restore it if the
* window is reparented back to be a toplevel
*/
impl->toplevel_window_type = GDK_WINDOW_TYPE (window);
GDK_WINDOW_TYPE (window) = GDK_WINDOW_CHILD;
if (impl->toplevel)
{
if (impl->toplevel->focus_window)
{
XDestroyWindow (GDK_WINDOW_XDISPLAY (window), impl->toplevel->focus_window);
_gdk_xid_table_remove (GDK_WINDOW_DISPLAY (window), impl->toplevel->focus_window);
}
gdk_toplevel_x11_free_contents (impl->toplevel);
g_free (impl->toplevel);
impl->toplevel = NULL;

View File

@ -71,6 +71,7 @@ struct _GdkWindowImplX11
GdkXPositionInfo position_info;
GdkToplevelX11 *toplevel; /* Toplevel-specific information */
gint8 toplevel_window_type;
};
struct _GdkWindowImplX11Class