push error trap around configure of withdrawn window, fixes a crash caused

2001-08-03  Havoc Pennington  <hp@pobox.com>

	* src/display.c (event_callback): push error trap around configure
	of withdrawn window, fixes a crash caused by rapidly
	creating/destroying a window.

	* src/window.c (recalc_window_features): don't allow shading
	undecorated windows.

	* src/wm-tester/main.c: add a program to torture window managers.
This commit is contained in:
Havoc Pennington 2001-08-03 04:20:27 +00:00 committed by rhp
parent 1f1e706aae
commit 204cf63805
9 changed files with 233 additions and 9 deletions

View File

@ -0,0 +1,17 @@
2001-08-03 Havoc Pennington <hp@pobox.com>
* src/display.c (event_callback): push error trap around configure
of withdrawn window, fixes a crash caused by rapidly
creating/destroying a window.
* src/window.c (recalc_window_features): don't allow shading
undecorated windows.
* src/wm-tester/main.c: add a program to torture window managers.
2001-08-01 Havoc Pennington <hp@pobox.com>
* src/window.c (recalc_window_features): if a window isn't
resizeable, turn off maximize function. If min size is equal to
max size, turn off resize function.

24
README
View File

@ -177,12 +177,6 @@ METACITY BUGS, NON-FEATURES, AND CAVEATS
- There are probably other ICCCM-compliance issues.
- I know there's at least one race condition involving rapidly
created and destroyed windows that will crash Metacity. I think a
small test app that did a lot of rapid show/hide on a GtkWindow,
in combination with the METACITY_SYNC environment variable and
Metacity in a debugger, would turn this up quickly.
- Window placement is always cascade for now; I want to implement
"first fit, falling back to cascade if no fit."
(Configurable placement algorithms are stupid though, don't
@ -246,6 +240,24 @@ METACITY BUGS, NON-FEATURES, AND CAVEATS
xstuff.c:xstuff_is_compliant_wm() in the panel to get started on
how the panel deals with this.)
- If you have "put panel below other windows" turned on
in panel Global Preferences, Miscellaneous tab, you need to change
this to "Put panel on top of other windows." That's because
Metacity uses semantic categories, not the legacy layer system
in the GNOME spec. It treats things in the legacy "dock" layer
as semantic type dock, but if you have the panel set to be
in another layer, Metacity will think it's a normal window.
You can diagnose this problem because Metacity will put panels in
the wrong place, and Alt+rightclick will let you perform operations
like minimize/maximize, and Alt+leftclick will let you move the panel.
If Metacity has detected that the panel is a panel, then none of
this will be enabled.
I put a patch in the CVS version of the panel to fix this by
setting the new non-legacy type hint, but a panel with that
patch hasn't been released yet.
FAQ
===

View File

@ -2,7 +2,7 @@ AC_INIT(src/display.c)
AM_CONFIG_HEADER(config.h)
AM_INIT_AUTOMAKE(metacity, 2.3.1)
AM_INIT_AUTOMAKE(metacity, 2.3.2)
GETTEXT_PACKAGE=metacity
AC_SUBST(GETTEXT_PACKAGE)
@ -71,6 +71,7 @@ AC_SUBST(HOST_ALIAS)
AC_OUTPUT([
Makefile
src/Makefile
src/wm-tester/Makefile
])

View File

@ -1,4 +1,6 @@
SUBDIRS=wm-tester
INCLUDES=@METACITY_CFLAGS@ -DMETACITY_LIBEXECDIR=\"$(libexecdir)\" -DHOST_ALIAS=\"@HOST_ALIAS@\"
metacity_SOURCES= \

View File

@ -825,8 +825,10 @@ event_callback (XEvent *event,
meta_verbose ("Configuring withdrawn window to %d,%d %dx%d border %d (some values may not be in mask)\n",
xwc.x, xwc.y, xwc.width, xwc.height, xwc.border_width);
meta_error_trap_push (display);
XConfigureWindow (display->xdisplay, event->xconfigurerequest.window,
xwcm, &xwc);
meta_error_trap_pop (display);
}
else
{

View File

@ -18,10 +18,18 @@ if test -z "$SM_CLIENTS"; then
SM_CLIENTS=0
fi
if test -n "$EVIL_TEST"; then
TEST_CLIENT='./wm-tester/wm-tester --evil'
fi
if test -z "$ONLY_WM"; then
Xnest -ac :1 -scrns $SCREENS -geometry 640x480 -bw 15 &
usleep 500000
if test -n "$TEST_CLIENT"; then
DISPLAY=:1 $TEST_CLIENT &
fi
if test $CLIENTS != 0; then
for I in `seq 1 $CLIENTS`; do
DISPLAY=:1 xterm -geometry 25x15 &
@ -40,5 +48,5 @@ if test -z "$ONLY_WM"; then
fi
if test -z "$ONLY_SETUP"; then
METACITY_DISPLAY=:1 exec unst libtool --mode=execute $DEBUG ./metacity $OPTIONS
METACITY_DEBUG_BUTTON_GRABS=1 METACITY_DISPLAY=:1 exec unst libtool --mode=execute $DEBUG ./metacity $OPTIONS
fi

View File

@ -2491,6 +2491,8 @@ update_size_hints (MetaWindow *window)
window->size_hints.flags |= PWinGravity;
}
recalc_window_features (window);
return meta_error_trap_pop (window->display);
}
@ -2552,7 +2554,7 @@ update_title (MetaWindow *window)
&err);
if (err != NULL)
{
meta_warning ("WM_NAME property for %s contained stuff we are too dumb to figure out: %s\n", window->desc, err->message);
meta_warning ("WM_NAME property for %s contained stuff window manager is too dumb to figure out: %s\n", window->desc, err->message);
g_error_free (err);
}
@ -3441,6 +3443,19 @@ recalc_window_features (MetaWindow *window)
window->has_maximize_func = FALSE;
}
/* If min_size == max_size, then don't allow resize */
if (window->size_hints.min_width == window->size_hints.max_width &&
window->size_hints.min_height == window->size_hints.max_height)
window->has_resize_func = FALSE;
/* don't allow maximize if we can't resize */
if (!window->has_resize_func)
window->has_maximize_func = FALSE;
/* no shading if not decorated */
if (!window->decorated)
window->has_shade_func = FALSE;
/* FIXME perhaps should ensure if we don't have a shade func,
* we aren't shaded, etc.
*/

View File

@ -0,0 +1,9 @@
INCLUDES=@METACITY_CFLAGS@
wm_tester_SOURCES= \
main.c
bin_PROGRAMS=wm-tester
wm_tester_LDADD= @METACITY_LIBS@

158
src/wm-tester/main.c Normal file
View File

@ -0,0 +1,158 @@
/* WM tester main() */
/*
* Copyright (C) 2001 Havoc Pennington
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include <gtk/gtk.h>
#include <stdlib.h>
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
static void set_up_the_evil (void);
static void
usage (void)
{
g_print ("wm-tester [--evil]\n");
exit (0);
}
int
main (int argc, char **argv)
{
int i;
gboolean do_evil;
gtk_init (&argc, &argv);
do_evil = FALSE;
i = 1;
while (i < argc)
{
const char *arg = argv[i];
if (strcmp (arg, "--help") == 0 ||
strcmp (arg, "-h") == 0 ||
strcmp (arg, "-?") == 0)
usage ();
else if (strcmp (arg, "--evil") == 0)
do_evil = TRUE;
else
usage ();
++i;
}
/* Be sure some option was provided */
if (! (do_evil))
return 1;
if (do_evil)
set_up_the_evil ();
gtk_main ();
return 0;
}
static GSList *evil_windows = NULL;
static gint
evil_timeout (gpointer data)
{
int i;
int n_windows;
int len;
int create_count;
int destroy_count;
len = g_slist_length (evil_windows);
if (len > 35)
{
create_count = 2;
destroy_count = 5;
}
else
{
create_count = 5;
destroy_count = 5;
}
/* Create some windows */
n_windows = g_random_int_range (0, create_count);
i = 0;
while (i < n_windows)
{
GtkWidget *w;
GtkWidget *c;
w = gtk_window_new (GTK_WINDOW_TOPLEVEL);
c = gtk_button_new_with_label ("Evil Window!");
gtk_container_add (GTK_CONTAINER (w), c);
gtk_widget_set_uposition (w,
g_random_int_range (0,
gdk_screen_width ()),
g_random_int_range (0,
gdk_screen_height ()));
gtk_widget_show_all (w);
evil_windows = g_slist_prepend (evil_windows, w);
++i;
}
/* Destroy some windows */
if (len > destroy_count)
{
n_windows = g_random_int_range (0, destroy_count);
i = 0;
while (i < n_windows)
{
GtkWidget *w;
w = g_slist_nth_data (evil_windows,
g_random_int_range (0, len));
if (w)
{
--len;
evil_windows = g_slist_remove (evil_windows, w);
gtk_widget_destroy (w);
}
++i;
}
}
return TRUE;
}
static void
set_up_the_evil (void)
{
g_timeout_add (40, evil_timeout, NULL);
}