mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-05 16:20:10 +00:00
Don't resize windows when request is rejected by WM. Only use the resize
Sat Mar 14 00:03:34 1998 Owen Taylor <owt1@cornell.edu> * gtk/gtkwindow.c: Don't resize windows when request is rejected by WM. Only use the resize count to guess whether a Configure event was a rejection by the WM, or a move. * gdk/gdk.c gdk/gdktypes.h: - Don't XDestroyWindow foreign windows (If they're a child of one of our windows, reparent them to root and send them a WM delete event, otherwise, just delete the GTK structure.) Handle notification of their deletion properly. (Made foreign windows a seperate window type to do this) * gtk/gtkobject.c (gtk_object_set_data_full): Call the DestroyNotify when replacing the object data.
This commit is contained in:
parent
294cfcdb22
commit
bc98ea9ce1
@ -110,6 +110,7 @@ typedef void* GdkIM;
|
||||
* and pixmaps transparently. (ie. You shouldn't pass a
|
||||
* pixmap to any procedure which accepts a window with the
|
||||
* exception of the drawing functions).
|
||||
* Foreign: A window that actually belongs to another application
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
@ -118,7 +119,8 @@ typedef enum
|
||||
GDK_WINDOW_CHILD,
|
||||
GDK_WINDOW_DIALOG,
|
||||
GDK_WINDOW_TEMP,
|
||||
GDK_WINDOW_PIXMAP
|
||||
GDK_WINDOW_PIXMAP,
|
||||
GDK_WINDOW_FOREIGN
|
||||
} GdkWindowType;
|
||||
|
||||
/* Classes of windows.
|
||||
|
110
gdk/gdkwindow.c
110
gdk/gdkwindow.c
@ -414,13 +414,21 @@ gdk_window_foreign_new (guint32 anid)
|
||||
GdkWindow *window;
|
||||
GdkWindowPrivate *private;
|
||||
XWindowAttributes attrs;
|
||||
Window root, parent;
|
||||
Window *children;
|
||||
guint nchildren;
|
||||
|
||||
private = g_new (GdkWindowPrivate, 1);
|
||||
window = (GdkWindow*) private;
|
||||
|
||||
XGetWindowAttributes (gdk_display, anid, &attrs);
|
||||
|
||||
private->parent = NULL;
|
||||
/* FIXME: This is pretty expensive. Maybe the caller should supply
|
||||
* the parent */
|
||||
XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren);
|
||||
XFree (children);
|
||||
private->parent = gdk_xid_table_lookup (parent);
|
||||
|
||||
private->xwindow = anid;
|
||||
private->xdisplay = gdk_display;
|
||||
private->x = attrs.x;
|
||||
@ -429,15 +437,20 @@ gdk_window_foreign_new (guint32 anid)
|
||||
private->height = attrs.height;
|
||||
private->resize_count = 0;
|
||||
private->ref_count = 1;
|
||||
if (anid == attrs.root)
|
||||
private->window_type = GDK_WINDOW_ROOT;
|
||||
else
|
||||
private->window_type = GDK_WINDOW_TOPLEVEL;
|
||||
/* the above is probably wrong, but it may not be worth the extra
|
||||
X call to get it right */
|
||||
|
||||
private->window_type = GDK_WINDOW_FOREIGN;
|
||||
private->destroyed = FALSE;
|
||||
private->extension_events = 0;
|
||||
|
||||
|
||||
private->dnd_drag_data_type = None;
|
||||
private->dnd_drag_data_typesavail =
|
||||
private->dnd_drop_data_typesavail = NULL;
|
||||
private->dnd_drop_enabled = private->dnd_drag_enabled =
|
||||
private->dnd_drag_accepted = private->dnd_drag_datashow =
|
||||
private->dnd_drop_data_numtypesavail =
|
||||
private->dnd_drag_data_numtypesavail = 0;
|
||||
private->dnd_drag_eventmask = private->dnd_drag_savedeventmask = 0;
|
||||
|
||||
private->filters = NULL;
|
||||
|
||||
window->user_data = NULL;
|
||||
@ -455,7 +468,8 @@ gdk_window_foreign_new (guint32 anid)
|
||||
window. */
|
||||
|
||||
static void
|
||||
gdk_window_internal_destroy (GdkWindow *window, int xdestroy)
|
||||
gdk_window_internal_destroy (GdkWindow *window, gboolean xdestroy,
|
||||
gboolean our_destroy)
|
||||
{
|
||||
GdkWindowPrivate *private;
|
||||
GdkWindowPrivate *temp_private;
|
||||
@ -473,23 +487,28 @@ gdk_window_internal_destroy (GdkWindow *window, int xdestroy)
|
||||
case GDK_WINDOW_CHILD:
|
||||
case GDK_WINDOW_DIALOG:
|
||||
case GDK_WINDOW_TEMP:
|
||||
case GDK_WINDOW_FOREIGN:
|
||||
if (!private->destroyed)
|
||||
{
|
||||
children = gdk_window_get_children (window);
|
||||
tmp = children;
|
||||
|
||||
while (tmp)
|
||||
if (private->window_type != GDK_WINDOW_FOREIGN)
|
||||
{
|
||||
temp_window = tmp->data;
|
||||
tmp = tmp->next;
|
||||
children = gdk_window_get_children (window);
|
||||
tmp = children;
|
||||
|
||||
temp_private = (GdkWindowPrivate*) temp_window;
|
||||
if (temp_private)
|
||||
gdk_window_internal_destroy (temp_window, FALSE);
|
||||
while (tmp)
|
||||
{
|
||||
temp_window = tmp->data;
|
||||
tmp = tmp->next;
|
||||
|
||||
temp_private = (GdkWindowPrivate*) temp_window;
|
||||
if (temp_private)
|
||||
gdk_window_internal_destroy (temp_window, FALSE,
|
||||
our_destroy);
|
||||
}
|
||||
|
||||
g_list_free (children);
|
||||
}
|
||||
|
||||
g_list_free (children);
|
||||
|
||||
if (private->extension_events != 0)
|
||||
gdk_input_window_destroy (window);
|
||||
|
||||
@ -504,8 +523,47 @@ gdk_window_internal_destroy (GdkWindow *window, int xdestroy)
|
||||
private->dnd_drop_data_typesavail = NULL;
|
||||
}
|
||||
|
||||
if (xdestroy)
|
||||
if (private->filters)
|
||||
{
|
||||
tmp = private->filters;
|
||||
|
||||
while (tmp)
|
||||
{
|
||||
g_free (tmp->data);
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
g_list_free (private->filters);
|
||||
private->filters = NULL;
|
||||
}
|
||||
|
||||
if (private->window_type == GDK_WINDOW_FOREIGN)
|
||||
{
|
||||
if (our_destroy && (private->parent != NULL))
|
||||
{
|
||||
/* It's somebody elses window, but in our heirarchy,
|
||||
* so reparent it to the root window, and then send
|
||||
* it a delete event, as if we were a WM
|
||||
*/
|
||||
XClientMessageEvent xevent;
|
||||
|
||||
gdk_window_hide (window);
|
||||
gdk_window_reparent (window, NULL, 0, 0);
|
||||
|
||||
xevent.type = ClientMessage;
|
||||
xevent.window = private->xwindow;
|
||||
xevent.message_type = gdk_wm_protocols;
|
||||
xevent.format = 32;
|
||||
xevent.data.l[0] = gdk_wm_delete_window;
|
||||
xevent.data.l[1] = CurrentTime;
|
||||
|
||||
XSendEvent (private->xdisplay, private->xwindow,
|
||||
False, 0, (XEvent *)&xevent);
|
||||
}
|
||||
}
|
||||
else if (xdestroy)
|
||||
XDestroyWindow (private->xdisplay, private->xwindow);
|
||||
|
||||
private->destroyed = TRUE;
|
||||
}
|
||||
break;
|
||||
@ -526,7 +584,7 @@ gdk_window_internal_destroy (GdkWindow *window, int xdestroy)
|
||||
void
|
||||
gdk_window_destroy (GdkWindow *window)
|
||||
{
|
||||
gdk_window_internal_destroy (window, TRUE);
|
||||
gdk_window_internal_destroy (window, TRUE, TRUE);
|
||||
gdk_window_unref (window);
|
||||
}
|
||||
|
||||
@ -541,6 +599,14 @@ gdk_window_destroy_notify (GdkWindow *window)
|
||||
|
||||
private = (GdkWindowPrivate*) window;
|
||||
|
||||
if (!private->destroyed)
|
||||
{
|
||||
if (private->window_type == GDK_WINDOW_FOREIGN)
|
||||
gdk_window_internal_destroy (window, FALSE, FALSE);
|
||||
else
|
||||
g_warning ("Window %#lx unexpectedly destroyed", private->xwindow);
|
||||
}
|
||||
|
||||
gdk_xid_table_remove (private->xwindow);
|
||||
gdk_window_unref (window);
|
||||
}
|
||||
|
@ -414,13 +414,21 @@ gdk_window_foreign_new (guint32 anid)
|
||||
GdkWindow *window;
|
||||
GdkWindowPrivate *private;
|
||||
XWindowAttributes attrs;
|
||||
Window root, parent;
|
||||
Window *children;
|
||||
guint nchildren;
|
||||
|
||||
private = g_new (GdkWindowPrivate, 1);
|
||||
window = (GdkWindow*) private;
|
||||
|
||||
XGetWindowAttributes (gdk_display, anid, &attrs);
|
||||
|
||||
private->parent = NULL;
|
||||
/* FIXME: This is pretty expensive. Maybe the caller should supply
|
||||
* the parent */
|
||||
XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren);
|
||||
XFree (children);
|
||||
private->parent = gdk_xid_table_lookup (parent);
|
||||
|
||||
private->xwindow = anid;
|
||||
private->xdisplay = gdk_display;
|
||||
private->x = attrs.x;
|
||||
@ -429,15 +437,20 @@ gdk_window_foreign_new (guint32 anid)
|
||||
private->height = attrs.height;
|
||||
private->resize_count = 0;
|
||||
private->ref_count = 1;
|
||||
if (anid == attrs.root)
|
||||
private->window_type = GDK_WINDOW_ROOT;
|
||||
else
|
||||
private->window_type = GDK_WINDOW_TOPLEVEL;
|
||||
/* the above is probably wrong, but it may not be worth the extra
|
||||
X call to get it right */
|
||||
|
||||
private->window_type = GDK_WINDOW_FOREIGN;
|
||||
private->destroyed = FALSE;
|
||||
private->extension_events = 0;
|
||||
|
||||
|
||||
private->dnd_drag_data_type = None;
|
||||
private->dnd_drag_data_typesavail =
|
||||
private->dnd_drop_data_typesavail = NULL;
|
||||
private->dnd_drop_enabled = private->dnd_drag_enabled =
|
||||
private->dnd_drag_accepted = private->dnd_drag_datashow =
|
||||
private->dnd_drop_data_numtypesavail =
|
||||
private->dnd_drag_data_numtypesavail = 0;
|
||||
private->dnd_drag_eventmask = private->dnd_drag_savedeventmask = 0;
|
||||
|
||||
private->filters = NULL;
|
||||
|
||||
window->user_data = NULL;
|
||||
@ -455,7 +468,8 @@ gdk_window_foreign_new (guint32 anid)
|
||||
window. */
|
||||
|
||||
static void
|
||||
gdk_window_internal_destroy (GdkWindow *window, int xdestroy)
|
||||
gdk_window_internal_destroy (GdkWindow *window, gboolean xdestroy,
|
||||
gboolean our_destroy)
|
||||
{
|
||||
GdkWindowPrivate *private;
|
||||
GdkWindowPrivate *temp_private;
|
||||
@ -473,23 +487,28 @@ gdk_window_internal_destroy (GdkWindow *window, int xdestroy)
|
||||
case GDK_WINDOW_CHILD:
|
||||
case GDK_WINDOW_DIALOG:
|
||||
case GDK_WINDOW_TEMP:
|
||||
case GDK_WINDOW_FOREIGN:
|
||||
if (!private->destroyed)
|
||||
{
|
||||
children = gdk_window_get_children (window);
|
||||
tmp = children;
|
||||
|
||||
while (tmp)
|
||||
if (private->window_type != GDK_WINDOW_FOREIGN)
|
||||
{
|
||||
temp_window = tmp->data;
|
||||
tmp = tmp->next;
|
||||
children = gdk_window_get_children (window);
|
||||
tmp = children;
|
||||
|
||||
temp_private = (GdkWindowPrivate*) temp_window;
|
||||
if (temp_private)
|
||||
gdk_window_internal_destroy (temp_window, FALSE);
|
||||
while (tmp)
|
||||
{
|
||||
temp_window = tmp->data;
|
||||
tmp = tmp->next;
|
||||
|
||||
temp_private = (GdkWindowPrivate*) temp_window;
|
||||
if (temp_private)
|
||||
gdk_window_internal_destroy (temp_window, FALSE,
|
||||
our_destroy);
|
||||
}
|
||||
|
||||
g_list_free (children);
|
||||
}
|
||||
|
||||
g_list_free (children);
|
||||
|
||||
if (private->extension_events != 0)
|
||||
gdk_input_window_destroy (window);
|
||||
|
||||
@ -504,8 +523,47 @@ gdk_window_internal_destroy (GdkWindow *window, int xdestroy)
|
||||
private->dnd_drop_data_typesavail = NULL;
|
||||
}
|
||||
|
||||
if (xdestroy)
|
||||
if (private->filters)
|
||||
{
|
||||
tmp = private->filters;
|
||||
|
||||
while (tmp)
|
||||
{
|
||||
g_free (tmp->data);
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
g_list_free (private->filters);
|
||||
private->filters = NULL;
|
||||
}
|
||||
|
||||
if (private->window_type == GDK_WINDOW_FOREIGN)
|
||||
{
|
||||
if (our_destroy && (private->parent != NULL))
|
||||
{
|
||||
/* It's somebody elses window, but in our heirarchy,
|
||||
* so reparent it to the root window, and then send
|
||||
* it a delete event, as if we were a WM
|
||||
*/
|
||||
XClientMessageEvent xevent;
|
||||
|
||||
gdk_window_hide (window);
|
||||
gdk_window_reparent (window, NULL, 0, 0);
|
||||
|
||||
xevent.type = ClientMessage;
|
||||
xevent.window = private->xwindow;
|
||||
xevent.message_type = gdk_wm_protocols;
|
||||
xevent.format = 32;
|
||||
xevent.data.l[0] = gdk_wm_delete_window;
|
||||
xevent.data.l[1] = CurrentTime;
|
||||
|
||||
XSendEvent (private->xdisplay, private->xwindow,
|
||||
False, 0, (XEvent *)&xevent);
|
||||
}
|
||||
}
|
||||
else if (xdestroy)
|
||||
XDestroyWindow (private->xdisplay, private->xwindow);
|
||||
|
||||
private->destroyed = TRUE;
|
||||
}
|
||||
break;
|
||||
@ -526,7 +584,7 @@ gdk_window_internal_destroy (GdkWindow *window, int xdestroy)
|
||||
void
|
||||
gdk_window_destroy (GdkWindow *window)
|
||||
{
|
||||
gdk_window_internal_destroy (window, TRUE);
|
||||
gdk_window_internal_destroy (window, TRUE, TRUE);
|
||||
gdk_window_unref (window);
|
||||
}
|
||||
|
||||
@ -541,6 +599,14 @@ gdk_window_destroy_notify (GdkWindow *window)
|
||||
|
||||
private = (GdkWindowPrivate*) window;
|
||||
|
||||
if (!private->destroyed)
|
||||
{
|
||||
if (private->window_type == GDK_WINDOW_FOREIGN)
|
||||
gdk_window_internal_destroy (window, FALSE, FALSE);
|
||||
else
|
||||
g_warning ("Window %#lx unexpectedly destroyed", private->xwindow);
|
||||
}
|
||||
|
||||
gdk_xid_table_remove (private->xwindow);
|
||||
gdk_window_unref (window);
|
||||
}
|
||||
|
@ -718,7 +718,8 @@ gtk_window_configure_event (GtkWidget *widget,
|
||||
|
||||
/* If the window was merely moved, do nothing */
|
||||
if ((widget->allocation.width == event->width) &&
|
||||
(widget->allocation.height == event->height))
|
||||
(widget->allocation.height == event->height) &&
|
||||
(window->resize_count == 0))
|
||||
return FALSE;
|
||||
|
||||
window = GTK_WINDOW (widget);
|
||||
@ -737,19 +738,7 @@ gtk_window_configure_event (GtkWidget *widget,
|
||||
gtk_widget_map (window->bin.child);
|
||||
|
||||
if (window->resize_count > 0)
|
||||
{
|
||||
window->resize_count -= 1;
|
||||
|
||||
if ((window->resize_count == 0) &&
|
||||
((event->width != widget->requisition.width) ||
|
||||
(event->height != widget->requisition.height)))
|
||||
{
|
||||
window->resize_count = 1;
|
||||
gdk_window_resize (widget->window,
|
||||
widget->requisition.width,
|
||||
widget->requisition.height);
|
||||
}
|
||||
}
|
||||
window->resize_count -= 1;
|
||||
|
||||
window->handling_resize = FALSE;
|
||||
|
||||
@ -1068,13 +1057,10 @@ gtk_real_window_move_resize (GtkWindow *window,
|
||||
(width < widget->requisition.width) ||
|
||||
(height < widget->requisition.height))
|
||||
{
|
||||
if (window->resize_count == 0)
|
||||
{
|
||||
window->resize_count = 1;
|
||||
gdk_window_resize (widget->window,
|
||||
widget->requisition.width,
|
||||
widget->requisition.height);
|
||||
}
|
||||
window->resize_count += 1;
|
||||
gdk_window_resize (widget->window,
|
||||
widget->requisition.width,
|
||||
widget->requisition.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user