mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-05 16:20:10 +00:00
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:
parent
b21fe1745c
commit
d2e744ca52
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -71,6 +71,7 @@ struct _GdkWindowImplX11
|
||||
|
||||
GdkXPositionInfo position_info;
|
||||
GdkToplevelX11 *toplevel; /* Toplevel-specific information */
|
||||
gint8 toplevel_window_type;
|
||||
};
|
||||
|
||||
struct _GdkWindowImplX11Class
|
||||
|
Loading…
Reference in New Issue
Block a user