aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2011-06-10 11:19:35 -0700
committerPaul Eggert2011-06-10 11:19:35 -0700
commite41e9a0e24877b0bc81e08df396f59115f8636da (patch)
treec0cf7e2838761b2c26047aeeac6415bb542bf5a0
parent6a54b501af0633c909c96de867c805222fde970c (diff)
parent529a133c390049085db38e7c8f745d650a2626ee (diff)
downloademacs-e41e9a0e24877b0bc81e08df396f59115f8636da.tar.gz
emacs-e41e9a0e24877b0bc81e08df396f59115f8636da.zip
Merge from trunk.
-rw-r--r--autogen/Makefile.in282
-rwxr-xr-xautogen/configure54
-rw-r--r--doc/emacs/ChangeLog5
-rw-r--r--doc/emacs/custom.texi2
-rw-r--r--etc/NEWS2
-rw-r--r--lib-src/ChangeLog10
-rw-r--r--lib-src/movemail.c35
-rw-r--r--lisp/ChangeLog71
-rw-r--r--lisp/calendar/appt.el92
-rw-r--r--lisp/cus-start.el15
-rw-r--r--lisp/doc-view.el2
-rw-r--r--lisp/files.el8
-rw-r--r--lisp/gnus/ChangeLog21
-rw-r--r--lisp/gnus/gnus-agent.el4
-rw-r--r--lisp/gnus/gnus-group.el32
-rw-r--r--lisp/gnus/gnus-srvr.el6
-rw-r--r--lisp/gnus/gnus-start.el17
-rw-r--r--lisp/gnus/gnus-sum.el23
-rw-r--r--lisp/mail/sendmail.el4
-rw-r--r--lisp/net/ange-ftp.el43
-rw-r--r--lisp/net/soap-client.el2
-rw-r--r--lisp/term/xterm.el192
-rw-r--r--lisp/window.el1365
-rw-r--r--src/ChangeLog109
-rw-r--r--src/buffer.c4
-rw-r--r--src/dispnew.c27
-rw-r--r--src/frame.c5
-rw-r--r--src/image.c2
-rw-r--r--src/w32fns.c7
-rw-r--r--src/window.c2850
-rw-r--r--src/window.h16
-rw-r--r--src/xdisp.c28
-rw-r--r--src/xfns.c8
33 files changed, 3079 insertions, 2264 deletions
diff --git a/autogen/Makefile.in b/autogen/Makefile.in
index b117c64655c..225fe879f19 100644
--- a/autogen/Makefile.in
+++ b/autogen/Makefile.in
@@ -1207,58 +1207,58 @@ stdio.h: stdio.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H)
1207 -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ 1207 -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
1208 -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ 1208 -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
1209 -e 's|@''NEXT_STDIO_H''@|$(NEXT_STDIO_H)|g' \ 1209 -e 's|@''NEXT_STDIO_H''@|$(NEXT_STDIO_H)|g' \
1210 -e 's|@''GNULIB_DPRINTF''@|$(GNULIB_DPRINTF)|g' \ 1210 -e 's/@''GNULIB_DPRINTF''@/$(GNULIB_DPRINTF)/g' \
1211 -e 's|@''GNULIB_FCLOSE''@|$(GNULIB_FCLOSE)|g' \ 1211 -e 's/@''GNULIB_FCLOSE''@/$(GNULIB_FCLOSE)/g' \
1212 -e 's|@''GNULIB_FFLUSH''@|$(GNULIB_FFLUSH)|g' \ 1212 -e 's/@''GNULIB_FFLUSH''@/$(GNULIB_FFLUSH)/g' \
1213 -e 's|@''GNULIB_FGETC''@|$(GNULIB_FGETC)|g' \ 1213 -e 's/@''GNULIB_FGETC''@/$(GNULIB_FGETC)/g' \
1214 -e 's|@''GNULIB_FGETS''@|$(GNULIB_FGETS)|g' \ 1214 -e 's/@''GNULIB_FGETS''@/$(GNULIB_FGETS)/g' \
1215 -e 's|@''GNULIB_FOPEN''@|$(GNULIB_FOPEN)|g' \ 1215 -e 's/@''GNULIB_FOPEN''@/$(GNULIB_FOPEN)/g' \
1216 -e 's|@''GNULIB_FPRINTF''@|$(GNULIB_FPRINTF)|g' \ 1216 -e 's/@''GNULIB_FPRINTF''@/$(GNULIB_FPRINTF)/g' \
1217 -e 's|@''GNULIB_FPRINTF_POSIX''@|$(GNULIB_FPRINTF_POSIX)|g' \ 1217 -e 's/@''GNULIB_FPRINTF_POSIX''@/$(GNULIB_FPRINTF_POSIX)/g' \
1218 -e 's|@''GNULIB_FPURGE''@|$(GNULIB_FPURGE)|g' \ 1218 -e 's/@''GNULIB_FPURGE''@/$(GNULIB_FPURGE)/g' \
1219 -e 's|@''GNULIB_FPUTC''@|$(GNULIB_FPUTC)|g' \ 1219 -e 's/@''GNULIB_FPUTC''@/$(GNULIB_FPUTC)/g' \
1220 -e 's|@''GNULIB_FPUTS''@|$(GNULIB_FPUTS)|g' \ 1220 -e 's/@''GNULIB_FPUTS''@/$(GNULIB_FPUTS)/g' \
1221 -e 's|@''GNULIB_FREAD''@|$(GNULIB_FREAD)|g' \ 1221 -e 's/@''GNULIB_FREAD''@/$(GNULIB_FREAD)/g' \
1222 -e 's|@''GNULIB_FREOPEN''@|$(GNULIB_FREOPEN)|g' \ 1222 -e 's/@''GNULIB_FREOPEN''@/$(GNULIB_FREOPEN)/g' \
1223 -e 's|@''GNULIB_FSCANF''@|$(GNULIB_FSCANF)|g' \ 1223 -e 's/@''GNULIB_FSCANF''@/$(GNULIB_FSCANF)/g' \
1224 -e 's|@''GNULIB_FSEEK''@|$(GNULIB_FSEEK)|g' \ 1224 -e 's/@''GNULIB_FSEEK''@/$(GNULIB_FSEEK)/g' \
1225 -e 's|@''GNULIB_FSEEKO''@|$(GNULIB_FSEEKO)|g' \ 1225 -e 's/@''GNULIB_FSEEKO''@/$(GNULIB_FSEEKO)/g' \
1226 -e 's|@''GNULIB_FTELL''@|$(GNULIB_FTELL)|g' \ 1226 -e 's/@''GNULIB_FTELL''@/$(GNULIB_FTELL)/g' \
1227 -e 's|@''GNULIB_FTELLO''@|$(GNULIB_FTELLO)|g' \ 1227 -e 's/@''GNULIB_FTELLO''@/$(GNULIB_FTELLO)/g' \
1228 -e 's|@''GNULIB_FWRITE''@|$(GNULIB_FWRITE)|g' \ 1228 -e 's/@''GNULIB_FWRITE''@/$(GNULIB_FWRITE)/g' \
1229 -e 's|@''GNULIB_GETC''@|$(GNULIB_GETC)|g' \ 1229 -e 's/@''GNULIB_GETC''@/$(GNULIB_GETC)/g' \
1230 -e 's|@''GNULIB_GETCHAR''@|$(GNULIB_GETCHAR)|g' \ 1230 -e 's/@''GNULIB_GETCHAR''@/$(GNULIB_GETCHAR)/g' \
1231 -e 's|@''GNULIB_GETDELIM''@|$(GNULIB_GETDELIM)|g' \ 1231 -e 's/@''GNULIB_GETDELIM''@/$(GNULIB_GETDELIM)/g' \
1232 -e 's|@''GNULIB_GETLINE''@|$(GNULIB_GETLINE)|g' \ 1232 -e 's/@''GNULIB_GETLINE''@/$(GNULIB_GETLINE)/g' \
1233 -e 's|@''GNULIB_GETS''@|$(GNULIB_GETS)|g' \ 1233 -e 's/@''GNULIB_GETS''@/$(GNULIB_GETS)/g' \
1234 -e 's|@''GNULIB_OBSTACK_PRINTF''@|$(GNULIB_OBSTACK_PRINTF)|g' \ 1234 -e 's/@''GNULIB_OBSTACK_PRINTF''@/$(GNULIB_OBSTACK_PRINTF)/g' \
1235 -e 's|@''GNULIB_OBSTACK_PRINTF_POSIX''@|$(GNULIB_OBSTACK_PRINTF_POSIX)|g' \ 1235 -e 's/@''GNULIB_OBSTACK_PRINTF_POSIX''@/$(GNULIB_OBSTACK_PRINTF_POSIX)/g' \
1236 -e 's|@''GNULIB_PERROR''@|$(GNULIB_PERROR)|g' \ 1236 -e 's/@''GNULIB_PERROR''@/$(GNULIB_PERROR)/g' \
1237 -e 's|@''GNULIB_POPEN''@|$(GNULIB_POPEN)|g' \ 1237 -e 's/@''GNULIB_POPEN''@/$(GNULIB_POPEN)/g' \
1238 -e 's|@''GNULIB_PRINTF''@|$(GNULIB_PRINTF)|g' \ 1238 -e 's/@''GNULIB_PRINTF''@/$(GNULIB_PRINTF)/g' \
1239 -e 's|@''GNULIB_PRINTF_POSIX''@|$(GNULIB_PRINTF_POSIX)|g' \ 1239 -e 's/@''GNULIB_PRINTF_POSIX''@/$(GNULIB_PRINTF_POSIX)/g' \
1240 -e 's|@''GNULIB_PUTC''@|$(GNULIB_PUTC)|g' \ 1240 -e 's/@''GNULIB_PUTC''@/$(GNULIB_PUTC)/g' \
1241 -e 's|@''GNULIB_PUTCHAR''@|$(GNULIB_PUTCHAR)|g' \ 1241 -e 's/@''GNULIB_PUTCHAR''@/$(GNULIB_PUTCHAR)/g' \
1242 -e 's|@''GNULIB_PUTS''@|$(GNULIB_PUTS)|g' \ 1242 -e 's/@''GNULIB_PUTS''@/$(GNULIB_PUTS)/g' \
1243 -e 's|@''GNULIB_REMOVE''@|$(GNULIB_REMOVE)|g' \ 1243 -e 's/@''GNULIB_REMOVE''@/$(GNULIB_REMOVE)/g' \
1244 -e 's|@''GNULIB_RENAME''@|$(GNULIB_RENAME)|g' \ 1244 -e 's/@''GNULIB_RENAME''@/$(GNULIB_RENAME)/g' \
1245 -e 's|@''GNULIB_RENAMEAT''@|$(GNULIB_RENAMEAT)|g' \ 1245 -e 's/@''GNULIB_RENAMEAT''@/$(GNULIB_RENAMEAT)/g' \
1246 -e 's|@''GNULIB_SCANF''@|$(GNULIB_SCANF)|g' \ 1246 -e 's/@''GNULIB_SCANF''@/$(GNULIB_SCANF)/g' \
1247 -e 's|@''GNULIB_SNPRINTF''@|$(GNULIB_SNPRINTF)|g' \ 1247 -e 's/@''GNULIB_SNPRINTF''@/$(GNULIB_SNPRINTF)/g' \
1248 -e 's|@''GNULIB_SPRINTF_POSIX''@|$(GNULIB_SPRINTF_POSIX)|g' \ 1248 -e 's/@''GNULIB_SPRINTF_POSIX''@/$(GNULIB_SPRINTF_POSIX)/g' \
1249 -e 's|@''GNULIB_STDIO_H_NONBLOCKING''@|$(GNULIB_STDIO_H_NONBLOCKING)|g' \ 1249 -e 's/@''GNULIB_STDIO_H_NONBLOCKING''@/$(GNULIB_STDIO_H_NONBLOCKING)/g' \
1250 -e 's|@''GNULIB_STDIO_H_SIGPIPE''@|$(GNULIB_STDIO_H_SIGPIPE)|g' \ 1250 -e 's/@''GNULIB_STDIO_H_SIGPIPE''@/$(GNULIB_STDIO_H_SIGPIPE)/g' \
1251 -e 's|@''GNULIB_TMPFILE''@|$(GNULIB_TMPFILE)|g' \ 1251 -e 's/@''GNULIB_TMPFILE''@/$(GNULIB_TMPFILE)/g' \
1252 -e 's|@''GNULIB_VASPRINTF''@|$(GNULIB_VASPRINTF)|g' \ 1252 -e 's/@''GNULIB_VASPRINTF''@/$(GNULIB_VASPRINTF)/g' \
1253 -e 's|@''GNULIB_VDPRINTF''@|$(GNULIB_VDPRINTF)|g' \ 1253 -e 's/@''GNULIB_VDPRINTF''@/$(GNULIB_VDPRINTF)/g' \
1254 -e 's|@''GNULIB_VFPRINTF''@|$(GNULIB_VFPRINTF)|g' \ 1254 -e 's/@''GNULIB_VFPRINTF''@/$(GNULIB_VFPRINTF)/g' \
1255 -e 's|@''GNULIB_VFPRINTF_POSIX''@|$(GNULIB_VFPRINTF_POSIX)|g' \ 1255 -e 's/@''GNULIB_VFPRINTF_POSIX''@/$(GNULIB_VFPRINTF_POSIX)/g' \
1256 -e 's|@''GNULIB_VFSCANF''@|$(GNULIB_VFSCANF)|g' \ 1256 -e 's/@''GNULIB_VFSCANF''@/$(GNULIB_VFSCANF)/g' \
1257 -e 's|@''GNULIB_VSCANF''@|$(GNULIB_VSCANF)|g' \ 1257 -e 's/@''GNULIB_VSCANF''@/$(GNULIB_VSCANF)/g' \
1258 -e 's|@''GNULIB_VPRINTF''@|$(GNULIB_VPRINTF)|g' \ 1258 -e 's/@''GNULIB_VPRINTF''@/$(GNULIB_VPRINTF)/g' \
1259 -e 's|@''GNULIB_VPRINTF_POSIX''@|$(GNULIB_VPRINTF_POSIX)|g' \ 1259 -e 's/@''GNULIB_VPRINTF_POSIX''@/$(GNULIB_VPRINTF_POSIX)/g' \
1260 -e 's|@''GNULIB_VSNPRINTF''@|$(GNULIB_VSNPRINTF)|g' \ 1260 -e 's/@''GNULIB_VSNPRINTF''@/$(GNULIB_VSNPRINTF)/g' \
1261 -e 's|@''GNULIB_VSPRINTF_POSIX''@|$(GNULIB_VSPRINTF_POSIX)|g' \ 1261 -e 's/@''GNULIB_VSPRINTF_POSIX''@/$(GNULIB_VSPRINTF_POSIX)/g' \
1262 < $(srcdir)/stdio.in.h | \ 1262 < $(srcdir)/stdio.in.h | \
1263 sed -e 's|@''HAVE_DECL_FPURGE''@|$(HAVE_DECL_FPURGE)|g' \ 1263 sed -e 's|@''HAVE_DECL_FPURGE''@|$(HAVE_DECL_FPURGE)|g' \
1264 -e 's|@''HAVE_DECL_FSEEKO''@|$(HAVE_DECL_FSEEKO)|g' \ 1264 -e 's|@''HAVE_DECL_FSEEKO''@|$(HAVE_DECL_FSEEKO)|g' \
@@ -1322,34 +1322,34 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
1322 -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ 1322 -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
1323 -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ 1323 -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
1324 -e 's|@''NEXT_STDLIB_H''@|$(NEXT_STDLIB_H)|g' \ 1324 -e 's|@''NEXT_STDLIB_H''@|$(NEXT_STDLIB_H)|g' \
1325 -e 's|@''GNULIB__EXIT''@|$(GNULIB__EXIT)|g' \ 1325 -e 's/@''GNULIB__EXIT''@/$(GNULIB__EXIT)/g' \
1326 -e 's|@''GNULIB_ATOLL''@|$(GNULIB_ATOLL)|g' \ 1326 -e 's/@''GNULIB_ATOLL''@/$(GNULIB_ATOLL)/g' \
1327 -e 's|@''GNULIB_CALLOC_POSIX''@|$(GNULIB_CALLOC_POSIX)|g' \ 1327 -e 's/@''GNULIB_CALLOC_POSIX''@/$(GNULIB_CALLOC_POSIX)/g' \
1328 -e 's|@''GNULIB_CANONICALIZE_FILE_NAME''@|$(GNULIB_CANONICALIZE_FILE_NAME)|g' \ 1328 -e 's/@''GNULIB_CANONICALIZE_FILE_NAME''@/$(GNULIB_CANONICALIZE_FILE_NAME)/g' \
1329 -e 's|@''GNULIB_GETLOADAVG''@|$(GNULIB_GETLOADAVG)|g' \ 1329 -e 's/@''GNULIB_GETLOADAVG''@/$(GNULIB_GETLOADAVG)/g' \
1330 -e 's|@''GNULIB_GETSUBOPT''@|$(GNULIB_GETSUBOPT)|g' \ 1330 -e 's/@''GNULIB_GETSUBOPT''@/$(GNULIB_GETSUBOPT)/g' \
1331 -e 's|@''GNULIB_GRANTPT''@|$(GNULIB_GRANTPT)|g' \ 1331 -e 's/@''GNULIB_GRANTPT''@/$(GNULIB_GRANTPT)/g' \
1332 -e 's|@''GNULIB_MALLOC_POSIX''@|$(GNULIB_MALLOC_POSIX)|g' \ 1332 -e 's/@''GNULIB_MALLOC_POSIX''@/$(GNULIB_MALLOC_POSIX)/g' \
1333 -e 's|@''GNULIB_MBTOWC''@|$(GNULIB_MBTOWC)|g' \ 1333 -e 's/@''GNULIB_MBTOWC''@/$(GNULIB_MBTOWC)/g' \
1334 -e 's|@''GNULIB_MKDTEMP''@|$(GNULIB_MKDTEMP)|g' \ 1334 -e 's/@''GNULIB_MKDTEMP''@/$(GNULIB_MKDTEMP)/g' \
1335 -e 's|@''GNULIB_MKOSTEMP''@|$(GNULIB_MKOSTEMP)|g' \ 1335 -e 's/@''GNULIB_MKOSTEMP''@/$(GNULIB_MKOSTEMP)/g' \
1336 -e 's|@''GNULIB_MKOSTEMPS''@|$(GNULIB_MKOSTEMPS)|g' \ 1336 -e 's/@''GNULIB_MKOSTEMPS''@/$(GNULIB_MKOSTEMPS)/g' \
1337 -e 's|@''GNULIB_MKSTEMP''@|$(GNULIB_MKSTEMP)|g' \ 1337 -e 's/@''GNULIB_MKSTEMP''@/$(GNULIB_MKSTEMP)/g' \
1338 -e 's|@''GNULIB_MKSTEMPS''@|$(GNULIB_MKSTEMPS)|g' \ 1338 -e 's/@''GNULIB_MKSTEMPS''@/$(GNULIB_MKSTEMPS)/g' \
1339 -e 's|@''GNULIB_PTSNAME''@|$(GNULIB_PTSNAME)|g' \ 1339 -e 's/@''GNULIB_PTSNAME''@/$(GNULIB_PTSNAME)/g' \
1340 -e 's|@''GNULIB_PUTENV''@|$(GNULIB_PUTENV)|g' \ 1340 -e 's/@''GNULIB_PUTENV''@/$(GNULIB_PUTENV)/g' \
1341 -e 's|@''GNULIB_RANDOM_R''@|$(GNULIB_RANDOM_R)|g' \ 1341 -e 's/@''GNULIB_RANDOM_R''@/$(GNULIB_RANDOM_R)/g' \
1342 -e 's|@''GNULIB_REALLOC_POSIX''@|$(GNULIB_REALLOC_POSIX)|g' \ 1342 -e 's/@''GNULIB_REALLOC_POSIX''@/$(GNULIB_REALLOC_POSIX)/g' \
1343 -e 's|@''GNULIB_REALPATH''@|$(GNULIB_REALPATH)|g' \ 1343 -e 's/@''GNULIB_REALPATH''@/$(GNULIB_REALPATH)/g' \
1344 -e 's|@''GNULIB_RPMATCH''@|$(GNULIB_RPMATCH)|g' \ 1344 -e 's/@''GNULIB_RPMATCH''@/$(GNULIB_RPMATCH)/g' \
1345 -e 's|@''GNULIB_SETENV''@|$(GNULIB_SETENV)|g' \ 1345 -e 's/@''GNULIB_SETENV''@/$(GNULIB_SETENV)/g' \
1346 -e 's|@''GNULIB_STRTOD''@|$(GNULIB_STRTOD)|g' \ 1346 -e 's/@''GNULIB_STRTOD''@/$(GNULIB_STRTOD)/g' \
1347 -e 's|@''GNULIB_STRTOLL''@|$(GNULIB_STRTOLL)|g' \ 1347 -e 's/@''GNULIB_STRTOLL''@/$(GNULIB_STRTOLL)/g' \
1348 -e 's|@''GNULIB_STRTOULL''@|$(GNULIB_STRTOULL)|g' \ 1348 -e 's/@''GNULIB_STRTOULL''@/$(GNULIB_STRTOULL)/g' \
1349 -e 's|@''GNULIB_SYSTEM_POSIX''@|$(GNULIB_SYSTEM_POSIX)|g' \ 1349 -e 's/@''GNULIB_SYSTEM_POSIX''@/$(GNULIB_SYSTEM_POSIX)/g' \
1350 -e 's|@''GNULIB_UNLOCKPT''@|$(GNULIB_UNLOCKPT)|g' \ 1350 -e 's/@''GNULIB_UNLOCKPT''@/$(GNULIB_UNLOCKPT)/g' \
1351 -e 's|@''GNULIB_UNSETENV''@|$(GNULIB_UNSETENV)|g' \ 1351 -e 's/@''GNULIB_UNSETENV''@/$(GNULIB_UNSETENV)/g' \
1352 -e 's|@''GNULIB_WCTOMB''@|$(GNULIB_WCTOMB)|g' \ 1352 -e 's/@''GNULIB_WCTOMB''@/$(GNULIB_WCTOMB)/g' \
1353 < $(srcdir)/stdlib.in.h | \ 1353 < $(srcdir)/stdlib.in.h | \
1354 sed -e 's|@''HAVE__EXIT''@|$(HAVE__EXIT)|g' \ 1354 sed -e 's|@''HAVE__EXIT''@|$(HAVE__EXIT)|g' \
1355 -e 's|@''HAVE_ATOLL''@|$(HAVE_ATOLL)|g' \ 1355 -e 's|@''HAVE_ATOLL''@|$(HAVE_ATOLL)|g' \
@@ -1404,18 +1404,18 @@ sys/stat.h: sys_stat.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNU
1404 -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ 1404 -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
1405 -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ 1405 -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
1406 -e 's|@''NEXT_SYS_STAT_H''@|$(NEXT_SYS_STAT_H)|g' \ 1406 -e 's|@''NEXT_SYS_STAT_H''@|$(NEXT_SYS_STAT_H)|g' \
1407 -e 's|@''GNULIB_FCHMODAT''@|$(GNULIB_FCHMODAT)|g' \ 1407 -e 's/@''GNULIB_FCHMODAT''@/$(GNULIB_FCHMODAT)/g' \
1408 -e 's|@''GNULIB_FSTATAT''@|$(GNULIB_FSTATAT)|g' \ 1408 -e 's/@''GNULIB_FSTATAT''@/$(GNULIB_FSTATAT)/g' \
1409 -e 's|@''GNULIB_FUTIMENS''@|$(GNULIB_FUTIMENS)|g' \ 1409 -e 's/@''GNULIB_FUTIMENS''@/$(GNULIB_FUTIMENS)/g' \
1410 -e 's|@''GNULIB_LCHMOD''@|$(GNULIB_LCHMOD)|g' \ 1410 -e 's/@''GNULIB_LCHMOD''@/$(GNULIB_LCHMOD)/g' \
1411 -e 's|@''GNULIB_LSTAT''@|$(GNULIB_LSTAT)|g' \ 1411 -e 's/@''GNULIB_LSTAT''@/$(GNULIB_LSTAT)/g' \
1412 -e 's|@''GNULIB_MKDIRAT''@|$(GNULIB_MKDIRAT)|g' \ 1412 -e 's/@''GNULIB_MKDIRAT''@/$(GNULIB_MKDIRAT)/g' \
1413 -e 's|@''GNULIB_MKFIFO''@|$(GNULIB_MKFIFO)|g' \ 1413 -e 's/@''GNULIB_MKFIFO''@/$(GNULIB_MKFIFO)/g' \
1414 -e 's|@''GNULIB_MKFIFOAT''@|$(GNULIB_MKFIFOAT)|g' \ 1414 -e 's/@''GNULIB_MKFIFOAT''@/$(GNULIB_MKFIFOAT)/g' \
1415 -e 's|@''GNULIB_MKNOD''@|$(GNULIB_MKNOD)|g' \ 1415 -e 's/@''GNULIB_MKNOD''@/$(GNULIB_MKNOD)/g' \
1416 -e 's|@''GNULIB_MKNODAT''@|$(GNULIB_MKNODAT)|g' \ 1416 -e 's/@''GNULIB_MKNODAT''@/$(GNULIB_MKNODAT)/g' \
1417 -e 's|@''GNULIB_STAT''@|$(GNULIB_STAT)|g' \ 1417 -e 's/@''GNULIB_STAT''@/$(GNULIB_STAT)/g' \
1418 -e 's|@''GNULIB_UTIMENSAT''@|$(GNULIB_UTIMENSAT)|g' \ 1418 -e 's/@''GNULIB_UTIMENSAT''@/$(GNULIB_UTIMENSAT)/g' \
1419 -e 's|@''HAVE_FCHMODAT''@|$(HAVE_FCHMODAT)|g' \ 1419 -e 's|@''HAVE_FCHMODAT''@|$(HAVE_FCHMODAT)|g' \
1420 -e 's|@''HAVE_FSTATAT''@|$(HAVE_FSTATAT)|g' \ 1420 -e 's|@''HAVE_FSTATAT''@|$(HAVE_FSTATAT)|g' \
1421 -e 's|@''HAVE_FUTIMENS''@|$(HAVE_FUTIMENS)|g' \ 1421 -e 's|@''HAVE_FUTIMENS''@|$(HAVE_FUTIMENS)|g' \
@@ -1453,11 +1453,11 @@ time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(
1453 -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ 1453 -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
1454 -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ 1454 -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
1455 -e 's|@''NEXT_TIME_H''@|$(NEXT_TIME_H)|g' \ 1455 -e 's|@''NEXT_TIME_H''@|$(NEXT_TIME_H)|g' \
1456 -e 's|@''GNULIB_MKTIME''@|$(GNULIB_MKTIME)|g' \ 1456 -e 's/@''GNULIB_MKTIME''@/$(GNULIB_MKTIME)/g' \
1457 -e 's|@''GNULIB_NANOSLEEP''@|$(GNULIB_NANOSLEEP)|g' \ 1457 -e 's/@''GNULIB_NANOSLEEP''@/$(GNULIB_NANOSLEEP)/g' \
1458 -e 's|@''GNULIB_STRPTIME''@|$(GNULIB_STRPTIME)|g' \ 1458 -e 's/@''GNULIB_STRPTIME''@/$(GNULIB_STRPTIME)/g' \
1459 -e 's|@''GNULIB_TIMEGM''@|$(GNULIB_TIMEGM)|g' \ 1459 -e 's/@''GNULIB_TIMEGM''@/$(GNULIB_TIMEGM)/g' \
1460 -e 's|@''GNULIB_TIME_R''@|$(GNULIB_TIME_R)|g' \ 1460 -e 's/@''GNULIB_TIME_R''@/$(GNULIB_TIME_R)/g' \
1461 -e 's|@''HAVE_DECL_LOCALTIME_R''@|$(HAVE_DECL_LOCALTIME_R)|g' \ 1461 -e 's|@''HAVE_DECL_LOCALTIME_R''@|$(HAVE_DECL_LOCALTIME_R)|g' \
1462 -e 's|@''HAVE_NANOSLEEP''@|$(HAVE_NANOSLEEP)|g' \ 1462 -e 's|@''HAVE_NANOSLEEP''@|$(HAVE_NANOSLEEP)|g' \
1463 -e 's|@''HAVE_STRPTIME''@|$(HAVE_STRPTIME)|g' \ 1463 -e 's|@''HAVE_STRPTIME''@|$(HAVE_STRPTIME)|g' \
@@ -1487,50 +1487,50 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
1487 -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ 1487 -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
1488 -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ 1488 -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
1489 -e 's|@''NEXT_UNISTD_H''@|$(NEXT_UNISTD_H)|g' \ 1489 -e 's|@''NEXT_UNISTD_H''@|$(NEXT_UNISTD_H)|g' \
1490 -e 's|@''GNULIB_CHOWN''@|$(GNULIB_CHOWN)|g' \ 1490 -e 's/@''GNULIB_CHOWN''@/$(GNULIB_CHOWN)/g' \
1491 -e 's|@''GNULIB_CLOSE''@|$(GNULIB_CLOSE)|g' \ 1491 -e 's/@''GNULIB_CLOSE''@/$(GNULIB_CLOSE)/g' \
1492 -e 's|@''GNULIB_DUP2''@|$(GNULIB_DUP2)|g' \ 1492 -e 's/@''GNULIB_DUP2''@/$(GNULIB_DUP2)/g' \
1493 -e 's|@''GNULIB_DUP3''@|$(GNULIB_DUP3)|g' \ 1493 -e 's/@''GNULIB_DUP3''@/$(GNULIB_DUP3)/g' \
1494 -e 's|@''GNULIB_ENVIRON''@|$(GNULIB_ENVIRON)|g' \ 1494 -e 's/@''GNULIB_ENVIRON''@/$(GNULIB_ENVIRON)/g' \
1495 -e 's|@''GNULIB_EUIDACCESS''@|$(GNULIB_EUIDACCESS)|g' \ 1495 -e 's/@''GNULIB_EUIDACCESS''@/$(GNULIB_EUIDACCESS)/g' \
1496 -e 's|@''GNULIB_FACCESSAT''@|$(GNULIB_FACCESSAT)|g' \ 1496 -e 's/@''GNULIB_FACCESSAT''@/$(GNULIB_FACCESSAT)/g' \
1497 -e 's|@''GNULIB_FCHDIR''@|$(GNULIB_FCHDIR)|g' \ 1497 -e 's/@''GNULIB_FCHDIR''@/$(GNULIB_FCHDIR)/g' \
1498 -e 's|@''GNULIB_FCHOWNAT''@|$(GNULIB_FCHOWNAT)|g' \ 1498 -e 's/@''GNULIB_FCHOWNAT''@/$(GNULIB_FCHOWNAT)/g' \
1499 -e 's|@''GNULIB_FSYNC''@|$(GNULIB_FSYNC)|g' \ 1499 -e 's/@''GNULIB_FSYNC''@/$(GNULIB_FSYNC)/g' \
1500 -e 's|@''GNULIB_FTRUNCATE''@|$(GNULIB_FTRUNCATE)|g' \ 1500 -e 's/@''GNULIB_FTRUNCATE''@/$(GNULIB_FTRUNCATE)/g' \
1501 -e 's|@''GNULIB_GETCWD''@|$(GNULIB_GETCWD)|g' \ 1501 -e 's/@''GNULIB_GETCWD''@/$(GNULIB_GETCWD)/g' \
1502 -e 's|@''GNULIB_GETDOMAINNAME''@|$(GNULIB_GETDOMAINNAME)|g' \ 1502 -e 's/@''GNULIB_GETDOMAINNAME''@/$(GNULIB_GETDOMAINNAME)/g' \
1503 -e 's|@''GNULIB_GETDTABLESIZE''@|$(GNULIB_GETDTABLESIZE)|g' \ 1503 -e 's/@''GNULIB_GETDTABLESIZE''@/$(GNULIB_GETDTABLESIZE)/g' \
1504 -e 's|@''GNULIB_GETGROUPS''@|$(GNULIB_GETGROUPS)|g' \ 1504 -e 's/@''GNULIB_GETGROUPS''@/$(GNULIB_GETGROUPS)/g' \
1505 -e 's|@''GNULIB_GETHOSTNAME''@|$(GNULIB_GETHOSTNAME)|g' \ 1505 -e 's/@''GNULIB_GETHOSTNAME''@/$(GNULIB_GETHOSTNAME)/g' \
1506 -e 's|@''GNULIB_GETLOGIN''@|$(GNULIB_GETLOGIN)|g' \ 1506 -e 's/@''GNULIB_GETLOGIN''@/$(GNULIB_GETLOGIN)/g' \
1507 -e 's|@''GNULIB_GETLOGIN_R''@|$(GNULIB_GETLOGIN_R)|g' \ 1507 -e 's/@''GNULIB_GETLOGIN_R''@/$(GNULIB_GETLOGIN_R)/g' \
1508 -e 's|@''GNULIB_GETPAGESIZE''@|$(GNULIB_GETPAGESIZE)|g' \ 1508 -e 's/@''GNULIB_GETPAGESIZE''@/$(GNULIB_GETPAGESIZE)/g' \
1509 -e 's|@''GNULIB_GETUSERSHELL''@|$(GNULIB_GETUSERSHELL)|g' \ 1509 -e 's/@''GNULIB_GETUSERSHELL''@/$(GNULIB_GETUSERSHELL)/g' \
1510 -e 's|@''GNULIB_GROUP_MEMBER''@|$(GNULIB_GROUP_MEMBER)|g' \ 1510 -e 's/@''GNULIB_GROUP_MEMBER''@/$(GNULIB_GROUP_MEMBER)/g' \
1511 -e 's|@''GNULIB_LCHOWN''@|$(GNULIB_LCHOWN)|g' \ 1511 -e 's/@''GNULIB_LCHOWN''@/$(GNULIB_LCHOWN)/g' \
1512 -e 's|@''GNULIB_LINK''@|$(GNULIB_LINK)|g' \ 1512 -e 's/@''GNULIB_LINK''@/$(GNULIB_LINK)/g' \
1513 -e 's|@''GNULIB_LINKAT''@|$(GNULIB_LINKAT)|g' \ 1513 -e 's/@''GNULIB_LINKAT''@/$(GNULIB_LINKAT)/g' \
1514 -e 's|@''GNULIB_LSEEK''@|$(GNULIB_LSEEK)|g' \ 1514 -e 's/@''GNULIB_LSEEK''@/$(GNULIB_LSEEK)/g' \
1515 -e 's|@''GNULIB_PIPE''@|$(GNULIB_PIPE)|g' \ 1515 -e 's/@''GNULIB_PIPE''@/$(GNULIB_PIPE)/g' \
1516 -e 's|@''GNULIB_PIPE2''@|$(GNULIB_PIPE2)|g' \ 1516 -e 's/@''GNULIB_PIPE2''@/$(GNULIB_PIPE2)/g' \
1517 -e 's|@''GNULIB_PREAD''@|$(GNULIB_PREAD)|g' \ 1517 -e 's/@''GNULIB_PREAD''@/$(GNULIB_PREAD)/g' \
1518 -e 's|@''GNULIB_PWRITE''@|$(GNULIB_PWRITE)|g' \ 1518 -e 's/@''GNULIB_PWRITE''@/$(GNULIB_PWRITE)/g' \
1519 -e 's|@''GNULIB_READ''@|$(GNULIB_READ)|g' \ 1519 -e 's/@''GNULIB_READ''@/$(GNULIB_READ)/g' \
1520 -e 's|@''GNULIB_READLINK''@|$(GNULIB_READLINK)|g' \ 1520 -e 's/@''GNULIB_READLINK''@/$(GNULIB_READLINK)/g' \
1521 -e 's|@''GNULIB_READLINKAT''@|$(GNULIB_READLINKAT)|g' \ 1521 -e 's/@''GNULIB_READLINKAT''@/$(GNULIB_READLINKAT)/g' \
1522 -e 's|@''GNULIB_RMDIR''@|$(GNULIB_RMDIR)|g' \ 1522 -e 's/@''GNULIB_RMDIR''@/$(GNULIB_RMDIR)/g' \
1523 -e 's|@''GNULIB_SLEEP''@|$(GNULIB_SLEEP)|g' \ 1523 -e 's/@''GNULIB_SLEEP''@/$(GNULIB_SLEEP)/g' \
1524 -e 's|@''GNULIB_SYMLINK''@|$(GNULIB_SYMLINK)|g' \ 1524 -e 's/@''GNULIB_SYMLINK''@/$(GNULIB_SYMLINK)/g' \
1525 -e 's|@''GNULIB_SYMLINKAT''@|$(GNULIB_SYMLINKAT)|g' \ 1525 -e 's/@''GNULIB_SYMLINKAT''@/$(GNULIB_SYMLINKAT)/g' \
1526 -e 's|@''GNULIB_TTYNAME_R''@|$(GNULIB_TTYNAME_R)|g' \ 1526 -e 's/@''GNULIB_TTYNAME_R''@/$(GNULIB_TTYNAME_R)/g' \
1527 -e 's|@''GNULIB_UNISTD_H_GETOPT''@|$(GNULIB_UNISTD_H_GETOPT)|g' \ 1527 -e 's/@''GNULIB_UNISTD_H_GETOPT''@/$(GNULIB_UNISTD_H_GETOPT)/g' \
1528 -e 's|@''GNULIB_UNISTD_H_NONBLOCKING''@|$(GNULIB_UNISTD_H_NONBLOCKING)|g' \ 1528 -e 's/@''GNULIB_UNISTD_H_NONBLOCKING''@/$(GNULIB_UNISTD_H_NONBLOCKING)/g' \
1529 -e 's|@''GNULIB_UNISTD_H_SIGPIPE''@|$(GNULIB_UNISTD_H_SIGPIPE)|g' \ 1529 -e 's/@''GNULIB_UNISTD_H_SIGPIPE''@/$(GNULIB_UNISTD_H_SIGPIPE)/g' \
1530 -e 's|@''GNULIB_UNLINK''@|$(GNULIB_UNLINK)|g' \ 1530 -e 's/@''GNULIB_UNLINK''@/$(GNULIB_UNLINK)/g' \
1531 -e 's|@''GNULIB_UNLINKAT''@|$(GNULIB_UNLINKAT)|g' \ 1531 -e 's/@''GNULIB_UNLINKAT''@/$(GNULIB_UNLINKAT)/g' \
1532 -e 's|@''GNULIB_USLEEP''@|$(GNULIB_USLEEP)|g' \ 1532 -e 's/@''GNULIB_USLEEP''@/$(GNULIB_USLEEP)/g' \
1533 -e 's|@''GNULIB_WRITE''@|$(GNULIB_WRITE)|g' \ 1533 -e 's/@''GNULIB_WRITE''@/$(GNULIB_WRITE)/g' \
1534 < $(srcdir)/unistd.in.h | \ 1534 < $(srcdir)/unistd.in.h | \
1535 sed -e 's|@''HAVE_CHOWN''@|$(HAVE_CHOWN)|g' \ 1535 sed -e 's|@''HAVE_CHOWN''@|$(HAVE_CHOWN)|g' \
1536 -e 's|@''HAVE_DUP2''@|$(HAVE_DUP2)|g' \ 1536 -e 's|@''HAVE_DUP2''@|$(HAVE_DUP2)|g' \
diff --git a/autogen/configure b/autogen/configure
index 63d0d9ee394..c76bb4acf18 100755
--- a/autogen/configure
+++ b/autogen/configure
@@ -17242,7 +17242,11 @@ fi
17242 17242
17243 17243
17244 17244
17245 GNULIB_GETLOADAVG=1 17245
17246
17247 GNULIB_GETLOADAVG=1
17248
17249
17246 17250
17247 17251
17248 17252
@@ -17315,7 +17319,11 @@ fi
17315 17319
17316 17320
17317 17321
17318 GNULIB_LSTAT=1 17322
17323
17324 GNULIB_LSTAT=1
17325
17326
17319 17327
17320 17328
17321 17329
@@ -17569,7 +17577,11 @@ fi
17569 17577
17570 17578
17571 17579
17572 GNULIB_MKTIME=1 17580
17581
17582 GNULIB_MKTIME=1
17583
17584
17573 17585
17574 17586
17575 17587
@@ -17690,7 +17702,11 @@ $as_echo "#define READLINK_TRAILING_SLASH_BUG 1" >>confdefs.h
17690 17702
17691 17703
17692 17704
17693 GNULIB_READLINK=1 17705
17706
17707 GNULIB_READLINK=1
17708
17709
17694 17710
17695 17711
17696 17712
@@ -18304,7 +18320,11 @@ _ACEOF
18304 18320
18305 18321
18306 18322
18307 GNULIB_STRTOUMAX=1 18323
18324
18325 GNULIB_STRTOUMAX=1
18326
18327
18308 18328
18309 18329
18310 18330
@@ -18382,7 +18402,11 @@ $as_echo "$gl_cv_func_symlink_works" >&6; }
18382 18402
18383 18403
18384 18404
18385 GNULIB_SYMLINK=1 18405
18406
18407 GNULIB_SYMLINK=1
18408
18409
18386 18410
18387 18411
18388 18412
@@ -18547,7 +18571,11 @@ $as_echo "$gl_cv_time_r_posix" >&6; }
18547 18571
18548 18572
18549 18573
18550 GNULIB_TIME_R=1 18574
18575
18576 GNULIB_TIME_R=1
18577
18578
18551 18579
18552 18580
18553 18581
@@ -18760,7 +18788,11 @@ $as_echo "#define REPLACE_FUNC_STAT_FILE 1" >>confdefs.h
18760 18788
18761 18789
18762 18790
18763 GNULIB_STAT=1 18791
18792
18793 GNULIB_STAT=1
18794
18795
18764 18796
18765 18797
18766 18798
@@ -18812,7 +18844,11 @@ done
18812 18844
18813 18845
18814 18846
18815 GNULIB_STRTOULL=1 18847
18848
18849 GNULIB_STRTOULL=1
18850
18851
18816 18852
18817 18853
18818 18854
diff --git a/doc/emacs/ChangeLog b/doc/emacs/ChangeLog
index 6e69a96a2a8..8853eb099d6 100644
--- a/doc/emacs/ChangeLog
+++ b/doc/emacs/ChangeLog
@@ -1,3 +1,8 @@
12011-06-09 Glenn Morris <rgm@gnu.org>
2
3 * custom.texi (Specifying File Variables):
4 Recommend explicit arguments for minor modes.
5
12011-06-02 Paul Eggert <eggert@cs.ucla.edu> 62011-06-02 Paul Eggert <eggert@cs.ucla.edu>
2 7
3 Document wide integers better. 8 Document wide integers better.
diff --git a/doc/emacs/custom.texi b/doc/emacs/custom.texi
index a0dce5b3216..434c574ac42 100644
--- a/doc/emacs/custom.texi
+++ b/doc/emacs/custom.texi
@@ -1215,7 +1215,7 @@ other context has no special meaning.
1215well as the major modes; in fact, you can use it more than once, first 1215well as the major modes; in fact, you can use it more than once, first
1216to set the major mode and then to enable minor modes which are 1216to set the major mode and then to enable minor modes which are
1217specific to particular buffers. Using @code{mode} for minor modes 1217specific to particular buffers. Using @code{mode} for minor modes
1218is deprecated, though---instead, use @code{eval: (minor-mode)}. 1218is deprecated, though---instead, use @code{eval: (minor-mode 1)}.
1219 1219
1220 Often, however, it is a mistake to enable minor modes in file local 1220 Often, however, it is a mistake to enable minor modes in file local
1221variables. Most minor modes, like Auto Fill mode, represent individual user 1221variables. Most minor modes, like Auto Fill mode, represent individual user
diff --git a/etc/NEWS b/etc/NEWS
index eaa6ee1b704..51b179d8ddc 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -294,7 +294,7 @@ the remote file-name cache is used for read access.
294 294
295+++ 295+++
296** The use of a "mode: minor" specification in a file local variables section 296** The use of a "mode: minor" specification in a file local variables section
297to enable a minor-mode is deprecated. Instead, use "eval: (minor-mode)". 297to enable a minor-mode is deprecated. Instead, use "eval: (minor-mode 1)".
298 298
299** The standalone programs lib-src/digest-doc and sorted-doc have been 299** The standalone programs lib-src/digest-doc and sorted-doc have been
300replaced with Lisp commands `doc-file-to-man' and `doc-file-to-info'. 300replaced with Lisp commands `doc-file-to-man' and `doc-file-to-info'.
diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog
index ff0d3da0a80..ec123e85036 100644
--- a/lib-src/ChangeLog
+++ b/lib-src/ChangeLog
@@ -1,3 +1,13 @@
12011-06-10 Paul Eggert <eggert@cs.ucla.edu>
2
3 * movemail.c: Fix race condition and related bugs (Bug#8836).
4 (main) [!MAIL_USE_SYSTEM_LOCK]: Prefer mkstemp to mktemp, as this
5 fixes some race conditions. Report mkstemp/mktemp errno rather
6 than a possibly-garbage errno. Reinitialize the template each
7 time through the loop, as earlier mkstemp/mktemp calls could have
8 trashed it. Pass 0600 (not 0666) to mktemp, for consistency
9 with mkstemp; the permissions don't matter anyway.
10
12011-06-01 Dan Nicolaescu <dann@ics.uci.edu> 112011-06-01 Dan Nicolaescu <dann@ics.uci.edu>
2 12
3 * emacsclient.c (socket_status): Use constant pointer. 13 * emacsclient.c (socket_status): Use constant pointer.
diff --git a/lib-src/movemail.c b/lib-src/movemail.c
index 4cf97cbac18..e8c09f090f3 100644
--- a/lib-src/movemail.c
+++ b/lib-src/movemail.c
@@ -168,8 +168,9 @@ main (int argc, char **argv)
168#ifndef MAIL_USE_SYSTEM_LOCK 168#ifndef MAIL_USE_SYSTEM_LOCK
169 struct stat st; 169 struct stat st;
170 int tem; 170 int tem;
171 char *lockname, *p; 171 char *lockname;
172 char *tempname; 172 char *tempname;
173 size_t inname_dirlen;
173 int desc; 174 int desc;
174#endif /* not MAIL_USE_SYSTEM_LOCK */ 175#endif /* not MAIL_USE_SYSTEM_LOCK */
175 176
@@ -298,26 +299,38 @@ main (int argc, char **argv)
298 to bug-gnu-emacs@prep.ai.mit.edu so we can fix it. */ 299 to bug-gnu-emacs@prep.ai.mit.edu so we can fix it. */
299 300
300 lockname = concat (inname, ".lock", ""); 301 lockname = concat (inname, ".lock", "");
301 tempname = (char *) xmalloc (strlen (inname) + strlen ("EXXXXXX") + 1); 302 for (inname_dirlen = strlen (inname);
302 strcpy (tempname, inname); 303 inname_dirlen && !IS_DIRECTORY_SEP (inname[inname_dirlen - 1]);
303 p = tempname + strlen (tempname); 304 inname_dirlen--)
304 while (p != tempname && !IS_DIRECTORY_SEP (p[-1])) 305 continue;
305 p--; 306 tempname = (char *) xmalloc (inname_dirlen + sizeof "EXXXXXX");
306 *p = 0;
307 strcpy (p, "EXXXXXX");
308 mktemp (tempname);
309 unlink (tempname);
310 307
311 while (1) 308 while (1)
312 { 309 {
313 /* Create the lock file, but not under the lock file name. */ 310 /* Create the lock file, but not under the lock file name. */
314 /* Give up if cannot do that. */ 311 /* Give up if cannot do that. */
315 desc = open (tempname, O_WRONLY | O_CREAT | O_EXCL, 0666); 312
313 memcpy (tempname, inname, inname_dirlen);
314 strcpy (tempname + inname_dirlen, "EXXXXXX");
315#ifdef HAVE_MKSTEMP
316 desc = mkstemp (tempname);
317#else
318 mktemp (tempname);
319 if (!*tempname)
320 desc = -1;
321 else
322 {
323 unlink (tempname);
324 desc = open (tempname, O_WRONLY | O_CREAT | O_EXCL, 0600);
325 }
326#endif
316 if (desc < 0) 327 if (desc < 0)
317 { 328 {
329 int mkstemp_errno = errno;
318 char *message = (char *) xmalloc (strlen (tempname) + 50); 330 char *message = (char *) xmalloc (strlen (tempname) + 50);
319 sprintf (message, "creating %s, which would become the lock file", 331 sprintf (message, "creating %s, which would become the lock file",
320 tempname); 332 tempname);
333 errno = mkstemp_errno;
321 pfatal_with_name (message); 334 pfatal_with_name (message);
322 } 335 }
323 close (desc); 336 close (desc);
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 2341c0c973a..1ac216dfbe2 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,74 @@
12011-06-10 Martin Rudalics <rudalics@gmx.at>
2
3 * window.el (window-min-height, window-min-width): Move here
4 from window.c. Add defcustoms and rewrite doc-strings.
5 (resize-mini-window, resize-window): New functions.
6 (adjust-window-trailing-edge, enlarge-window, shrink-window):
7 Move here from window.c.
8 (maximize-window, minimize-window): New functions.
9 (delete-window, delete-other-windows, split-window): Move here
10 from window.c.
11 (window-split-min-size): New function.
12 (split-window-keep-point): Mention split-window-above-each-other
13 instead of split-window-vertically.
14 (split-window-above-each-other, split-window-vertically): Rename
15 split-window-vertically to split-window-above-each-other and
16 provide defalias for old definition.
17 (split-window-side-by-side, split-window-horizontally): Rename
18 split-window-horizontally to split-window-side-by-side and provide
19 defalias for the old definition.
20 (ctl-x-map): Move bindings for delete-window,
21 delete-other-windows and enlarge-window here from window.c.
22 Replace bindings for split-window-vertically and
23 split-window-horizontally by bindings for
24 split-window-above-each-other and split-window-side-by-side.
25
26 * cus-start.el (all): Remove entries for window-min-height and
27 window-min-width. Add entries for window-splits and
28 window-nest.
29
302011-06-09 Glenn Morris <rgm@gnu.org>
31
32 * calendar/appt.el (appt-mode-line): New function.
33 (appt-check, appt-disp-window): Use it.
34
35 * files.el (hack-one-local-variable-eval-safep):
36 Allow minor-modes with explicit +/-1 arguments.
37
382011-06-09 Teodor Zlatanov <tzz@lifelogs.com>
39
40 * term/xterm.el (xterm): Add defgroup.
41 (xterm-extra-capabilities): Add defcustom to supply known xterm
42 capabilities, skip querying them, or query them (default).
43 (terminal-init-xterm): Use it.
44 (terminal-init-xterm-modify-other-keys): New function to set up
45 modifyOtherKeys support to simplify `terminal-init-xterm'.
46
472011-06-09 Martin Rudalics <rudalics@gmx.at>
48
49 * window.el (resize-window-reset, resize-window-reset-1)
50 (resize-subwindows-skip-p, resize-subwindows-normal)
51 (resize-subwindows, resize-other-windows, resize-this-window)
52 (resize-root-window, resize-root-window-vertically)
53 (window-deletable-p, window-or-subwindow-p)
54 (frame-root-window-p): New functions.
55
562011-06-09 Glenn Morris <rgm@gnu.org>
57
58 * net/ange-ftp.el (ange-ftp-switches-ok): New function.
59 (ange-ftp-get-files): Use it.
60
612011-06-09 Alexander Klimov <alserkli@inbox.ru> (tiny change)
62
63 * mail/sendmail.el (mail-recover-1, mail-recover):
64 * files.el (recover-file, recover-session):
65 Handle dired-listing-switches not being just a single short option.
66
672011-06-09 Glenn Morris <rgm@gnu.org>
68
69 * calendar/appt.el (appt-display-message, appt-disp-window):
70 Handle lists of appointments.
71
12011-06-08 Martin Rudalics <rudalics@gmx.at> 722011-06-08 Martin Rudalics <rudalics@gmx.at>
2 73
3 * window.el (one-window-p): Move down in code. Rewrite 74 * window.el (one-window-p): Move down in code. Rewrite
diff --git a/lisp/calendar/appt.el b/lisp/calendar/appt.el
index 5089df1d8ed..6148babfd11 100644
--- a/lisp/calendar/appt.el
+++ b/lisp/calendar/appt.el
@@ -214,21 +214,60 @@ If this is non-nil, appointment checking is active.")
214(defun appt-display-message (string mins) 214(defun appt-display-message (string mins)
215 "Display a reminder about an appointment. 215 "Display a reminder about an appointment.
216The string STRING describes the appointment, due in integer MINS minutes. 216The string STRING describes the appointment, due in integer MINS minutes.
217The format of the visible reminder is controlled by `appt-display-format'. 217The arguments may also be lists, where each element relates to a
218The variable `appt-audible' controls the audible reminder." 218separate appointment. The variable `appt-display-format' controls
219the format of the visible reminder. If `appt-audible' is non-nil,
220also calls `beep' for an audible reminder."
219 (if appt-audible (beep 1)) 221 (if appt-audible (beep 1))
222 ;; Backwards compatibility: avoid passing lists to a-d-w-f if not necessary.
223 (and (listp mins)
224 (= (length mins) 1)
225 (setq mins (car mins)
226 string (car string)))
220 (cond ((eq appt-display-format 'window) 227 (cond ((eq appt-display-format 'window)
221 (funcall appt-disp-window-function 228 ;; TODO use calendar-month-abbrev-array rather than %b?
222 (number-to-string mins) 229 (let ((time (format-time-string "%a %b %e " (current-time)))
223 ;; TODO - use calendar-month-abbrev-array rather than %b? 230 err)
224 (format-time-string "%a %b %e " (current-time)) 231 (condition-case err
225 string) 232 (funcall appt-disp-window-function
233 (if (listp mins)
234 (mapcar 'number-to-string mins)
235 (number-to-string mins))
236 time string)
237 (wrong-type-argument
238 (if (not (listp mins))
239 (signal (car err) (cdr err))
240 (message "Argtype error in `appt-disp-window-function' - \
241update it for multiple appts?")
242 ;; Fallback to just displaying the first appt, as we used to.
243 (funcall appt-disp-window-function
244 (number-to-string (car mins)) time
245 (car string))))))
226 (run-at-time (format "%d sec" appt-display-duration) 246 (run-at-time (format "%d sec" appt-display-duration)
227 nil 247 nil
228 appt-delete-window-function)) 248 appt-delete-window-function))
229 ((eq appt-display-format 'echo) 249 ((eq appt-display-format 'echo)
230 (message "%s" string)))) 250 (message "%s" (if (listp string)
231 251 (mapconcat 'identity string "\n")
252 string)))))
253
254(defun appt-mode-line (min-to-app &optional abbrev)
255 "Return an appointment string suitable for use in the mode-line.
256MIN-TO-APP is a list of minutes, as strings.
257If ABBREV is non-nil, abbreviates some text."
258 ;; All this silliness is just to make the formatting slightly nicer.
259 (let* ((multiple (> (length min-to-app) 1))
260 (imin (if (or (not multiple)
261 (not (delete (car min-to-app) min-to-app)))
262 (car min-to-app))))
263 (format "%s%s %s"
264 (if abbrev "App't" "Appointment")
265 (if multiple "s" "")
266 (if (equal imin "0") "now"
267 (format "in %s %s"
268 (or imin (mapconcat 'identity min-to-app ","))
269 (if abbrev "min."
270 (format "minute%s" (if (equal imin "1") "" "s"))))))))
232 271
233(defun appt-check (&optional force) 272(defun appt-check (&optional force)
234 "Check for an appointment and update any reminder display. 273 "Check for an appointment and update any reminder display.
@@ -351,9 +390,8 @@ displayed in a window:
351 (when appt-display-mode-line 390 (when appt-display-mode-line
352 (setq appt-mode-string 391 (setq appt-mode-string
353 (concat " " (propertize 392 (concat " " (propertize
354 (format "App't %s" 393 (appt-mode-line (mapcar 'number-to-string
355 (if (zerop min-to-app) "NOW" 394 (list min-to-app)) t)
356 (format "in %s min." min-to-app)))
357 'face 'mode-line-emphasis)))) 395 'face 'mode-line-emphasis))))
358 ;; When an appointment is reached, delete it from the 396 ;; When an appointment is reached, delete it from the
359 ;; list. Reset the count to 0 in case we display another 397 ;; list. Reset the count to 0 in case we display another
@@ -373,8 +411,10 @@ displayed in a window:
373 411
374(defun appt-disp-window (min-to-app new-time appt-msg) 412(defun appt-disp-window (min-to-app new-time appt-msg)
375 "Display appointment due in MIN-TO-APP (a string) minutes. 413 "Display appointment due in MIN-TO-APP (a string) minutes.
376NEW-TIME is a string giving the date. Displays the appointment 414NEW-TIME is a string giving the current date.
377message APPT-MSG in a separate buffer." 415Displays the appointment message APPT-MSG in a separate buffer.
416The arguments may also be lists, where each element relates to a
417separate appointment."
378 (let ((this-window (selected-window)) 418 (let ((this-window (selected-window))
379 (appt-disp-buf (get-buffer-create appt-buffer-name))) 419 (appt-disp-buf (get-buffer-create appt-buffer-name)))
380 ;; Make sure we're not in the minibuffer before splitting the window. 420 ;; Make sure we're not in the minibuffer before splitting the window.
@@ -395,17 +435,29 @@ message APPT-MSG in a separate buffer."
395 (when (>= (window-height) (* 2 window-min-height)) 435 (when (>= (window-height) (* 2 window-min-height))
396 (select-window (split-window)))) 436 (select-window (split-window))))
397 (switch-to-buffer appt-disp-buf)) 437 (switch-to-buffer appt-disp-buf))
438 (or (listp min-to-app)
439 (setq min-to-app (list min-to-app)
440 appt-msg (list appt-msg)))
441 ;; I don't really see the point of the new-time argument.
442 ;; It repeatedly reminds you of the date?
443 ;; It would make more sense if it was eg the time of the appointment.
444 ;; Let's allow it to be a list or not independent of the other elements.
445 (or (listp new-time)
446 (setq new-time (list new-time)))
398 ;; FIXME Link to diary entry? 447 ;; FIXME Link to diary entry?
399 (calendar-set-mode-line 448 (calendar-set-mode-line
400 (format " Appointment %s. %s " 449 (format " %s. %s" (appt-mode-line min-to-app)
401 (if (string-equal "0" min-to-app) "now" 450 (mapconcat 'identity new-time ", ")))
402 (format "in %s minute%s" min-to-app
403 (if (string-equal "1" min-to-app) "" "s")))
404 new-time))
405 (setq buffer-read-only nil 451 (setq buffer-read-only nil
406 buffer-undo-list t) 452 buffer-undo-list t)
407 (erase-buffer) 453 (erase-buffer)
408 (insert appt-msg) 454 ;; If we have appointments at different times, prepend the times.
455 (if (or (= 1 (length min-to-app))
456 (not (delete (car min-to-app) min-to-app)))
457 (insert (mapconcat 'identity appt-msg "\n"))
458 (dotimes (i (length appt-msg))
459 (insert (format "%s%sm: %s" (if (> i 0) "\n" "")
460 (nth i min-to-app) (nth i appt-msg)))))
409 (shrink-window-if-larger-than-buffer (get-buffer-window appt-disp-buf t)) 461 (shrink-window-if-larger-than-buffer (get-buffer-window appt-disp-buf t))
410 (set-buffer-modified-p nil) 462 (set-buffer-modified-p nil)
411 (setq buffer-read-only t) 463 (setq buffer-read-only t)
diff --git a/lisp/cus-start.el b/lisp/cus-start.el
index 6113a4321c5..389716b35b9 100644
--- a/lisp/cus-start.el
+++ b/lisp/cus-start.el
@@ -388,19 +388,18 @@ since it could result in memory overflow and make Emacs crash."
388 ;; window.c 388 ;; window.c
389 (temp-buffer-show-function windows (choice (const nil) function)) 389 (temp-buffer-show-function windows (choice (const nil) function))
390 (next-screen-context-lines windows integer) 390 (next-screen-context-lines windows integer)
391 (window-min-height windows integer)
392 (window-min-width windows integer)
393 (scroll-preserve-screen-position 391 (scroll-preserve-screen-position
394 windows (choice 392 windows (choice
395 (const :tag "Off (nil)" :value nil) 393 (const :tag "Off (nil)" :value nil)
396 (const :tag "Full screen (t)" :value t) 394 (const :tag "Full screen (t)" :value t)
397 (other :tag "Always" 1)) "22.1") 395 (other :tag "Always" 1)) "22.1")
398 (recenter-redisplay windows 396 (recenter-redisplay
399 (choice 397 windows (choice
400 (const :tag "Never (nil)" :value nil) 398 (const :tag "Never (nil)" :value nil)
401 (const :tag "Only on ttys" :value tty) 399 (const :tag "Only on ttys" :value tty)
402 (other :tag "Always" t)) 400 (other :tag "Always" t)) "23.1")
403 "23.1") 401 (window-splits windows boolean "24.1")
402 (window-nest windows boolean "24.1")
404 ;; xdisp.c 403 ;; xdisp.c
405 (show-trailing-whitespace whitespace-faces boolean nil 404 (show-trailing-whitespace whitespace-faces boolean nil
406 :safe booleanp) 405 :safe booleanp)
diff --git a/lisp/doc-view.el b/lisp/doc-view.el
index 06c3b70a3a6..666c6a8b034 100644
--- a/lisp/doc-view.el
+++ b/lisp/doc-view.el
@@ -1550,7 +1550,7 @@ See the command `doc-view-mode' for more information on this mode."
1550(provide 'doc-view) 1550(provide 'doc-view)
1551 1551
1552;; Local Variables: 1552;; Local Variables:
1553;; eval: (outline-minor-mode) 1553;; eval: (outline-minor-mode 1)
1554;; End: 1554;; End:
1555 1555
1556;;; doc-view.el ends here 1556;;; doc-view.el ends here
diff --git a/lisp/files.el b/lisp/files.el
index cc1ad23925d..317153dc9bf 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -2635,7 +2635,7 @@ we don't actually set it to the same mode the buffer already has."
2635 ;; Look for -*-MODENAME-*- or -*- ... mode: MODENAME; ... -*- 2635 ;; Look for -*-MODENAME-*- or -*- ... mode: MODENAME; ... -*-
2636 (let (end done mode modes) 2636 (let (end done mode modes)
2637 ;; Once we drop the deprecated feature where mode: is also allowed to 2637 ;; Once we drop the deprecated feature where mode: is also allowed to
2638 ;; specify minor-modes (ie, there can be more than one "mode:), we can 2638 ;; specify minor-modes (ie, there can be more than one "mode:"), we can
2639 ;; remove this section and just let (hack-local-variables t) handle it. 2639 ;; remove this section and just let (hack-local-variables t) handle it.
2640 ;; Find a -*- mode tag. 2640 ;; Find a -*- mode tag.
2641 (save-excursion 2641 (save-excursion
@@ -3367,7 +3367,7 @@ It is dangerous if either of these conditions are met:
3367 (and (symbolp (car exp)) 3367 (and (symbolp (car exp))
3368 ;; Allow (minor)-modes calls with no arguments. 3368 ;; Allow (minor)-modes calls with no arguments.
3369 ;; This obsoletes the use of "mode:" for such things. (Bug#8613) 3369 ;; This obsoletes the use of "mode:" for such things. (Bug#8613)
3370 (or (and (null (cdr exp)) 3370 (or (and (member (cdr exp) '(nil (1) (-1)))
3371 (string-match "-mode\\'" (symbol-name (car exp)))) 3371 (string-match "-mode\\'" (symbol-name (car exp))))
3372 (let ((prop (get (car exp) 'safe-local-eval-function))) 3372 (let ((prop (get (car exp) 'safe-local-eval-function)))
3373 (cond ((eq prop t) 3373 (cond ((eq prop t)
@@ -5256,7 +5256,7 @@ non-nil, it is called instead of rereading visited file contents."
5256 (save-excursion 5256 (save-excursion
5257 (let ((switches dired-listing-switches)) 5257 (let ((switches dired-listing-switches))
5258 (if (file-symlink-p file) 5258 (if (file-symlink-p file)
5259 (setq switches (concat switches "L"))) 5259 (setq switches (concat switches " -L")))
5260 (set-buffer standard-output) 5260 (set-buffer standard-output)
5261 ;; Use insert-directory-safely, not insert-directory, 5261 ;; Use insert-directory-safely, not insert-directory,
5262 ;; because these files might not exist. In particular, 5262 ;; because these files might not exist. In particular,
@@ -5299,7 +5299,7 @@ Then you'll be asked about a number of files to recover."
5299 (error "No previous sessions to recover"))) 5299 (error "No previous sessions to recover")))
5300 (let ((ls-lisp-support-shell-wildcards t)) 5300 (let ((ls-lisp-support-shell-wildcards t))
5301 (dired (concat auto-save-list-file-prefix "*") 5301 (dired (concat auto-save-list-file-prefix "*")
5302 (concat dired-listing-switches "t"))) 5302 (concat dired-listing-switches " -t")))
5303 (save-excursion 5303 (save-excursion
5304 (goto-char (point-min)) 5304 (goto-char (point-min))
5305 (or (looking-at " Move to the session you want to recover,") 5305 (or (looking-at " Move to the session you want to recover,")
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog
index ff3eb98bb97..2bfaf32f958 100644
--- a/lisp/gnus/ChangeLog
+++ b/lisp/gnus/ChangeLog
@@ -1,3 +1,24 @@
12011-06-10 Katsumi Yamaoka <yamaoka@jpl.org>
2
3 * gnus-group.el (gnus-group-update-group): Add new argument
4 `info-unchanged' that stops updating dribble buffer.
5
6 * gnus-start.el (gnus-dribble-enter): Add new argument `regexp' that
7 deletes lines matching to it in dribble buffer.
8
9 * gnus-agent.el (gnus-agent-fetch-group-1):
10 * gnus-group.el (gnus-group-update-group-line, gnus-group-make-group):
11 * gnus-srvr.el (gnus-server-update-server, gnus-server-set-info):
12 * gnus-start.el (gnus-group-change-level):
13 * gnus-sum.el (gnus-summary-move-article): Delete old dribble entry.
14
15 * gnus-sum.el (gnus-summary-update-info): Don't update dribble buffer
16 if newsgroup info is not changed.
17
18 * gnus-group.el (gnus-group-get-new-news-this-group):
19 * gnus-sum.el (gnus-summary-read-group-1, gnus-summary-exit-no-update):
20 Don't update dribble buffer.
21
12011-06-01 Teodor Zlatanov <tzz@lifelogs.com> 222011-06-01 Teodor Zlatanov <tzz@lifelogs.com>
2 23
3 * gnus-registry.el (gnus-registry-remove-ignored): New function to 24 * gnus-registry.el (gnus-registry-remove-ignored): New function to
diff --git a/lisp/gnus/gnus-agent.el b/lisp/gnus/gnus-agent.el
index b4f0dc38e7e..424c55c40f5 100644
--- a/lisp/gnus/gnus-agent.el
+++ b/lisp/gnus/gnus-agent.el
@@ -2614,7 +2614,9 @@ modified) original contents, they are first saved to their own file."
2614 (gnus-dribble-enter 2614 (gnus-dribble-enter
2615 (concat "(gnus-group-set-info '" 2615 (concat "(gnus-group-set-info '"
2616 (gnus-prin1-to-string info) 2616 (gnus-prin1-to-string info)
2617 ")")))))))))))) 2617 ")")
2618 (concat "^(gnus-group-set-info '(\""
2619 (regexp-quote group) "\""))))))))))))
2618 2620
2619;;; 2621;;;
2620;;; Agent Category Mode 2622;;; Agent Category Mode
diff --git a/lisp/gnus/gnus-group.el b/lisp/gnus/gnus-group.el
index 4c474b0aa23..518f215a7ba 100644
--- a/lisp/gnus/gnus-group.el
+++ b/lisp/gnus/gnus-group.el
@@ -1437,7 +1437,8 @@ if it is a string, only list groups matching REGEXP."
1437 (gnus-dribble-enter 1437 (gnus-dribble-enter
1438 (concat "(gnus-group-set-info '" 1438 (concat "(gnus-group-set-info '"
1439 (gnus-prin1-to-string (nth 2 entry)) 1439 (gnus-prin1-to-string (nth 2 entry))
1440 ")"))) 1440 ")")
1441 (concat "^(gnus-group-set-info '(\"" (regexp-quote group) "\"")))
1441 (setq gnus-group-indentation (gnus-group-group-indentation)) 1442 (setq gnus-group-indentation (gnus-group-group-indentation))
1442 (gnus-delete-line) 1443 (gnus-delete-line)
1443 (gnus-group-insert-group-line-info group) 1444 (gnus-group-insert-group-line-info group)
@@ -1685,10 +1686,11 @@ and ends at END."
1685 (gnus-active group)) 1686 (gnus-active group))
1686 (gnus-group-update-group group)) 1687 (gnus-group-update-group group))
1687 1688
1688(defun gnus-group-update-group (group &optional visible-only) 1689(defun gnus-group-update-group (group &optional visible-only
1690 info-unchanged)
1689 "Update all lines where GROUP appear. 1691 "Update all lines where GROUP appear.
1690If VISIBLE-ONLY is non-nil, the group won't be displayed if it isn't 1692If VISIBLE-ONLY is non-nil, the group won't be displayed if it isn't
1691already." 1693already. If INFO-UNCHANGED is non-nil, dribble buffer is not updated."
1692 (with-current-buffer gnus-group-buffer 1694 (with-current-buffer gnus-group-buffer
1693 (save-excursion 1695 (save-excursion
1694 ;; The buffer may be narrowed. 1696 ;; The buffer may be narrowed.
@@ -1697,14 +1699,17 @@ already."
1697 (let ((ident (gnus-intern-safe group gnus-active-hashtb)) 1699 (let ((ident (gnus-intern-safe group gnus-active-hashtb))
1698 (loc (point-min)) 1700 (loc (point-min))
1699 found buffer-read-only) 1701 found buffer-read-only)
1700 ;; Enter the current status into the dribble buffer. 1702 (unless info-unchanged
1701 (let ((entry (gnus-group-entry group))) 1703 ;; Enter the current status into the dribble buffer.
1702 (when (and entry 1704 (let ((entry (gnus-group-entry group)))
1703 (not (gnus-ephemeral-group-p group))) 1705 (when (and entry
1704 (gnus-dribble-enter 1706 (not (gnus-ephemeral-group-p group)))
1705 (concat "(gnus-group-set-info '" 1707 (gnus-dribble-enter
1706 (gnus-prin1-to-string (nth 2 entry)) 1708 (concat "(gnus-group-set-info '"
1707 ")")))) 1709 (gnus-prin1-to-string (nth 2 entry))
1710 ")")
1711 (concat "^(gnus-group-set-info '(\""
1712 (regexp-quote group) "\"")))))
1708 ;; Find all group instances. If topics are in use, each group 1713 ;; Find all group instances. If topics are in use, each group
1709 ;; may be listed in more than once. 1714 ;; may be listed in more than once.
1710 (while (setq loc (text-property-any 1715 (while (setq loc (text-property-any
@@ -2715,7 +2720,8 @@ server."
2715 (unless (gnus-ephemeral-group-p name) 2720 (unless (gnus-ephemeral-group-p name)
2716 (gnus-dribble-enter 2721 (gnus-dribble-enter
2717 (concat "(gnus-group-set-info '" 2722 (concat "(gnus-group-set-info '"
2718 (gnus-prin1-to-string (cdr info)) ")"))) 2723 (gnus-prin1-to-string (cdr info)) ")")
2724 (concat "^(gnus-group-set-info '(\"" (regexp-quote name) "\"")))
2719 ;; Insert the line. 2725 ;; Insert the line.
2720 (gnus-group-insert-group-line-info nname) 2726 (gnus-group-insert-group-line-info nname)
2721 (forward-line -1) 2727 (forward-line -1)
@@ -4032,7 +4038,7 @@ If DONT-SCAN is non-nil, scan non-activated groups as well."
4032 (when gnus-agent 4038 (when gnus-agent
4033 (gnus-agent-save-group-info 4039 (gnus-agent-save-group-info
4034 method (gnus-group-real-name group) active)) 4040 method (gnus-group-real-name group) active))
4035 (gnus-group-update-group group)) 4041 (gnus-group-update-group group nil t))
4036 (if (eq (gnus-server-status (gnus-find-method-for-group group)) 4042 (if (eq (gnus-server-status (gnus-find-method-for-group group))
4037 'denied) 4043 'denied)
4038 (gnus-error 3 "Server denied access") 4044 (gnus-error 3 "Server denied access")
diff --git a/lisp/gnus/gnus-srvr.el b/lisp/gnus/gnus-srvr.el
index 9bf2d37a3e4..ec98b2ff749 100644
--- a/lisp/gnus/gnus-srvr.el
+++ b/lisp/gnus/gnus-srvr.el
@@ -362,7 +362,8 @@ The following commands are available:
362 (when entry 362 (when entry
363 (gnus-dribble-enter 363 (gnus-dribble-enter
364 (concat "(gnus-server-set-info \"" server "\" '" 364 (concat "(gnus-server-set-info \"" server "\" '"
365 (gnus-prin1-to-string (cdr entry)) ")\n"))) 365 (gnus-prin1-to-string (cdr entry)) ")\n")
366 (concat "^(gnus-server-set-info \"" (regexp-quote server) "\"")))
366 (when (or entry oentry) 367 (when (or entry oentry)
367 ;; Buffer may be narrowed. 368 ;; Buffer may be narrowed.
368 (save-restriction 369 (save-restriction
@@ -381,7 +382,8 @@ The following commands are available:
381 (when (and server info) 382 (when (and server info)
382 (gnus-dribble-enter 383 (gnus-dribble-enter
383 (concat "(gnus-server-set-info \"" server "\" '" 384 (concat "(gnus-server-set-info \"" server "\" '"
384 (gnus-prin1-to-string info) ")")) 385 (gnus-prin1-to-string info) ")")
386 (concat "^(gnus-server-set-info \"" (regexp-quote server) "\""))
385 (let* ((server (nth 1 info)) 387 (let* ((server (nth 1 info))
386 (entry (assoc server gnus-server-alist)) 388 (entry (assoc server gnus-server-alist))
387 (cached (assoc server gnus-server-method-cache))) 389 (cached (assoc server gnus-server-method-cache)))
diff --git a/lisp/gnus/gnus-start.el b/lisp/gnus/gnus-start.el
index 719d0c9e472..aa9af012a1c 100644
--- a/lisp/gnus/gnus-start.el
+++ b/lisp/gnus/gnus-start.el
@@ -832,13 +832,22 @@ prompt the user for the name of an NNTP server to use."
832 gnus-current-startup-file) 832 gnus-current-startup-file)
833 "-dribble")) 833 "-dribble"))
834 834
835(defun gnus-dribble-enter (string) 835(defun gnus-dribble-enter (string &optional regexp)
836 "Enter STRING into the dribble buffer." 836 "Enter STRING into the dribble buffer.
837If REGEXP is given, lines that match it will be deleted."
837 (when (and (not gnus-dribble-ignore) 838 (when (and (not gnus-dribble-ignore)
838 gnus-dribble-buffer 839 gnus-dribble-buffer
839 (buffer-name gnus-dribble-buffer)) 840 (buffer-name gnus-dribble-buffer))
840 (let ((obuf (current-buffer))) 841 (let ((obuf (current-buffer)))
841 (set-buffer gnus-dribble-buffer) 842 (set-buffer gnus-dribble-buffer)
843 (when regexp
844 (goto-char (point-min))
845 (let (end)
846 (while (re-search-forward regexp nil t)
847 (unless (bolp) (forward-line 1))
848 (setq end (point))
849 (goto-char (match-beginning 0))
850 (delete-region (point-at-bol) end))))
842 (goto-char (point-max)) 851 (goto-char (point-max))
843 (insert string "\n") 852 (insert string "\n")
844 ;; This has been commented by Josh Huber <huber@alum.wpi.edu> 853 ;; This has been commented by Josh Huber <huber@alum.wpi.edu>
@@ -1354,8 +1363,8 @@ for new groups, and subscribe the new groups as zombies."
1354 (when (cdr entry) 1363 (when (cdr entry)
1355 (setcdr (gnus-group-entry (caadr entry)) entry)) 1364 (setcdr (gnus-group-entry (caadr entry)) entry))
1356 (gnus-dribble-enter 1365 (gnus-dribble-enter
1357 (format 1366 (format "(gnus-group-set-info '%S)" info)
1358 "(gnus-group-set-info '%S)" info))))) 1367 (concat "^(gnus-group-set-info '(\"" (regexp-quote group) "\"")))))
1359 (when gnus-group-change-level-function 1368 (when gnus-group-change-level-function
1360 (funcall gnus-group-change-level-function 1369 (funcall gnus-group-change-level-function
1361 group level oldlevel previous))))) 1370 group level oldlevel previous)))))
diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el
index 1c4382b24a6..f974d386acb 100644
--- a/lisp/gnus/gnus-sum.el
+++ b/lisp/gnus/gnus-sum.el
@@ -4098,7 +4098,7 @@ If NO-DISPLAY, don't generate a summary buffer."
4098 (setq gnus-newsgroup-prepared t) 4098 (setq gnus-newsgroup-prepared t)
4099 (gnus-run-hooks 'gnus-summary-prepared-hook) 4099 (gnus-run-hooks 'gnus-summary-prepared-hook)
4100 (unless (gnus-ephemeral-group-p group) 4100 (unless (gnus-ephemeral-group-p group)
4101 (gnus-group-update-group group)) 4101 (gnus-group-update-group group nil t))
4102 t))))) 4102 t)))))
4103 4103
4104(defun gnus-summary-auto-select-subject () 4104(defun gnus-summary-auto-select-subject ()
@@ -7140,7 +7140,12 @@ The prefix argument ALL means to select all articles."
7140 t))) 7140 t)))
7141 (unless (listp (cdr gnus-newsgroup-killed)) 7141 (unless (listp (cdr gnus-newsgroup-killed))
7142 (setq gnus-newsgroup-killed (list gnus-newsgroup-killed))) 7142 (setq gnus-newsgroup-killed (list gnus-newsgroup-killed)))
7143 (let ((headers gnus-newsgroup-headers)) 7143 (let ((headers gnus-newsgroup-headers)
7144 (ephemeral-p (gnus-ephemeral-group-p group))
7145 info)
7146 (unless ephemeral-p
7147 (setq info (copy-sequence (gnus-get-info group))
7148 info (delq (gnus-info-params info) info)))
7144 ;; Set the new ranges of read articles. 7149 ;; Set the new ranges of read articles.
7145 (with-current-buffer gnus-group-buffer 7150 (with-current-buffer gnus-group-buffer
7146 (gnus-undo-force-boundary)) 7151 (gnus-undo-force-boundary))
@@ -7160,8 +7165,12 @@ The prefix argument ALL means to select all articles."
7160 (gnus-mark-xrefs-as-read group headers gnus-newsgroup-unreads)) 7165 (gnus-mark-xrefs-as-read group headers gnus-newsgroup-unreads))
7161 ;; Do not switch windows but change the buffer to work. 7166 ;; Do not switch windows but change the buffer to work.
7162 (set-buffer gnus-group-buffer) 7167 (set-buffer gnus-group-buffer)
7163 (unless (gnus-ephemeral-group-p group) 7168 (unless ephemeral-p
7164 (gnus-group-update-group group))))))) 7169 (gnus-group-update-group
7170 group nil
7171 (equal info
7172 (setq info (copy-sequence (gnus-get-info group))
7173 info (delq (gnus-info-params info) info))))))))))
7165 7174
7166(defun gnus-summary-save-newsrc (&optional force) 7175(defun gnus-summary-save-newsrc (&optional force)
7167 "Save the current number of read/marked articles in the dribble buffer. 7176 "Save the current number of read/marked articles in the dribble buffer.
@@ -7314,7 +7323,7 @@ If FORCE (the prefix), also save the .newsrc file(s)."
7314 ;; Clear the current group name. 7323 ;; Clear the current group name.
7315 (setq gnus-newsgroup-name nil) 7324 (setq gnus-newsgroup-name nil)
7316 (unless (gnus-ephemeral-group-p group) 7325 (unless (gnus-ephemeral-group-p group)
7317 (gnus-group-update-group group)) 7326 (gnus-group-update-group group nil t))
7318 (when (equal (gnus-group-group-name) group) 7327 (when (equal (gnus-group-group-name) group)
7319 (gnus-group-next-unread-group 1)) 7328 (gnus-group-next-unread-group 1))
7320 (when quit-config 7329 (when quit-config
@@ -9994,7 +10003,9 @@ ACTION can be either `move' (the default), `crosspost' or `copy'."
9994 (gnus-dribble-enter 10003 (gnus-dribble-enter
9995 (concat "(gnus-group-set-info '" 10004 (concat "(gnus-group-set-info '"
9996 (gnus-prin1-to-string (gnus-get-info to-group)) 10005 (gnus-prin1-to-string (gnus-get-info to-group))
9997 ")")))) 10006 ")")
10007 (concat "^(gnus-group-set-info '(\""
10008 (regexp-quote to-group) "\""))))
9998 10009
9999 ;; Update the Xref header in this article to point to 10010 ;; Update the Xref header in this article to point to
10000 ;; the new crossposted article we have just created. 10011 ;; the new crossposted article we have just created.
diff --git a/lisp/mail/sendmail.el b/lisp/mail/sendmail.el
index 2c5fa014a94..f4ef9b91903 100644
--- a/lisp/mail/sendmail.el
+++ b/lisp/mail/sendmail.el
@@ -1801,7 +1801,7 @@ The seventh argument ACTIONS is a list of actions to take
1801 ;; unbound on exit from the let. 1801 ;; unbound on exit from the let.
1802 (require 'dired) 1802 (require 'dired)
1803 (let ((dired-trivial-filenames t)) 1803 (let ((dired-trivial-filenames t))
1804 (dired-other-window wildcard (concat dired-listing-switches "t"))) 1804 (dired-other-window wildcard (concat dired-listing-switches " -t")))
1805 (rename-buffer "*Auto-saved Drafts*" t) 1805 (rename-buffer "*Auto-saved Drafts*" t)
1806 (save-excursion 1806 (save-excursion
1807 (goto-char (point-min)) 1807 (goto-char (point-min))
@@ -1881,7 +1881,7 @@ you can move to one of them and type C-c C-c to recover that one."
1881 ;; `ls' is not a standard program (it will use 1881 ;; `ls' is not a standard program (it will use
1882 ;; ls-lisp instead). 1882 ;; ls-lisp instead).
1883 (dired-noselect file-name 1883 (dired-noselect file-name
1884 (concat dired-listing-switches "t")))) 1884 (concat dired-listing-switches " -t"))))
1885 (save-selected-window 1885 (save-selected-window
1886 (select-window (display-buffer dispbuf t)) 1886 (select-window (display-buffer dispbuf t))
1887 (goto-char (point-min)) 1887 (goto-char (point-min))
diff --git a/lisp/net/ange-ftp.el b/lisp/net/ange-ftp.el
index b1d8279e93f..0493ead7bbf 100644
--- a/lisp/net/ange-ftp.el
+++ b/lisp/net/ange-ftp.el
@@ -2806,6 +2806,19 @@ match subdirectories as well.")
2806 (and files (puthash (file-name-as-directory directory) 2806 (and files (puthash (file-name-as-directory directory)
2807 files ange-ftp-files-hashtable))) 2807 files ange-ftp-files-hashtable)))
2808 2808
2809(defun ange-ftp-switches-ok (switches)
2810 "Return SWITCHES (a string) if suitable for our use."
2811 (and (stringp switches)
2812 ;; We allow the A switch, which lists all files except "." and
2813 ;; "..". This is OK because we manually insert these entries
2814 ;; in the hash table.
2815 (string-match
2816 "--\\(almost-\\)?all\\>\\|\\(\\`\\| \\)-[[:alpha:]]*[aA]" switches)
2817 (string-match "\\(\\`\\| \\)-[[:alpha:]]*l" switches)
2818 (not (string-match
2819 "--recursive\\>\\|\\(\\`\\| \\)-[[:alpha:]]*R" switches))
2820 switches))
2821
2809(defun ange-ftp-get-files (directory &optional no-error) 2822(defun ange-ftp-get-files (directory &optional no-error)
2810 "Given a DIRECTORY, return a hashtable of file entries. 2823 "Given a DIRECTORY, return a hashtable of file entries.
2811This will give an error or return nil, depending on the value of 2824This will give an error or return nil, depending on the value of
@@ -2817,30 +2830,12 @@ NO-ERROR, if a listing for DIRECTORY cannot be obtained."
2817 ;; This is an efficiency hack. We try to 2830 ;; This is an efficiency hack. We try to
2818 ;; anticipate what sort of listing dired 2831 ;; anticipate what sort of listing dired
2819 ;; might want, and cache just such a listing. 2832 ;; might want, and cache just such a listing.
2820 (if (and (boundp 'dired-actual-switches) 2833 (or (and (boundp 'dired-actual-switches)
2821 (stringp dired-actual-switches) 2834 (ange-ftp-switches-ok dired-actual-switches))
2822 ;; We allow the A switch, which lists 2835 (and (boundp 'dired-listing-switches)
2823 ;; all files except "." and "..". 2836 (ange-ftp-switches-ok
2824 ;; This is OK because we manually 2837 dired-listing-switches))
2825 ;; insert these entries 2838 "-al")
2826 ;; in the hash table.
2827 (string-match
2828 "[aA]" dired-actual-switches)
2829 (string-match
2830 "l" dired-actual-switches)
2831 (not (string-match
2832 "R" dired-actual-switches)))
2833 dired-actual-switches
2834 (if (and (boundp 'dired-listing-switches)
2835 (stringp dired-listing-switches)
2836 (string-match
2837 "[aA]" dired-listing-switches)
2838 (string-match
2839 "l" dired-listing-switches)
2840 (not (string-match
2841 "R" dired-listing-switches)))
2842 dired-listing-switches
2843 "-al"))
2844 t no-error) 2839 t no-error)
2845 (gethash directory ange-ftp-files-hashtable))))) 2840 (gethash directory ange-ftp-files-hashtable)))))
2846 2841
diff --git a/lisp/net/soap-client.el b/lisp/net/soap-client.el
index 9862332bf3f..b7b0b61f4e1 100644
--- a/lisp/net/soap-client.el
+++ b/lisp/net/soap-client.el
@@ -1745,7 +1745,7 @@ operations in a WSDL document."
1745 1745
1746 1746
1747;;; Local Variables: 1747;;; Local Variables:
1748;;; eval: (outline-minor-mode) 1748;;; eval: (outline-minor-mode 1)
1749;;; outline-regexp: ";;;;+" 1749;;; outline-regexp: ";;;;+"
1750;;; End: 1750;;; End:
1751 1751
diff --git a/lisp/term/xterm.el b/lisp/term/xterm.el
index 0db33b5a4de..c2b870bd535 100644
--- a/lisp/term/xterm.el
+++ b/lisp/term/xterm.el
@@ -24,6 +24,23 @@
24 24
25;;; Code: 25;;; Code:
26 26
27(defgroup xterm nil
28 "XTerm support."
29 :version "24.1"
30 :group 'emacs)
31
32(defcustom xterm-extra-capabilities 'check
33 "Set to a list if the XTerm supports modifyOtherKeys or
34reporting the background color. Set to 'check to check for those
35features. Set to nil to skip the checks."
36 :group 'xterm
37 :type '(choice (const :tag "No" nil)
38 (const :tag "Check" check)
39 ;; NOTE: If you add entries here, make sure to update
40 ;; `tocheck-capabilities' in `terminal-init-xterm' as well.
41 (set (const :tag "modifyOtherKeys support" modifyOtherKeys)
42 (const :tag "report background" reportBackground))))
43
27(defvar xterm-function-map 44(defvar xterm-function-map
28 (let ((map (make-sparse-keymap))) 45 (let ((map (make-sparse-keymap)))
29 46
@@ -460,81 +477,116 @@
460 (set-keymap-parent map (keymap-parent input-decode-map)) 477 (set-keymap-parent map (keymap-parent input-decode-map))
461 (set-keymap-parent input-decode-map map))) 478 (set-keymap-parent input-decode-map map)))
462 479
463 (xterm-register-default-colors) 480 (xterm-register-default-colors)
464 (tty-set-up-initial-frame-faces) 481 (tty-set-up-initial-frame-faces)
465 482
466 ;; Try to turn on the modifyOtherKeys feature on modern xterms. 483 ;; Try to turn on the modifyOtherKeys feature on modern xterms.
467 ;; When it is turned on many more key bindings work: things like 484 ;; When it is turned on many more key bindings work: things like
468 ;; C-. C-, etc. 485 ;; C-. C-, etc.
469 ;; To do that we need to find out if the current terminal supports 486 ;; To do that we need to find out if the current terminal supports
470 ;; modifyOtherKeys. At this time only xterm does. 487 ;; modifyOtherKeys. At this time only xterm does.
488 (when xterm-extra-capabilities
471 (let ((coding-system-for-read 'binary) 489 (let ((coding-system-for-read 'binary)
472 (chr nil) 490 (chr nil)
473 (str nil) 491 (str nil)
474 (recompute-faces nil) 492 (background-regex
475 version) 493 "11;rgb:\\([a-f0-9]+\\)/\\([a-f0-9]+\\)/\\([a-f0-9]+\\)")
476 ;; Pending input can be mistakenly returned by the calls to 494 (recompute-faces nil)
477 ;; read-event below. Discard it. 495 ;; If `xterm-extra-capabilities' is 'check, we don't know
478 (discard-input) 496 ;; the capabilities. We need to check for those defined
479 ;; Try to find out the type of terminal by sending a "Secondary 497 ;; as `xterm-extra-capabilities' set options. Otherwise,
480 ;; Device Attributes (DA)" query. 498 ;; we don't need to check for any capabilities because
481 (send-string-to-terminal "\e[>0c") 499 ;; they are given by setting `xterm-extra-capabilities' to
482 500 ;; a list (which could be empty).
483 ;; The reply should be of the form: \e [ > NUMBER1 ; NUMBER2 ; NUMBER3 c 501 (tocheck-capabilities (when (eq 'check xterm-extra-capabilities)
484 ;; If the timeout is completely removed for read-event, this 502 '(modifyOtherKeys reportBackground)))
485 ;; might hang for terminals that pretend to be xterm, but don't 503 ;; The given capabilities are either the contents of
486 ;; respond to this escape sequence. RMS' opinion was to remove 504 ;; `xterm-extra-capabilities', if it's a list, or an empty
487 ;; it completely. That might be right, but let's first try to 505 ;; list.
488 ;; see if by using a longer timeout we get rid of most issues. 506 (given-capabilities (when (consp xterm-extra-capabilities)
489 (when (equal (read-event nil nil 2) ?\e) 507 xterm-extra-capabilities))
490 (when (equal (read-event nil nil 2) ?\[) 508 version)
491 (while (not (equal (setq chr (read-event nil nil 2)) ?c)) 509
492 (setq str (concat str (string chr)))) 510 ;; Do the following if `xterm-extra-capabilities' is anything but nil.
493 (when (string-match ">0;\\([0-9]+\\);0" str) 511 (when xterm-extra-capabilities
494 (setq version (string-to-number 512 ;; 1. Set `version'
495 (substring str (match-beginning 1) (match-end 1)))) 513
496 ;; xterm version 242 supports reporting the background 514 ;; Pending input can be mistakenly returned by the calls to
497 ;; color, maybe earlier versions do too... 515 ;; read-event below. Discard it.
498 (when (>= version 242) 516 (discard-input)
499 (send-string-to-terminal "\e]11;?\e\\") 517 ;; Try to find out the type of terminal by sending a "Secondary
500 (when (equal (read-event nil nil 2) ?\e) 518 ;; Device Attributes (DA)" query.
501 (when (equal (read-event nil nil 2) ?\]) 519 (send-string-to-terminal "\e[>0c")
502 (setq str "") 520
503 (while (not (equal (setq chr (read-event nil nil 2)) ?\\)) 521 ;; The reply should be: \e [ > NUMBER1 ; NUMBER2 ; NUMBER3 c
504 (setq str (concat str (string chr)))) 522 ;; If the timeout is completely removed for read-event, this
505 (when (string-match "11;rgb:\\([a-f0-9]+\\)/\\([a-f0-9]+\\)/\\([a-f0-9]+\\)" str) 523 ;; might hang for terminals that pretend to be xterm, but don't
506 (setq recompute-faces 524 ;; respond to this escape sequence. RMS' opinion was to remove
507 (xterm-maybe-set-dark-background-mode 525 ;; it completely. That might be right, but let's first try to
508 (string-to-number (match-string 1 str) 16) 526 ;; see if by using a longer timeout we get rid of most issues.
509 (string-to-number (match-string 2 str) 16) 527 (when (equal (read-event nil nil 2) ?\e)
510 (string-to-number (match-string 3 str) 16))))))) 528 (when (equal (read-event nil nil 2) ?\[)
511 ;; NUMBER2 is the xterm version number, look for something 529 (while (not (equal (setq chr (read-event nil nil 2)) ?c))
512 ;; greater than 216, the version when modifyOtherKeys was 530 (setq str (concat str (string chr))))
513 ;; introduced. 531 (when (string-match ">0;\\([0-9]+\\);0" str)
514 (when (>= version 216) 532 (setq version
515 ;; Make sure that the modifyOtherKeys state is restored when 533 (string-to-number
516 ;; suspending, resuming and exiting. 534 (substring str (match-beginning 1) (match-end 1)))))))
517 (add-hook 'suspend-hook 'xterm-turn-off-modify-other-keys) 535
518 (add-hook 'suspend-resume-hook 'xterm-turn-on-modify-other-keys) 536 ;; 2. If reportBackground is known to be supported, or the
519 (add-hook 'kill-emacs-hook 'xterm-remove-modify-other-keys) 537 ;; version is 242 or higher, assume the xterm supports
520 (add-hook 'delete-terminal-functions 'xterm-remove-modify-other-keys) 538 ;; reporting the background color (TODO: maybe earlier
521 ;; Add the selected frame to the list of frames that 539 ;; versions do too...)
522 ;; need to deal with modify-other-keys. 540 (when (or (memq 'reportBackground given-capabilities)
523 (push (frame-terminal (selected-frame)) 541 (and (memq 'reportBackground tocheck-capabilities)
524 xterm-modify-other-keys-terminal-list) 542 (>= version 242)))
525 (xterm-turn-on-modify-other-keys)) 543 (send-string-to-terminal "\e]11;?\e\\")
526 544 (when (equal (read-event nil nil 2) ?\e)
527 ;; Recompute faces here in case the background mode was 545 (when (equal (read-event nil nil 2) ?\])
528 ;; set to dark. We used to call 546 (setq str "")
529 ;; `tty-set-up-initial-frame-faces' only once, but that 547 (while (not (equal (setq chr (read-event nil nil 2)) ?\\))
530 ;; caused the light background faces to be computed 548 (setq str (concat str (string chr))))
531 ;; incorrectly. See: 549 (when (string-match background-regex str)
532 ;; http://permalink.gmane.org/gmane.emacs.devel/119627 550 (setq recompute-faces
533 (when recompute-faces 551 (xterm-maybe-set-dark-background-mode
534 (tty-set-up-initial-frame-faces)))))) 552 (string-to-number (match-string 1 str) 16)
553 (string-to-number (match-string 2 str) 16)
554 (string-to-number (match-string 3 str) 16)))))))
555
556 ;; 3. If modifyOtherKeys is known to be supported or the
557 ;; version is 216 (the version when modifyOtherKeys was
558 ;; introduced) or higher, initialize the modifyOtherKeys
559 ;; support.
560 (when (or (memq 'modifyOtherKeys given-capabilities)
561 (and (memq 'modifyOtherKeys tocheck-capabilities)
562 (>= version 216)))
563 (terminal-init-xterm-modify-other-keys))
564
565 ;; Recompute faces here in case the background mode was
566 ;; set to dark. We used to call
567 ;; `tty-set-up-initial-frame-faces' only once, but that
568 ;; caused the light background faces to be computed
569 ;; incorrectly. See:
570 ;; http://permalink.gmane.org/gmane.emacs.devel/119627
571 (when recompute-faces
572 (tty-set-up-initial-frame-faces)))))
535 573
536 (run-hooks 'terminal-init-xterm-hook)) 574 (run-hooks 'terminal-init-xterm-hook))
537 575
576(defun terminal-init-xterm-modify-other-keys ()
577 "Terminal initialization for xterm's modifyOtherKeys support."
578 ;; Make sure that the modifyOtherKeys state is restored when
579 ;; suspending, resuming and exiting.
580 (add-hook 'suspend-hook 'xterm-turn-off-modify-other-keys)
581 (add-hook 'suspend-resume-hook 'xterm-turn-on-modify-other-keys)
582 (add-hook 'kill-emacs-hook 'xterm-remove-modify-other-keys)
583 (add-hook 'delete-terminal-functions 'xterm-remove-modify-other-keys)
584 ;; Add the selected frame to the list of frames that
585 ;; need to deal with modify-other-keys.
586 (push (frame-terminal (selected-frame))
587 xterm-modify-other-keys-terminal-list)
588 (xterm-turn-on-modify-other-keys))
589
538;; Set up colors, for those versions of xterm that support it. 590;; Set up colors, for those versions of xterm that support it.
539(defvar xterm-standard-colors 591(defvar xterm-standard-colors
540 ;; The names in the comments taken from XTerm-col.ad in the xterm 592 ;; The names in the comments taken from XTerm-col.ad in the xterm
diff --git a/lisp/window.el b/lisp/window.el
index eafa8a4764a..a88e56be83c 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -161,10 +161,41 @@ these functions to inhibit processing of window parameters.")
161 "The absolut minimum number of lines of a window. 161 "The absolut minimum number of lines of a window.
162Anything less might crash Emacs.") 162Anything less might crash Emacs.")
163 163
164(defcustom window-min-height 4
165 "The minimum number of lines of any window.
166The value has to accomodate a mode- or header-line if present. A
167value less than `window-safe-min-height' is ignored. The value
168of this variable is honored when windows are resized or split.
169
170Applications should never rebind this variable. To resize a
171window to a height less than the one specified here, an
172application should instead call `resize-window' with a non-nil
173IGNORE argument. In order to have `split-window' make a window
174shorter, explictly specify the SIZE argument of that function."
175 :type 'integer
176 :version "24.1"
177 :group 'windows)
178
164(defconst window-safe-min-width 2 179(defconst window-safe-min-width 2
165 "The absolut minimum number of columns of a window. 180 "The absolut minimum number of columns of a window.
166Anything less might crash Emacs.") 181Anything less might crash Emacs.")
167 182
183(defcustom window-min-width 10
184 "The minimum number of columns of any window.
185The value has to accomodate margins, fringes, or scrollbars if
186present. A value less than `window-safe-min-width' is ignored.
187The value of this variable is honored when windows are resized or
188split.
189
190Applications should never rebind this variable. To resize a
191window to a width less than the one specified here, an
192application should instead call `resize-window' with a non-nil
193IGNORE argument. In order to have `split-window' make a window
194narrower, explictly specify the SIZE argument of that function."
195 :type 'integer
196 :version "24.1"
197 :group 'windows)
198
168(defun window-iso-combination-p (&optional window horizontal) 199(defun window-iso-combination-p (&optional window horizontal)
169 "If WINDOW is a vertical combination return WINDOW's first child. 200 "If WINDOW is a vertical combination return WINDOW's first child.
170WINDOW can be any window and defaults to the selected one. 201WINDOW can be any window and defaults to the selected one.
@@ -1312,7 +1343,741 @@ The optional argument MINIBUF specifies whether the minibuffer
1312window shall be counted. See `walk-windows' for the precise 1343window shall be counted. See `walk-windows' for the precise
1313meaning of this argument." 1344meaning of this argument."
1314 (length (window-list-1 nil minibuf))) 1345 (length (window-list-1 nil minibuf)))
1346
1347;;; Resizing windows.
1348(defun resize-window-reset (&optional frame horizontal)
1349 "Reset resize values for all windows on FRAME.
1350FRAME defaults to the selected frame.
1351
1352This function stores the current value of `window-total-size' applied
1353with argument HORIZONTAL in the new total size of all windows on
1354FRAME. It also resets the new normal size of each of these
1355windows."
1356 (resize-window-reset-1
1357 (frame-root-window (normalize-live-frame frame)) horizontal))
1358
1359(defun resize-window-reset-1 (window horizontal)
1360 "Internal function of `resize-window-reset'."
1361 ;; Register old size in the new total size.
1362 (set-window-new-total window (window-total-size window horizontal))
1363 ;; Reset new normal size.
1364 (set-window-new-normal window)
1365 (when (window-child window)
1366 (resize-window-reset-1 (window-child window) horizontal))
1367 (when (window-right window)
1368 (resize-window-reset-1 (window-right window) horizontal)))
1369
1370;; The following routine is used to manually resize the minibuffer
1371;; window and is currently used, for example, by ispell.el.
1372(defun resize-mini-window (window delta)
1373 "Resize minibuffer window WINDOW by DELTA lines.
1374If WINDOW cannot be resized by DELTA lines make it as large \(or
1375as small) as possible but don't signal an error."
1376 (when (window-minibuffer-p window)
1377 (let* ((frame (window-frame window))
1378 (root (frame-root-window frame))
1379 (height (window-total-size window))
1380 (min-delta
1381 (- (window-total-size root)
1382 (window-min-size root))))
1383 ;; Sanitize DELTA.
1384 (cond
1385 ((<= (+ height delta) 0)
1386 (setq delta (- (- height 1))))
1387 ((> delta min-delta)
1388 (setq delta min-delta)))
1389
1390 ;; Resize now.
1391 (resize-window-reset frame)
1392 ;; Ideally we should be able to resize just the last subwindow of
1393 ;; root here. See the comment in `resize-root-window-vertically'
1394 ;; for why we do not do that.
1395 (resize-this-window root (- delta) nil nil t)
1396 (set-window-new-total window (+ height delta))
1397 ;; The following routine catches the case where we want to resize
1398 ;; a minibuffer-only frame.
1399 (resize-mini-window-internal window))))
1400
1401(defun resize-window (window delta &optional horizontal ignore)
1402 "Resize WINDOW vertically by DELTA lines.
1403WINDOW can be an arbitrary window and defaults to the selected
1404one. An attempt to resize the root window of a frame will raise
1405an error though.
1406
1407DELTA a positive number means WINDOW shall be enlarged by DELTA
1408lines. DELTA negative means WINDOW shall be shrunk by -DELTA
1409lines.
1410
1411Optional argument HORIZONTAL non-nil means resize WINDOW
1412horizontally by DELTA columns. In this case a positive DELTA
1413means enlarge WINDOW by DELTA columns. DELTA negative means
1414WINDOW shall be shrunk by -DELTA columns.
1415
1416Optional argument IGNORE non-nil means ignore any restrictions
1417imposed by fixed size windows, `window-min-height' or
1418`window-min-width' settings. IGNORE any window means ignore
1419restrictions for that window only. IGNORE equal `safe' means
1420live windows may get as small as `window-safe-min-height' lines
1421and `window-safe-min-width' columns.
1422
1423This function resizes other windows proportionally and never
1424deletes any windows. If you want to move only the low (right)
1425edge of WINDOW consider using `adjust-window-trailing-edge'
1426instead."
1427 (setq window (normalize-any-window window))
1428 (let* ((frame (window-frame window))
1429 sibling)
1430 (cond
1431 ((eq window (frame-root-window frame))
1432 (error "Cannot resize the root window of a frame"))
1433 ((window-minibuffer-p window)
1434 (resize-mini-window window delta))
1435 ((window-resizable-p window delta horizontal ignore)
1436 (resize-window-reset frame horizontal)
1437 (resize-this-window window delta horizontal ignore t)
1438 (if (and (not (window-splits window))
1439 (window-iso-combined-p window horizontal)
1440 (setq sibling (or (window-right window) (window-left window)))
1441 (window-sizable-p sibling (- delta) horizontal ignore))
1442 ;; If window-splits returns nil for WINDOW, WINDOW is part of
1443 ;; an iso-combination, and WINDOW's neighboring right or left
1444 ;; sibling can be resized as requested, resize that sibling.
1445 (let ((normal-delta
1446 (/ (float delta)
1447 (window-total-size (window-parent window) horizontal))))
1448 (resize-this-window sibling (- delta) horizontal nil t)
1449 (set-window-new-normal
1450 window (+ (window-normal-size window horizontal)
1451 normal-delta))
1452 (set-window-new-normal
1453 sibling (- (window-normal-size sibling horizontal)
1454 normal-delta)))
1455 ;; Otherwise, resize all other windows in the same combination.
1456 (resize-other-windows window delta horizontal ignore))
1457 (resize-window-apply frame horizontal))
1458 (t
1459 (error "Cannot resize window %s" window)))))
1460
1461(defsubst resize-subwindows-skip-p (window)
1462 "Return non-nil if WINDOW shall be skipped by resizing routines."
1463 (memq (window-new-normal window) '(ignore stuck skip)))
1464
1465(defun resize-subwindows-normal (parent horizontal window this-delta &optional trail other-delta)
1466 "Set the new normal height of subwindows of window PARENT.
1467HORIZONTAL non-nil means set the new normal width of these
1468windows. WINDOW specifies a subwindow of PARENT that has been
1469resized by THIS-DELTA lines \(columns).
1470
1471Optional argument TRAIL either 'before or 'after means set values
1472for windows before or after WINDOW only. Optional argument
1473OTHER-DELTA a number specifies that this many lines \(columns)
1474have been obtained from \(or returned to) an ancestor window of
1475PARENT in order to resize WINDOW."
1476 (let* ((delta-normal
1477 (if (and (= (- this-delta) (window-total-size window horizontal))
1478 (zerop other-delta))
1479 ;; When WINDOW gets deleted and we can return its entire
1480 ;; space to its siblings, use WINDOW's normal size as the
1481 ;; normal delta.
1482 (- (window-normal-size window horizontal))
1483 ;; In any other case calculate the normal delta from the
1484 ;; relation of THIS-DELTA to the total size of PARENT.
1485 (/ (float this-delta) (window-total-size parent horizontal))))
1486 (sub (window-child parent))
1487 (parent-normal 0.0)
1488 (skip (eq trail 'after)))
1489
1490 ;; Set parent-normal to the sum of the normal sizes of all
1491 ;; subwindows of PARENT that shall be resized, excluding only WINDOW
1492 ;; and any windows specified by the optional TRAIL argument.
1493 (while sub
1494 (cond
1495 ((eq sub window)
1496 (setq skip (eq trail 'before)))
1497 (skip)
1498 (t
1499 (setq parent-normal
1500 (+ parent-normal (window-normal-size sub horizontal)))))
1501 (setq sub (window-right sub)))
1502
1503 ;; Set the new normal size of all subwindows of PARENT from what
1504 ;; they should have contributed for recovering THIS-DELTA lines
1505 ;; (columns).
1506 (setq sub (window-child parent))
1507 (setq skip (eq trail 'after))
1508 (while sub
1509 (cond
1510 ((eq sub window)
1511 (setq skip (eq trail 'before)))
1512 (skip)
1513 (t
1514 (let ((old-normal (window-normal-size sub horizontal)))
1515 (set-window-new-normal
1516 sub (min 1.0 ; Don't get larger than 1.
1517 (max (- old-normal
1518 (* (/ old-normal parent-normal)
1519 delta-normal))
1520 ;; Don't drop below 0.
1521 0.0))))))
1522 (setq sub (window-right sub)))
1523
1524 (when (numberp other-delta)
1525 ;; Set the new normal size of windows from what they should have
1526 ;; contributed for recovering OTHER-DELTA lines (columns).
1527 (setq delta-normal (/ (float (window-total-size parent horizontal))
1528 (+ (window-total-size parent horizontal)
1529 other-delta)))
1530 (setq sub (window-child parent))
1531 (setq skip (eq trail 'after))
1532 (while sub
1533 (cond
1534 ((eq sub window)
1535 (setq skip (eq trail 'before)))
1536 (skip)
1537 (t
1538 (set-window-new-normal
1539 sub (min 1.0 ; Don't get larger than 1.
1540 (max (* (window-new-normal sub) delta-normal)
1541 ;; Don't drop below 0.
1542 0.0)))))
1543 (setq sub (window-right sub))))
1544
1545 ;; Set the new normal size of WINDOW to what is left by the sum of
1546 ;; the normal sizes of its siblings.
1547 (set-window-new-normal
1548 window
1549 (let ((sum 0))
1550 (setq sub (window-child parent))
1551 (while sub
1552 (cond
1553 ((eq sub window))
1554 ((not (numberp (window-new-normal sub)))
1555 (setq sum (+ sum (window-normal-size sub horizontal))))
1556 (t
1557 (setq sum (+ sum (window-new-normal sub)))))
1558 (setq sub (window-right sub)))
1559 ;; Don't get larger than 1 or smaller than 0.
1560 (min 1.0 (max (- 1.0 sum) 0.0))))))
1561
1562(defun resize-subwindows (parent delta &optional horizontal window ignore trail edge)
1563 "Resize subwindows of window PARENT vertically by DELTA lines.
1564PARENT must be a vertically combined internal window.
1565
1566Optional argument HORIZONTAL non-nil means resize subwindows of
1567PARENT horizontally by DELTA columns. In this case PARENT must
1568be a horizontally combined internal window.
1569
1570WINDOW, if specified, must denote a child window of PARENT that
1571is resized by DELTA lines.
1572
1573Optional argument IGNORE non-nil means ignore any restrictions
1574imposed by fixed size windows, `window-min-height' or
1575`window-min-width' settings. IGNORE equal `safe' means live
1576windows may get as small as `window-safe-min-height' lines and
1577`window-safe-min-width' columns. IGNORE any window means ignore
1578restrictions for that window only.
1579
1580Optional arguments TRAIL and EDGE, when non-nil, restrict the set
1581of windows that shall be resized. If TRAIL equals `before',
1582resize only windows on the left or above EDGE. If TRAIL equals
1583`after', resize only windows on the right or below EDGE. Also,
1584preferably only resize windows adjacent to EDGE.
1585
1586Return the symbol `normalized' if new normal sizes have been
1587already set by this routine."
1588 (let* ((first (window-child parent))
1589 (sub first)
1590 (parent-total (+ (window-total-size parent horizontal) delta))
1591 best-window best-value)
1592
1593 (if (and edge (memq trail '(before after))
1594 (progn
1595 (setq sub first)
1596 (while (and (window-right sub)
1597 (or (and (eq trail 'before)
1598 (not (resize-subwindows-skip-p
1599 (window-right sub))))
1600 (and (eq trail 'after)
1601 (resize-subwindows-skip-p sub))))
1602 (setq sub (window-right sub)))
1603 sub)
1604 (if horizontal
1605 (if (eq trail 'before)
1606 (= (+ (window-left-column sub)
1607 (window-total-size sub t))
1608 edge)
1609 (= (window-left-column sub) edge))
1610 (if (eq trail 'before)
1611 (= (+ (window-top-line sub)
1612 (window-total-size sub))
1613 edge)
1614 (= (window-top-line sub) edge)))
1615 (window-sizable-p sub delta horizontal ignore))
1616 ;; Resize only windows adjacent to EDGE.
1617 (progn
1618 (resize-this-window sub delta horizontal ignore t trail edge)
1619 (if (and window (eq (window-parent sub) parent))
1620 (progn
1621 ;; Assign new normal sizes.
1622 (set-window-new-normal
1623 sub (/ (float (window-new-total sub)) parent-total))
1624 (set-window-new-normal
1625 window (- (window-normal-size window horizontal)
1626 (- (window-new-normal sub)
1627 (window-normal-size sub horizontal)))))
1628 (resize-subwindows-normal parent horizontal sub 0 trail delta))
1629 ;; Return 'normalized to notify `resize-other-windows' that
1630 ;; normal sizes have been already set.
1631 'normalized)
1632 ;; Resize all windows proportionally.
1633 (setq sub first)
1634 (while sub
1635 (cond
1636 ((or (resize-subwindows-skip-p sub)
1637 ;; Ignore windows to skip and fixed-size subwindows - in
1638 ;; the latter case make it a window to skip.
1639 (and (not ignore)
1640 (window-size-fixed-p sub horizontal)
1641 (set-window-new-normal sub 'ignore))))
1642 ((< delta 0)
1643 ;; When shrinking store the number of lines/cols we can get
1644 ;; from this window here together with the total/normal size
1645 ;; factor.
1646 (set-window-new-normal
1647 sub
1648 (cons
1649 ;; We used to call this with NODOWN t, "fixed" 2011-05-11.
1650 (window-min-delta sub horizontal ignore trail t) ; t)
1651 (- (/ (float (window-total-size sub horizontal))
1652 parent-total)
1653 (window-normal-size sub horizontal)))))
1654 ((> delta 0)
1655 ;; When enlarging store the total/normal size factor only
1656 (set-window-new-normal
1657 sub
1658 (- (/ (float (window-total-size sub horizontal))
1659 parent-total)
1660 (window-normal-size sub horizontal)))))
1661
1662 (setq sub (window-right sub)))
1663
1664 (cond
1665 ((< delta 0)
1666 ;; Shrink windows by delta.
1667 (setq best-window t)
1668 (while (and best-window (not (zerop delta)))
1669 (setq sub first)
1670 (setq best-window nil)
1671 (setq best-value most-negative-fixnum)
1672 (while sub
1673 (when (and (consp (window-new-normal sub))
1674 (not (zerop (car (window-new-normal sub))))
1675 (> (cdr (window-new-normal sub)) best-value))
1676 (setq best-window sub)
1677 (setq best-value (cdr (window-new-normal sub))))
1678
1679 (setq sub (window-right sub)))
1680
1681 (when best-window
1682 (setq delta (1+ delta)))
1683 (set-window-new-total best-window -1 t)
1684 (set-window-new-normal
1685 best-window
1686 (if (= (car (window-new-normal best-window)) 1)
1687 'skip ; We can't shrink best-window any further.
1688 (cons (1- (car (window-new-normal best-window)))
1689 (- (/ (float (window-new-total best-window))
1690 parent-total)
1691 (window-normal-size best-window horizontal)))))))
1692 ((> delta 0)
1693 ;; Enlarge windows by delta.
1694 (setq best-window t)
1695 (while (and best-window (not (zerop delta)))
1696 (setq sub first)
1697 (setq best-window nil)
1698 (setq best-value most-positive-fixnum)
1699 (while sub
1700 (when (and (numberp (window-new-normal sub))
1701 (< (window-new-normal sub) best-value))
1702 (setq best-window sub)
1703 (setq best-value (window-new-normal sub)))
1704
1705 (setq sub (window-right sub)))
1706
1707 (when best-window
1708 (setq delta (1- delta)))
1709 (set-window-new-total best-window 1 t)
1710 (set-window-new-normal
1711 best-window
1712 (- (/ (float (window-new-total best-window))
1713 parent-total)
1714 (window-normal-size best-window horizontal))))))
1715
1716 (when best-window
1717 (setq sub first)
1718 (while sub
1719 (when (or (consp (window-new-normal sub))
1720 (numberp (window-new-normal sub)))
1721 ;; Reset new normal size fields so `resize-window-apply'
1722 ;; won't use them to apply new sizes.
1723 (set-window-new-normal sub))
1724
1725 (unless (eq (window-new-normal sub) 'ignore)
1726 ;; Resize this subwindow's subwindows (back-engineering
1727 ;; delta from sub's old and new total sizes).
1728 (let ((delta (- (window-new-total sub)
1729 (window-total-size sub horizontal))))
1730 (unless (and (zerop delta) (not trail))
1731 ;; For the TRAIL non-nil case we have to resize SUB
1732 ;; recursively even if it's size does not change.
1733 (resize-this-window
1734 sub delta horizontal ignore nil trail edge))))
1735 (setq sub (window-right sub)))))))
1736
1737(defun resize-other-windows (window delta &optional horizontal ignore trail edge)
1738 "Resize other windows when WINDOW is resized vertically by DELTA lines.
1739Optional argument HORIZONTAL non-nil means resize other windows
1740when WINDOW is resized horizontally by DELTA columns. WINDOW
1741itself is not resized by this function.
1315 1742
1743Optional argument IGNORE non-nil means ignore any restrictions
1744imposed by fixed size windows, `window-min-height' or
1745`window-min-width' settings. IGNORE equal `safe' means live
1746windows may get as small as `window-safe-min-height' lines and
1747`window-safe-min-width' columns. IGNORE any window means ignore
1748restrictions for that window only.
1749
1750Optional arguments TRAIL and EDGE, when non-nil, refine the set
1751of windows that shall be resized. If TRAIL equals `before',
1752resize only windows on the left or above EDGE. If TRAIL equals
1753`after', resize only windows on the right or below EDGE. Also,
1754preferably only resize windows adjacent to EDGE."
1755 (when (window-parent window)
1756 (let* ((parent (window-parent window))
1757 (sub (window-child parent)))
1758 (if (window-iso-combined-p sub horizontal)
1759 ;; In an iso-combination try to extract DELTA from WINDOW's
1760 ;; siblings.
1761 (let ((first sub)
1762 (skip (eq trail 'after))
1763 this-delta other-delta)
1764 ;; Decide which windows shall be left alone.
1765 (while sub
1766 (cond
1767 ((eq sub window)
1768 ;; Make sure WINDOW is left alone when
1769 ;; resizing its siblings.
1770 (set-window-new-normal sub 'ignore)
1771 (setq skip (eq trail 'before)))
1772 (skip
1773 ;; Make sure this sibling is left alone when
1774 ;; resizing its siblings.
1775 (set-window-new-normal sub 'ignore))
1776 ((or (window-size-ignore sub ignore)
1777 (not (window-size-fixed-p sub horizontal)))
1778 ;; Set this-delta to t to signal that we found a sibling
1779 ;; of WINDOW whose size is not fixed.
1780 (setq this-delta t)))
1781
1782 (setq sub (window-right sub)))
1783
1784 ;; Set this-delta to what we can get from WINDOW's siblings.
1785 (if (= (- delta) (window-total-size window horizontal))
1786 ;; A deletion, presumably. We must handle this case
1787 ;; specially since `window-resizable' can't be used.
1788 (if this-delta
1789 ;; There's at least one resizable sibling we can
1790 ;; give WINDOW's size to.
1791 (setq this-delta delta)
1792 ;; No resizable sibling exists.
1793 (setq this-delta 0))
1794 ;; Any other form of resizing.
1795 (setq this-delta
1796 (window-resizable window delta horizontal ignore trail t)))
1797
1798 ;; Set other-delta to what we still have to get from
1799 ;; ancestor windows of parent.
1800 (setq other-delta (- delta this-delta))
1801 (unless (zerop other-delta)
1802 ;; Unless we got everything from WINDOW's siblings, PARENT
1803 ;; must be resized by other-delta lines or columns.
1804 (set-window-new-total parent other-delta 'add))
1805
1806 (if (zerop this-delta)
1807 ;; We haven't got anything from WINDOW's siblings but we
1808 ;; must update the normal sizes to respect other-delta.
1809 (resize-subwindows-normal
1810 parent horizontal window this-delta trail other-delta)
1811 ;; We did get something from WINDOW's siblings which means
1812 ;; we have to resize their subwindows.
1813 (unless (eq (resize-subwindows parent (- this-delta) horizontal
1814 window ignore trail edge)
1815 ;; `resize-subwindows' returning 'normalized,
1816 ;; means it has set the normal sizes already.
1817 'normalized)
1818 ;; Set the normal sizes.
1819 (resize-subwindows-normal
1820 parent horizontal window this-delta trail other-delta))
1821 ;; Set DELTA to what we still have to get from ancestor
1822 ;; windows.
1823 (setq delta other-delta)))
1824
1825 ;; In an ortho-combination all siblings of WINDOW must be
1826 ;; resized by DELTA.
1827 (set-window-new-total parent delta 'add)
1828 (while sub
1829 (unless (eq sub window)
1830 (resize-this-window sub delta horizontal ignore t))
1831 (setq sub (window-right sub))))
1832
1833 (unless (zerop delta)
1834 ;; "Go up."
1835 (resize-other-windows parent delta horizontal ignore trail edge)))))
1836
1837(defun resize-this-window (window delta &optional horizontal ignore add trail edge)
1838 "Resize WINDOW vertically by DELTA lines.
1839Optional argument HORIZONTAL non-nil means resize WINDOW
1840horizontally by DELTA columns.
1841
1842Optional argument IGNORE non-nil means ignore any restrictions
1843imposed by fixed size windows, `window-min-height' or
1844`window-min-width' settings. IGNORE equal `safe' means live
1845windows may get as small as `window-safe-min-height' lines and
1846`window-safe-min-width' columns. IGNORE any window means ignore
1847restrictions for that window only.
1848
1849Optional argument ADD non-nil means add DELTA to the new total
1850size of WINDOW.
1851
1852Optional arguments TRAIL and EDGE, when non-nil, refine the set
1853of windows that shall be resized. If TRAIL equals `before',
1854resize only windows on the left or above EDGE. If TRAIL equals
1855`after', resize only windows on the right or below EDGE. Also,
1856preferably only resize windows adjacent to EDGE.
1857
1858This function recursively resizes WINDOW's subwindows to fit the
1859new size. Make sure that WINDOW is `window-resizable' before
1860calling this function. Note that this function does not resize
1861siblings of WINDOW or WINDOW's parent window. You have to
1862eventually call `resize-window-apply' in order to make resizing
1863actually take effect."
1864 (when add
1865 ;; Add DELTA to the new total size of WINDOW.
1866 (set-window-new-total window delta t))
1867
1868 (let ((sub (window-child window)))
1869 (cond
1870 ((not sub))
1871 ((window-iso-combined-p sub horizontal)
1872 ;; In an iso-combination resize subwindows according to their
1873 ;; normal sizes.
1874 (resize-subwindows window delta horizontal nil ignore trail edge))
1875 ;; In an ortho-combination resize each subwindow by DELTA.
1876 (t
1877 (while sub
1878 (resize-this-window sub delta horizontal ignore t trail edge)
1879 (setq sub (window-right sub)))))))
1880
1881(defun resize-root-window (window delta horizontal ignore)
1882 "Resize root window WINDOW vertically by DELTA lines.
1883HORIZONTAL non-nil means resize root window WINDOW horizontally
1884by DELTA columns.
1885
1886IGNORE non-nil means ignore any restrictions imposed by fixed
1887size windows, `window-min-height' or `window-min-width' settings.
1888
1889This function is only called by the frame resizing routines. It
1890resizes windows proportionally and never deletes any windows."
1891 (when (and (windowp window) (numberp delta)
1892 (window-sizable-p window delta horizontal ignore))
1893 (resize-window-reset (window-frame window) horizontal)
1894 (resize-this-window window delta horizontal ignore t)))
1895
1896(defun resize-root-window-vertically (window delta)
1897 "Resize root window WINDOW vertically by DELTA lines.
1898If DELTA is less than zero and we can't shrink WINDOW by DELTA
1899lines, shrink it as much as possible. If DELTA is greater than
1900zero, this function can resize fixed-size subwindows in order to
1901recover the necessary lines.
1902
1903Return the number of lines that were recovered.
1904
1905This function is only called by the minibuffer window resizing
1906routines. It resizes windows proportionally and never deletes
1907any windows."
1908 (when (numberp delta)
1909 (let (ignore)
1910 (cond
1911 ((< delta 0)
1912 (setq delta (window-sizable window delta)))
1913 ((> delta 0)
1914 (unless (window-sizable window delta)
1915 (setq ignore t))))
1916
1917 (resize-window-reset (window-frame window))
1918 ;; Ideally, we would resize just the last window in a combination
1919 ;; but that's not feasible for the following reason: If we grow
1920 ;; the minibuffer window and the last window cannot be shrunk any
1921 ;; more, we shrink another window instead. But if we then shrink
1922 ;; the minibuffer window again, the last window might get enlarged
1923 ;; and the state after shrinking is not the state before growing.
1924 ;; So, in practice, we'd need a history variable to record how to
1925 ;; proceed. But I'm not sure how such a variable could work with
1926 ;; repeated minibuffer window growing steps.
1927 (resize-this-window window delta nil ignore t)
1928 delta)))
1929
1930(defun adjust-window-trailing-edge (window delta &optional horizontal)
1931 "Move WINDOW's bottom edge by DELTA lines.
1932Optional argument HORIZONTAL non-nil means move WINDOW's right
1933edge by DELTA columns. WINDOW defaults to the selected window.
1934
1935If DELTA is greater zero, then move the edge downwards or to the
1936right. If DELTA is less than zero, move the edge upwards or to
1937the left. If the edge can't be moved by DELTA lines or columns,
1938move it as far as possible in the desired direction."
1939 (setq window (normalize-any-window window))
1940 (let ((frame (window-frame window))
1941 (right window)
1942 left this-delta min-delta max-delta failed)
1943 ;; Find the edge we want to move.
1944 (while (and (or (not (window-iso-combined-p right horizontal))
1945 (not (window-right right)))
1946 (setq right (window-parent right))))
1947 (cond
1948 ((and (not right) (not horizontal) (not resize-mini-windows)
1949 (eq (window-frame (minibuffer-window frame)) frame))
1950 (resize-mini-window (minibuffer-window frame) (- delta)))
1951 ((or (not (setq left right)) (not (setq right (window-right right))))
1952 (if horizontal
1953 (error "No window on the right of this one")
1954 (error "No window below this one")))
1955 (t
1956 ;; Set LEFT to the first resizable window on the left. This step is
1957 ;; needed to handle fixed-size windows.
1958 (while (and left (window-size-fixed-p left horizontal))
1959 (setq left
1960 (or (window-left left)
1961 (progn
1962 (while (and (setq left (window-parent left))
1963 (not (window-iso-combined-p left horizontal))))
1964 (window-left left)))))
1965 (unless left
1966 (if horizontal
1967 (error "No resizable window on the left of this one")
1968 (error "No resizable window above this one")))
1969
1970 ;; Set RIGHT to the first resizable window on the right. This step
1971 ;; is needed to handle fixed-size windows.
1972 (while (and right (window-size-fixed-p right horizontal))
1973 (setq right
1974 (or (window-right right)
1975 (progn
1976 (while (and (setq right (window-parent right))
1977 (not (window-iso-combined-p right horizontal))))
1978 (window-right right)))))
1979 (unless right
1980 (if horizontal
1981 (error "No resizable window on the right of this one")
1982 (error "No resizable window below this one")))
1983
1984 ;; LEFT and RIGHT (which might be both internal windows) are now the
1985 ;; two windows we want to resize.
1986 (cond
1987 ((> delta 0)
1988 (setq max-delta (window-max-delta-1 left 0 horizontal nil 'after))
1989 (setq min-delta (window-min-delta-1 right (- delta) horizontal nil 'before))
1990 (when (or (< max-delta delta) (> min-delta (- delta)))
1991 ;; We can't get the whole DELTA - move as far as possible.
1992 (setq delta (min max-delta (- min-delta))))
1993 (unless (zerop delta)
1994 ;; Start resizing.
1995 (resize-window-reset frame horizontal)
1996 ;; Try to enlarge LEFT first.
1997 (setq this-delta (window-resizable left delta horizontal))
1998 (unless (zerop this-delta)
1999 (resize-this-window
2000 left this-delta horizontal nil t 'before
2001 (if horizontal
2002 (+ (window-left-column left) (window-total-size left t))
2003 (+ (window-top-line left) (window-total-size left)))))
2004 ;; Shrink windows on right of LEFT.
2005 (resize-other-windows
2006 left delta horizontal nil 'after
2007 (if horizontal
2008 (window-left-column right)
2009 (window-top-line right)))))
2010 ((< delta 0)
2011 (setq max-delta (window-max-delta-1 right 0 horizontal nil 'before))
2012 (setq min-delta (window-min-delta-1 left delta horizontal nil 'after))
2013 (when (or (< max-delta (- delta)) (> min-delta delta))
2014 ;; We can't get the whole DELTA - move as far as possible.
2015 (setq delta (max (- max-delta) min-delta)))
2016 (unless (zerop delta)
2017 ;; Start resizing.
2018 (resize-window-reset frame horizontal)
2019 ;; Try to enlarge RIGHT.
2020 (setq this-delta (window-resizable right (- delta) horizontal))
2021 (unless (zerop this-delta)
2022 (resize-this-window
2023 right this-delta horizontal nil t 'after
2024 (if horizontal
2025 (window-left-column right)
2026 (window-top-line right))))
2027 ;; Shrink windows on left of RIGHT.
2028 (resize-other-windows
2029 right (- delta) horizontal nil 'before
2030 (if horizontal
2031 (+ (window-left-column left) (window-total-size left t))
2032 (+ (window-top-line left) (window-total-size left)))))))
2033 (unless (zerop delta)
2034 ;; Don't report an error in the standard case.
2035 (unless (resize-window-apply frame horizontal)
2036 ;; But do report an error if applying the changes fails.
2037 (error "Failed adjusting window %s" window)))))))
2038
2039(defun enlarge-window (delta &optional horizontal)
2040 "Make selected window DELTA lines taller.
2041Interactively, if no argument is given, make the selected window
2042one line taller. If optional argument HORIZONTAL is non-nil,
2043make selected window wider by DELTA columns. If DELTA is
2044negative, shrink selected window by -DELTA lines or columns.
2045Return nil."
2046 (interactive "p")
2047 (resize-window (selected-window) delta horizontal))
2048
2049(defun shrink-window (delta &optional horizontal)
2050 "Make selected window DELTA lines smaller.
2051Interactively, if no argument is given, make the selected window
2052one line smaller. If optional argument HORIZONTAL is non-nil,
2053make selected window narrower by DELTA columns. If DELTA is
2054negative, enlarge selected window by -DELTA lines or columns.
2055Return nil."
2056 (interactive "p")
2057 (resize-window (selected-window) (- delta) horizontal))
2058
2059(defun maximize-window (&optional window)
2060 "Maximize WINDOW.
2061Make WINDOW as large as possible without deleting any windows.
2062WINDOW can be any window and defaults to the selected window."
2063 (interactive)
2064 (setq window (normalize-any-window window))
2065 (resize-window window (window-max-delta window))
2066 (resize-window window (window-max-delta window t) t))
2067
2068(defun minimize-window (&optional window)
2069 "Minimize WINDOW.
2070Make WINDOW as small as possible without deleting any windows.
2071WINDOW can be any window and defaults to the selected window."
2072 (interactive)
2073 (setq window (normalize-any-window window))
2074 (resize-window window (- (window-min-delta window)))
2075 (resize-window window (- (window-min-delta window t)) t))
2076
2077(defsubst frame-root-window-p (window)
2078 "Return non-nil if WINDOW is the root window of its frame."
2079 (eq window (frame-root-window window)))
2080
1316;; This should probably return non-nil when the selected window is part 2081;; This should probably return non-nil when the selected window is part
1317;; of an atomic window whose root is the frame's root window. 2082;; of an atomic window whose root is the frame's root window.
1318(defun one-window-p (&optional nomini all-frames) 2083(defun one-window-p (&optional nomini all-frames)
@@ -1347,6 +2112,501 @@ and no others."
1347 (eq base-window 2112 (eq base-window
1348 (next-window base-window (if nomini 'arg) all-frames)))) 2113 (next-window base-window (if nomini 'arg) all-frames))))
1349 2114
2115;;; Deleting windows.
2116(defun window-deletable-p (&optional window)
2117 "Return t if WINDOW can be safely deleted from its frame.
2118Return `frame' if deleting WINDOW should delete its frame
2119instead."
2120 (setq window (normalize-any-window window))
2121 (unless ignore-window-parameters
2122 ;; Handle atomicity.
2123 (when (window-parameter window 'window-atom)
2124 (setq window (window-atom-root window))))
2125 (let ((parent (window-parent window))
2126 (frame (window-frame window))
2127 (dedicated (and (window-buffer window) (window-dedicated-p window)))
2128 (quit-restore (window-parameter window 'quit-restore)))
2129 (cond
2130 ((frame-root-window-p window)
2131 (when (and (or dedicated
2132 (and (eq (car-safe quit-restore) 'new-frame)
2133 (eq (nth 1 quit-restore) (window-buffer window))))
2134 (other-visible-frames-p frame))
2135 ;; WINDOW is the root window of its frame. Return `frame' but
2136 ;; only if WINDOW is (1) either dedicated or quit-restore's car
2137 ;; is new-frame and the window still displays the same buffer
2138 ;; and (2) there are other frames left.
2139 'frame))
2140 ((and (not ignore-window-parameters)
2141 (eq (window-parameter window 'window-side) 'none)
2142 (or (not parent)
2143 (not (eq (window-parameter parent 'window-side) 'none))))
2144 ;; Can't delete last main window.
2145 nil)
2146 (t))))
2147
2148(defun window-or-subwindow-p (subwindow window)
2149 "Return t if SUBWINDOW is either WINDOW or a subwindow of WINDOW."
2150 (or (eq subwindow window)
2151 (let ((parent (window-parent subwindow)))
2152 (catch 'done
2153 (while parent
2154 (if (eq parent window)
2155 (throw 'done t)
2156 (setq parent (window-parent parent))))))))
2157
2158(defun delete-window (&optional window)
2159 "Delete WINDOW.
2160WINDOW can be an arbitrary window and defaults to the selected
2161one. Return nil.
2162
2163If the variable `ignore-window-parameters' is non-nil or the
2164`delete-window' parameter of WINDOW equals t, do not process any
2165parameters of WINDOW. Otherwise, if the `delete-window'
2166parameter of WINDOW specifies a function, call that function with
2167WINDOW as its sole argument and return the value returned by that
2168function.
2169
2170Otherwise, if WINDOW is part of an atomic window, call
2171`delete-window' with the root of the atomic window as its
2172argument. If WINDOW is the only window on its frame or the last
2173non-side window, signal an error."
2174 (interactive)
2175 (setq window (normalize-any-window window))
2176 (let* ((frame (window-frame window))
2177 (function (window-parameter window 'delete-window))
2178 (parent (window-parent window))
2179 atom-root)
2180 (window-check frame)
2181 (catch 'done
2182 ;; Handle window parameters.
2183 (cond
2184 ;; Ignore window parameters if `ignore-window-parameters' tells
2185 ;; us so or `delete-window' equals t.
2186 ((or ignore-window-parameters (eq function t)))
2187 ((functionp function)
2188 ;; The `delete-window' parameter specifies the function to call.
2189 ;; If that function is `ignore' nothing is done. It's up to the
2190 ;; function called here to avoid infinite recursion.
2191 (throw 'done (funcall function window)))
2192 ((and (window-parameter window 'window-atom)
2193 (setq atom-root (window-atom-root window))
2194 (not (eq atom-root window)))
2195 (throw 'done (delete-window atom-root)))
2196 ((and (eq (window-parameter window 'window-side) 'none)
2197 (or (not parent)
2198 (not (eq (window-parameter parent 'window-side) 'none))))
2199 (error "Attempt to delete last non-side window"))
2200 ((not parent)
2201 (error "Attempt to delete minibuffer or sole ordinary window")))
2202
2203 (let* ((horizontal (window-hchild parent))
2204 (size (window-total-size window horizontal))
2205 (frame-selected
2206 (window-or-subwindow-p (frame-selected-window frame) window))
2207 ;; Emacs 23 preferably gives WINDOW's space to its left
2208 ;; sibling.
2209 (sibling (or (window-left window) (window-right window))))
2210 (resize-window-reset frame horizontal)
2211 (cond
2212 ((and (not (window-splits window))
2213 sibling (window-sizable-p sibling size))
2214 ;; Resize WINDOW's sibling.
2215 (resize-this-window sibling size horizontal nil t)
2216 (set-window-new-normal
2217 sibling (+ (window-normal-size sibling horizontal)
2218 (window-normal-size window horizontal))))
2219 ((window-resizable-p window (- size) horizontal nil nil nil t)
2220 ;; Can do without resizing fixed-size windows.
2221 (resize-other-windows window (- size) horizontal))
2222 (t
2223 ;; Can't do without resizing fixed-size windows.
2224 (resize-other-windows window (- size) horizontal t)))
2225 ;; Actually delete WINDOW.
2226 (delete-window-internal window)
2227 (when (and frame-selected
2228 (window-parameter
2229 (frame-selected-window frame) 'no-other-window))
2230 ;; `delete-window-internal' has selected a window that should
2231 ;; not be selected, fix this here.
2232 (other-window -1 frame))
2233 (run-window-configuration-change-hook frame)
2234 (window-check frame)
2235 ;; Always return nil.
2236 nil))))
2237
2238(defun delete-other-windows (&optional window)
2239 "Make WINDOW fill its frame.
2240WINDOW may be any window and defaults to the selected one.
2241Return nil.
2242
2243If the variable `ignore-window-parameters' is non-nil or the
2244`delete-other-windows' parameter of WINDOW equals t, do not
2245process any parameters of WINDOW. Otherwise, if the
2246`delete-other-windows' parameter of WINDOW specifies a function,
2247call that function with WINDOW as its sole argument and return
2248the value returned by that function.
2249
2250Otherwise, if WINDOW is part of an atomic window, call this
2251function with the root of the atomic window as its argument. If
2252WINDOW is a non-side window, make WINDOW the only non-side window
2253on the frame. Side windows are not deleted. If WINDOW is a side
2254window signal an error."
2255 (interactive)
2256 (setq window (normalize-any-window window))
2257 (let* ((frame (window-frame window))
2258 (function (window-parameter window 'delete-other-windows))
2259 (window-side (window-parameter window 'window-side))
2260 atom-root side-main)
2261 (window-check frame)
2262 (catch 'done
2263 (cond
2264 ;; Ignore window parameters if `ignore-window-parameters' is t or
2265 ;; `delete-other-windows' is t.
2266 ((or ignore-window-parameters (eq function t)))
2267 ((functionp function)
2268 ;; The `delete-other-windows' parameter specifies the function
2269 ;; to call. If the function is `ignore' no windows are deleted.
2270 ;; It's up to the function called to avoid infinite recursion.
2271 (throw 'done (funcall function window)))
2272 ((and (window-parameter window 'window-atom)
2273 (setq atom-root (window-atom-root window))
2274 (not (eq atom-root window)))
2275 (throw 'done (delete-other-windows atom-root)))
2276 ((eq window-side 'none)
2277 ;; Set side-main to the major non-side window.
2278 (setq side-main (window-with-parameter 'window-side 'none nil t)))
2279 ((memq window-side window-sides)
2280 (error "Cannot make side window the only window")))
2281 ;; If WINDOW is the main non-side window, do nothing.
2282 (unless (eq window side-main)
2283 (delete-other-windows-internal window side-main)
2284 (run-window-configuration-change-hook frame)
2285 (window-check frame))
2286 ;; Always return nil.
2287 nil)))
2288
2289;;; Splitting windows.
2290(defsubst window-split-min-size (&optional horizontal)
2291 "Return minimum height of any window when splitting windows.
2292Optional argument HORIZONTAL non-nil means return minimum width."
2293 (if horizontal
2294 (max window-min-width window-safe-min-width)
2295 (max window-min-height window-safe-min-height)))
2296
2297(defun split-window (&optional window size side)
2298 "Make a new window adjacent to WINDOW.
2299WINDOW can be any window and defaults to the selected one.
2300Return the new window which is always a live window.
2301
2302Optional argument SIZE a positive number means make WINDOW SIZE
2303lines or columns tall. If SIZE is negative, make the new window
2304-SIZE lines or columns tall. If and only if SIZE is non-nil, its
2305absolute value can be less than `window-min-height' or
2306`window-min-width'; so this command can make a new window as
2307small as one line or two columns. SIZE defaults to half of
2308WINDOW's size. Interactively, SIZE is the prefix argument.
2309
2310Optional third argument SIDE nil (or `below') specifies that the
2311new window shall be located below WINDOW. SIDE `above' means the
2312new window shall be located above WINDOW. In both cases SIZE
2313specifies the new number of lines for WINDOW \(or the new window
2314if SIZE is negative) including space reserved for the mode and/or
2315header line.
2316
2317SIDE t (or `right') specifies that the new window shall be
2318located on the right side of WINDOW. SIDE `left' means the new
2319window shall be located on the left of WINDOW. In both cases
2320SIZE specifies the new number of columns for WINDOW \(or the new
2321window provided SIZE is negative) including space reserved for
2322fringes and the scrollbar or a divider column. Any other non-nil
2323value for SIDE is currently handled like t (or `right').
2324
2325If the variable `ignore-window-parameters' is non-nil or the
2326`split-window' parameter of WINDOW equals t, do not process any
2327parameters of WINDOW. Otherwise, if the `split-window' parameter
2328of WINDOW specifies a function, call that function with all three
2329arguments and return the value returned by that function.
2330
2331Otherwise, if WINDOW is part of an atomic window, \"split\" the
2332root of that atomic window. The new window does not become a
2333member of that atomic window.
2334
2335If WINDOW is live, properties of the new window like margins and
2336scrollbars are inherited from WINDOW. If WINDOW is an internal
2337window, these properties as well as the buffer displayed in the
2338new window are inherited from the window selected on WINDOW's
2339frame. The selected window is not changed by this function."
2340 (interactive "i")
2341 (setq window (normalize-any-window window))
2342 (let* ((horizontal (not (memq side '(nil below above))))
2343 (frame (window-frame window))
2344 (parent (window-parent window))
2345 (function (window-parameter window 'split-window))
2346 (window-side (window-parameter window 'window-side))
2347 ;; Rebind `window-nest' since in some cases we may have to
2348 ;; override its value.
2349 (window-nest window-nest)
2350 atom-root)
2351
2352 (window-check frame)
2353 (catch 'done
2354 (cond
2355 ;; Ignore window parameters if either `ignore-window-parameters'
2356 ;; is t or the `split-window' parameter equals t.
2357 ((or ignore-window-parameters (eq function t)))
2358 ((functionp function)
2359 ;; The `split-window' parameter specifies the function to call.
2360 ;; If that function is `ignore', do nothing.
2361 (throw 'done (funcall function window size side)))
2362 ;; If WINDOW is a subwindow of an atomic window, split the root
2363 ;; window of that atomic window instead.
2364 ((and (window-parameter window 'window-atom)
2365 (setq atom-root (window-atom-root window))
2366 (not (eq atom-root window)))
2367 (throw 'done (split-window atom-root size side))))
2368
2369 (when (and window-side
2370 (or (not parent)
2371 (not (window-parameter parent 'window-side))))
2372 ;; WINDOW is a side root window. To make sure that a new parent
2373 ;; window gets created set `window-nest' to t.
2374 (setq window-nest t))
2375
2376 (when (and window-splits size (> size 0))
2377 ;; If `window-splits' is non-nil and SIZE is a non-negative
2378 ;; integer, we cannot reasonably resize other windows. Rather
2379 ;; bind `window-nest' to t to make sure that subsequent window
2380 ;; deletions are handled correctly.
2381 (setq window-nest t))
2382
2383 (let* ((parent-size
2384 ;; `parent-size' is the size of WINDOW's parent, provided
2385 ;; it has one.
2386 (when parent (window-total-size parent horizontal)))
2387 ;; `resize' non-nil means we are supposed to resize other
2388 ;; windows in WINDOW's combination.
2389 (resize
2390 (and window-splits (not window-nest)
2391 ;; Resize makes sense in iso-combinations only.
2392 (window-iso-combined-p window horizontal)))
2393 ;; `old-size' is the current size of WINDOW.
2394 (old-size (window-total-size window horizontal))
2395 ;; `new-size' is the specified or calculated size of the
2396 ;; new window.
2397 (new-size
2398 (cond
2399 ((not size)
2400 (max (window-split-min-size horizontal)
2401 (if resize
2402 ;; When resizing try to give the new window the
2403 ;; average size of a window in its combination.
2404 (min (- parent-size
2405 (window-min-size parent horizontal))
2406 (/ parent-size
2407 (1+ (window-iso-combinations
2408 parent horizontal))))
2409 ;; Else try to give the new window half the size
2410 ;; of WINDOW (plus an eventual odd line).
2411 (+ (/ old-size 2) (% old-size 2)))))
2412 ((>= size 0)
2413 ;; SIZE non-negative specifies the new size of WINDOW.
2414
2415 ;; Note: Specifying a non-negative SIZE is practically
2416 ;; always done as workaround for making the new window
2417 ;; appear above or on the left of the new window (the
2418 ;; ispell window is a typical example of that). In all
2419 ;; these cases the SIDE argument should be set to 'above
2420 ;; or 'left in order to support the 'resize option.
2421 ;; Here we have to nest the windows instead, see above.
2422 (- old-size size))
2423 (t
2424 ;; SIZE negative specifies the size of the new window.
2425 (- size))))
2426 new-parent new-normal)
2427
2428 ;; Check SIZE.
2429 (cond
2430 ((not size)
2431 (cond
2432 (resize
2433 ;; SIZE unspecified, resizing.
2434 (when (and (not (window-sizable-p parent (- new-size) horizontal))
2435 ;; Try again with minimum split size.
2436 (setq new-size
2437 (max new-size (window-split-min-size horizontal)))
2438 (not (window-sizable-p parent (- new-size) horizontal)))
2439 (error "Window %s too small for splitting" parent)))
2440 ((> (+ new-size (window-min-size window horizontal)) old-size)
2441 ;; SIZE unspecified, no resizing.
2442 (error "Window %s too small for splitting" window))))
2443 ((and (>= size 0)
2444 (or (>= size old-size)
2445 (< new-size (if horizontal
2446 window-safe-min-width
2447 window-safe-min-width))))
2448 ;; SIZE specified as new size of old window. If the new size
2449 ;; is larger than the old size or the size of the new window
2450 ;; would be less than the safe minimum, signal an error.
2451 (error "Window %s too small for splitting" window))
2452 (resize
2453 ;; SIZE specified, resizing.
2454 (unless (window-sizable-p parent (- new-size) horizontal)
2455 ;; If we cannot resize the parent give up.
2456 (error "Window %s too small for splitting" parent)))
2457 ((or (< new-size
2458 (if horizontal window-safe-min-width window-safe-min-height))
2459 (< (- old-size new-size)
2460 (if horizontal window-safe-min-width window-safe-min-height)))
2461 ;; SIZE specification violates minimum size restrictions.
2462 (error "Window %s too small for splitting" window)))
2463
2464 (resize-window-reset frame horizontal)
2465
2466 (setq new-parent
2467 ;; Make new-parent non-nil if we need a new parent window;
2468 ;; either because we want to nest or because WINDOW is not
2469 ;; iso-combined.
2470 (or window-nest (not (window-iso-combined-p window horizontal))))
2471 (setq new-normal
2472 ;; Make new-normal the normal size of the new window.
2473 (cond
2474 (size (/ (float new-size) (if new-parent old-size parent-size)))
2475 (new-parent 0.5)
2476 (resize (/ 1.0 (1+ (window-iso-combinations parent horizontal))))
2477 (t (/ (window-normal-size window horizontal) 2.0))))
2478
2479 (if resize
2480 ;; Try to get space from OLD's siblings. We could go "up" and
2481 ;; try getting additional space from surrounding windows but
2482 ;; we won't be able to return space to those windows when we
2483 ;; delete the one we create here. Hence we do not go up.
2484 (progn
2485 (resize-subwindows parent (- new-size) horizontal)
2486 (let* ((normal (- 1.0 new-normal))
2487 (sub (window-child parent)))
2488 (while sub
2489 (set-window-new-normal
2490 sub (* (window-normal-size sub horizontal) normal))
2491 (setq sub (window-right sub)))))
2492 ;; Get entire space from WINDOW.
2493 (set-window-new-total window (- old-size new-size))
2494 (resize-this-window window (- new-size) horizontal)
2495 (set-window-new-normal
2496 window (- (if new-parent 1.0 (window-normal-size window horizontal))
2497 new-normal)))
2498
2499 (let* ((new (split-window-internal window new-size side new-normal)))
2500 ;; Inherit window-side parameters, if any.
2501 (when (and window-side new-parent)
2502 (set-window-parameter (window-parent new) 'window-side window-side)
2503 (set-window-parameter new 'window-side window-side))
2504
2505 (run-window-configuration-change-hook frame)
2506 (window-check frame)
2507 ;; Always return the new window.
2508 new)))))
2509
2510;; I think this should be the default; I think people will prefer it--rms.
2511(defcustom split-window-keep-point t
2512 "If non-nil, \\[split-window-above-each-other] keeps the original point \
2513in both children.
2514This is often more convenient for editing.
2515If nil, adjust point in each of the two windows to minimize redisplay.
2516This is convenient on slow terminals, but point can move strangely.
2517
2518This option applies only to `split-window-above-each-other' and
2519functions that call it. `split-window' always keeps the original
2520point in both children."
2521 :type 'boolean
2522 :group 'windows)
2523
2524(defun split-window-above-each-other (&optional size)
2525 "Split selected window into two windows, one above the other.
2526The upper window gets SIZE lines and the lower one gets the rest.
2527SIZE negative means the lower window gets -SIZE lines and the
2528upper one the rest. With no argument, split windows equally or
2529close to it. Both windows display the same buffer, now current.
2530
2531If the variable `split-window-keep-point' is non-nil, both new
2532windows will get the same value of point as the selected window.
2533This is often more convenient for editing. The upper window is
2534the selected window.
2535
2536Otherwise, we choose window starts so as to minimize the amount of
2537redisplay; this is convenient on slow terminals. The new selected
2538window is the one that the current value of point appears in. The
2539value of point can change if the text around point is hidden by the
2540new mode line.
2541
2542Regardless of the value of `split-window-keep-point', the upper
2543window is the original one and the return value is the new, lower
2544window."
2545 (interactive "P")
2546 (let ((old-window (selected-window))
2547 (old-point (point))
2548 (size (and size (prefix-numeric-value size)))
2549 moved-by-window-height moved new-window bottom)
2550 (when (and size (< size 0) (< (- size) window-min-height))
2551 ;; `split-window' would not signal an error here.
2552 (error "Size of new window too small"))
2553 (setq new-window (split-window nil size))
2554 (unless split-window-keep-point
2555 (with-current-buffer (window-buffer)
2556 (goto-char (window-start))
2557 (setq moved (vertical-motion (window-height)))
2558 (set-window-start new-window (point))
2559 (when (> (point) (window-point new-window))
2560 (set-window-point new-window (point)))
2561 (when (= moved (window-height))
2562 (setq moved-by-window-height t)
2563 (vertical-motion -1))
2564 (setq bottom (point)))
2565 (and moved-by-window-height
2566 (<= bottom (point))
2567 (set-window-point old-window (1- bottom)))
2568 (and moved-by-window-height
2569 (<= (window-start new-window) old-point)
2570 (set-window-point new-window old-point)
2571 (select-window new-window)))
2572 (split-window-save-restore-data new-window old-window)))
2573
2574(defalias 'split-window-vertically 'split-window-above-each-other)
2575
2576;; This is to avoid compiler warnings.
2577(defvar view-return-to-alist)
2578
2579(defun split-window-save-restore-data (new-window old-window)
2580 (with-current-buffer (window-buffer)
2581 (when view-mode
2582 (let ((old-info (assq old-window view-return-to-alist)))
2583 (when old-info
2584 (push (cons new-window (cons (car (cdr old-info)) t))
2585 view-return-to-alist))))
2586 new-window))
2587
2588(defun split-window-side-by-side (&optional size)
2589 "Split selected window into two windows side by side.
2590The selected window becomes the left one and gets SIZE columns.
2591SIZE negative means the right window gets -SIZE lines.
2592
2593SIZE includes the width of the window's scroll bar; if there are
2594no scroll bars, it includes the width of the divider column to
2595the window's right, if any. SIZE omitted or nil means split
2596window equally.
2597
2598The selected window remains selected. Return the new window."
2599 (interactive "P")
2600 (let ((old-window (selected-window))
2601 (size (and size (prefix-numeric-value size)))
2602 new-window)
2603 (when (and size (< size 0) (< (- size) window-min-width))
2604 ;; `split-window' would not signal an error here.
2605 (error "Size of new window too small"))
2606 (split-window-save-restore-data (split-window nil size t) old-window)))
2607
2608(defalias 'split-window-horizontally 'split-window-side-by-side)
2609
1350;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2610;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1351;;; `balance-windows' subroutines using `window-tree' 2611;;; `balance-windows' subroutines using `window-tree'
1352 2612
@@ -2327,102 +3587,6 @@ at the front of the list of recently selected ones."
2327 ;; input focus and is risen. 3587 ;; input focus and is risen.
2328 (select-frame-set-input-focus new-frame)) 3588 (select-frame-set-input-focus new-frame))
2329 buffer)) 3589 buffer))
2330
2331;; I think this should be the default; I think people will prefer it--rms.
2332(defcustom split-window-keep-point t
2333 "If non-nil, \\[split-window-vertically] keeps the original point \
2334in both children.
2335This is often more convenient for editing.
2336If nil, adjust point in each of the two windows to minimize redisplay.
2337This is convenient on slow terminals, but point can move strangely.
2338
2339This option applies only to `split-window-vertically' and
2340functions that call it. `split-window' always keeps the original
2341point in both children."
2342 :type 'boolean
2343 :group 'windows)
2344
2345(defun split-window-vertically (&optional size)
2346 "Split selected window into two windows, one above the other.
2347The upper window gets SIZE lines and the lower one gets the rest.
2348SIZE negative means the lower window gets -SIZE lines and the
2349upper one the rest. With no argument, split windows equally or
2350close to it. Both windows display the same buffer, now current.
2351
2352If the variable `split-window-keep-point' is non-nil, both new
2353windows will get the same value of point as the selected window.
2354This is often more convenient for editing. The upper window is
2355the selected window.
2356
2357Otherwise, we choose window starts so as to minimize the amount of
2358redisplay; this is convenient on slow terminals. The new selected
2359window is the one that the current value of point appears in. The
2360value of point can change if the text around point is hidden by the
2361new mode line.
2362
2363Regardless of the value of `split-window-keep-point', the upper
2364window is the original one and the return value is the new, lower
2365window."
2366 (interactive "P")
2367 (let ((old-window (selected-window))
2368 (old-point (point))
2369 (size (and size (prefix-numeric-value size)))
2370 moved-by-window-height moved new-window bottom)
2371 (and size (< size 0)
2372 ;; Handle negative SIZE value.
2373 (setq size (+ (window-height) size)))
2374 (setq new-window (split-window nil size))
2375 (unless split-window-keep-point
2376 (with-current-buffer (window-buffer)
2377 (goto-char (window-start))
2378 (setq moved (vertical-motion (window-height)))
2379 (set-window-start new-window (point))
2380 (when (> (point) (window-point new-window))
2381 (set-window-point new-window (point)))
2382 (when (= moved (window-height))
2383 (setq moved-by-window-height t)
2384 (vertical-motion -1))
2385 (setq bottom (point)))
2386 (and moved-by-window-height
2387 (<= bottom (point))
2388 (set-window-point old-window (1- bottom)))
2389 (and moved-by-window-height
2390 (<= (window-start new-window) old-point)
2391 (set-window-point new-window old-point)
2392 (select-window new-window)))
2393 (split-window-save-restore-data new-window old-window)))
2394
2395;; This is to avoid compiler warnings.
2396(defvar view-return-to-alist)
2397
2398(defun split-window-save-restore-data (new-window old-window)
2399 (with-current-buffer (window-buffer)
2400 (when view-mode
2401 (let ((old-info (assq old-window view-return-to-alist)))
2402 (when old-info
2403 (push (cons new-window (cons (car (cdr old-info)) t))
2404 view-return-to-alist))))
2405 new-window))
2406
2407(defun split-window-horizontally (&optional size)
2408 "Split selected window into two windows side by side.
2409The selected window becomes the left one and gets SIZE columns.
2410SIZE negative means the right window gets -SIZE lines.
2411
2412SIZE includes the width of the window's scroll bar; if there are
2413no scroll bars, it includes the width of the divider column to
2414the window's right, if any. SIZE omitted or nil means split
2415window equally.
2416
2417The selected window remains selected. Return the new window."
2418 (interactive "P")
2419 (let ((old-window (selected-window))
2420 (size (and size (prefix-numeric-value size))))
2421 (and size (< size 0)
2422 ;; Handle negative SIZE value.
2423 (setq size (+ (window-width) size)))
2424 (split-window-save-restore-data (split-window nil size t) old-window)))
2425
2426 3590
2427(defun set-window-text-height (window height) 3591(defun set-window-text-height (window height)
2428 "Set the height in lines of the text display area of WINDOW to HEIGHT. 3592 "Set the height in lines of the text display area of WINDOW to HEIGHT.
@@ -3124,9 +4288,12 @@ Otherwise, consult the value of `truncate-partial-width-windows'
3124 (if (integerp t-p-w-w) 4288 (if (integerp t-p-w-w)
3125 (< (window-width window) t-p-w-w) 4289 (< (window-width window) t-p-w-w)
3126 t-p-w-w)))) 4290 t-p-w-w))))
3127 4291
3128(define-key ctl-x-map "2" 'split-window-vertically) 4292(define-key ctl-x-map "0" 'delete-window)
3129(define-key ctl-x-map "3" 'split-window-horizontally) 4293(define-key ctl-x-map "1" 'delete-other-windows)
4294(define-key ctl-x-map "2" 'split-window-above-each-other)
4295(define-key ctl-x-map "3" 'split-window-side-by-side)
4296(define-key ctl-x-map "^" 'enlarge-window)
3130(define-key ctl-x-map "}" 'enlarge-window-horizontally) 4297(define-key ctl-x-map "}" 'enlarge-window-horizontally)
3131(define-key ctl-x-map "{" 'shrink-window-horizontally) 4298(define-key ctl-x-map "{" 'shrink-window-horizontally)
3132(define-key ctl-x-map "-" 'shrink-window-if-larger-than-buffer) 4299(define-key ctl-x-map "-" 'shrink-window-if-larger-than-buffer)
diff --git a/src/ChangeLog b/src/ChangeLog
index 1222c04d091..fa9ed02614a 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,4 +1,4 @@
12011-06-09 Paul Eggert <eggert@cs.ucla.edu> 12011-06-10 Paul Eggert <eggert@cs.ucla.edu>
2 2
3 * xmenu.c (dialog_selection_callback) [!USE_GTK]: Cast to intptr_t, 3 * xmenu.c (dialog_selection_callback) [!USE_GTK]: Cast to intptr_t,
4 not to EMACS_INT, to avoid GCC warning. 4 not to EMACS_INT, to avoid GCC warning.
@@ -14,8 +14,6 @@
14 14
15 * data.c (Qcompiled_function): Now static. 15 * data.c (Qcompiled_function): Now static.
16 16
172011-06-08 Paul Eggert <eggert@cs.ucla.edu>
18
19 * window.c (window_body_lines): Now static. 17 * window.c (window_body_lines): Now static.
20 18
21 * image.c (gif_load): Rename local to avoid shadowing. 19 * image.c (gif_load): Rename local to avoid shadowing.
@@ -72,6 +70,111 @@
72 70
73 * alloc.c (Fmake_string): Check for out-of-range init. 71 * alloc.c (Fmake_string): Check for out-of-range init.
74 72
732011-06-10 Chong Yidong <cyd@stupidchicken.com>
74
75 * image.c (gif_load): Fix omitted cast error introduced by
76 2011-06-06 change.
77
782011-06-10 Martin Rudalics <rudalics@gmx.at>
79
80 * window.h (resize_proportionally, orig_total_lines)
81 (orig_top_line): Remove from window structure.
82 (set_window_height, set_window_width, change_window_heights)
83 (Fdelete_window): Remove prototypes.
84 (resize_frame_windows): Remove duplicate declaration.
85
862011-06-10 Eli Zaretskii <eliz@gnu.org>
87
88 * window.h (resize_frame_windows, resize_window_check)
89 (delete_deletable_window, resize_root_window)
90 (resize_frame_windows): Declare prototypes.
91
92 * window.c (resize_window_apply): Make definition be "static" to
93 match the prototype.
94
952011-06-10 Martin Rudalics <rudalics@gmx.at>
96
97 * window.c: Remove declarations of Qwindow_size_fixed,
98 window_min_size_1, window_min_size_2, window_min_size,
99 size_window, window_fixed_size_p, enlarge_window, delete_window.
100 Remove static from declaration of Qdelete_window, it's
101 temporarily needed by Fbury_buffer.
102 (replace_window): Don't assign orig_top_line and
103 orig_total_lines.
104 (Fdelete_window, delete_window): Remove. Window deletion is
105 handled by window.el.
106 (window_loop): Remove DELETE_OTHER_WINDOWS case. Replace
107 Fdelete_window calls with calls to Qdelete_window.
108 (Fdelete_other_windows): Remove. Deleting other windows is
109 handled by window.el.
110 (window_fixed_size_p): Remove. Fixed-sizeness of windows is
111 handled in window.el.
112 (window_min_size_2, window_min_size_1, window_min_size): Remove.
113 Window minimum sizes are handled in window.el.
114 (shrink_windows, size_window, set_window_height)
115 (set_window_width, change_window_heights, window_height)
116 (window_width, CURBEG, CURSIZE, enlarge_window)
117 (adjust_window_trailing_edge, Fadjust_window_trailing_edge)
118 (Fenlarge_window, Fshrink_window): Remove. Window resizing is
119 handled in window.el.
120 (make_dummy_parent): Rename to make_parent_window and give it a
121 second argument horflag.
122 (make_window): Don't set resize_proportionally any more.
123 (Fsplit_window): Remove. Windows are split in window.el.
124 (save_restore_action, save_restore_orig_size)
125 (shrink_window_lowest_first, save_restore_orig_size): Remove.
126 Resize mini windows in window.el.
127 (grow_mini_window, shrink_mini_window): Implement by calling
128 Qresize_root_window_vertically, resize_window_check and
129 resize_window_apply.
130 (saved_window, Fset_window_configuration, save_window_save): Do
131 not handle orig_top_line, orig_total_lines, and
132 resize_proportionally.
133 (window_min_height, window_min_width): Move to window.el.
134 (keys_of_window): Move bindings for delete-other-windows,
135 split-window, delete-window and enlarge-window to window.el.
136
137 * buffer.c: Temporarily extern Qdelete_window.
138 (Fbury_buffer): Temporarily call Qdelete_window instead of
139 Fdelete_window (Fbury_buffer will move to window.el soon).
140
141 * frame.c (set_menu_bar_lines_1): Remove code handling
142 orig_top_line and orig_total_lines.
143
144 * dispnew.c (adjust_frame_glyphs_initially): Don't use
145 set_window_height but set heights directly.
146 (change_frame_size_1): Use resize_frame_windows.
147
148 * xdisp.c (init_xdisp): Don't use set_window_height but set
149 heights directly.
150
151 * xfns.c (x_set_menu_bar_lines, x_set_tool_bar_lines): Use
152 resize_frame_windows instead of change_window_heights and run
153 run_window_configuration_change_hook.
154
155 * w32fns.c (x_set_tool_bar_lines): Use resize_frame_windows
156 instead of change_window_heights and run
157 run_window_configuration_change_hook.
158
1592011-06-09 Martin Rudalics <rudalics@gmx.at>
160
161 * window.c (replace_window): Rename second argument REPLACEMENT to
162 NEW. New third argument SETFLAG. Rewrite.
163 (delete_window, make_dummy_parent): Call replace_window with
164 third argument 1.
165 (window_list_1): Move down in code.
166 (run_window_configuration_change_hook): Move set_buffer part
167 before select_frame_norecord part in order to unwind correctly.
168 Rename count1 to count.
169 (recombine_windows, delete_deletable_window, resize_root_window)
170 (Fdelete_other_windows_internal)
171 (Frun_window_configuration_change_hook, make_parent_window)
172 (resize_window_check, resize_window_apply, Fresize_window_apply)
173 (resize_frame_windows, Fsplit_window_internal)
174 (Fdelete_window_internal, Fresize_mini_window_internal): New
175 functions.
176 (syms_of_window): New variables Vwindow_splits and Vwindow_nest.
177
752011-06-08 Martin Rudalics <rudalics@gmx.at> 1782011-06-08 Martin Rudalics <rudalics@gmx.at>
76 179
77 * window.h (window): Add some new members to window structure - 180 * window.h (window): Add some new members to window structure -
diff --git a/src/buffer.c b/src/buffer.c
index 8fdd094a20d..0c4cdb544a5 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1938,6 +1938,8 @@ DEFUN ("barf-if-buffer-read-only", Fbarf_if_buffer_read_only,
1938 return Qnil; 1938 return Qnil;
1939} 1939}
1940 1940
1941extern Lisp_Object Qdelete_window;
1942
1941DEFUN ("bury-buffer", Fbury_buffer, Sbury_buffer, 0, 1, "", 1943DEFUN ("bury-buffer", Fbury_buffer, Sbury_buffer, 0, 1, "",
1942 doc: /* Put BUFFER-OR-NAME at the end of the list of all buffers. 1944 doc: /* Put BUFFER-OR-NAME at the end of the list of all buffers.
1943There it is the least likely candidate for `other-buffer' to return; 1945There it is the least likely candidate for `other-buffer' to return;
@@ -1969,7 +1971,7 @@ its frame, iconify that frame. */)
1969 else if (NILP (XWINDOW (selected_window)->parent)) 1971 else if (NILP (XWINDOW (selected_window)->parent))
1970 Ficonify_frame (Fwindow_frame (selected_window)); 1972 Ficonify_frame (Fwindow_frame (selected_window));
1971 else 1973 else
1972 Fdelete_window (selected_window); 1974 call1 (Qdelete_window, selected_window);
1973 } 1975 }
1974 } 1976 }
1975 else 1977 else
diff --git a/src/dispnew.c b/src/dispnew.c
index 501dc4ffd80..2dffc0dce25 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -1933,13 +1933,13 @@ adjust_frame_glyphs_initially (void)
1933 1933
1934 /* Do it for the root window. */ 1934 /* Do it for the root window. */
1935 XSETFASTINT (root->top_line, top_margin); 1935 XSETFASTINT (root->top_line, top_margin);
1936 XSETFASTINT (root->total_lines, frame_lines - 1 - top_margin);
1936 XSETFASTINT (root->total_cols, frame_cols); 1937 XSETFASTINT (root->total_cols, frame_cols);
1937 set_window_height (sf->root_window, frame_lines - 1 - top_margin, 0);
1938 1938
1939 /* Do it for the mini-buffer window. */ 1939 /* Do it for the mini-buffer window. */
1940 XSETFASTINT (mini->top_line, frame_lines - 1); 1940 XSETFASTINT (mini->top_line, frame_lines - 1);
1941 XSETFASTINT (mini->total_lines, 1);
1941 XSETFASTINT (mini->total_cols, frame_cols); 1942 XSETFASTINT (mini->total_cols, frame_cols);
1942 set_window_height (root->next, 1, 0);
1943 1943
1944 adjust_frame_glyphs (sf); 1944 adjust_frame_glyphs (sf);
1945 glyphs_initialized_initially_p = 1; 1945 glyphs_initialized_initially_p = 1;
@@ -5715,24 +5715,7 @@ change_frame_size_1 (register struct frame *f, int newheight, int newwidth, int
5715 5715
5716 if (newheight != FRAME_LINES (f)) 5716 if (newheight != FRAME_LINES (f))
5717 { 5717 {
5718 if (FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f)) 5718 resize_frame_windows (f, newheight, 0);
5719 {
5720 /* Frame has both root and mini-buffer. */
5721 XSETFASTINT (XWINDOW (FRAME_ROOT_WINDOW (f))->top_line,
5722 FRAME_TOP_MARGIN (f));
5723 set_window_height (FRAME_ROOT_WINDOW (f),
5724 (newheight
5725 - 1
5726 - FRAME_TOP_MARGIN (f)),
5727 2);
5728 XSETFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (f))->top_line,
5729 newheight - 1);
5730 set_window_height (FRAME_MINIBUF_WINDOW (f), 1, 0);
5731 }
5732 else
5733 /* Frame has just one top-level window. */
5734 set_window_height (FRAME_ROOT_WINDOW (f),
5735 newheight - FRAME_TOP_MARGIN (f), 2);
5736 5719
5737 /* MSDOS frames cannot PRETEND, as they change frame size by 5720 /* MSDOS frames cannot PRETEND, as they change frame size by
5738 manipulating video hardware. */ 5721 manipulating video hardware. */
@@ -5742,9 +5725,7 @@ change_frame_size_1 (register struct frame *f, int newheight, int newwidth, int
5742 5725
5743 if (new_frame_total_cols != FRAME_TOTAL_COLS (f)) 5726 if (new_frame_total_cols != FRAME_TOTAL_COLS (f))
5744 { 5727 {
5745 set_window_width (FRAME_ROOT_WINDOW (f), new_frame_total_cols, 2); 5728 resize_frame_windows (f, new_frame_total_cols, 1);
5746 if (FRAME_HAS_MINIBUF_P (f))
5747 set_window_width (FRAME_MINIBUF_WINDOW (f), new_frame_total_cols, 0);
5748 5729
5749 /* MSDOS frames cannot PRETEND, as they change frame size by 5730 /* MSDOS frames cannot PRETEND, as they change frame size by
5750 manipulating video hardware. */ 5731 manipulating video hardware. */
diff --git a/src/frame.c b/src/frame.c
index 71881265b44..6baf2d0e671 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -135,11 +135,6 @@ set_menu_bar_lines_1 (Lisp_Object window, int n)
135 XSETFASTINT (w->top_line, XFASTINT (w->top_line) + n); 135 XSETFASTINT (w->top_line, XFASTINT (w->top_line) + n);
136 XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - n); 136 XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - n);
137 137
138 if (INTEGERP (w->orig_top_line))
139 XSETFASTINT (w->orig_top_line, XFASTINT (w->orig_top_line) + n);
140 if (INTEGERP (w->orig_total_lines))
141 XSETFASTINT (w->orig_total_lines, XFASTINT (w->orig_total_lines) - n);
142
143 /* Handle just the top child in a vertical split. */ 138 /* Handle just the top child in a vertical split. */
144 if (!NILP (w->vchild)) 139 if (!NILP (w->vchild))
145 set_menu_bar_lines_1 (w->vchild, n); 140 set_menu_bar_lines_1 (w->vchild, n);
diff --git a/src/image.c b/src/image.c
index 31b3f01c17d..7d15a4725c5 100644
--- a/src/image.c
+++ b/src/image.c
@@ -7238,7 +7238,7 @@ gif_load (struct frame *f, struct image *img)
7238 /* From gif89a spec: 1 = "keep in place", 2 = "restore 7238 /* From gif89a spec: 1 = "keep in place", 2 = "restore
7239 to background". Treat any other value like 2. */ 7239 to background". Treat any other value like 2. */
7240 disposal = (extblock->Bytes[0] >> 2) & 7; 7240 disposal = (extblock->Bytes[0] >> 2) & 7;
7241 transparency_color_index = extblock->Bytes[3]; 7241 transparency_color_index = (unsigned char) extblock->Bytes[3];
7242 break; 7242 break;
7243 } 7243 }
7244 } 7244 }
diff --git a/src/w32fns.c b/src/w32fns.c
index bdf9dce9411..823dbe3567e 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -1596,7 +1596,7 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1596 } 1596 }
1597 1597
1598 FRAME_TOOL_BAR_LINES (f) = nlines; 1598 FRAME_TOOL_BAR_LINES (f) = nlines;
1599 change_window_heights (root_window, delta); 1599 resize_frame_windows (f, FRAME_LINES (f), 0);
1600 adjust_glyphs (f); 1600 adjust_glyphs (f);
1601 1601
1602 /* We also have to make sure that the internal border at the top of 1602 /* We also have to make sure that the internal border at the top of
@@ -1631,6 +1631,9 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1631 if (WINDOWP (f->tool_bar_window)) 1631 if (WINDOWP (f->tool_bar_window))
1632 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix); 1632 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1633 } 1633 }
1634
1635 run_window_configuration_change_hook (f);
1636
1634} 1637}
1635 1638
1636 1639
@@ -5822,8 +5825,6 @@ Value is t if tooltip was open, nil otherwise. */)
5822 UNGCPRO; 5825 UNGCPRO;
5823 return unbind_to (count, deleted); 5826 return unbind_to (count, deleted);
5824} 5827}
5825
5826
5827 5828
5828/*********************************************************************** 5829/***********************************************************************
5829 File selection dialog 5830 File selection dialog
diff --git a/src/window.c b/src/window.c
index 493972c7545..31a25286bcc 100644
--- a/src/window.c
+++ b/src/window.c
@@ -50,17 +50,15 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
50#include "nsterm.h" 50#include "nsterm.h"
51#endif 51#endif
52 52
53Lisp_Object Qwindowp, Qwindow_live_p; 53Lisp_Object Qwindowp, Qwindow_live_p, Qdelete_window;
54static Lisp_Object Qwindow_configuration_p, Qrecord_window_buffer; 54static Lisp_Object Qwindow_configuration_p, Qrecord_window_buffer;
55static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer; 55static Lisp_Object Qwindow_deletable_p, Qdisplay_buffer;
56static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window; 56static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window;
57static Lisp_Object Qresize_root_window, Qresize_root_window_vertically; 57static Lisp_Object Qresize_root_window, Qresize_root_window_vertically;
58static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command; 58static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command;
59static Lisp_Object Qsafe, Qabove, Qbelow; 59static Lisp_Object Qsafe, Qabove, Qbelow;
60static Lisp_Object Qauto_buffer_name; 60static Lisp_Object Qauto_buffer_name;
61 61
62static Lisp_Object Qwindow_size_fixed;
63
64static int displayed_window_lines (struct window *); 62static int displayed_window_lines (struct window *);
65static struct window *decode_window (Lisp_Object); 63static struct window *decode_window (Lisp_Object);
66static int count_windows (struct window *); 64static int count_windows (struct window *);
@@ -68,13 +66,7 @@ static int get_leaf_windows (struct window *, struct window **, int);
68static void window_scroll (Lisp_Object, int, int, int); 66static void window_scroll (Lisp_Object, int, int, int);
69static void window_scroll_pixel_based (Lisp_Object, int, int, int); 67static void window_scroll_pixel_based (Lisp_Object, int, int, int);
70static void window_scroll_line_based (Lisp_Object, int, int, int); 68static void window_scroll_line_based (Lisp_Object, int, int, int);
71static int window_min_size_1 (struct window *, int, int);
72static int window_min_size_2 (struct window *, int, int);
73static int window_min_size (struct window *, int, int, int, int *);
74static void size_window (Lisp_Object, int, int, int, int, int);
75static int freeze_window_start (struct window *, void *); 69static int freeze_window_start (struct window *, void *);
76static int window_fixed_size_p (struct window *, int, int);
77static void enlarge_window (Lisp_Object, int, int);
78static Lisp_Object window_list (void); 70static Lisp_Object window_list (void);
79static int add_window_to_list (struct window *, void *); 71static int add_window_to_list (struct window *, void *);
80static int candidate_window_p (Lisp_Object, Lisp_Object, Lisp_Object, 72static int candidate_window_p (Lisp_Object, Lisp_Object, Lisp_Object,
@@ -90,6 +82,7 @@ static int foreach_window_1 (struct window *,
90 int (* fn) (struct window *, void *), 82 int (* fn) (struct window *, void *),
91 void *); 83 void *);
92static Lisp_Object window_list_1 (Lisp_Object, Lisp_Object, Lisp_Object); 84static Lisp_Object window_list_1 (Lisp_Object, Lisp_Object, Lisp_Object);
85static void resize_window_apply (struct window *, int);
93static Lisp_Object select_window (Lisp_Object, Lisp_Object, int); 86static Lisp_Object select_window (Lisp_Object, Lisp_Object, int);
94 87
95/* This is the window in which the terminal's cursor should 88/* This is the window in which the terminal's cursor should
@@ -1802,9 +1795,7 @@ DEFUN ("set-window-display-table", Fset_window_display_table, Sset_window_displa
1802 return table; 1795 return table;
1803} 1796}
1804 1797
1805static void delete_window (Lisp_Object); 1798/* Record info on buffer window W is displaying
1806
1807/* Record info on buffer window w is displaying
1808 when it is about to cease to display that buffer. */ 1799 when it is about to cease to display that buffer. */
1809static void 1800static void
1810unshow_buffer (register struct window *w) 1801unshow_buffer (register struct window *w)
@@ -1853,285 +1844,144 @@ unshow_buffer (register struct window *w)
1853 BVAR (b, last_selected_window) = Qnil; 1844 BVAR (b, last_selected_window) = Qnil;
1854} 1845}
1855 1846
1856/* Put replacement into the window structure in place of old. */ 1847/* Put NEW into the window structure in place of OLD. SETFLAG zero
1848 means change window structure only. Otherwise store geometry and
1849 other settings as well. */
1857static void 1850static void
1858replace_window (Lisp_Object old, Lisp_Object replacement) 1851replace_window (Lisp_Object old, Lisp_Object new, int setflag)
1859{ 1852{
1860 register Lisp_Object tem; 1853 register Lisp_Object tem;
1861 register struct window *o = XWINDOW (old), *p = XWINDOW (replacement); 1854 register struct window *o = XWINDOW (old), *n = XWINDOW (new);
1862
1863 /* If OLD is its frame's root_window, then replacement is the new
1864 root_window for that frame. */
1865 1855
1856 /* If OLD is its frame's root window, then NEW is the new
1857 root window for that frame. */
1866 if (EQ (old, FRAME_ROOT_WINDOW (XFRAME (o->frame)))) 1858 if (EQ (old, FRAME_ROOT_WINDOW (XFRAME (o->frame))))
1867 FRAME_ROOT_WINDOW (XFRAME (o->frame)) = replacement; 1859 FRAME_ROOT_WINDOW (XFRAME (o->frame)) = new;
1868 1860
1869 p->left_col = o->left_col; 1861 if (setflag)
1870 p->top_line = o->top_line; 1862 {
1871 p->total_cols = o->total_cols; 1863 n->left_col = o->left_col;
1872 p->total_lines = o->total_lines; 1864 n->top_line = o->top_line;
1873 p->desired_matrix = p->current_matrix = 0; 1865 n->total_cols = o->total_cols;
1874 p->vscroll = 0; 1866 n->total_lines = o->total_lines;
1875 memset (&p->cursor, 0, sizeof (p->cursor)); 1867 n->normal_cols = o->normal_cols;
1876 memset (&p->last_cursor, 0, sizeof (p->last_cursor)); 1868 o->normal_cols = make_float (1.0);
1877 memset (&p->phys_cursor, 0, sizeof (p->phys_cursor)); 1869 n->normal_lines = o->normal_lines;
1878 p->phys_cursor_type = -1; 1870 o->normal_lines = make_float (1.0);
1879 p->phys_cursor_width = -1; 1871 n->desired_matrix = n->current_matrix = 0;
1880 p->must_be_updated_p = 0; 1872 n->vscroll = 0;
1881 p->pseudo_window_p = 0; 1873 memset (&n->cursor, 0, sizeof (n->cursor));
1882 XSETFASTINT (p->window_end_vpos, 0); 1874 memset (&n->last_cursor, 0, sizeof (n->last_cursor));
1883 XSETFASTINT (p->window_end_pos, 0); 1875 memset (&n->phys_cursor, 0, sizeof (n->phys_cursor));
1884 p->window_end_valid = Qnil; 1876 n->phys_cursor_type = -1;
1885 p->frozen_window_start_p = 0; 1877 n->phys_cursor_width = -1;
1886 p->orig_top_line = p->orig_total_lines = Qnil; 1878 n->must_be_updated_p = 0;
1887 1879 n->pseudo_window_p = 0;
1888 p->next = tem = o->next; 1880 XSETFASTINT (n->window_end_vpos, 0);
1881 XSETFASTINT (n->window_end_pos, 0);
1882 n->window_end_valid = Qnil;
1883 n->frozen_window_start_p = 0;
1884 }
1885
1886 n->next = tem = o->next;
1889 if (!NILP (tem)) 1887 if (!NILP (tem))
1890 XWINDOW (tem)->prev = replacement; 1888 XWINDOW (tem)->prev = new;
1891 1889
1892 p->prev = tem = o->prev; 1890 n->prev = tem = o->prev;
1893 if (!NILP (tem)) 1891 if (!NILP (tem))
1894 XWINDOW (tem)->next = replacement; 1892 XWINDOW (tem)->next = new;
1895 1893
1896 p->parent = tem = o->parent; 1894 n->parent = tem = o->parent;
1897 if (!NILP (tem)) 1895 if (!NILP (tem))
1898 { 1896 {
1899 if (EQ (XWINDOW (tem)->vchild, old)) 1897 if (EQ (XWINDOW (tem)->vchild, old))
1900 XWINDOW (tem)->vchild = replacement; 1898 XWINDOW (tem)->vchild = new;
1901 if (EQ (XWINDOW (tem)->hchild, old)) 1899 if (EQ (XWINDOW (tem)->hchild, old))
1902 XWINDOW (tem)->hchild = replacement; 1900 XWINDOW (tem)->hchild = new;
1903 } 1901 }
1904
1905/*** Here, if replacement is a vertical combination
1906and so is its new parent, we should make replacement's
1907children be children of that parent instead. ***/
1908} 1902}
1909 1903
1910DEFUN ("delete-window", Fdelete_window, Sdelete_window, 0, 1, "", 1904/* If window WINDOW and its parent window are iso-combined, merge
1911 doc: /* Remove WINDOW from its frame. 1905 WINDOW's children into those of its parent window and mark WINDOW as
1912WINDOW defaults to the selected window. Return nil. 1906 deleted. */
1913Signal an error when WINDOW is the only window on its frame. */)
1914 (register Lisp_Object window)
1915{
1916 struct frame *f;
1917 if (NILP (window))
1918 window = selected_window;
1919 else
1920 CHECK_LIVE_WINDOW (window);
1921
1922 f = XFRAME (WINDOW_FRAME (XWINDOW (window)));
1923 delete_window (window);
1924
1925 run_window_configuration_change_hook (f);
1926
1927 return Qnil;
1928}
1929 1907
1930static void 1908static void
1931delete_window (register Lisp_Object window) 1909recombine_windows (Lisp_Object window)
1932{ 1910{
1933 register Lisp_Object tem, parent, sib; 1911 struct window *w, *p, *c;
1934 register struct window *p; 1912 Lisp_Object parent, child;
1935 register struct window *par; 1913 int horflag;
1936 struct frame *f;
1937
1938 /* Because this function is called by other C code on non-leaf
1939 windows, the CHECK_LIVE_WINDOW macro would choke inappropriately,
1940 so we can't decode_window here. */
1941 CHECK_WINDOW (window);
1942 p = XWINDOW (window);
1943
1944 /* It's a no-op to delete an already-deleted window. */
1945 if (NILP (p->buffer)
1946 && NILP (p->hchild)
1947 && NILP (p->vchild))
1948 return;
1949
1950 parent = p->parent;
1951 if (NILP (parent))
1952 error ("Attempt to delete minibuffer or sole ordinary window");
1953 par = XWINDOW (parent);
1954
1955 windows_or_buffers_changed++;
1956 Vwindow_list = Qnil;
1957 f = XFRAME (WINDOW_FRAME (p));
1958 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
1959
1960 /* Are we trying to delete any frame's selected window? */
1961 {
1962 Lisp_Object swindow, pwindow;
1963
1964 /* See if the frame's selected window is either WINDOW
1965 or any subwindow of it, by finding all that window's parents
1966 and comparing each one with WINDOW. */
1967 swindow = FRAME_SELECTED_WINDOW (f);
1968
1969 while (1)
1970 {
1971 pwindow = swindow;
1972 while (!NILP (pwindow))
1973 {
1974 if (EQ (window, pwindow))
1975 break;
1976 pwindow = XWINDOW (pwindow)->parent;
1977 }
1978
1979 /* If the window being deleted is not a parent of SWINDOW,
1980 then SWINDOW is ok as the new selected window. */
1981 if (!EQ (window, pwindow))
1982 break;
1983 /* Otherwise, try another window for SWINDOW. */
1984 swindow = Fnext_window (swindow, Qlambda, Qnil);
1985
1986 /* If we get back to the frame's selected window,
1987 it means there was no acceptable alternative,
1988 so we cannot delete. */
1989 if (EQ (swindow, FRAME_SELECTED_WINDOW (f)))
1990 error ("Cannot delete window");
1991 }
1992
1993 /* If we need to change SWINDOW, do it. */
1994 if (! EQ (swindow, FRAME_SELECTED_WINDOW (f)))
1995 {
1996 /* If we're about to delete the selected window on the
1997 selected frame, then we should use Fselect_window to select
1998 the new window. On the other hand, if we're about to
1999 delete the selected window on any other frame, we shouldn't do
2000 anything but set the frame's selected_window slot. */
2001 if (EQ (FRAME_SELECTED_WINDOW (f), selected_window))
2002 Fselect_window (swindow, Qnil);
2003 else
2004 FRAME_SELECTED_WINDOW (f) = swindow;
2005 }
2006 }
2007
2008 /* Now we know we can delete this one. */
2009 window_deletion_count++;
2010
2011 tem = p->buffer;
2012 /* tem is null for dummy parent windows
2013 (which have inferiors but not any contents themselves) */
2014 if (!NILP (tem))
2015 {
2016 unshow_buffer (p);
2017 unchain_marker (XMARKER (p->pointm));
2018 unchain_marker (XMARKER (p->start));
2019 }
2020
2021 /* Free window glyph matrices. It is sure that they are allocated
2022 again when ADJUST_GLYPHS is called. Block input so that expose
2023 events and other events that access glyph matrices are not
2024 processed while we are changing them. */
2025 BLOCK_INPUT;
2026 free_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (f)));
2027
2028 tem = p->next;
2029 if (!NILP (tem))
2030 XWINDOW (tem)->prev = p->prev;
2031 1914
2032 tem = p->prev; 1915 w = XWINDOW (window);
2033 if (!NILP (tem)) 1916 parent = w->parent;
2034 XWINDOW (tem)->next = p->next; 1917 if (!NILP (parent) && NILP (w->nest))
2035 1918 {
2036 if (EQ (window, par->hchild)) 1919 p = XWINDOW (parent);
2037 par->hchild = p->next; 1920 if (((!NILP (p->vchild) && !NILP (w->vchild))
2038 if (EQ (window, par->vchild)) 1921 || (!NILP (p->hchild) && !NILP (w->hchild))))
2039 par->vchild = p->next; 1922 /* WINDOW and PARENT are both either a vertical or a horizontal
2040 1923 combination. */
2041 /* Find one of our siblings to give our space to. */ 1924 {
2042 sib = p->prev; 1925 horflag = NILP (w->vchild);
2043 if (NILP (sib)) 1926 child = horflag ? w->hchild : w->vchild;
2044 { 1927 c = XWINDOW (child);
2045 /* If p gives its space to its next sibling, that sibling needs
2046 to have its top/left side pulled back to where p's is.
2047 set_window_{height,width} will re-position the sibling's
2048 children. */
2049 sib = p->next;
2050 XWINDOW (sib)->top_line = p->top_line;
2051 XWINDOW (sib)->left_col = p->left_col;
2052 }
2053
2054 /* Stretch that sibling. */
2055 if (!NILP (par->vchild))
2056 set_window_height (sib,
2057 XFASTINT (XWINDOW (sib)->total_lines) + XFASTINT (p->total_lines),
2058 1);
2059 if (!NILP (par->hchild))
2060 set_window_width (sib,
2061 XFASTINT (XWINDOW (sib)->total_cols) + XFASTINT (p->total_cols),
2062 1);
2063
2064 /* If parent now has only one child,
2065 put the child into the parent's place. */
2066 tem = par->hchild;
2067 if (NILP (tem))
2068 tem = par->vchild;
2069 if (NILP (XWINDOW (tem)->next)) {
2070 replace_window (parent, tem);
2071 par = XWINDOW (tem);
2072 }
2073 1928
2074 /* Since we may be deleting combination windows, we must make sure that 1929 /* Splice WINDOW's children into its parent's children and
2075 not only p but all its children have been marked as deleted. */ 1930 assign new normal sizes. */
2076 if (! NILP (p->hchild)) 1931 if (NILP (w->prev))
2077 delete_all_subwindows (p->hchild); 1932 if (horflag)
2078 else if (! NILP (p->vchild)) 1933 p->hchild = child;
2079 delete_all_subwindows (p->vchild); 1934 else
1935 p->vchild = child;
1936 else
1937 {
1938 c->prev = w->prev;
1939 XWINDOW (w->prev)->next = child;
1940 }
2080 1941
2081 /* Mark this window as deleted. */ 1942 while (c)
2082 p->buffer = p->hchild = p->vchild = Qnil; 1943 {
1944 c->parent = parent;
2083 1945
2084 if (! NILP (par->parent)) 1946 if (horflag)
2085 par = XWINDOW (par->parent); 1947 c->normal_cols
1948 = make_float (XFLOATINT (c->total_cols)
1949 / XFLOATINT (p->total_cols));
1950 else
1951 c->normal_lines
1952 = make_float (XFLOATINT (c->total_lines)
1953 / XFLOATINT (p->total_lines));
2086 1954
2087 /* Check if we have a v/hchild with a v/hchild. In that case remove 1955 if (NILP (c->next))
2088 one of them. */ 1956 {
1957 if (!NILP (w->next))
1958 {
1959 c->next = w->next;
1960 XWINDOW (c->next)->prev = child;
1961 }
2089 1962
2090 if (! NILP (par->vchild) && ! NILP (XWINDOW (par->vchild)->vchild)) 1963 c = 0;
2091 { 1964 }
2092 p = XWINDOW (par->vchild); 1965 else
2093 par->vchild = p->vchild; 1966 {
2094 tem = p->vchild; 1967 child = c->next;
2095 } 1968 c = XWINDOW (child);
2096 else if (! NILP (par->hchild) && ! NILP (XWINDOW (par->hchild)->hchild)) 1969 }
2097 { 1970 }
2098 p = XWINDOW (par->hchild);
2099 par->hchild = p->hchild;
2100 tem = p->hchild;
2101 }
2102 else
2103 p = 0;
2104 1971
2105 if (p) 1972 /* WINDOW can be deleted now. */
2106 { 1973 w->vchild = w->hchild = Qnil;
2107 while (! NILP (tem)) { 1974 }
2108 XWINDOW (tem)->parent = p->parent;
2109 if (NILP (XWINDOW (tem)->next))
2110 break;
2111 tem = XWINDOW (tem)->next;
2112 }
2113 if (! NILP (tem)) {
2114 /* The next of the v/hchild we are removing is now the next of the
2115 last child for the v/hchild:
2116 Before v/hchild -> v/hchild -> next1 -> next2
2117 |
2118 -> next3
2119 After: v/hchild -> next1 -> next2 -> next3
2120 */
2121 XWINDOW (tem)->next = p->next;
2122 if (! NILP (p->next))
2123 XWINDOW (p->next)->prev = tem;
2124 }
2125 p->next = p->prev = p->vchild = p->hchild = p->buffer = Qnil;
2126 } 1975 }
2127
2128
2129 /* Adjust glyph matrices. */
2130 adjust_glyphs (f);
2131 UNBLOCK_INPUT;
2132} 1976}
2133 1977
2134 1978/* If WINDOW can be deleted, delete it. */
1979Lisp_Object
1980delete_deletable_window (Lisp_Object window)
1981{
1982 if (!NILP (call1 (Qwindow_deletable_p, window)))
1983 call1 (Qdelete_window, window);
1984}
2135 1985
2136/*********************************************************************** 1986/***********************************************************************
2137 Window List 1987 Window List
@@ -2427,43 +2277,6 @@ reverse order. */)
2427} 2277}
2428 2278
2429 2279
2430DEFUN ("window-list-1", Fwindow_list_1, Swindow_list_1, 0, 3, 0,
2431 doc: /* Return a list of all live windows.
2432WINDOW specifies the first window to list and defaults to the selected
2433window.
2434
2435Optional argument MINIBUF nil or omitted means consider the minibuffer
2436window only if the minibuffer is active. MINIBUF t means consider the
2437minibuffer window even if the minibuffer is not active. Any other value
2438means do not consider the minibuffer window even if the minibuffer is
2439active.
2440
2441Optional argument ALL-FRAMES nil or omitted means consider all windows
2442on WINDOW's frame, plus the minibuffer window if specified by the
2443MINIBUF argument. If the minibuffer counts, consider all windows on all
2444frames that share that minibuffer too. The following non-nil values of
2445ALL-FRAMES have special meanings:
2446
2447- t means consider all windows on all existing frames.
2448
2449- `visible' means consider all windows on all visible frames.
2450
2451- 0 (the number zero) means consider all windows on all visible and
2452 iconified frames.
2453
2454- A frame means consider all windows on that frame only.
2455
2456Anything else means consider all windows on WINDOW's frame and no
2457others.
2458
2459If WINDOW is not on the list of windows returned, some other window will
2460be listed first but no error is signalled. */)
2461 (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames)
2462{
2463 return window_list_1 (window, minibuf, all_frames);
2464}
2465
2466
2467DEFUN ("other-window", Fother_window, Sother_window, 1, 2, "p", 2280DEFUN ("other-window", Fother_window, Sother_window, 1, 2, "p",
2468 doc: /* Select another window in cyclic ordering of windows. 2281 doc: /* Select another window in cyclic ordering of windows.
2469COUNT specifies the number of windows to skip, starting with the 2282COUNT specifies the number of windows to skip, starting with the
@@ -2547,6 +2360,41 @@ MINIBUF neither nil nor t means never include the minibuffer window. */)
2547} 2360}
2548 2361
2549 2362
2363DEFUN ("window-list-1", Fwindow_list_1, Swindow_list_1, 0, 3, 0,
2364 doc: /* Return a list of all live windows.
2365WINDOW specifies the first window to list and defaults to the selected
2366window.
2367
2368Optional argument MINIBUF nil or omitted means consider the minibuffer
2369window only if the minibuffer is active. MINIBUF t means consider the
2370minibuffer window even if the minibuffer is not active. Any other value
2371means do not consider the minibuffer window even if the minibuffer is
2372active.
2373
2374Optional argument ALL-FRAMES nil or omitted means consider all windows
2375on WINDOW's frame, plus the minibuffer window if specified by the
2376MINIBUF argument. If the minibuffer counts, consider all windows on all
2377frames that share that minibuffer too. The following non-nil values of
2378ALL-FRAMES have special meanings:
2379
2380- t means consider all windows on all existing frames.
2381
2382- `visible' means consider all windows on all visible frames.
2383
2384- 0 (the number zero) means consider all windows on all visible and
2385 iconified frames.
2386
2387- A frame means consider all windows on that frame only.
2388
2389Anything else means consider all windows on WINDOW's frame and no
2390others.
2391
2392If WINDOW is not on the list of windows returned, some other window will
2393be listed first but no error is signalled. */)
2394 (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames)
2395{
2396 return window_list_1 (window, minibuf, all_frames);
2397}
2550 2398
2551/* Look at all windows, performing an operation specified by TYPE 2399/* Look at all windows, performing an operation specified by TYPE
2552 with argument OBJ. 2400 with argument OBJ.
@@ -2560,7 +2408,6 @@ enum window_loop
2560{ 2408{
2561 WINDOW_LOOP_UNUSED, 2409 WINDOW_LOOP_UNUSED,
2562 GET_BUFFER_WINDOW, /* Arg is buffer */ 2410 GET_BUFFER_WINDOW, /* Arg is buffer */
2563 DELETE_OTHER_WINDOWS, /* Arg is window not to delete */
2564 DELETE_BUFFER_WINDOWS, /* Arg is buffer */ 2411 DELETE_BUFFER_WINDOWS, /* Arg is buffer */
2565 UNSHOW_BUFFER, /* Arg is buffer */ 2412 UNSHOW_BUFFER, /* Arg is buffer */
2566 REDISPLAY_BUFFER_WINDOWS, /* Arg is buffer */ 2413 REDISPLAY_BUFFER_WINDOWS, /* Arg is buffer */
@@ -2644,11 +2491,6 @@ window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frame
2644 } 2491 }
2645 break; 2492 break;
2646 2493
2647 case DELETE_OTHER_WINDOWS:
2648 if (!EQ (window, obj))
2649 Fdelete_window (window);
2650 break;
2651
2652 case DELETE_BUFFER_WINDOWS: 2494 case DELETE_BUFFER_WINDOWS:
2653 if (EQ (w->buffer, obj)) 2495 if (EQ (w->buffer, obj))
2654 { 2496 {
@@ -2684,7 +2526,7 @@ window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frame
2684 Fset_buffer (w->buffer); 2526 Fset_buffer (w->buffer);
2685 } 2527 }
2686 else 2528 else
2687 Fdelete_window (window); 2529 call1 (Qdelete_window, window);
2688 } 2530 }
2689 break; 2531 break;
2690 2532
@@ -2719,7 +2561,7 @@ window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frame
2719 XSETWINDOW (window_to_delete, w); 2561 XSETWINDOW (window_to_delete, w);
2720 /* If this window is dedicated and not the only window 2562 /* If this window is dedicated and not the only window
2721 in its frame, then kill it. */ 2563 in its frame, then kill it. */
2722 Fdelete_window (window_to_delete); 2564 call1 (Qdelete_window, window_to_delete);
2723 } 2565 }
2724 else 2566 else
2725 { 2567 {
@@ -2801,68 +2643,248 @@ selected frame and no others. */)
2801 return Qnil; 2643 return Qnil;
2802} 2644}
2803 2645
2804DEFUN ("delete-other-windows", Fdelete_other_windows, Sdelete_other_windows, 2646Lisp_Object
2805 0, 1, "", 2647resize_root_window (Lisp_Object window, Lisp_Object delta, Lisp_Object horizontal, Lisp_Object ignore)
2806 doc: /* Make WINDOW (or the selected window) fill its frame. 2648{
2807Only the frame WINDOW is on is affected. 2649 return call4 (Qresize_root_window, window, delta, horizontal, ignore);
2808This function tries to reduce display jumps by keeping the text 2650}
2651
2652
2653DEFUN ("delete-other-windows-internal", Fdelete_other_windows_internal,
2654 Sdelete_other_windows_internal, 0, 2, "",
2655 doc: /* Make WINDOW fill its frame.
2656Only the frame WINDOW is on is affected. WINDOW may be any window and
2657defaults to the selected one.
2658
2659Optional argument ROOT, if non-nil, must specify an internal window
2660containing WINDOW as a subwindow. If this is the case, replace ROOT by
2661WINDOW and leave alone any windows not contained in ROOT.
2662
2663When WINDOW is live try to reduce display jumps by keeping the text
2809previously visible in WINDOW in the same place on the frame. Doing this 2664previously visible in WINDOW in the same place on the frame. Doing this
2810depends on the value of (window-start WINDOW), so if calling this 2665depends on the value of (window-start WINDOW), so if calling this
2811function in a program gives strange scrolling, make sure the 2666function in a program gives strange scrolling, make sure the
2812window-start value is reasonable when this function is called. */) 2667window-start value is reasonable when this function is called. */)
2813 (Lisp_Object window) 2668 (Lisp_Object window, Lisp_Object root)
2814{ 2669{
2815 struct window *w; 2670 struct window *w, *r, *s;
2671 struct frame *f;
2672 Lisp_Object sibling, pwindow, swindow, delta;
2816 EMACS_INT startpos; 2673 EMACS_INT startpos;
2817 int top, new_top; 2674 int top, new_top, resize_failed;
2818 2675
2819 if (NILP (window)) 2676 w = decode_any_window (window);
2820 window = selected_window; 2677 XSETWINDOW (window, w);
2821 else 2678 f = XFRAME (w->frame);
2822 CHECK_LIVE_WINDOW (window);
2823 w = XWINDOW (window);
2824 2679
2825 startpos = marker_position (w->start); 2680 if (NILP (root))
2826 top = WINDOW_TOP_EDGE_LINE (w) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w))); 2681 /* ROOT is the frame's root window. */
2682 {
2683 root = FRAME_ROOT_WINDOW (f);
2684 r = XWINDOW (root);
2685 }
2686 else
2687 /* ROOT must be an ancestor of WINDOW. */
2688 {
2689 r = decode_any_window (root);
2690 pwindow = XWINDOW (window)->parent;
2691 while (!NILP (pwindow))
2692 if (EQ (pwindow, root))
2693 break;
2694 else
2695 pwindow = XWINDOW (pwindow)->parent;
2696 if (!EQ (pwindow, root))
2697 error ("Specified root is not an ancestor of specified window");
2698 }
2827 2699
2828 if (MINI_WINDOW_P (w) && top > 0) 2700 if (EQ (window, root))
2701 /* A noop. */
2702 return Qnil;
2703 /* I don't understand the "top > 0" part below. If we deal with a
2704 standalone minibuffer it would have been caught by the preceding
2705 test. */
2706 else if (MINI_WINDOW_P (w)) /* && top > 0) */
2829 error ("Can't expand minibuffer to full frame"); 2707 error ("Can't expand minibuffer to full frame");
2830 2708
2831 window_loop (DELETE_OTHER_WINDOWS, window, 0, WINDOW_FRAME (w)); 2709 if (!NILP (w->buffer))
2710 {
2711 startpos = marker_position (w->start);
2712 top = WINDOW_TOP_EDGE_LINE (w)
2713 - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w)));
2714 /* Make sure WINDOW is the frame's selected window. */
2715 if (!EQ (window, FRAME_SELECTED_WINDOW (f)))
2716 {
2717 if (EQ (selected_frame, w->frame))
2718 Fselect_window (window, Qnil);
2719 else
2720 FRAME_SELECTED_WINDOW (f) = window;
2721 }
2722 }
2723 else
2724 {
2725 /* See if the frame's selected window is a subwindow of WINDOW, by
2726 finding all the selected window's parents and comparing each
2727 one with WINDOW. If it isn't we need a new selected window for
2728 this frame. */
2729 swindow = FRAME_SELECTED_WINDOW (f);
2730 while (1)
2731 {
2732 pwindow = swindow;
2733 while (!NILP (pwindow) && !EQ (window, pwindow))
2734 pwindow = XWINDOW (pwindow)->parent;
2735
2736 if (EQ (window, pwindow))
2737 /* If WINDOW is an ancestor of SWINDOW, then SWINDOW is ok
2738 as the new selected window. */
2739 break;
2740 else
2741 /* Else try the previous window of SWINDOW. */
2742 swindow = Fprevious_window (swindow, Qlambda, Qnil);
2743 }
2832 2744
2833 /* Try to minimize scrolling, by setting the window start to the point 2745 if (!EQ (swindow, FRAME_SELECTED_WINDOW (f)))
2834 will cause the text at the old window start to be at the same place 2746 {
2835 on the frame. But don't try to do this if the window start is 2747 if (EQ (selected_frame, w->frame))
2836 outside the visible portion (as might happen when the display is 2748 Fselect_window (swindow, Qnil);
2837 not current, due to typeahead). */ 2749 else
2838 new_top = WINDOW_TOP_EDGE_LINE (w) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w))); 2750 FRAME_SELECTED_WINDOW (f) = swindow;
2839 if (new_top != top 2751 }
2840 && startpos >= BUF_BEGV (XBUFFER (w->buffer)) 2752 }
2841 && startpos <= BUF_ZV (XBUFFER (w->buffer))) 2753
2754 BLOCK_INPUT;
2755 free_window_matrices (r);
2756
2757 windows_or_buffers_changed++;
2758 Vwindow_list = Qnil;
2759 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
2760
2761 if (NILP (w->buffer))
2842 { 2762 {
2843 struct position pos; 2763 resize_failed = 0;
2844 struct buffer *obuf = current_buffer; 2764 /* Resize subwindows vertically. */
2765 XSETINT (delta, XINT (r->total_lines) - XINT (w->total_lines));
2766 w->top_line = r->top_line;
2767 resize_root_window (window, delta, Qnil, Qnil);
2768 if (resize_window_check (w, 0))
2769 resize_window_apply (w, 0);
2770 else
2771 {
2772 resize_root_window (window, delta, Qnil, Qt);
2773 if (resize_window_check (w, 0))
2774 resize_window_apply (w, 0);
2775 else
2776 resize_failed = 1;
2777 }
2845 2778
2846 Fset_buffer (w->buffer); 2779 /* Resize subwindows horizontally. */
2847 /* This computation used to temporarily move point, but that can 2780 if (!resize_failed)
2848 have unwanted side effects due to text properties. */ 2781 {
2849 pos = *vmotion (startpos, -top, w); 2782 w->left_col = r->left_col;
2783 XSETINT (delta, XINT (r->total_cols) - XINT (w->total_cols));
2784 w->left_col = r->left_col;
2785 resize_root_window (window, delta, Qt, Qnil);
2786 if (resize_window_check (w, 1))
2787 resize_window_apply (w, 1);
2788 else
2789 {
2790 resize_root_window (window, delta, Qt, Qt);
2791 if (resize_window_check (w, 1))
2792 resize_window_apply (w, 1);
2793 else
2794 resize_failed = 1;
2795 }
2796 }
2850 2797
2851 set_marker_both (w->start, w->buffer, pos.bufpos, pos.bytepos); 2798 if (resize_failed)
2852 w->window_end_valid = Qnil; 2799 /* Play safe, if we still can ... */
2853 w->start_at_line_beg = ((pos.bytepos == BEGV_BYTE 2800 {
2854 || FETCH_BYTE (pos.bytepos - 1) == '\n') ? Qt 2801 window = swindow;
2855 : Qnil); 2802 w = XWINDOW (window);
2856 /* We need to do this, so that the window-scroll-functions 2803 }
2857 get called. */ 2804 }
2858 w->optional_new_start = Qt;
2859 2805
2860 set_buffer_internal (obuf); 2806 /* Cleanly unlink WINDOW from window-tree. */
2807 if (!NILP (w->prev))
2808 /* Get SIBLING above (on the left of) WINDOW. */
2809 {
2810 sibling = w->prev;
2811 s = XWINDOW (sibling);
2812 s->next = w->next;
2813 if (!NILP (s->next))
2814 XWINDOW (s->next)->prev = sibling;
2815 }
2816 else
2817 /* Get SIBLING below (on the right of) WINDOW. */
2818 {
2819 sibling = w->next;
2820 s = XWINDOW (sibling);
2821 s->prev = Qnil;
2822 if (!NILP (XWINDOW (w->parent)->vchild))
2823 XWINDOW (w->parent)->vchild = sibling;
2824 else
2825 XWINDOW (w->parent)->hchild = sibling;
2826 }
2827
2828 /* Delete ROOT and all subwindows of ROOT. */
2829 if (!NILP (r->vchild))
2830 {
2831 delete_all_subwindows (r->vchild);
2832 r->vchild = Qnil;
2833 }
2834 else if (!NILP (r->hchild))
2835 {
2836 delete_all_subwindows (r->hchild);
2837 r->hchild = Qnil;
2861 } 2838 }
2862 2839
2840 replace_window (root, window, 1);
2841
2842 /* Reset WINDOW's splits status. */
2843 w->splits = Qnil;
2844
2845 /* This must become SWINDOW anyway ....... */
2846 if (!NILP (w->buffer) && !resize_failed)
2847 {
2848 /* Try to minimize scrolling, by setting the window start to the
2849 point will cause the text at the old window start to be at the
2850 same place on the frame. But don't try to do this if the
2851 window start is outside the visible portion (as might happen
2852 when the display is not current, due to typeahead). */
2853 new_top = WINDOW_TOP_EDGE_LINE (w) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w)));
2854 if (new_top != top
2855 && startpos >= BUF_BEGV (XBUFFER (w->buffer))
2856 && startpos <= BUF_ZV (XBUFFER (w->buffer)))
2857 {
2858 struct position pos;
2859 struct buffer *obuf = current_buffer;
2860
2861 Fset_buffer (w->buffer);
2862 /* This computation used to temporarily move point, but that
2863 can have unwanted side effects due to text properties. */
2864 pos = *vmotion (startpos, -top, w);
2865
2866 set_marker_both (w->start, w->buffer, pos.bufpos, pos.bytepos);
2867 w->window_end_valid = Qnil;
2868 w->start_at_line_beg = ((pos.bytepos == BEGV_BYTE
2869 || FETCH_BYTE (pos.bytepos - 1) == '\n') ? Qt
2870 : Qnil);
2871 /* We need to do this, so that the window-scroll-functions
2872 get called. */
2873 w->optional_new_start = Qt;
2874
2875 set_buffer_internal (obuf);
2876 }
2877 }
2878
2879 adjust_glyphs (f);
2880 UNBLOCK_INPUT;
2881
2882 run_window_configuration_change_hook (f);
2883
2863 return Qnil; 2884 return Qnil;
2864} 2885}
2865 2886
2887
2866DEFUN ("delete-windows-on", Fdelete_windows_on, Sdelete_windows_on, 2888DEFUN ("delete-windows-on", Fdelete_windows_on, Sdelete_windows_on,
2867 0, 2, "bDelete windows on (buffer): ", 2889 0, 2, "bDelete windows on (buffer): ",
2868 doc: /* Delete all windows showing BUFFER-OR-NAME. 2890 doc: /* Delete all windows showing BUFFER-OR-NAME.
@@ -2944,8 +2966,6 @@ replace_buffer_in_all_windows (Lisp_Object buffer)
2944 window_loop (UNSHOW_BUFFER, buffer, 1, frame); 2966 window_loop (UNSHOW_BUFFER, buffer, 1, frame);
2945} 2967}
2946 2968
2947/* Set the height of WINDOW and all its inferiors. */
2948
2949/* If *ROWS or *COLS are too small a size for FRAME, set them to the 2969/* If *ROWS or *COLS are too small a size for FRAME, set them to the
2950 minimum allowable size. */ 2970 minimum allowable size. */
2951 2971
@@ -2969,243 +2989,6 @@ check_frame_size (FRAME_PTR frame, int *rows, int *cols)
2969 *cols = MIN_SAFE_WINDOW_WIDTH; 2989 *cols = MIN_SAFE_WINDOW_WIDTH;
2970} 2990}
2971 2991
2972/* Value is non-zero if window W is fixed-size. WIDTH_P non-zero means
2973 check if W's width can be changed, otherwise check W's height.
2974 CHECK_SIBLINGS_P non-zero means check resizablity of WINDOW's
2975 siblings, too. If none of the siblings is resizable, WINDOW isn't
2976 either. */
2977
2978static int
2979window_fixed_size_p (struct window *w, int width_p, int check_siblings_p)
2980{
2981 int fixed_p;
2982 struct window *c;
2983
2984 if (!NILP (w->hchild))
2985 {
2986 c = XWINDOW (w->hchild);
2987
2988 if (width_p)
2989 {
2990 /* A horizontal combination is fixed-width if all of if its
2991 children are. */
2992 while (c && window_fixed_size_p (c, width_p, 0))
2993 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
2994 fixed_p = c == NULL;
2995 }
2996 else
2997 {
2998 /* A horizontal combination is fixed-height if one of if its
2999 children is. */
3000 while (c && !window_fixed_size_p (c, width_p, 0))
3001 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
3002 fixed_p = c != NULL;
3003 }
3004 }
3005 else if (!NILP (w->vchild))
3006 {
3007 c = XWINDOW (w->vchild);
3008
3009 if (width_p)
3010 {
3011 /* A vertical combination is fixed-width if one of if its
3012 children is. */
3013 while (c && !window_fixed_size_p (c, width_p, 0))
3014 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
3015 fixed_p = c != NULL;
3016 }
3017 else
3018 {
3019 /* A vertical combination is fixed-height if all of if its
3020 children are. */
3021 while (c && window_fixed_size_p (c, width_p, 0))
3022 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
3023 fixed_p = c == NULL;
3024 }
3025 }
3026 else if (BUFFERP (w->buffer))
3027 {
3028 struct buffer *old = current_buffer;
3029 Lisp_Object val;
3030
3031 current_buffer = XBUFFER (w->buffer);
3032 val = find_symbol_value (Qwindow_size_fixed);
3033 current_buffer = old;
3034
3035 fixed_p = 0;
3036 if (!EQ (val, Qunbound))
3037 {
3038 fixed_p = !NILP (val);
3039
3040 if (fixed_p
3041 && ((EQ (val, Qheight) && width_p)
3042 || (EQ (val, Qwidth) && !width_p)))
3043 fixed_p = 0;
3044 }
3045
3046 /* Can't tell if this one is resizable without looking at
3047 siblings. If all siblings are fixed-size this one is too. */
3048 if (!fixed_p && check_siblings_p && WINDOWP (w->parent))
3049 {
3050 Lisp_Object child;
3051
3052 for (child = w->prev; WINDOWP (child); child = XWINDOW (child)->prev)
3053 if (!window_fixed_size_p (XWINDOW (child), width_p, 0))
3054 break;
3055
3056 if (NILP (child))
3057 for (child = w->next; WINDOWP (child); child = XWINDOW (child)->next)
3058 if (!window_fixed_size_p (XWINDOW (child), width_p, 0))
3059 break;
3060
3061 if (NILP (child))
3062 fixed_p = 1;
3063 }
3064 }
3065 else
3066 fixed_p = 1;
3067
3068 return fixed_p;
3069}
3070
3071/* Return minimum size of leaf window W. WIDTH_P non-zero means return
3072 the minimum width of W, WIDTH_P zero means return the minimum height
3073 of W. SAFE_P non-zero means ignore window-min-height|width but just
3074 return values that won't crash Emacs and don't hide components like
3075 fringes, scrollbars, or modelines. If WIDTH_P is zero and W is the
3076 minibuffer window, always return 1. */
3077
3078static int
3079window_min_size_2 (struct window *w, int width_p, int safe_p)
3080{
3081 /* We should consider buffer-local values of window_min_height and
3082 window_min_width here. */
3083 if (width_p)
3084 {
3085 int safe_size = (MIN_SAFE_WINDOW_WIDTH
3086 + WINDOW_FRINGE_COLS (w)
3087 + WINDOW_SCROLL_BAR_COLS (w));
3088
3089 return safe_p ? safe_size : max (window_min_width, safe_size);
3090 }
3091 else if (MINI_WINDOW_P (w))
3092 return 1;
3093 else
3094 {
3095 int safe_size = (MIN_SAFE_WINDOW_HEIGHT
3096 + ((BUFFERP (w->buffer)
3097 && !NILP (BVAR (XBUFFER (w->buffer), mode_line_format)))
3098 ? 1 : 0));
3099
3100 return safe_p ? safe_size : max (window_min_height, safe_size);
3101 }
3102}
3103
3104/* Return minimum size of window W, not taking fixed-width windows into
3105 account. WIDTH_P non-zero means return the minimum width, otherwise
3106 return the minimum height. SAFE_P non-zero means ignore
3107 window-min-height|width but just return values that won't crash Emacs
3108 and don't hide components like fringes, scrollbars, or modelines. If
3109 W is a combination window, compute the minimum size from the minimum
3110 sizes of W's children. */
3111
3112static int
3113window_min_size_1 (struct window *w, int width_p, int safe_p)
3114{
3115 struct window *c;
3116 int size;
3117
3118 if (!NILP (w->hchild))
3119 {
3120 /* W is a horizontal combination. */
3121 c = XWINDOW (w->hchild);
3122 size = 0;
3123
3124 if (width_p)
3125 {
3126 /* The minimum width of a horizontal combination is the sum of
3127 the minimum widths of its children. */
3128 while (c)
3129 {
3130 size += window_min_size_1 (c, 1, safe_p);
3131 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
3132 }
3133 }
3134 else
3135 {
3136 /* The minimum height of a horizontal combination is the
3137 maximum of the minimum heights of its children. */
3138 while (c)
3139 {
3140 size = max (window_min_size_1 (c, 0, safe_p), size);
3141 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
3142 }
3143 }
3144 }
3145 else if (!NILP (w->vchild))
3146 {
3147 /* W is a vertical combination. */
3148 c = XWINDOW (w->vchild);
3149 size = 0;
3150
3151 if (width_p)
3152 {
3153 /* The minimum width of a vertical combination is the maximum
3154 of the minimum widths of its children. */
3155 while (c)
3156 {
3157 size = max (window_min_size_1 (c, 1, safe_p), size);
3158 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
3159 }
3160 }
3161 else
3162 {
3163 /* The minimum height of a vertical combination is the sum of
3164 the minimum height of its children. */
3165 while (c)
3166 {
3167 size += window_min_size_1 (c, 0, safe_p);
3168 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
3169 }
3170 }
3171 }
3172 else
3173 /* W is a leaf window. */
3174 size = window_min_size_2 (w, width_p, safe_p);
3175
3176 return size;
3177}
3178
3179/* Return the minimum size of window W, taking fixed-size windows into
3180 account. WIDTH_P non-zero means return the minimum width, otherwise
3181 return the minimum height. SAFE_P non-zero means ignore
3182 window-min-height|width but just return values that won't crash Emacs
3183 and don't hide components like fringes, scrollbars, or modelines.
3184 IGNORE_FIXED_P non-zero means ignore if W is fixed-size. Set *FIXED
3185 to 1 if W is fixed-size unless FIXED is null. */
3186
3187static int
3188window_min_size (struct window *w, int width_p, int safe_p, int ignore_fixed_p, int *fixed)
3189{
3190 int size, fixed_p;
3191
3192 if (ignore_fixed_p)
3193 fixed_p = 0;
3194 else
3195 fixed_p = window_fixed_size_p (w, width_p, 1);
3196
3197 if (fixed)
3198 *fixed = fixed_p;
3199
3200 if (fixed_p)
3201 size = WINDOW_TOTAL_SIZE (w, width_p);
3202 else
3203 size = window_min_size_1 (w, width_p, safe_p);
3204
3205 return size;
3206}
3207
3208
3209/* Adjust the margins of window W if text area is too small. 2992/* Adjust the margins of window W if text area is too small.
3210 Return 1 if window width is ok after adjustment; 0 if window 2993 Return 1 if window width is ok after adjustment; 0 if window
3211 is still too narrow. */ 2994 is still too narrow. */
@@ -3240,410 +3023,6 @@ adjust_window_margins (struct window *w)
3240 w->left_margin_cols = make_number (margin_cols); 3023 w->left_margin_cols = make_number (margin_cols);
3241 return 1; 3024 return 1;
3242} 3025}
3243
3244/* Calculate new sizes for windows in the list FORWARD when their
3245 compound size goes from TOTAL to SIZE. TOTAL must be greater than
3246 SIZE. The number of windows in FORWARD is NCHILDREN, and the number
3247 that can shrink is SHRINKABLE. Fixed-size windows may be shrunk if
3248 and only if RESIZE_FIXED_P is non-zero. WIDTH_P non-zero means
3249 shrink columns, otherwise shrink lines.
3250
3251 SAFE_P zero means windows may be sized down to window-min-height
3252 lines (window-min-window columns for WIDTH_P non-zero). SAFE_P
3253 non-zero means windows may be sized down to their minimum safe sizes
3254 taking into account the space needed to display modelines, fringes,
3255 and scrollbars.
3256
3257 This function returns an allocated array of new sizes that the caller
3258 must free. A size -1 means the window is fixed and RESIZE_FIXED_P is
3259 zero. A size zero means the window shall be deleted. Array index 0
3260 refers to the first window in FORWARD, 1 to the second, and so on.
3261
3262 This function resizes windows proportionally to their size. It also
3263 tries to preserve smaller windows by resizing larger windows before
3264 resizing any window to zero. If resize_proportionally is non-nil for
3265 a specific window, it will attempt to strictly resize that window
3266 proportionally, even at the expense of deleting smaller windows. */
3267static int *
3268shrink_windows (int total, int size, int nchildren, int shrinkable,
3269 int resize_fixed_p, Lisp_Object forward, int width_p, int safe_p)
3270{
3271 int available_resize = 0;
3272 int *new_sizes, *min_sizes;
3273 struct window *c;
3274 Lisp_Object child;
3275 int smallest = total;
3276 int total_removed = 0;
3277 int total_shrink = total - size;
3278 int i;
3279
3280 new_sizes = xmalloc (sizeof (*new_sizes) * nchildren);
3281 min_sizes = xmalloc (sizeof (*min_sizes) * nchildren);
3282
3283 for (i = 0, child = forward; !NILP (child); child = c->next, ++i)
3284 {
3285 int child_size;
3286
3287 c = XWINDOW (child);
3288 child_size = WINDOW_TOTAL_SIZE (c, width_p);
3289
3290 if (!resize_fixed_p && window_fixed_size_p (c, width_p, 0))
3291 new_sizes[i] = -1;
3292 else
3293 {
3294 new_sizes[i] = child_size;
3295 min_sizes[i] = window_min_size_1 (c, width_p, safe_p);
3296 if (child_size > min_sizes[i]
3297 && NILP (c->resize_proportionally))
3298 available_resize += child_size - min_sizes[i];
3299 }
3300 }
3301 /* We might need to shrink some windows to zero. Find the smallest
3302 windows and set them to 0 until we can fulfil the new size. */
3303
3304 while (shrinkable > 1 && size + available_resize < total)
3305 {
3306 for (i = 0; i < nchildren; ++i)
3307 if (new_sizes[i] > 0 && smallest > new_sizes[i])
3308 smallest = new_sizes[i];
3309
3310 for (i = 0; i < nchildren; ++i)
3311 if (new_sizes[i] == smallest)
3312 {
3313 /* Resize this window down to zero. */
3314 new_sizes[i] = 0;
3315 if (smallest > min_sizes[i])
3316 available_resize -= smallest - min_sizes[i];
3317 available_resize += smallest;
3318 --shrinkable;
3319 total_removed += smallest;
3320
3321 /* We don't know what the smallest is now. */
3322 smallest = total;
3323
3324 /* Out of for, just remove one window at the time and
3325 check again if we have enough space. */
3326 break;
3327 }
3328 }
3329
3330 /* Now, calculate the new sizes. Try to shrink each window
3331 proportional to its size. */
3332 for (i = 0; i < nchildren; ++i)
3333 {
3334 if (new_sizes[i] > min_sizes[i])
3335 {
3336 int to_shrink = total_shrink * new_sizes[i] / total;
3337
3338 if (new_sizes[i] - to_shrink < min_sizes[i])
3339 to_shrink = new_sizes[i] - min_sizes[i];
3340 new_sizes[i] -= to_shrink;
3341 total_removed += to_shrink;
3342 }
3343 }
3344
3345 /* Any reminder due to rounding, we just subtract from windows
3346 that are left and still can be shrunk. */
3347 while (total_shrink > total_removed)
3348 {
3349 int nonzero_sizes = 0;
3350
3351 for (i = 0; i < nchildren; ++i)
3352 if (new_sizes[i] > 0)
3353 ++nonzero_sizes;
3354
3355 for (i = 0; i < nchildren; ++i)
3356 if (new_sizes[i] > min_sizes[i])
3357 {
3358 --new_sizes[i];
3359 ++total_removed;
3360
3361 /* Out of for, just shrink one window at the time and
3362 check again if we have enough space. */
3363 break;
3364 }
3365
3366 /* Special case, only one window left. */
3367 if (nonzero_sizes == 1)
3368 break;
3369 }
3370
3371 /* Any surplus due to rounding, we add to windows that are left. */
3372 while (total_shrink < total_removed)
3373 {
3374 for (i = 0; i < nchildren; ++i)
3375 {
3376 if (new_sizes[i] != 0 && total_shrink < total_removed)
3377 {
3378 ++new_sizes[i];
3379 --total_removed;
3380 break;
3381 }
3382 }
3383 }
3384
3385 xfree (min_sizes);
3386
3387 return new_sizes;
3388}
3389
3390/* Set WINDOW's height or width to SIZE. WIDTH_P non-zero means set
3391 WINDOW's width. Resize WINDOW's children, if any, so that they keep
3392 their proportionate size relative to WINDOW.
3393
3394 If FIRST_ONLY is 1, change only the first of WINDOW's children when
3395 they are in series. If LAST_ONLY is 1, change only the last of
3396 WINDOW's children when they are in series.
3397
3398 Propagate WINDOW's top or left edge position to children. Delete
3399 windows that become too small unless NODELETE_P is 1. When
3400 NODELETE_P equals 2 do not honor settings for window-min-height and
3401 window-min-width when resizing windows but use safe defaults instead.
3402 This should give better behavior when resizing frames. */
3403
3404static void
3405size_window (Lisp_Object window, int size, int width_p, int nodelete_p, int first_only, int last_only)
3406{
3407 struct window *w = XWINDOW (window);
3408 struct window *c;
3409 Lisp_Object child, *forward, *sideward;
3410 int old_size = WINDOW_TOTAL_SIZE (w, width_p);
3411
3412 size = max (0, size);
3413
3414 /* Delete WINDOW if it's too small. */
3415 if (nodelete_p != 1 && !NILP (w->parent)
3416 && size < window_min_size_1 (w, width_p, nodelete_p == 2))
3417 {
3418 delete_window (window);
3419 return;
3420 }
3421
3422 /* Set redisplay hints. */
3423 w->last_modified = make_number (0);
3424 w->last_overlay_modified = make_number (0);
3425 windows_or_buffers_changed++;
3426 FRAME_WINDOW_SIZES_CHANGED (XFRAME (w->frame)) = 1;
3427
3428 if (width_p)
3429 {
3430 sideward = &w->vchild;
3431 forward = &w->hchild;
3432 w->total_cols = make_number (size);
3433 adjust_window_margins (w);
3434 }
3435 else
3436 {
3437 sideward = &w->hchild;
3438 forward = &w->vchild;
3439 w->total_lines = make_number (size);
3440 w->orig_total_lines = Qnil;
3441 }
3442
3443 if (!NILP (*sideward))
3444 {
3445 /* We have a chain of parallel siblings whose size should all change. */
3446 for (child = *sideward; !NILP (child); child = c->next)
3447 {
3448 c = XWINDOW (child);
3449 if (width_p)
3450 c->left_col = w->left_col;
3451 else
3452 c->top_line = w->top_line;
3453 size_window (child, size, width_p, nodelete_p,
3454 first_only, last_only);
3455 }
3456 }
3457 else if (!NILP (*forward) && last_only)
3458 {
3459 /* Change the last in a series of siblings. */
3460 Lisp_Object last_child;
3461 int child_size;
3462
3463 child = *forward;
3464 do
3465 {
3466 c = XWINDOW (child);
3467 last_child = child;
3468 child = c->next;
3469 }
3470 while (!NILP (child));
3471
3472 child_size = WINDOW_TOTAL_SIZE (c, width_p);
3473 size_window (last_child, size - old_size + child_size,
3474 width_p, nodelete_p, first_only, last_only);
3475 }
3476 else if (!NILP (*forward) && first_only)
3477 {
3478 /* Change the first in a series of siblings. */
3479 int child_size;
3480
3481 child = *forward;
3482 c = XWINDOW (child);
3483
3484 if (width_p)
3485 c->left_col = w->left_col;
3486 else
3487 c->top_line = w->top_line;
3488
3489 child_size = WINDOW_TOTAL_SIZE (c, width_p);
3490 size_window (child, size - old_size + child_size,
3491 width_p, nodelete_p, first_only, last_only);
3492 }
3493 else if (!NILP (*forward))
3494 {
3495 int fixed_size, each IF_LINT (= 0), extra IF_LINT (= 0), n;
3496 int resize_fixed_p, nfixed;
3497 int last_pos, first_pos, nchildren, total;
3498 int *new_sizes = NULL;
3499
3500 /* Determine the fixed-size portion of this window, and the
3501 number of child windows. */
3502 fixed_size = nchildren = nfixed = total = 0;
3503 for (child = *forward; !NILP (child); child = c->next, ++nchildren)
3504 {
3505 int child_size;
3506
3507 c = XWINDOW (child);
3508 child_size = WINDOW_TOTAL_SIZE (c, width_p);
3509 total += child_size;
3510
3511 if (window_fixed_size_p (c, width_p, 0))
3512 {
3513 fixed_size += child_size;
3514 ++nfixed;
3515 }
3516 }
3517
3518 /* If the new size is smaller than fixed_size, or if there
3519 aren't any resizable windows, allow resizing fixed-size
3520 windows. */
3521 resize_fixed_p = nfixed == nchildren || size < fixed_size;
3522
3523 /* Compute how many lines/columns to add/remove to each child. The
3524 value of extra takes care of rounding errors. */
3525 n = resize_fixed_p ? nchildren : nchildren - nfixed;
3526 if (size < total && n > 1)
3527 new_sizes = shrink_windows (total, size, nchildren, n,
3528 resize_fixed_p, *forward, width_p,
3529 nodelete_p == 2);
3530 else
3531 {
3532 each = (size - total) / n;
3533 extra = (size - total) - n * each;
3534 }
3535
3536 /* Compute new children heights and edge positions. */
3537 first_pos = width_p ? XINT (w->left_col) : XINT (w->top_line);
3538 last_pos = first_pos;
3539 for (n = 0, child = *forward; !NILP (child); child = c->next, ++n)
3540 {
3541 int new_child_size, old_child_size;
3542
3543 c = XWINDOW (child);
3544 old_child_size = WINDOW_TOTAL_SIZE (c, width_p);
3545 new_child_size = old_child_size;
3546
3547 /* The top or left edge position of this child equals the
3548 bottom or right edge of its predecessor. */
3549 if (width_p)
3550 c->left_col = make_number (last_pos);
3551 else
3552 c->top_line = make_number (last_pos);
3553
3554 /* If this child can be resized, do it. */
3555 if (resize_fixed_p || !window_fixed_size_p (c, width_p, 0))
3556 {
3557 new_child_size =
3558 new_sizes ? new_sizes[n] : old_child_size + each + extra;
3559 extra = 0;
3560 }
3561
3562 /* Set new size. Note that size_window also propagates
3563 edge positions to children, so it's not a no-op if we
3564 didn't change the child's size. */
3565 size_window (child, new_child_size, width_p, 1,
3566 first_only, last_only);
3567
3568 /* Remember the bottom/right edge position of this child; it
3569 will be used to set the top/left edge of the next child. */
3570 last_pos += new_child_size;
3571 }
3572
3573 xfree (new_sizes);
3574
3575 /* We should have covered the parent exactly with child windows. */
3576 xassert (size == last_pos - first_pos);
3577
3578 /* Now delete any children that became too small. */
3579 if (nodelete_p != 1)
3580 for (child = *forward; !NILP (child); child = c->next)
3581 {
3582 int child_size;
3583
3584 c = XWINDOW (child);
3585 child_size = WINDOW_TOTAL_SIZE (c, width_p);
3586 size_window (child, child_size, width_p, nodelete_p,
3587 first_only, last_only);
3588 }
3589 }
3590}
3591
3592/* Set WINDOW's height to HEIGHT, and recursively change the height of
3593 WINDOW's children. NODELETE zero means windows that have become
3594 smaller than window-min-height in the process may be deleted.
3595 NODELETE 1 means never delete windows that become too small in the
3596 process. (The caller should check later and do so if appropriate.)
3597 NODELETE 2 means delete only windows that have become too small to be
3598 displayed correctly. */
3599
3600void
3601set_window_height (Lisp_Object window, int height, int nodelete)
3602{
3603 size_window (window, height, 0, nodelete, 0, 0);
3604}
3605
3606/* Set WINDOW's width to WIDTH, and recursively change the width of
3607 WINDOW's children. NODELETE zero means windows that have become
3608 smaller than window-min-width in the process may be deleted.
3609 NODELETE 1 means never delete windows that become too small in the
3610 process. (The caller should check later and do so if appropriate.)
3611 NODELETE 2 means delete only windows that have become too small to be
3612 displayed correctly. */
3613
3614void
3615set_window_width (Lisp_Object window, int width, int nodelete)
3616{
3617 size_window (window, width, 1, nodelete, 0, 0);
3618}
3619
3620/* Change window heights in windows rooted in WINDOW by N lines. */
3621
3622void
3623change_window_heights (Lisp_Object window, int n)
3624{
3625 struct window *w = XWINDOW (window);
3626
3627 XSETFASTINT (w->top_line, XFASTINT (w->top_line) + n);
3628 XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - n);
3629
3630 if (INTEGERP (w->orig_top_line))
3631 XSETFASTINT (w->orig_top_line, XFASTINT (w->orig_top_line) + n);
3632 if (INTEGERP (w->orig_total_lines))
3633 XSETFASTINT (w->orig_total_lines, XFASTINT (w->orig_total_lines) - n);
3634
3635 /* Handle just the top child in a vertical split. */
3636 if (!NILP (w->vchild))
3637 change_window_heights (w->vchild, n);
3638
3639 /* Adjust all children in a horizontal split. */
3640 for (window = w->hchild; !NILP (window); window = w->next)
3641 {
3642 w = XWINDOW (window);
3643 change_window_heights (window, n);
3644 }
3645}
3646
3647 3026
3648int window_select_count; 3027int window_select_count;
3649 3028
@@ -3676,12 +3055,6 @@ run_window_configuration_change_hook (struct frame *f)
3676 if (NILP (Vrun_hooks)) 3055 if (NILP (Vrun_hooks))
3677 return; 3056 return;
3678 3057
3679 if (SELECTED_FRAME () != f)
3680 {
3681 record_unwind_protect (select_frame_norecord, Fselected_frame ());
3682 Fselect_frame (frame, Qt);
3683 }
3684
3685 /* Use the right buffer. Matters when running the local hooks. */ 3058 /* Use the right buffer. Matters when running the local hooks. */
3686 if (current_buffer != XBUFFER (Fwindow_buffer (Qnil))) 3059 if (current_buffer != XBUFFER (Fwindow_buffer (Qnil)))
3687 { 3060 {
@@ -3689,6 +3062,12 @@ run_window_configuration_change_hook (struct frame *f)
3689 Fset_buffer (Fwindow_buffer (Qnil)); 3062 Fset_buffer (Fwindow_buffer (Qnil));
3690 } 3063 }
3691 3064
3065 if (SELECTED_FRAME () != f)
3066 {
3067 record_unwind_protect (select_frame_norecord, Fselected_frame ());
3068 select_frame_norecord (frame);
3069 }
3070
3692 /* Look for buffer-local values. */ 3071 /* Look for buffer-local values. */
3693 { 3072 {
3694 Lisp_Object windows = Fwindow_list (frame, Qlambda, Qnil); 3073 Lisp_Object windows = Fwindow_list (frame, Qlambda, Qnil);
@@ -3699,12 +3078,12 @@ run_window_configuration_change_hook (struct frame *f)
3699 if (!NILP (Flocal_variable_p (Qwindow_configuration_change_hook, 3078 if (!NILP (Flocal_variable_p (Qwindow_configuration_change_hook,
3700 buffer))) 3079 buffer)))
3701 { 3080 {
3702 int count1 = SPECPDL_INDEX (); 3081 int count = SPECPDL_INDEX ();
3703 record_unwind_protect (select_window_norecord, Fselected_window ()); 3082 record_unwind_protect (select_window_norecord, Fselected_window ());
3704 select_window_norecord (window); 3083 select_window_norecord (window);
3705 run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook, 3084 run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook,
3706 buffer)); 3085 buffer));
3707 unbind_to (count1, Qnil); 3086 unbind_to (count, Qnil);
3708 } 3087 }
3709 } 3088 }
3710 } 3089 }
@@ -3713,6 +3092,16 @@ run_window_configuration_change_hook (struct frame *f)
3713 unbind_to (count, Qnil); 3092 unbind_to (count, Qnil);
3714} 3093}
3715 3094
3095DEFUN ("run-window-configuration-change-hook", Frun_window_configuration_change_hook,
3096 Srun_window_configuration_change_hook, 1, 1, 0,
3097 doc: /* Run `window-configuration-change-hook' for FRAME. */)
3098 (Lisp_Object frame)
3099{
3100 CHECK_LIVE_FRAME (frame);
3101 run_window_configuration_change_hook (XFRAME (frame));
3102 return Qnil;
3103}
3104
3716/* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero 3105/* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero
3717 means it's allowed to run hooks. See make_frame for a case where 3106 means it's allowed to run hooks. See make_frame for a case where
3718 it's not allowed. KEEP_MARGINS_P non-zero means that the current 3107 it's not allowed. KEEP_MARGINS_P non-zero means that the current
@@ -4000,10 +3389,13 @@ DEFUN ("internal-temp-output-buffer-show",
4000 return Qnil; 3389 return Qnil;
4001} 3390}
4002 3391
3392/* Make new window, have it replace WINDOW in window-tree, and make
3393 WINDOW its only vertical child (HORFLAG 1 means make WINDOW its only
3394 horizontal child). */
4003static void 3395static void
4004make_dummy_parent (Lisp_Object window) 3396make_parent_window (Lisp_Object window, int horflag)
4005{ 3397{
4006 Lisp_Object new; 3398 Lisp_Object parent;
4007 register struct window *o, *p; 3399 register struct window *o, *p;
4008 int i; 3400 int i;
4009 3401
@@ -4011,30 +3403,27 @@ make_dummy_parent (Lisp_Object window)
4011 p = allocate_window (); 3403 p = allocate_window ();
4012 for (i = 0; i < VECSIZE (struct window); ++i) 3404 for (i = 0; i < VECSIZE (struct window); ++i)
4013 ((struct Lisp_Vector *) p)->contents[i] 3405 ((struct Lisp_Vector *) p)->contents[i]
4014 = ((struct Lisp_Vector *)o)->contents[i]; 3406 = ((struct Lisp_Vector *) o)->contents[i];
4015 XSETWINDOW (new, p); 3407 XSETWINDOW (parent, p);
4016 3408
4017 ++sequence_number; 3409 ++sequence_number;
4018 XSETFASTINT (p->sequence_number, sequence_number); 3410 XSETFASTINT (p->sequence_number, sequence_number);
4019 XSETFASTINT (p->clone_number, sequence_number); 3411 XSETFASTINT (p->clone_number, sequence_number);
4020 3412
4021 /* Put new into window structure in place of window */ 3413 replace_window (window, parent, 1);
4022 replace_window (window, new);
4023 3414
4024 o->next = Qnil; 3415 o->next = Qnil;
4025 o->prev = Qnil; 3416 o->prev = Qnil;
4026 o->vchild = Qnil; 3417 o->parent = parent;
4027 o->hchild = Qnil;
4028 o->parent = new;
4029 3418
3419 p->hchild = horflag ? window : Qnil;
3420 p->vchild = horflag ? Qnil : window;
4030 p->start = Qnil; 3421 p->start = Qnil;
4031 p->pointm = Qnil; 3422 p->pointm = Qnil;
4032 p->buffer = Qnil; 3423 p->buffer = Qnil;
4033
4034 p->splits = Qnil; 3424 p->splits = Qnil;
4035 p->nest = Qnil; 3425 p->nest = Qnil;
4036 p->window_parameters = Qnil; 3426 p->window_parameters = Qnil;
4037
4038} 3427}
4039 3428
4040/* Make new window from scratch. */ 3429/* Make new window from scratch. */
@@ -4096,7 +3485,6 @@ make_window (void)
4096 w->pseudo_window_p = 0; 3485 w->pseudo_window_p = 0;
4097 w->frozen_window_start_p = 0; 3486 w->frozen_window_start_p = 0;
4098 w->vscroll = 0; 3487 w->vscroll = 0;
4099 w->resize_proportionally = Qnil;
4100 /* Reset window_list. */ 3488 /* Reset window_list. */
4101 Vwindow_list = Qnil; 3489 Vwindow_list = Qnil;
4102 /* Return window. */ 3490 /* Return window. */
@@ -4138,872 +3526,770 @@ Note: This function does not operate on any subwindows of WINDOW. */)
4138 return w->new_normal; 3526 return w->new_normal;
4139} 3527}
4140 3528
4141DEFUN ("split-window", Fsplit_window, Ssplit_window, 0, 3, "", 3529/* Return 1 if setting w->total_lines (w->total_cols if HORFLAG is
4142 doc: /* Split WINDOW, putting SIZE lines in the first of the pair. 3530 non-zero) to w->new_total would result in correct heights (widths)
4143WINDOW defaults to selected one and SIZE to half its size. 3531 for window W and recursively all subwindows of W.
4144If optional third arg HORIZONTAL is non-nil, split side by side and put
4145SIZE columns in the first of the pair. In that case, SIZE includes that
4146window's scroll bar, or the divider column to its right.
4147Interactively, all arguments are nil.
4148Returns the newly created window (which is the lower or rightmost one).
4149The upper or leftmost window is the original one, and remains selected
4150if it was selected before.
4151 3532
4152See Info node `(elisp)Splitting Windows' for more details and examples. */) 3533 Note: This function does not check any of `window-fixed-size-p',
4153 (Lisp_Object window, Lisp_Object size, Lisp_Object horizontal) 3534 `window-min-height' or `window-min-width'. It does check that window
3535 sizes do not drop below one line (two columns). */
3536int
3537resize_window_check (struct window *w, int horflag)
4154{ 3538{
4155 register Lisp_Object new; 3539 struct window *c;
4156 register struct window *o, *p;
4157 FRAME_PTR fo;
4158 register int size_int;
4159
4160 if (NILP (window))
4161 window = selected_window;
4162 else
4163 CHECK_LIVE_WINDOW (window);
4164
4165 o = XWINDOW (window);
4166 fo = XFRAME (WINDOW_FRAME (o));
4167 3540
4168 if (NILP (size)) 3541 if (!NILP (w->vchild))
3542 /* W is a vertical combination. */
4169 { 3543 {
4170 if (!NILP (horizontal)) 3544 c = XWINDOW (w->vchild);
4171 /* Calculate the size of the left-hand window, by dividing 3545 if (horflag)
4172 the usable space in columns by two. 3546 /* All subwindows of W must have the same width as W. */
4173 We round up, since the left-hand window may include 3547 {
4174 a dividing line, while the right-hand may not. */ 3548 while (c)
4175 size_int = (XFASTINT (o->total_cols) + 1) >> 1; 3549 {
3550 if ((XINT (c->new_total) != XINT (w->new_total))
3551 || !resize_window_check (c, horflag))
3552 return 0;
3553 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3554 }
3555 return 1;
3556 }
4176 else 3557 else
4177 size_int = XFASTINT (o->total_lines) >> 1; 3558 /* The sum of the heights of the subwindows of W must equal W's
3559 height. */
3560 {
3561 int sum_of_sizes = 0;
3562 while (c)
3563 {
3564 if (!resize_window_check (c, horflag))
3565 return 0;
3566 sum_of_sizes = sum_of_sizes + XINT (c->new_total);
3567 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3568 }
3569 return (sum_of_sizes == XINT (w->new_total));
3570 }
4178 } 3571 }
4179 else 3572 else if (!NILP (w->hchild))
3573 /* W is a horizontal combination. */
4180 { 3574 {
4181 CHECK_NUMBER (size); 3575 c = XWINDOW (w->hchild);
4182 size_int = XINT (size); 3576 if (horflag)
3577 /* The sum of the widths of the subwindows of W must equal W's
3578 width. */
3579 {
3580 int sum_of_sizes = 0;
3581 while (c)
3582 {
3583 if (!resize_window_check (c, horflag))
3584 return 0;
3585 sum_of_sizes = sum_of_sizes + XINT (c->new_total);
3586 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3587 }
3588 return (sum_of_sizes == XINT (w->new_total));
3589 }
3590 else
3591 /* All subwindows of W must have the same height as W. */
3592 {
3593 while (c)
3594 {
3595 if ((XINT (c->new_total) != XINT (w->new_total))
3596 || !resize_window_check (c, horflag))
3597 return 0;
3598 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3599 }
3600 return 1;
3601 }
4183 } 3602 }
3603 else
3604 /* A leaf window. Make sure it's not too small. The following
3605 hardcodes the values of `window-safe-min-width' (2) and
3606 `window-safe-min-height' (1) which are defined in window.el. */
3607 return XINT (w->new_total) >= (horflag ? 2 : 1);
3608}
4184 3609
4185 if (MINI_WINDOW_P (o)) 3610/* Set w->total_lines (w->total_cols if HORIZONTAL is non-zero) to
4186 error ("Attempt to split minibuffer window"); 3611 w->new_total for window W and recursively all subwindows of W. Also
4187 else if (window_fixed_size_p (o, !NILP (horizontal), 0)) 3612 calculate and assign the new vertical (horizontal) start positions of
4188 error ("Attempt to split fixed-size window"); 3613 each of these windows.
4189 3614
4190 if (NILP (horizontal)) 3615 This function does not perform any error checks. Make sure you have
3616 run resize_window_check on W before applying this function. */
3617static void
3618resize_window_apply (struct window *w, int horflag)
3619{
3620 struct window *c, *p;
3621 int pos;
3622
3623 /* Note: Assigning new_normal requires that the new total size of the
3624 parent window has been set *before*. */
3625 if (horflag)
4191 { 3626 {
4192 int window_safe_height = window_min_size_2 (o, 0, 0); 3627 w->total_cols = w->new_total;
3628 if (NUMBERP (w->new_normal))
3629 w->normal_cols = w->new_normal;
4193 3630
4194 if (size_int < window_safe_height) 3631 pos = XINT (w->left_col);
4195 error ("Window height %d too small (after splitting)", size_int);
4196 if (size_int + window_safe_height > XFASTINT (o->total_lines))
4197 error ("Window height %d too small (after splitting)",
4198 (int) (XFASTINT (o->total_lines) - size_int));
4199 if (NILP (o->parent)
4200 || NILP (XWINDOW (o->parent)->vchild))
4201 {
4202 make_dummy_parent (window);
4203 new = o->parent;
4204 XWINDOW (new)->vchild = window;
4205 }
4206 } 3632 }
4207 else 3633 else
4208 { 3634 {
4209 int window_safe_width = window_min_size_2 (o, 1, 0); 3635 w->total_lines = w->new_total;
3636 if (NUMBERP (w->new_normal))
3637 w->normal_lines = w->new_normal;
4210 3638
4211 if (size_int < window_safe_width) 3639 pos = XINT (w->top_line);
4212 error ("Window width %d too small (after splitting)", size_int);
4213 if (size_int + window_safe_width > XFASTINT (o->total_cols))
4214 error ("Window width %d too small (after splitting)",
4215 (int) (XFASTINT (o->total_cols) - size_int));
4216 if (NILP (o->parent)
4217 || NILP (XWINDOW (o->parent)->hchild))
4218 {
4219 make_dummy_parent (window);
4220 new = o->parent;
4221 XWINDOW (new)->hchild = window;
4222 }
4223 } 3640 }
4224 3641
4225 /* Now we know that window's parent is a vertical combination 3642 if (!NILP (w->vchild))
4226 if we are dividing vertically, or a horizontal combination 3643 /* W is a vertical combination. */
4227 if we are making side-by-side windows */ 3644 {
4228 3645 c = XWINDOW (w->vchild);
4229 windows_or_buffers_changed++; 3646 while (c)
4230 FRAME_WINDOW_SIZES_CHANGED (fo) = 1; 3647 {
4231 new = make_window (); 3648 if (horflag)
4232 p = XWINDOW (new); 3649 XSETFASTINT (c->left_col, pos);
4233 3650 else
4234 p->frame = o->frame; 3651 XSETFASTINT (c->top_line, pos);
4235 p->next = o->next; 3652 resize_window_apply (c, horflag);
4236 if (!NILP (p->next)) 3653 if (!horflag)
4237 XWINDOW (p->next)->prev = new; 3654 pos = pos + XINT (c->total_lines);
4238 p->prev = window; 3655 c = NILP (c->next) ? 0 : XWINDOW (c->next);
4239 o->next = new; 3656 }
4240 p->parent = o->parent;
4241 p->buffer = Qt;
4242 p->window_end_valid = Qnil;
4243 memset (&p->last_cursor, 0, sizeof p->last_cursor);
4244
4245 /* Duplicate special geometry settings. */
4246
4247 p->left_margin_cols = o->left_margin_cols;
4248 p->right_margin_cols = o->right_margin_cols;
4249 p->left_fringe_width = o->left_fringe_width;
4250 p->right_fringe_width = o->right_fringe_width;
4251 p->fringes_outside_margins = o->fringes_outside_margins;
4252 p->scroll_bar_width = o->scroll_bar_width;
4253 p->vertical_scroll_bar_type = o->vertical_scroll_bar_type;
4254
4255 /* Apportion the available frame space among the two new windows */
4256
4257 if (!NILP (horizontal))
4258 {
4259 p->total_lines = o->total_lines;
4260 p->top_line = o->top_line;
4261 XSETFASTINT (p->total_cols, XFASTINT (o->total_cols) - size_int);
4262 XSETFASTINT (o->total_cols, size_int);
4263 XSETFASTINT (p->left_col, XFASTINT (o->left_col) + size_int);
4264 adjust_window_margins (p);
4265 adjust_window_margins (o);
4266 } 3657 }
4267 else 3658 else if (!NILP (w->hchild))
3659 /* W is a horizontal combination. */
4268 { 3660 {
4269 p->left_col = o->left_col; 3661 c = XWINDOW (w->hchild);
4270 p->total_cols = o->total_cols; 3662 while (c)
4271 XSETFASTINT (p->total_lines, XFASTINT (o->total_lines) - size_int); 3663 {
4272 XSETFASTINT (o->total_lines, size_int); 3664 if (horflag)
4273 XSETFASTINT (p->top_line, XFASTINT (o->top_line) + size_int); 3665 XSETFASTINT (c->left_col, pos);
3666 else
3667 XSETFASTINT (c->top_line, pos);
3668 resize_window_apply (c, horflag);
3669 if (horflag)
3670 pos = pos + XINT (c->total_cols);
3671 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3672 }
4274 } 3673 }
4275 3674
4276 /* Adjust glyph matrices. */ 3675 /* Clear out some redisplay caches. */
4277 adjust_glyphs (fo); 3676 XSETFASTINT (w->last_modified, 0);
4278 3677 XSETFASTINT (w->last_overlay_modified, 0);
4279 Fset_window_buffer (new, o->buffer, Qt);
4280 return new;
4281}
4282
4283DEFUN ("enlarge-window", Fenlarge_window, Senlarge_window, 1, 2, "p",
4284 doc: /* Make selected window SIZE lines taller.
4285Interactively, if no argument is given, make the selected window one
4286line taller. If optional argument HORIZONTAL is non-nil, make selected
4287window wider by SIZE columns. If SIZE is negative, shrink the window by
4288-SIZE lines or columns. Return nil.
4289
4290This function can delete windows if they get too small. The size of
4291fixed size windows is not altered by this function. */)
4292 (Lisp_Object size, Lisp_Object horizontal)
4293{
4294 CHECK_NUMBER (size);
4295 enlarge_window (selected_window, XINT (size), !NILP (horizontal));
4296
4297 run_window_configuration_change_hook (SELECTED_FRAME ());
4298
4299 return Qnil;
4300} 3678}
4301 3679
4302DEFUN ("shrink-window", Fshrink_window, Sshrink_window, 1, 2, "p",
4303 doc: /* Make selected window SIZE lines smaller.
4304Interactively, if no argument is given, make the selected window one
4305line smaller. If optional argument HORIZONTAL is non-nil, make the
4306window narrower by SIZE columns. If SIZE is negative, enlarge selected
4307window by -SIZE lines or columns. Return nil.
4308
4309This function can delete windows if they get too small. The size of
4310fixed size windows is not altered by this function. */)
4311 (Lisp_Object size, Lisp_Object horizontal)
4312{
4313 CHECK_NUMBER (size);
4314 enlarge_window (selected_window, -XINT (size), !NILP (horizontal));
4315
4316 run_window_configuration_change_hook (SELECTED_FRAME ());
4317 3680
4318 return Qnil; 3681DEFUN ("resize-window-apply", Fresize_window_apply, Sresize_window_apply, 1, 2, 0,
4319} 3682 doc: /* Apply requested size values for window-tree of FRAME.
3683Optional argument HORIZONTAL omitted or nil means apply requested height
3684values. HORIZONTAL non-nil means apply requested width values.
4320 3685
4321static int 3686This function checks whether the requested values sum up to a valid
4322window_height (Lisp_Object window) 3687window layout, recursively assigns the new sizes of all subwindows and
4323{ 3688calculates and assigns the new start positions of these windows.
4324 register struct window *p = XWINDOW (window);
4325 return WINDOW_TOTAL_LINES (p);
4326}
4327 3689
4328static int 3690Note: This function does not check any of `window-fixed-size-p',
4329window_width (Lisp_Object window) 3691`window-min-height' or `window-min-width'. All these checks have to
3692be applied on the Elisp level. */)
3693 (Lisp_Object frame, Lisp_Object horizontal)
4330{ 3694{
4331 register struct window *p = XWINDOW (window); 3695 struct frame *f;
4332 return WINDOW_TOTAL_COLS (p); 3696 struct window *r;
4333} 3697 int horflag = !NILP (horizontal);
4334
4335
4336#define CURBEG(w) \
4337 *(horiz_flag ? &(XWINDOW (w)->left_col) : &(XWINDOW (w)->top_line))
4338
4339#define CURSIZE(w) \
4340 *(horiz_flag ? &(XWINDOW (w)->total_cols) : &(XWINDOW (w)->total_lines))
4341
4342 3698
4343/* Enlarge WINDOW by DELTA. HORIZ_FLAG nonzero means enlarge it 3699 if (NILP (frame))
4344 horizontally; zero means do it vertically. 3700 frame = selected_frame;
3701 CHECK_LIVE_FRAME (frame);
4345 3702
4346 Siblings of the selected window are resized to fulfill the size 3703 f = XFRAME (frame);
4347 request. If they become too small in the process, they may be 3704 r = XWINDOW (FRAME_ROOT_WINDOW (f));
4348 deleted. */
4349 3705
4350static void 3706 if (!resize_window_check (r, horflag)
4351enlarge_window (Lisp_Object window, int delta, int horiz_flag) 3707 || ! EQ (r->new_total, (horflag ? r->total_cols : r->total_lines)))
4352{ 3708 return Qnil;
4353 Lisp_Object parent, next, prev;
4354 struct window *p;
4355 Lisp_Object *sizep;
4356 int maximum;
4357 int (*sizefun) (Lisp_Object)
4358 = horiz_flag ? window_width : window_height;
4359 void (*setsizefun) (Lisp_Object, int, int)
4360 = (horiz_flag ? set_window_width : set_window_height);
4361 3709
4362 /* Give up if this window cannot be resized. */ 3710 BLOCK_INPUT;
4363 if (window_fixed_size_p (XWINDOW (window), horiz_flag, 1)) 3711 resize_window_apply (r, horflag);
4364 error ("Window is not resizable");
4365 3712
4366 /* Find the parent of the selected window. */ 3713 windows_or_buffers_changed++;
4367 while (1) 3714 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
4368 {
4369 p = XWINDOW (window);
4370 parent = p->parent;
4371 3715
4372 if (NILP (parent)) 3716 adjust_glyphs (f);
4373 { 3717 UNBLOCK_INPUT;
4374 if (horiz_flag)
4375 error ("No other window to side of this one");
4376 break;
4377 }
4378 3718
4379 if (horiz_flag 3719 run_window_configuration_change_hook (f);
4380 ? !NILP (XWINDOW (parent)->hchild)
4381 : !NILP (XWINDOW (parent)->vchild))
4382 break;
4383 3720
4384 window = parent; 3721 return Qt;
4385 } 3722}
4386 3723
4387 sizep = &CURSIZE (window);
4388 3724
4389 { 3725/* Resize frame F's windows when number of lines of F is set to SIZE.
4390 register int maxdelta; 3726 HORFLAG 1 means resize windows when number of columns of F is set to
4391 3727 SIZE.
4392 /* Compute the maximum size increment this window can have. */
4393
4394 maxdelta = (!NILP (parent) ? (*sizefun) (parent) - XINT (*sizep)
4395 /* This is a main window followed by a minibuffer. */
4396 : !NILP (p->next) ? ((*sizefun) (p->next)
4397 - window_min_size (XWINDOW (p->next),
4398 horiz_flag, 0, 0, 0))
4399 /* This is a minibuffer following a main window. */
4400 : !NILP (p->prev) ? ((*sizefun) (p->prev)
4401 - window_min_size (XWINDOW (p->prev),
4402 horiz_flag, 0, 0, 0))
4403 /* This is a frame with only one window, a minibuffer-only
4404 or a minibufferless frame. */
4405 : (delta = 0));
4406
4407 if (delta > maxdelta)
4408 /* This case traps trying to make the minibuffer
4409 the full frame, or make the only window aside from the
4410 minibuffer the full frame. */
4411 delta = maxdelta;
4412 }
4413 3728
4414 if (XINT (*sizep) + delta < window_min_size (XWINDOW (window), 3729 This function can delete all windows but the selected one in order to
4415 horiz_flag, 0, 0, 0)) 3730 satisfy the request. The result will be meaningful if and only if
3731 F's windows have meaningful sizes when you call this. */
3732void
3733resize_frame_windows (struct frame *f, int size, int horflag)
3734{
3735 Lisp_Object root = f->root_window;
3736 struct window *r = XWINDOW (root);
3737 Lisp_Object mini = f->minibuffer_window;
3738 struct window *m;
3739 /* new_size is the new size of the frame's root window. */
3740 int new_size = (horflag
3741 ? size
3742 : (size
3743 - FRAME_TOP_MARGIN (f)
3744 - ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
3745 ? 1 : 0)));
3746
3747 XSETFASTINT (r->top_line, FRAME_TOP_MARGIN (f));
3748 if (NILP (r->vchild) && NILP (r->hchild))
3749 /* For a leaf root window just set the size. */
3750 if (horflag)
3751 XSETFASTINT (r->total_cols, new_size);
3752 else
3753 XSETFASTINT (r->total_lines, new_size);
3754 else
4416 { 3755 {
4417 delete_window (window); 3756 /* old_size is the old size of the frame's root window. */
4418 return; 3757 int old_size = XFASTINT (horflag ? r->total_cols : r->total_lines);
4419 } 3758 Lisp_Object delta;
4420
4421 if (delta == 0)
4422 return;
4423 3759
4424 /* Find the total we can get from other siblings without deleting them. */ 3760 XSETINT (delta, new_size - old_size);
4425 maximum = 0; 3761 /* Try a "normal" resize first. */
4426 for (next = p->next; WINDOWP (next); next = XWINDOW (next)->next) 3762 resize_root_window (root, delta, horflag ? Qt : Qnil, Qnil);
4427 maximum += (*sizefun) (next) - window_min_size (XWINDOW (next), 3763 if (resize_window_check (r, horflag) && new_size == XINT (r->new_total))
4428 horiz_flag, 0, 0, 0); 3764 resize_window_apply (r, horflag);
4429 for (prev = p->prev; WINDOWP (prev); prev = XWINDOW (prev)->prev) 3765 else
4430 maximum += (*sizefun) (prev) - window_min_size (XWINDOW (prev),
4431 horiz_flag, 0, 0, 0);
4432
4433 /* If we can get it all from them without deleting them, do so. */
4434 if (delta <= maximum)
4435 {
4436 Lisp_Object first_unaffected;
4437 Lisp_Object first_affected;
4438 int fixed_p;
4439
4440 next = p->next;
4441 prev = p->prev;
4442 first_affected = window;
4443 /* Look at one sibling at a time,
4444 moving away from this window in both directions alternately,
4445 and take as much as we can get without deleting that sibling. */
4446 while (delta != 0
4447 && (!NILP (next) || !NILP (prev)))
4448 { 3766 {
4449 if (! NILP (next)) 3767 /* Try with "reasonable" minimum sizes next. */
4450 { 3768 resize_root_window (root, delta, horflag ? Qt : Qnil, Qt);
4451 int this_one = ((*sizefun) (next) 3769 if (resize_window_check (r, horflag)
4452 - window_min_size (XWINDOW (next), horiz_flag, 3770 && new_size == XINT (r->new_total))
4453 0, 0, &fixed_p)); 3771 resize_window_apply (r, horflag);
4454 if (!fixed_p) 3772 else
4455 {
4456 if (this_one > delta)
4457 this_one = delta;
4458
4459 (*setsizefun) (next, (*sizefun) (next) - this_one, 0);
4460 (*setsizefun) (window, XINT (*sizep) + this_one, 0);
4461
4462 delta -= this_one;
4463 }
4464
4465 next = XWINDOW (next)->next;
4466 }
4467
4468 if (delta == 0)
4469 break;
4470
4471 if (! NILP (prev))
4472 { 3773 {
4473 int this_one = ((*sizefun) (prev) 3774 /* Finally, try with "safe" minimum sizes. */
4474 - window_min_size (XWINDOW (prev), horiz_flag, 3775 resize_root_window (root, delta, horflag ? Qt : Qnil, Qsafe);
4475 0, 0, &fixed_p)); 3776 if (resize_window_check (r, horflag)
4476 if (!fixed_p) 3777 && new_size == XINT (r->new_total))
3778 resize_window_apply (r, horflag);
3779 else
4477 { 3780 {
4478 if (this_one > delta) 3781 /* We lost. Delete all windows but the frame's
4479 this_one = delta; 3782 selected one. */
4480 3783 root = f->selected_window;
4481 first_affected = prev; 3784 Fdelete_other_windows_internal (root, Qnil);
4482 3785 if (horflag)
4483 (*setsizefun) (prev, (*sizefun) (prev) - this_one, 0); 3786 XSETFASTINT (XWINDOW (root)->total_cols, new_size);
4484 (*setsizefun) (window, XINT (*sizep) + this_one, 0); 3787 else
4485 3788 XSETFASTINT (XWINDOW (root)->total_lines, new_size);
4486 delta -= this_one;
4487 } 3789 }
4488
4489 prev = XWINDOW (prev)->prev;
4490 } 3790 }
4491 } 3791 }
4492
4493 xassert (delta == 0);
4494
4495 /* Now recalculate the edge positions of all the windows affected,
4496 based on the new sizes. */
4497 first_unaffected = next;
4498 prev = first_affected;
4499 for (next = XWINDOW (prev)->next; ! EQ (next, first_unaffected);
4500 prev = next, next = XWINDOW (next)->next)
4501 {
4502 XSETINT (CURBEG (next), XINT (CURBEG (prev)) + (*sizefun) (prev));
4503 /* This does not change size of NEXT,
4504 but it propagates the new top edge to its children */
4505 (*setsizefun) (next, (*sizefun) (next), 0);
4506 }
4507 } 3792 }
4508 else
4509 {
4510 register int delta1;
4511 register int opht = (*sizefun) (parent);
4512
4513 if (opht <= XINT (*sizep) + delta)
4514 {
4515 /* If trying to grow this window to or beyond size of the parent,
4516 just delete all the sibling windows. */
4517 Lisp_Object start, tem;
4518
4519 start = XWINDOW (parent)->vchild;
4520 if (NILP (start))
4521 start = XWINDOW (parent)->hchild;
4522 3793
4523 /* Delete any siblings that come after WINDOW. */ 3794 if (FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
4524 tem = XWINDOW (window)->next; 3795 {
4525 while (! NILP (tem)) 3796 m = XWINDOW (mini);
4526 { 3797 if (horflag)
4527 Lisp_Object next1 = XWINDOW (tem)->next; 3798 XSETFASTINT (m->total_cols, size);
4528 delete_window (tem);
4529 tem = next1;
4530 }
4531
4532 /* Delete any siblings that come after WINDOW.
4533 Note that if START is not WINDOW, then WINDOW still
4534 has siblings, so WINDOW has not yet replaced its parent. */
4535 tem = start;
4536 while (! EQ (tem, window))
4537 {
4538 Lisp_Object next1 = XWINDOW (tem)->next;
4539 delete_window (tem);
4540 tem = next1;
4541 }
4542 }
4543 else 3799 else
4544 { 3800 {
4545 /* Otherwise, make delta1 just right so that if we add 3801 /* Are we sure we always want 1 line here? */
4546 delta1 lines to this window and to the parent, and then 3802 XSETFASTINT (m->total_lines, 1);
4547 shrink the parent back to its original size, the new 3803 XSETFASTINT (m->top_line, XINT (r->top_line) + XINT (r->total_lines));
4548 proportional size of this window will increase by delta.
4549
4550 The function size_window will compute the new height h'
4551 of the window from delta1 as:
4552
4553 e = delta1/n
4554 x = delta1 - delta1/n * n for the 1st resizable child
4555 h' = h + e + x
4556
4557 where n is the number of children that can be resized.
4558 We can ignore x by choosing a delta1 that is a multiple of
4559 n. We want the height of this window to come out as
4560
4561 h' = h + delta
4562
4563 So, delta1 must be
4564
4565 h + e = h + delta
4566 delta1/n = delta
4567 delta1 = n * delta.
4568
4569 The number of children n equals the number of resizable
4570 children of this window + 1 because we know window itself
4571 is resizable (otherwise we would have signaled an error).
4572
4573 This reasoning is not correct when other windows become too
4574 small and shrink_windows refuses to delete them. Below we
4575 use resize_proportionally to work around this problem. */
4576
4577 struct window *w = XWINDOW (window);
4578 Lisp_Object s;
4579 int n = 1;
4580
4581 for (s = w->next; WINDOWP (s); s = XWINDOW (s)->next)
4582 if (!window_fixed_size_p (XWINDOW (s), horiz_flag, 0))
4583 ++n;
4584 for (s = w->prev; WINDOWP (s); s = XWINDOW (s)->prev)
4585 if (!window_fixed_size_p (XWINDOW (s), horiz_flag, 0))
4586 ++n;
4587
4588 delta1 = n * delta;
4589
4590 /* Add delta1 lines or columns to this window, and to the parent,
4591 keeping things consistent while not affecting siblings. */
4592 XSETINT (CURSIZE (parent), opht + delta1);
4593 (*setsizefun) (window, XINT (*sizep) + delta1, 0);
4594
4595 /* Squeeze out delta1 lines or columns from our parent,
4596 shrinking this window and siblings proportionately. This
4597 brings parent back to correct size. Delta1 was calculated
4598 so this makes this window the desired size, taking it all
4599 out of the siblings.
4600
4601 Temporarily set resize_proportionally to Qt to assure that,
4602 if necessary, shrink_windows deletes smaller windows rather
4603 than shrink this window. */
4604 w->resize_proportionally = Qt;
4605 (*setsizefun) (parent, opht, 0);
4606 w->resize_proportionally = Qnil;
4607 } 3804 }
4608 } 3805 }
3806}
4609 3807
4610 XSETFASTINT (p->last_modified, 0);
4611 XSETFASTINT (p->last_overlay_modified, 0);
4612 3808
4613 /* Adjust glyph matrices. */ 3809DEFUN ("split-window-internal", Fsplit_window_internal, Ssplit_window_internal, 4, 4, 0,
4614 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window)))); 3810 doc: /* Split window OLD.
4615} 3811Second argument TOTAL-SIZE specifies the number of lines or columns of the
3812new window. In any case TOTAL-SIZE must be a positive integer
4616 3813
3814Third argument SIDE nil (or `below') specifies that the new window shall
3815be located below WINDOW. SIDE `above' means the new window shall be
3816located above WINDOW. In both cases TOTAL-SIZE specifies the number of
3817lines of the new window including space reserved for the mode and/or
3818header line.
4617 3819
4618/* Adjust the size of WINDOW by DELTA, moving only its trailing edge. 3820SIDE t (or `right') specifies that the new window shall be located on
4619 HORIZ_FLAG nonzero means adjust the width, moving the right edge. 3821the right side of WINDOW. SIDE `left' means the new window shall be
4620 zero means adjust the height, moving the bottom edge. 3822located on the left of WINDOW. In both cases TOTAL-SIZE specifies the
3823number of columns of the new window including space reserved for fringes
3824and the scrollbar or a divider column.
4621 3825
4622 Following siblings of the selected window are resized to fulfill 3826Fourth argument NORMAL-SIZE specifies the normal size of the new window
4623 the size request. If they become too small in the process, they 3827according to the SIDE argument.
4624 are not deleted; instead, we signal an error. */
4625 3828
4626static void 3829The new total and normal sizes of all involved windows must have been
4627adjust_window_trailing_edge (Lisp_Object window, int delta, int horiz_flag) 3830set correctly. See the code of `split-window' for how this is done. */)
3831 (Lisp_Object old, Lisp_Object total_size, Lisp_Object side, Lisp_Object normal_size)
4628{ 3832{
4629 Lisp_Object parent, child; 3833 /* OLD (*o) is the window we have to split. (*p) is either OLD's
4630 struct window *p; 3834 parent window or an internal window we have to install as OLD's new
4631 Lisp_Object old_config = Fcurrent_window_configuration (Qnil); 3835 parent. REFERENCE (*r) must denote a live window, or is set to OLD
4632 int delcount = window_deletion_count; 3836 provided OLD is a leaf window, or to the frame's selected window.
4633 3837 NEW (*n) is the new window created with some parameters taken from
4634 CHECK_WINDOW (window); 3838 REFERENCE (*r). */
3839 register Lisp_Object new, frame, reference;
3840 register struct window *o, *p, *n, *r;
3841 struct frame *f;
3842 int horflag
3843 /* HORFLAG is 1 when we split side-by-side, 0 otherwise. */
3844 = EQ (side, Qt) || EQ (side, Qleft) || EQ (side, Qright);
3845 int do_nest = 0;
3846
3847 CHECK_WINDOW (old);
3848 o = XWINDOW (old);
3849 frame = WINDOW_FRAME (o);
3850 f = XFRAME (frame);
4635 3851
4636 /* Give up if this window cannot be resized. */ 3852 CHECK_NUMBER (total_size);
4637 if (window_fixed_size_p (XWINDOW (window), horiz_flag, 1)) 3853
4638 error ("Window is not resizable"); 3854 /* Set do_nest to 1 if we have to make a new parent window. We do
3855 that if either `window-nest' is non-nil, or OLD has no parent, or
3856 OLD is ortho-combined. */
3857 do_nest =
3858 !NILP (Vwindow_nest)
3859 || NILP (o->parent)
3860 || NILP (horflag
3861 ? (XWINDOW (o->parent)->hchild)
3862 : (XWINDOW (o->parent)->vchild));
3863
3864 /* We need a live reference window to initialize some parameters. */
3865 if (WINDOW_LIVE_P (old))
3866 /* OLD is live, use it as reference window. */
3867 reference = old;
3868 else
3869 /* Use the frame's selected window as reference window. */
3870 reference = FRAME_SELECTED_WINDOW (f);
3871 r = XWINDOW (reference);
4639 3872
4640 while (1) 3873 /* The following bugs are caught by `split-window'. */
3874 if (MINI_WINDOW_P (o))
3875 error ("Attempt to split minibuffer window");
3876 else if (XINT (total_size) < (horflag ? 2 : 1))
3877 error ("Size of new window too small (after split)");
3878 else if (!do_nest && !NILP (Vwindow_splits))
3879 /* `window-splits' non-nil means try to resize OLD's siblings
3880 proportionally. */
3881 {
3882 p = XWINDOW (o->parent);
3883 /* Temporarily pretend we split the parent window. */
3884 XSETINT (p->new_total,
3885 XINT (horflag ? p->total_cols : p->total_lines)
3886 - XINT (total_size));
3887 if (!resize_window_check (p, horflag))
3888 error ("Window sizes don't fit");
3889 else
3890 /* Undo the temporary pretension. */
3891 p->new_total = horflag ? p->total_cols : p->total_lines;
3892 }
3893 else
4641 { 3894 {
4642 Lisp_Object first_parallel = Qnil; 3895 if (!resize_window_check (o, horflag))
4643 3896 error ("Resizing old window failed");
4644 if (NILP (window)) 3897 else if (XINT (total_size) + XINT (o->new_total)
4645 { 3898 != XINT (horflag ? o->total_cols : o->total_lines))
4646 /* This happens if WINDOW on the previous iteration was 3899 error ("Sum of sizes of old and new window don't fit");
4647 at top level of the window tree. */ 3900 }
4648 Fset_window_configuration (old_config); 3901
4649 error ("Specified window edge is fixed"); 3902 /* This is our point of no return. */
4650 } 3903 if (do_nest)
3904 {
3905 /* Save the old value of o->normal_cols/lines. It gets corrupted
3906 by make_parent_window and we need it below for assigning it to
3907 p->new_normal. */
3908 Lisp_Object new_normal = horflag ? o->normal_cols : o->normal_lines;
3909
3910 make_parent_window (old, horflag);
3911 p = XWINDOW (o->parent);
3912 /* Store value of `window-nest' in new parent's nest slot. */
3913 p->nest = Vwindow_nest;
3914 /* Have PARENT inherit splits slot value from OLD. */
3915 p->splits = o->splits;
3916 /* Store value of `window-splits' in OLD's splits slot. */
3917 o->splits = Vwindow_splits;
3918 /* These get applied below. */
3919 p->new_total = horflag ? o->total_cols : o->total_lines;
3920 p->new_normal = new_normal;
3921 }
3922 else
3923 p = XWINDOW (o->parent);
4651 3924
4652 p = XWINDOW (window); 3925 windows_or_buffers_changed++;
4653 parent = p->parent; 3926 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
3927 new = make_window ();
3928 n = XWINDOW (new);
3929 n->frame = frame;
3930 n->parent = o->parent;
3931 n->vchild = n->hchild = Qnil;
4654 3932
4655 /* See if this level has windows in parallel in the specified 3933 if (EQ (side, Qabove) || EQ (side, Qleft))
4656 direction. If so, set FIRST_PARALLEL to the first one. */ 3934 {
4657 if (horiz_flag) 3935 n->prev = o->prev;
4658 { 3936 if (NILP (n->prev))
4659 if (! NILP (parent) && !NILP (XWINDOW (parent)->vchild)) 3937 if (horflag)
4660 first_parallel = XWINDOW (parent)->vchild; 3938 p->hchild = new;
4661 else if (NILP (parent) && !NILP (p->next)) 3939 else
4662 { 3940 p->vchild = new;
4663 /* Handle the vertical chain of main window and minibuffer
4664 which has no parent. */
4665 first_parallel = window;
4666 while (! NILP (XWINDOW (first_parallel)->prev))
4667 first_parallel = XWINDOW (first_parallel)->prev;
4668 }
4669 }
4670 else 3941 else
4671 { 3942 XWINDOW (n->prev)->next = new;
4672 if (! NILP (parent) && !NILP (XWINDOW (parent)->hchild)) 3943 n->next = old;
4673 first_parallel = XWINDOW (parent)->hchild; 3944 o->prev = new;
4674 } 3945 }
4675 3946 else
4676 /* If this level's succession is in the desired dimension, 3947 {
4677 and this window is the last one, and there is no higher level, 3948 n->next = o->next;
4678 its trailing edge is fixed. */ 3949 if (!NILP (n->next))
4679 if (NILP (XWINDOW (window)->next) && NILP (first_parallel) 3950 XWINDOW (n->next)->prev = new;
4680 && NILP (parent)) 3951 n->prev = old;
4681 { 3952 o->next = new;
4682 Fset_window_configuration (old_config); 3953 }
4683 error ("Specified window edge is fixed");
4684 }
4685
4686 /* Don't make this window too small. */
4687 if (XINT (CURSIZE (window)) + delta
4688 < window_min_size_2 (XWINDOW (window), horiz_flag, 0))
4689 {
4690 Fset_window_configuration (old_config);
4691 error ("Cannot adjust window size as specified");
4692 }
4693 3954
4694 /* Clear out some redisplay caches. */ 3955 n->buffer = Qt;
4695 XSETFASTINT (p->last_modified, 0); 3956 n->window_end_valid = Qnil;
4696 XSETFASTINT (p->last_overlay_modified, 0); 3957 memset (&n->last_cursor, 0, sizeof n->last_cursor);
4697 3958
4698 /* Adjust this window's edge. */ 3959 /* Get special geometry settings from reference window. */
4699 XSETINT (CURSIZE (window), 3960 n->left_margin_cols = r->left_margin_cols;
4700 XINT (CURSIZE (window)) + delta); 3961 n->right_margin_cols = r->right_margin_cols;
3962 n->left_fringe_width = r->left_fringe_width;
3963 n->right_fringe_width = r->right_fringe_width;
3964 n->fringes_outside_margins = r->fringes_outside_margins;
3965 n->scroll_bar_width = r->scroll_bar_width;
3966 n->vertical_scroll_bar_type = r->vertical_scroll_bar_type;
4701 3967
4702 /* If this window has following siblings in the desired dimension, 3968 /* Store `window-splits' in NEW's splits slot. */
4703 make them smaller, and exit the loop. 3969 n->splits = Vwindow_splits;
4704 3970
4705 (If we reach the top of the tree and can never do this, 3971 /* Directly assign orthogonal coordinates and sizes. */
4706 we will fail and report an error, above.) */ 3972 if (horflag)
4707 if (NILP (first_parallel)) 3973 {
4708 { 3974 n->top_line = o->top_line;
4709 if (!NILP (p->next)) 3975 n->total_lines = o->total_lines;
4710 {
4711 /* This may happen for the minibuffer. In that case
4712 the window_deletion_count check below does not work. */
4713 if (XINT (CURSIZE (p->next)) - delta <= 0)
4714 {
4715 Fset_window_configuration (old_config);
4716 error ("Cannot adjust window size as specified");
4717 }
4718
4719 XSETINT (CURBEG (p->next),
4720 XINT (CURBEG (p->next)) + delta);
4721 size_window (p->next, XINT (CURSIZE (p->next)) - delta,
4722 horiz_flag, 0, 1, 0);
4723 break;
4724 }
4725 }
4726 else
4727 /* Here we have a chain of parallel siblings, in the other dimension.
4728 Change the size of the other siblings. */
4729 for (child = first_parallel;
4730 ! NILP (child);
4731 child = XWINDOW (child)->next)
4732 if (! EQ (child, window))
4733 size_window (child, XINT (CURSIZE (child)) + delta,
4734 horiz_flag, 0, 0, 1);
4735
4736 window = parent;
4737 } 3976 }
4738 3977 else
4739 /* If we made a window so small it got deleted,
4740 we failed. Report failure. */
4741 if (delcount != window_deletion_count)
4742 { 3978 {
4743 Fset_window_configuration (old_config); 3979 n->left_col = o->left_col;
4744 error ("Cannot adjust window size as specified"); 3980 n->total_cols = o->total_cols;
4745 } 3981 }
4746 3982
4747 /* Adjust glyph matrices. */ 3983 /* Iso-coordinates and sizes are assigned by resize_window_apply,
4748 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window)))); 3984 get them ready here. */
4749} 3985 n->new_total = total_size;
4750 3986 n->new_normal = normal_size;
4751#undef CURBEG
4752#undef CURSIZE
4753
4754DEFUN ("adjust-window-trailing-edge", Fadjust_window_trailing_edge,
4755 Sadjust_window_trailing_edge, 3, 3, 0,
4756 doc: /* Adjust the bottom or right edge of WINDOW by DELTA.
4757If HORIZONTAL is non-nil, that means adjust the width, moving the right edge.
4758Otherwise, adjust the height, moving the bottom edge.
4759 3987
4760Following siblings of the selected window are resized to fulfill 3988 BLOCK_INPUT;
4761the size request. If they become too small in the process, they 3989 resize_window_apply (p, horflag);
4762are not deleted; instead, we signal an error. */) 3990 adjust_glyphs (f);
4763 (Lisp_Object window, Lisp_Object delta, Lisp_Object horizontal) 3991 /* Set buffer of NEW to buffer of reference window. Don't run
4764{ 3992 any hooks. */
4765 CHECK_NUMBER (delta); 3993 set_window_buffer (new, r->buffer, 0, 1);
4766 if (NILP (window)) 3994 UNBLOCK_INPUT;
4767 window = selected_window;
4768 adjust_window_trailing_edge (window, XINT (delta), !NILP (horizontal));
4769
4770 run_window_configuration_change_hook
4771 (XFRAME (WINDOW_FRAME (XWINDOW (window))));
4772 3995
4773 return Qnil; 3996 /* Maybe we should run the scroll functions in Elisp (which already
3997 runs the configuration change hook). */
3998 if (! NILP (Vwindow_scroll_functions))
3999 run_hook_with_args_2 (Qwindow_scroll_functions, new,
4000 Fmarker_position (n->start));
4001 /* Return NEW. */
4002 return new;
4774} 4003}
4775 4004
4776 4005
4777 4006DEFUN ("delete-window-internal", Fdelete_window_internal, Sdelete_window_internal, 1, 1, 0,
4778/*********************************************************************** 4007 doc: /* Remove WINDOW from its frame.
4779 Resizing Mini-Windows 4008WINDOW defaults to the selected window. Return nil. Signal an error
4780 ***********************************************************************/ 4009when WINDOW is the only window on its frame. */)
4781 4010 (register Lisp_Object window)
4782static void shrink_window_lowest_first (struct window *, int);
4783
4784enum save_restore_action
4785{ 4011{
4786 CHECK_ORIG_SIZES, 4012 register Lisp_Object parent, sibling, frame, root;
4787 SAVE_ORIG_SIZES, 4013 struct window *w, *p, *s, *r;
4788 RESTORE_ORIG_SIZES 4014 struct frame *f;
4789}; 4015 int horflag;
4790 4016 int before_sibling = 0;
4791static int save_restore_orig_size (struct window *,
4792 enum save_restore_action);
4793
4794/* Shrink windows rooted in window W to HEIGHT. Take the space needed
4795 from lowest windows first. */
4796 4017
4797static void 4018 w = decode_any_window (window);
4798shrink_window_lowest_first (struct window *w, int height) 4019 XSETWINDOW (window, w);
4799{ 4020 if (NILP (w->buffer) && NILP (w->hchild) && NILP (w->vchild))
4800 struct window *c; 4021 /* It's a no-op to delete an already deleted window. */
4801 Lisp_Object child; 4022 return Qnil;
4802 int old_height;
4803 4023
4804 xassert (!MINI_WINDOW_P (w)); 4024 parent = w->parent;
4025 if (NILP (parent))
4026 /* Never delete a minibuffer or frame root window. */
4027 error ("Attempt to delete minibuffer or sole ordinary window");
4028 else if (NILP (w->prev) && NILP (w->next))
4029 /* Rather bow out here, this case should be handled on the Elisp
4030 level. */
4031 error ("Attempt to delete sole window of parent");
4805 4032
4806 /* Set redisplay hints. */ 4033 p = XWINDOW (parent);
4807 XSETFASTINT (w->last_modified, 0); 4034 horflag = NILP (p->vchild);
4808 XSETFASTINT (w->last_overlay_modified, 0);
4809 windows_or_buffers_changed++;
4810 FRAME_WINDOW_SIZES_CHANGED (XFRAME (WINDOW_FRAME (w))) = 1;
4811 4035
4812 old_height = XFASTINT (w->total_lines); 4036 frame = WINDOW_FRAME (w);
4813 XSETFASTINT (w->total_lines, height); 4037 f = XFRAME (frame);
4814 4038
4815 if (!NILP (w->hchild)) 4039 root = FRAME_ROOT_WINDOW (f);
4040 r = XWINDOW (root);
4041
4042 /* Unlink WINDOW from window tree. */
4043 if (NILP (w->prev))
4044 /* Get SIBLING below (on the right of) WINDOW. */
4045 {
4046 /* before_sibling 1 means WINDOW is the first child of its
4047 parent and thus before the sibling. */
4048 before_sibling = 1;
4049 sibling = w->next;
4050 s = XWINDOW (sibling);
4051 s->prev = Qnil;
4052 if (horflag)
4053 p->hchild = sibling;
4054 else
4055 p->vchild = sibling;
4056 }
4057 else
4058 /* Get SIBLING above (on the left of) WINDOW. */
4816 { 4059 {
4817 for (child = w->hchild; !NILP (child); child = c->next) 4060 sibling = w->prev;
4818 { 4061 s = XWINDOW (sibling);
4819 c = XWINDOW (child); 4062 s->next = w->next;
4820 c->top_line = w->top_line; 4063 if (!NILP (s->next))
4821 shrink_window_lowest_first (c, height); 4064 XWINDOW (s->next)->prev = sibling;
4822 }
4823 } 4065 }
4824 else if (!NILP (w->vchild)) 4066
4067 if (resize_window_check (r, horflag)
4068 && EQ (r->new_total, (horflag ? r->total_cols : r->total_lines)))
4069 /* We can delete WINDOW now. */
4825 { 4070 {
4826 Lisp_Object last_child; 4071 /* Block input. */
4827 int delta = old_height - height; 4072 BLOCK_INPUT;
4828 int last_top; 4073 resize_window_apply (p, horflag);
4829 4074
4830 last_child = Qnil; 4075 windows_or_buffers_changed++;
4076 Vwindow_list = Qnil;
4077 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
4831 4078
4832 /* Find the last child. We are taking space from lowest windows 4079 w->next = Qnil; /* Don't delete w->next too. */
4833 first, so we iterate over children from the last child 4080 free_window_matrices (w);
4834 backwards. */
4835 for (child = w->vchild; WINDOWP (child); child = XWINDOW (child)->next)
4836 last_child = child;
4837 4081
4838 /* Size children down to their safe heights. */ 4082 if (!NILP (w->vchild))
4839 for (child = last_child; delta && !NILP (child); child = c->prev)
4840 { 4083 {
4841 int this_one; 4084 delete_all_subwindows (w->vchild);
4842 4085 w->vchild = Qnil;
4843 c = XWINDOW (child);
4844 this_one = XFASTINT (c->total_lines) - window_min_size_1 (c, 0, 1);
4845
4846 if (this_one > delta)
4847 this_one = delta;
4848
4849 shrink_window_lowest_first (c, XFASTINT (c->total_lines) - this_one);
4850 delta -= this_one;
4851 } 4086 }
4852 4087 else if (!NILP (w->hchild))
4853 /* Compute new positions. */
4854 last_top = XINT (w->top_line);
4855 for (child = w->vchild; !NILP (child); child = c->next)
4856 { 4088 {
4857 c = XWINDOW (child); 4089 delete_all_subwindows (w->hchild);
4858 c->top_line = make_number (last_top); 4090 w->hchild = Qnil;
4859 shrink_window_lowest_first (c, XFASTINT (c->total_lines)); 4091 }
4860 last_top += XFASTINT (c->total_lines); 4092 else if (!NILP (w->buffer))
4093 {
4094 unshow_buffer (w);
4095 unchain_marker (XMARKER (w->pointm));
4096 unchain_marker (XMARKER (w->start));
4097 w->buffer = Qnil;
4861 } 4098 }
4862 }
4863}
4864 4099
4100 if (NILP (s->prev) && NILP (s->next))
4101 /* A matrjoshka where SIBLING has become the only child of
4102 PARENT. */
4103 {
4104 /* Put SIBLING into PARENT's place. */
4105 replace_window (parent, sibling, 0);
4106 /* Have SIBLING inherit the following three slot values from
4107 PARENT (the nest slot is not inherited). */
4108 s->normal_cols = p->normal_cols;
4109 s->normal_lines = p->normal_lines;
4110 s->splits = p->splits;
4111 /* Mark PARENT as deleted. */
4112 p->vchild = p->hchild = Qnil;
4113 /* Try to merge SIBLING into its new parent. */
4114 recombine_windows (sibling);
4115 }
4865 4116
4866/* Save, restore, or check positions and sizes in the window tree 4117 adjust_glyphs (f);
4867 rooted at W. ACTION says what to do.
4868 4118
4869 If ACTION is CHECK_ORIG_SIZES, check if orig_top_line and 4119 if (!WINDOW_LIVE_P (FRAME_SELECTED_WINDOW (f)))
4870 orig_total_lines members are valid for all windows in the window 4120 /* We deleted the frame's selected window. */
4871 tree. Value is non-zero if they are valid. 4121 {
4122 /* Use the frame's first window as fallback ... */
4123 Lisp_Object new_selected_window = Fframe_first_window (frame);
4124 /* ... but preferably use its most recently used window. */
4125 Lisp_Object mru_window;
4126
4127 /* `get-mru-window' might fail for some reason so play it safe
4128 - promote the first window _without recording it_ first. */
4129 if (EQ (FRAME_SELECTED_WINDOW (f), selected_window))
4130 Fselect_window (new_selected_window, Qt);
4131 else
4132 FRAME_SELECTED_WINDOW (f) = new_selected_window;
4872 4133
4873 If ACTION is SAVE_ORIG_SIZES, save members top and height in 4134 UNBLOCK_INPUT;
4874 orig_top_line and orig_total_lines for all windows in the tree.
4875 4135
4876 If ACTION is RESTORE_ORIG_SIZES, restore top and height from values 4136 /* Now look whether `get-mru-window' gets us something. */
4877 stored in orig_top_line and orig_total_lines for all windows. */ 4137 mru_window = call1 (Qget_mru_window, frame);
4138 if (WINDOW_LIVE_P (mru_window)
4139 && EQ (XWINDOW (mru_window)->frame, frame))
4140 new_selected_window = mru_window;
4878 4141
4879static int 4142 /* If all ended up well, we now promote the mru window. */
4880save_restore_orig_size (struct window *w, enum save_restore_action action) 4143 if (EQ (FRAME_SELECTED_WINDOW (f), selected_window))
4881{ 4144 Fselect_window (new_selected_window, Qnil);
4882 int success_p = 1; 4145 else
4146 FRAME_SELECTED_WINDOW (f) = new_selected_window;
4147 }
4148 else
4149 UNBLOCK_INPUT;
4883 4150
4884 while (w) 4151 /* Must be run by the caller:
4152 run_window_configuration_change_hook (f); */
4153 }
4154 else
4155 /* We failed: Relink WINDOW into window tree. */
4885 { 4156 {
4886 if (!NILP (w->hchild)) 4157 if (before_sibling)
4887 {
4888 if (!save_restore_orig_size (XWINDOW (w->hchild), action))
4889 success_p = 0;
4890 }
4891 else if (!NILP (w->vchild))
4892 { 4158 {
4893 if (!save_restore_orig_size (XWINDOW (w->vchild), action)) 4159 s->prev = window;
4894 success_p = 0; 4160 if (horflag)
4161 p->hchild = window;
4162 else
4163 p->vchild = window;
4895 } 4164 }
4896 4165 else
4897 switch (action)
4898 { 4166 {
4899 case CHECK_ORIG_SIZES: 4167 s->next = window;
4900 if (!INTEGERP (w->orig_top_line) || !INTEGERP (w->orig_total_lines)) 4168 if (!NILP (w->next))
4901 return 0; 4169 XWINDOW (w->next)->prev = window;
4902 break;
4903
4904 case SAVE_ORIG_SIZES:
4905 w->orig_top_line = w->top_line;
4906 w->orig_total_lines = w->total_lines;
4907 XSETFASTINT (w->last_modified, 0);
4908 XSETFASTINT (w->last_overlay_modified, 0);
4909 break;
4910
4911 case RESTORE_ORIG_SIZES:
4912 xassert (INTEGERP (w->orig_top_line) && INTEGERP (w->orig_total_lines));
4913 w->top_line = w->orig_top_line;
4914 w->total_lines = w->orig_total_lines;
4915 w->orig_total_lines = w->orig_top_line = Qnil;
4916 XSETFASTINT (w->last_modified, 0);
4917 XSETFASTINT (w->last_overlay_modified, 0);
4918 break;
4919
4920 default:
4921 abort ();
4922 } 4170 }
4923 4171 error ("Deletion failed");
4924 w = NILP (w->next) ? NULL : XWINDOW (w->next);
4925 } 4172 }
4926 4173
4927 return success_p; 4174 return Qnil;
4928} 4175}
4176
4177/***********************************************************************
4178 Resizing Mini-Windows
4179 ***********************************************************************/
4929 4180
4930 4181/* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we
4931/* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we can 4182 can. */
4932 without deleting other windows. */
4933
4934void 4183void
4935grow_mini_window (struct window *w, int delta) 4184grow_mini_window (struct window *w, int delta)
4936{ 4185{
4937 struct frame *f = XFRAME (w->frame); 4186 struct frame *f = XFRAME (w->frame);
4938 struct window *root; 4187 struct window *r;
4188 Lisp_Object root, value;
4939 4189
4940 xassert (MINI_WINDOW_P (w)); 4190 xassert (MINI_WINDOW_P (w));
4941 /* Commenting out the following assertion goes against the stated interface 4191 xassert (delta >= 0);
4942 of the function, but it currently does not seem to do anything useful.
4943 See discussion of this issue in the thread for bug#4534.
4944 xassert (delta >= 0); */
4945 4192
4946 /* Compute how much we can enlarge the mini-window without deleting 4193 root = FRAME_ROOT_WINDOW (f);
4947 other windows. */ 4194 r = XWINDOW (root);
4948 root = XWINDOW (FRAME_ROOT_WINDOW (f)); 4195 value = call2 (Qresize_root_window_vertically, root, make_number (- delta));
4949 if (delta > 0) 4196 if (INTEGERP (value) && resize_window_check (r, 0))
4950 { 4197 {
4951 int min_height = window_min_size (root, 0, 0, 0, 0); 4198 BLOCK_INPUT;
4952 if (XFASTINT (root->total_lines) - delta < min_height) 4199 resize_window_apply (r, 0);
4953 /* Note that the root window may already be smaller than
4954 min_height. */
4955 delta = max (0, XFASTINT (root->total_lines) - min_height);
4956 }
4957
4958 if (delta)
4959 {
4960 /* Save original window sizes and positions, if not already done. */
4961 if (!save_restore_orig_size (root, CHECK_ORIG_SIZES))
4962 save_restore_orig_size (root, SAVE_ORIG_SIZES);
4963
4964 /* Shrink other windows. */
4965 shrink_window_lowest_first (root, XFASTINT (root->total_lines) - delta);
4966 4200
4967 /* Grow the mini-window. */ 4201 /* Grow the mini-window. */
4968 w->top_line = make_number (XFASTINT (root->top_line) + XFASTINT (root->total_lines)); 4202 XSETFASTINT (w->top_line, XFASTINT (r->top_line) + XFASTINT (r->total_lines));
4969 w->total_lines = make_number (XFASTINT (w->total_lines) + delta); 4203 XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - XINT (value));
4970 XSETFASTINT (w->last_modified, 0); 4204 XSETFASTINT (w->last_modified, 0);
4971 XSETFASTINT (w->last_overlay_modified, 0); 4205 XSETFASTINT (w->last_overlay_modified, 0);
4972 4206
4973 adjust_glyphs (f); 4207 adjust_glyphs (f);
4208 UNBLOCK_INPUT;
4974 } 4209 }
4975} 4210}
4976 4211
4977 4212
4978/* Shrink mini-window W. If there is recorded info about window sizes 4213/* Shrink mini-window W. */
4979 before a call to grow_mini_window, restore recorded window sizes.
4980 Otherwise, if the mini-window is higher than 1 line, resize it to 1
4981 line. */
4982
4983void 4214void
4984shrink_mini_window (struct window *w) 4215shrink_mini_window (struct window *w)
4985{ 4216{
4986 struct frame *f = XFRAME (w->frame); 4217 struct frame *f = XFRAME (w->frame);
4987 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f)); 4218 struct window *r;
4219 Lisp_Object root, value;
4220 EMACS_INT size;
4988 4221
4989 if (save_restore_orig_size (root, CHECK_ORIG_SIZES)) 4222 xassert (MINI_WINDOW_P (w));
4990 { 4223
4991 save_restore_orig_size (root, RESTORE_ORIG_SIZES); 4224 size = XINT (w->total_lines);
4992 adjust_glyphs (f); 4225 if (size > 1)
4993 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
4994 windows_or_buffers_changed = 1;
4995 }
4996 else if (XFASTINT (w->total_lines) > 1)
4997 { 4226 {
4998 /* Distribute the additional lines of the mini-window 4227 root = FRAME_ROOT_WINDOW (f);
4999 among the other windows. */ 4228 r = XWINDOW (root);
5000 Lisp_Object window; 4229 value = call2 (Qresize_root_window_vertically,
5001 XSETWINDOW (window, w); 4230 root, make_number (size - 1));
5002 enlarge_window (window, 1 - XFASTINT (w->total_lines), 0); 4231 if (INTEGERP (value) && resize_window_check (r, 0))
4232 {
4233 BLOCK_INPUT;
4234 resize_window_apply (r, 0);
4235
4236 /* Shrink the mini-window. */
4237 XSETFASTINT (w->top_line, XFASTINT (r->top_line) + XFASTINT (r->total_lines));
4238 XSETFASTINT (w->total_lines, 1);
4239
4240 XSETFASTINT (w->last_modified, 0);
4241 XSETFASTINT (w->last_overlay_modified, 0);
4242
4243 adjust_glyphs (f);
4244 UNBLOCK_INPUT;
4245 }
4246 /* If the above failed for whatever strange reason we must make a
4247 one window frame here. The same routine will be needed when
4248 shrinking the frame (and probably when making the initial
4249 *scratch* window). For the moment leave things as they are. */
5003 } 4250 }
5004} 4251}
5005 4252
4253DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, Sresize_mini_window_internal, 1, 1, 0,
4254 doc: /* Resize minibuffer window WINDOW. */)
4255 (Lisp_Object window)
4256{
4257 struct window *w = XWINDOW (window);
4258 struct window *r;
4259 struct frame *f;
4260 int height;
5006 4261
4262 CHECK_WINDOW (window);
4263 f = XFRAME (w->frame);
4264
4265 if (!EQ (FRAME_MINIBUF_WINDOW (XFRAME (w->frame)), window))
4266 error ("Not a valid minibuffer window");
4267 else if (FRAME_MINIBUF_ONLY_P (f))
4268 error ("Cannot resize a minibuffer-only frame");
4269
4270 r = XWINDOW (FRAME_ROOT_WINDOW (f));
4271 height = XINT (r->total_lines) + XINT (w->total_lines);
4272 if (resize_window_check (r, 0)
4273 && XINT (w->new_total) > 0
4274 && height == XINT (r->new_total) + XINT (w->new_total))
4275 {
4276 BLOCK_INPUT;
4277 resize_window_apply (r, 0);
4278
4279 w->total_lines = w->new_total;
4280 XSETFASTINT (w->top_line, XINT (r->top_line) + XINT (r->total_lines));
4281
4282 windows_or_buffers_changed++;
4283 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
4284 adjust_glyphs (f);
4285 UNBLOCK_INPUT;
4286
4287 run_window_configuration_change_hook (f);
4288 return Qt;
4289 }
4290 else error ("Failed to resize minibuffer window");
4291}
4292
5007 4293
5008/* Mark window cursors off for all windows in the window tree rooted 4294/* Mark window cursors off for all windows in the window tree rooted
5009 at W by setting their phys_cursor_on_p flag to zero. Called from 4295 at W by setting their phys_cursor_on_p flag to zero. Called from
@@ -6190,11 +5476,9 @@ struct saved_window
6190 Lisp_Object parent, prev; 5476 Lisp_Object parent, prev;
6191 Lisp_Object start_at_line_beg; 5477 Lisp_Object start_at_line_beg;
6192 Lisp_Object display_table; 5478 Lisp_Object display_table;
6193 Lisp_Object orig_top_line, orig_total_lines;
6194 Lisp_Object left_margin_cols, right_margin_cols; 5479 Lisp_Object left_margin_cols, right_margin_cols;
6195 Lisp_Object left_fringe_width, right_fringe_width, fringes_outside_margins; 5480 Lisp_Object left_fringe_width, right_fringe_width, fringes_outside_margins;
6196 Lisp_Object scroll_bar_width, vertical_scroll_bar_type; 5481 Lisp_Object scroll_bar_width, vertical_scroll_bar_type, dedicated;
6197 Lisp_Object dedicated, resize_proportionally;
6198 Lisp_Object splits, nest, window_parameters; 5482 Lisp_Object splits, nest, window_parameters;
6199}; 5483};
6200 5484
@@ -6414,8 +5698,6 @@ the return value is nil. Otherwise the value is t. */)
6414 w->hscroll = p->hscroll; 5698 w->hscroll = p->hscroll;
6415 w->min_hscroll = p->min_hscroll; 5699 w->min_hscroll = p->min_hscroll;
6416 w->display_table = p->display_table; 5700 w->display_table = p->display_table;
6417 w->orig_top_line = p->orig_top_line;
6418 w->orig_total_lines = p->orig_total_lines;
6419 w->left_margin_cols = p->left_margin_cols; 5701 w->left_margin_cols = p->left_margin_cols;
6420 w->right_margin_cols = p->right_margin_cols; 5702 w->right_margin_cols = p->right_margin_cols;
6421 w->left_fringe_width = p->left_fringe_width; 5703 w->left_fringe_width = p->left_fringe_width;
@@ -6427,7 +5709,6 @@ the return value is nil. Otherwise the value is t. */)
6427 w->splits = p->splits; 5709 w->splits = p->splits;
6428 w->nest = p->nest; 5710 w->nest = p->nest;
6429 w->window_parameters = p->window_parameters; 5711 w->window_parameters = p->window_parameters;
6430 w->resize_proportionally = p->resize_proportionally;
6431 XSETFASTINT (w->last_modified, 0); 5712 XSETFASTINT (w->last_modified, 0);
6432 XSETFASTINT (w->last_overlay_modified, 0); 5713 XSETFASTINT (w->last_overlay_modified, 0);
6433 5714
@@ -6556,6 +5837,7 @@ the return value is nil. Otherwise the value is t. */)
6556 return (FRAME_LIVE_P (f) ? Qt : Qnil); 5837 return (FRAME_LIVE_P (f) ? Qt : Qnil);
6557} 5838}
6558 5839
5840
6559/* Delete all subwindows reachable via the next, vchild, and hchild 5841/* Delete all subwindows reachable via the next, vchild, and hchild
6560 slots of WINDOW. */ 5842 slots of WINDOW. */
6561void 5843void
@@ -6608,7 +5890,6 @@ count_windows (register struct window *window)
6608 5890
6609/* Fill vector FLAT with leaf windows under W, starting at index I. 5891/* Fill vector FLAT with leaf windows under W, starting at index I.
6610 Value is last index + 1. */ 5892 Value is last index + 1. */
6611
6612static int 5893static int
6613get_leaf_windows (struct window *w, struct window **flat, int i) 5894get_leaf_windows (struct window *w, struct window **flat, int i)
6614{ 5895{
@@ -6631,7 +5912,6 @@ get_leaf_windows (struct window *w, struct window **flat, int i)
6631/* Return a pointer to the glyph W's physical cursor is on. Value is 5912/* Return a pointer to the glyph W's physical cursor is on. Value is
6632 null if W's current matrix is invalid, so that no meaningfull glyph 5913 null if W's current matrix is invalid, so that no meaningfull glyph
6633 can be returned. */ 5914 can be returned. */
6634
6635struct glyph * 5915struct glyph *
6636get_phys_cursor_glyph (struct window *w) 5916get_phys_cursor_glyph (struct window *w)
6637{ 5917{
@@ -6676,8 +5956,6 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
6676 p->hscroll = w->hscroll; 5956 p->hscroll = w->hscroll;
6677 p->min_hscroll = w->min_hscroll; 5957 p->min_hscroll = w->min_hscroll;
6678 p->display_table = w->display_table; 5958 p->display_table = w->display_table;
6679 p->orig_top_line = w->orig_top_line;
6680 p->orig_total_lines = w->orig_total_lines;
6681 p->left_margin_cols = w->left_margin_cols; 5959 p->left_margin_cols = w->left_margin_cols;
6682 p->right_margin_cols = w->right_margin_cols; 5960 p->right_margin_cols = w->right_margin_cols;
6683 p->left_fringe_width = w->left_fringe_width; 5961 p->left_fringe_width = w->left_fringe_width;
@@ -6688,7 +5966,6 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
6688 p->dedicated = w->dedicated; 5966 p->dedicated = w->dedicated;
6689 p->splits = w->splits; 5967 p->splits = w->splits;
6690 p->nest = w->nest; 5968 p->nest = w->nest;
6691 p->resize_proportionally = w->resize_proportionally;
6692 p->window_parameters = w->window_parameters; 5969 p->window_parameters = w->window_parameters;
6693 if (!NILP (w->buffer)) 5970 if (!NILP (w->buffer))
6694 { 5971 {
@@ -7382,10 +6659,6 @@ syms_of_window (void)
7382 Fput (Qscroll_up, Qscroll_command, Qt); 6659 Fput (Qscroll_up, Qscroll_command, Qt);
7383 Fput (Qscroll_down, Qscroll_command, Qt); 6660 Fput (Qscroll_down, Qscroll_command, Qt);
7384 6661
7385 Qwindow_size_fixed = intern_c_string ("window-size-fixed");
7386 staticpro (&Qwindow_size_fixed);
7387 Fset (Qwindow_size_fixed, Qnil);
7388
7389 staticpro (&Qwindow_configuration_change_hook); 6662 staticpro (&Qwindow_configuration_change_hook);
7390 Qwindow_configuration_change_hook 6663 Qwindow_configuration_change_hook
7391 = intern_c_string ("window-configuration-change-hook"); 6664 = intern_c_string ("window-configuration-change-hook");
@@ -7478,24 +6751,6 @@ is displayed in the `mode-line' face. */);
7478 doc: /* *Number of lines of continuity when scrolling by screenfuls. */); 6751 doc: /* *Number of lines of continuity when scrolling by screenfuls. */);
7479 next_screen_context_lines = 2; 6752 next_screen_context_lines = 2;
7480 6753
7481 DEFVAR_INT ("window-min-height", window_min_height,
7482 doc: /* Allow deleting windows less than this tall.
7483The value is measured in line units. If a window wants a modeline it
7484is counted as one line.
7485
7486Emacs honors settings of this variable when enlarging or shrinking
7487windows vertically. A value less than 1 is invalid. */);
7488 window_min_height = 4;
7489
7490 DEFVAR_INT ("window-min-width", window_min_width,
7491 doc: /* Allow deleting windows less than this wide.
7492The value is measured in characters and includes any fringes or
7493the scrollbar.
7494
7495Emacs honors settings of this variable when enlarging or shrinking
7496windows horizontally. A value less than 2 is invalid. */);
7497 window_min_width = 10;
7498
7499 DEFVAR_LISP ("scroll-preserve-screen-position", 6754 DEFVAR_LISP ("scroll-preserve-screen-position",
7500 Vscroll_preserve_screen_position, 6755 Vscroll_preserve_screen_position,
7501 doc: /* *Controls if scroll commands move point to keep its screen position unchanged. 6756 doc: /* *Controls if scroll commands move point to keep its screen position unchanged.
@@ -7527,6 +6782,41 @@ will redraw the entire frame; the special value `tty' causes the
7527frame to be redrawn only if it is a tty frame. */); 6782frame to be redrawn only if it is a tty frame. */);
7528 Vrecenter_redisplay = Qtty; 6783 Vrecenter_redisplay = Qtty;
7529 6784
6785 DEFVAR_LISP ("window-splits", Vwindow_splits,
6786 doc: /* Non-nil means splitting windows is handled specially.
6787If this variable is nil, splitting a window gets the entire screen space
6788for displaying the new window from the window to split. If this
6789variable is non-nil, splitting a window may resize all windows in the
6790same combination. This also allows to split a window that is otherwise
6791too small or of fixed size.
6792
6793The value of this variable is also assigned to the split status of the
6794new window and, provided the old and new window form a new combination,
6795to the window that was split as well. The split status of a window can
6796be retrieved with the function `window-splits' and altered by the
6797function `set-window-splits'.
6798
6799If the value of the variable `window-nest' is non-nil, the space for the
6800new window is exclusively taken from the window that shall be split, but
6801the split status of the window that is split as well as that of the new
6802window are still set to the value of this variable. */);
6803 Vwindow_splits = Qnil;
6804
6805 DEFVAR_LISP ("window-nest", Vwindow_nest,
6806 doc: /* Non-nil means splitting a window makes a new parent window.
6807If this variable is nil, splitting a window will create a new parent
6808window only if the window has no parent window or the window shall
6809become a combination orthogonal to the one it it is part of.
6810
6811If this variable is non-nil, splitting a window always creates a new
6812parent window. If all splits behave this way, each frame's window tree
6813is a binary tree and every window but the frame's root window has
6814exactly one sibling.
6815
6816The value of this variable is also assigned to the nest status of the
6817new parent window. The nest status of a window can be retrieved via the
6818function `window-nest' and altered by the function `set-window-nest'. */);
6819 Vwindow_nest = Qnil;
7530 6820
7531 defsubr (&Sselected_window); 6821 defsubr (&Sselected_window);
7532 defsubr (&Sminibuffer_window); 6822 defsubr (&Sminibuffer_window);
@@ -7560,6 +6850,7 @@ frame to be redrawn only if it is a tty frame. */);
7560 defsubr (&Swindow_new_normal); 6850 defsubr (&Swindow_new_normal);
7561 defsubr (&Sset_window_new_total); 6851 defsubr (&Sset_window_new_total);
7562 defsubr (&Sset_window_new_normal); 6852 defsubr (&Sset_window_new_normal);
6853 defsubr (&Sresize_window_apply);
7563 defsubr (&Swindow_body_size); 6854 defsubr (&Swindow_body_size);
7564 defsubr (&Swindow_hscroll); 6855 defsubr (&Swindow_hscroll);
7565 defsubr (&Sset_window_hscroll); 6856 defsubr (&Sset_window_hscroll);
@@ -7586,19 +6877,18 @@ frame to be redrawn only if it is a tty frame. */);
7586 defsubr (&Sprevious_window); 6877 defsubr (&Sprevious_window);
7587 defsubr (&Sother_window); 6878 defsubr (&Sother_window);
7588 defsubr (&Sget_buffer_window); 6879 defsubr (&Sget_buffer_window);
7589 defsubr (&Sdelete_other_windows);
7590 defsubr (&Sdelete_windows_on); 6880 defsubr (&Sdelete_windows_on);
7591 defsubr (&Sreplace_buffer_in_windows); 6881 defsubr (&Sreplace_buffer_in_windows);
7592 defsubr (&Sdelete_window); 6882 defsubr (&Sdelete_other_windows_internal);
6883 defsubr (&Sdelete_window_internal);
6884 defsubr (&Sresize_mini_window_internal);
7593 defsubr (&Sset_window_buffer); 6885 defsubr (&Sset_window_buffer);
7594 defsubr (&Sset_window_clone_number); 6886 defsubr (&Sset_window_clone_number);
6887 defsubr (&Srun_window_configuration_change_hook);
7595 defsubr (&Sselect_window); 6888 defsubr (&Sselect_window);
7596 defsubr (&Sforce_window_update); 6889 defsubr (&Sforce_window_update);
7597 defsubr (&Stemp_output_buffer_show); 6890 defsubr (&Stemp_output_buffer_show);
7598 defsubr (&Ssplit_window); 6891 defsubr (&Ssplit_window_internal);
7599 defsubr (&Senlarge_window);
7600 defsubr (&Sshrink_window);
7601 defsubr (&Sadjust_window_trailing_edge);
7602 defsubr (&Sscroll_up); 6892 defsubr (&Sscroll_up);
7603 defsubr (&Sscroll_down); 6893 defsubr (&Sscroll_down);
7604 defsubr (&Sscroll_left); 6894 defsubr (&Sscroll_left);
@@ -7637,11 +6927,7 @@ frame to be redrawn only if it is a tty frame. */);
7637void 6927void
7638keys_of_window (void) 6928keys_of_window (void)
7639{ 6929{
7640 initial_define_key (control_x_map, '1', "delete-other-windows");
7641 initial_define_key (control_x_map, '2', "split-window");
7642 initial_define_key (control_x_map, '0', "delete-window");
7643 initial_define_key (control_x_map, 'o', "other-window"); 6930 initial_define_key (control_x_map, 'o', "other-window");
7644 initial_define_key (control_x_map, '^', "enlarge-window");
7645 initial_define_key (control_x_map, '<', "scroll-left"); 6931 initial_define_key (control_x_map, '<', "scroll-left");
7646 initial_define_key (control_x_map, '>', "scroll-right"); 6932 initial_define_key (control_x_map, '>', "scroll-right");
7647 6933
diff --git a/src/window.h b/src/window.h
index c33179de9ba..236464775d3 100644
--- a/src/window.h
+++ b/src/window.h
@@ -261,12 +261,6 @@ struct window
261 /* If redisplay in this window goes beyond this buffer position, 261 /* If redisplay in this window goes beyond this buffer position,
262 must run the redisplay-end-trigger-hook. */ 262 must run the redisplay-end-trigger-hook. */
263 Lisp_Object redisplay_end_trigger; 263 Lisp_Object redisplay_end_trigger;
264 /* Non-nil means resizing windows will attempt to resize this window
265 proportionally. */
266 Lisp_Object resize_proportionally;
267
268 /* Original window height and top before mini-window was enlarged. */
269 Lisp_Object orig_total_lines, orig_top_line;
270 264
271 /* Non-nil means deleting or resizing this window distributes 265 /* Non-nil means deleting or resizing this window distributes
272 space among all windows in the same combination. */ 266 space among all windows in the same combination. */
@@ -833,9 +827,6 @@ extern Lisp_Object make_window (void);
833extern Lisp_Object window_from_coordinates (struct frame *, int, int, 827extern Lisp_Object window_from_coordinates (struct frame *, int, int,
834 enum window_part *, int); 828 enum window_part *, int);
835EXFUN (Fwindow_dedicated_p, 1); 829EXFUN (Fwindow_dedicated_p, 1);
836extern void set_window_height (Lisp_Object, int, int);
837extern void set_window_width (Lisp_Object, int, int);
838extern void change_window_heights (Lisp_Object, int);
839extern void delete_all_subwindows (Lisp_Object); 830extern void delete_all_subwindows (Lisp_Object);
840extern void freeze_window_starts (struct frame *, int); 831extern void freeze_window_starts (struct frame *, int);
841extern void grow_mini_window (struct window *, int); 832extern void grow_mini_window (struct window *, int);
@@ -918,7 +909,6 @@ EXFUN (Fselected_window, 0);
918EXFUN (Fframe_root_window, 1); 909EXFUN (Fframe_root_window, 1);
919EXFUN (Fframe_first_window, 1); 910EXFUN (Fframe_first_window, 1);
920EXFUN (Fset_frame_selected_window, 3); 911EXFUN (Fset_frame_selected_window, 3);
921EXFUN (Fdelete_window, 1);
922EXFUN (Fset_window_configuration, 1); 912EXFUN (Fset_window_configuration, 1);
923EXFUN (Fcurrent_window_configuration, 1); 913EXFUN (Fcurrent_window_configuration, 1);
924extern int compare_window_configurations (Lisp_Object, Lisp_Object, int); 914extern int compare_window_configurations (Lisp_Object, Lisp_Object, int);
@@ -933,5 +923,11 @@ extern void init_window_once (void);
933extern void init_window (void); 923extern void init_window (void);
934extern void syms_of_window (void); 924extern void syms_of_window (void);
935extern void keys_of_window (void); 925extern void keys_of_window (void);
926extern void resize_frame_windows (struct frame *, int, int);
927extern int resize_window_check (struct window *, int);
928extern Lisp_Object delete_deletable_window (Lisp_Object);
929extern Lisp_Object resize_root_window (Lisp_Object, Lisp_Object, Lisp_Object,
930 Lisp_Object);
931
936 932
937#endif /* not WINDOW_H_INCLUDED */ 933#endif /* not WINDOW_H_INCLUDED */
diff --git a/src/xdisp.c b/src/xdisp.c
index 02467c7bedd..65f6ddd3889 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -27115,31 +27115,27 @@ Its value should be an ASCII acronym string, `hex-code', `empty-box', or
27115void 27115void
27116init_xdisp (void) 27116init_xdisp (void)
27117{ 27117{
27118 Lisp_Object root_window;
27119 struct window *mini_w;
27120
27121 current_header_line_height = current_mode_line_height = -1; 27118 current_header_line_height = current_mode_line_height = -1;
27122 27119
27123 CHARPOS (this_line_start_pos) = 0; 27120 CHARPOS (this_line_start_pos) = 0;
27124 27121
27125 mini_w = XWINDOW (minibuf_window);
27126 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
27127 echo_area_window = minibuf_window;
27128
27129 if (!noninteractive) 27122 if (!noninteractive)
27130 { 27123 {
27131 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window))); 27124 struct window *m = XWINDOW (minibuf_window);
27125 Lisp_Object frame = m->frame;
27126 struct frame *f = XFRAME (frame);
27127 Lisp_Object root = FRAME_ROOT_WINDOW (f);
27128 struct window *r = XWINDOW (root);
27132 int i; 27129 int i;
27133 27130
27134 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f)); 27131 echo_area_window = minibuf_window;
27135 set_window_height (root_window,
27136 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
27137 0);
27138 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
27139 set_window_height (minibuf_window, 1, 0);
27140 27132
27141 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f)); 27133 XSETFASTINT (r->top_line, FRAME_TOP_MARGIN (f));
27142 mini_w->total_cols = make_number (FRAME_COLS (f)); 27134 XSETFASTINT (r->total_lines, FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f));
27135 XSETFASTINT (r->total_cols, FRAME_COLS (f));
27136 XSETFASTINT (m->top_line, FRAME_LINES (f) - 1);
27137 XSETFASTINT (m->total_lines, 1);
27138 XSETFASTINT (m->total_cols, FRAME_COLS (f));
27143 27139
27144 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs; 27140 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
27145 scratch_glyph_row.glyphs[TEXT_AREA + 1] 27141 scratch_glyph_row.glyphs[TEXT_AREA + 1]
diff --git a/src/xfns.c b/src/xfns.c
index 25fa05c0a6e..8417db7d6e5 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -1227,7 +1227,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1227 } 1227 }
1228#else /* not USE_X_TOOLKIT && not USE_GTK */ 1228#else /* not USE_X_TOOLKIT && not USE_GTK */
1229 FRAME_MENU_BAR_LINES (f) = nlines; 1229 FRAME_MENU_BAR_LINES (f) = nlines;
1230 change_window_heights (f->root_window, nlines - olines); 1230 resize_frame_windows (f, FRAME_LINES (f), 0);
1231 1231
1232 /* If the menu bar height gets changed, the internal border below 1232 /* If the menu bar height gets changed, the internal border below
1233 the top margin has to be cleared. Also, if the menu bar gets 1233 the top margin has to be cleared. Also, if the menu bar gets
@@ -1266,6 +1266,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1266 } 1266 }
1267#endif /* not USE_X_TOOLKIT && not USE_GTK */ 1267#endif /* not USE_X_TOOLKIT && not USE_GTK */
1268 adjust_glyphs (f); 1268 adjust_glyphs (f);
1269 run_window_configuration_change_hook (f);
1269} 1270}
1270 1271
1271 1272
@@ -1326,7 +1327,7 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1326 } 1327 }
1327 1328
1328 FRAME_TOOL_BAR_LINES (f) = nlines; 1329 FRAME_TOOL_BAR_LINES (f) = nlines;
1329 change_window_heights (root_window, delta); 1330 resize_frame_windows (f, FRAME_LINES (f), 0);
1330 adjust_glyphs (f); 1331 adjust_glyphs (f);
1331 1332
1332 /* We also have to make sure that the internal border at the top of 1333 /* We also have to make sure that the internal border at the top of
@@ -1362,6 +1363,9 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1362 if (WINDOWP (f->tool_bar_window)) 1363 if (WINDOWP (f->tool_bar_window))
1363 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix); 1364 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1364 } 1365 }
1366
1367 run_window_configuration_change_hook (f);
1368
1365} 1369}
1366 1370
1367 1371