summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKaroly Lorentey <lorentey@elte.hu>2006-06-27 15:06:36 +0000
committerKaroly Lorentey <lorentey@elte.hu>2006-06-27 15:06:36 +0000
commit556b89447234f15d1784a23dadbfe429464463a8 (patch)
treed5b94bbdde7b399bb0ffdf03a01f3e8398ee0afa /src
parent476e9367ec1f440aa23904b7bc482ea4a3b8041c (diff)
parent08b1eb21d5a3f935eb245acf0844a19acc42f57c (diff)
downloademacs-556b89447234f15d1784a23dadbfe429464463a8.tar.gz
emacs-556b89447234f15d1784a23dadbfe429464463a8.tar.bz2
emacs-556b89447234f15d1784a23dadbfe429464463a8.zip
Merged from emacs@sv.gnu.org
Patches applied: * emacs@sv.gnu.org/emacs--devo--0--patch-305 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-306 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-307 Update from CVS: lispref/display.texi (Forcing Redisplay): Fix typo. * emacs@sv.gnu.org/emacs--devo--0--patch-308 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-309 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-310 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-311 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-312 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-313 Merge from gnus--rel--5.10 * emacs@sv.gnu.org/emacs--devo--0--patch-314 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-315 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-316 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-317 Merge from gnus--rel--5.10 * emacs@sv.gnu.org/emacs--devo--0--patch-318 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-319 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-320 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-321 Merge from gnus--rel--5.10 * emacs@sv.gnu.org/emacs--devo--0--patch-322 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-323 lisp/play/cookie1.el (cookie): Work properly when there's only one entry * emacs@sv.gnu.org/emacs--devo--0--patch-324 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-325 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-326 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-327 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-328 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-329 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-330 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-105 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-106 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-107 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-108 Merge from emacs--devo--0 * emacs@sv.gnu.org/gnus--rel--5.10--patch-109 Clean up merge mistakes * emacs@sv.gnu.org/gnus--rel--5.10--patch-110 Update from CVS git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-571
Diffstat (limited to 'src')
-rw-r--r--src/.gdbinit138
-rw-r--r--src/ChangeLog165
-rw-r--r--src/callproc.c4
-rw-r--r--src/dired.c10
-rw-r--r--src/dispextern.h41
-rw-r--r--src/dispnew.c133
-rw-r--r--src/eval.c4
-rw-r--r--src/fileio.c8
-rw-r--r--src/lread.c19
-rw-r--r--src/macfns.c26
-rw-r--r--src/macterm.c141
-rw-r--r--src/s/gnu-linux.h9
-rw-r--r--src/syntax.c14
-rw-r--r--src/window.c101
-rw-r--r--src/xdisp.c240
-rw-r--r--src/xfns.c3
-rw-r--r--src/xterm.c139
-rw-r--r--src/xterm.h12
18 files changed, 982 insertions, 225 deletions
diff --git a/src/.gdbinit b/src/.gdbinit
index 54d68dc123d..acdb959a869 100644
--- a/src/.gdbinit
+++ b/src/.gdbinit
@@ -190,12 +190,8 @@ define pitx
printf " ch=[%d,%d]", $it->c, $it->len
end
else
- if ($it->what == IT_IMAGE)
- printf " IMAGE=%d", $it->image_id
- else
- printf " "
- output $it->what
- end
+ printf " "
+ output $it->what
end
if ($it->method != GET_FROM_BUFFER)
printf " next="
@@ -203,6 +199,12 @@ define pitx
if ($it->method == GET_FROM_STRING)
printf "[%d]", $it->current.string_pos.charpos
end
+ if ($it->method == GET_FROM_IMAGE)
+ printf "[%d]", $it->image_id
+ end
+ if ($it->method == GET_FROM_COMPOSITION)
+ printf "[%d,%d,%d]", $it->cmp_id, $it->len, $it->cmp_len
+ end
end
printf "\n"
if ($it->region_beg_charpos >= 0)
@@ -215,6 +217,15 @@ define pitx
printf " a+d=%d+%d=%d", $it->ascent, $it->descent, $it->ascent+$it->descent
printf " max=%d+%d=%d", $it->max_ascent, $it->max_descent, $it->max_ascent+$it->max_descent
printf "\n"
+ set $i = 0
+ while ($i < $it->sp)
+ set $e = $it->stack[$i]
+ printf "stack[%d]: ", $i
+ output $e->method
+ printf "[%d]", $e->position.charpos
+ printf "\n"
+ set $i = $i + 1
+ end
end
document pitx
Pretty print a display iterator.
@@ -372,6 +383,121 @@ document pwin
Pretty print window structure w.
end
+define pgx
+ set $g = $arg0
+ if ($g->type == CHAR_GLYPH)
+ if ($g->u.ch >= ' ' && $g->u.ch < 127)
+ printf "CHAR[%c]", $g->u.ch
+ else
+ printf "CHAR[0x%x]", $g->u.ch
+ end
+ end
+ if ($g->type == COMPOSITE_GLYPH)
+ printf "COMP[%d]", $g->u.cmp_id
+ end
+ if ($g->type == IMAGE_GLYPH)
+ printf "IMAGE[%d]", $g->u.img_id
+ end
+ if ($g->type == STRETCH_GLYPH)
+ printf "STRETCH[%d+%d]", $g->u.stretch.height, $g->u.stretch.ascent
+ end
+ xgettype ($g->object)
+ if ($type == Lisp_String)
+ printf " str=%x[%d]", $g->object, $g->charpos
+ else
+ printf " pos=%d", $g->charpos
+ end
+ printf " w=%d a+d=%d+%d", $g->pixel_width, $g->ascent, $g->descent
+ if ($g->face_id != DEFAULT_FACE_ID)
+ printf " face=%d", $g->face_id
+ end
+ if ($g->voffset)
+ printf " vof=%d", $g->voffset
+ end
+ if ($g->multibyte_p)
+ printf " MB"
+ end
+ if ($g->padding_p)
+ printf " PAD"
+ end
+ if ($g->glyph_not_available_p)
+ printf " N/A"
+ end
+ if ($g->overlaps_vertically_p)
+ printf " OVL"
+ end
+ if ($g->left_box_line_p)
+ printf " ["
+ end
+ if ($g->right_box_line_p)
+ printf " ]"
+ end
+ if ($g->slice.x || $g->slice.y || $g->slice.width || $g->slice.height)
+ printf " slice=%d,%d,%d,%d" ,$g->slice.x, $g->slice.y, $g->slice.width, $g->slice.height
+ end
+ printf "\n"
+end
+document pgx
+Pretty print a glyph structure.
+Takes one argument, a pointer to a glyph structure
+end
+
+define pg
+ set $pgidx = 0
+ pgx glyph
+end
+document pg
+Pretty print glyph structure glyph.
+end
+
+define pgi
+ set $pgidx = $arg0
+ pgx (&glyph[$pgidx])
+end
+document pgi
+Pretty print glyph structure glyph[I].
+Takes one argument, a integer I.
+end
+
+define pgn
+ set $pgidx = $pgidx + 1
+ pgx (&glyph[$pgidx])
+end
+document pgn
+Pretty print next glyph structure.
+end
+
+define pgrowx
+ set $row = $arg0
+ set $area = 0
+ set $xofs = $row->x
+ while ($area < 3)
+ set $used = $row->used[$area]
+ if ($used > 0)
+ set $gl0 = $row->glyphs[$area]
+ set $pgidx = 0
+ printf "%s: %d glyphs\n", ($area == 0 ? "LEFT" : $area == 2 ? "RIGHT" : "TEXT"), $used
+ while ($pgidx < $used)
+ printf "%3d %4d: ", $pgidx, $xofs
+ pgx $gl0[$pgidx]
+ set $xofs = $xofs + $gl0[$pgidx]->pixel_width
+ set $pgidx = $pgidx + 1
+ end
+ end
+ set $area = $area + 1
+ end
+end
+document pgrowx
+Pretty print all glyphs in a row structure.
+Takes one argument, a pointer to a row structure.
+end
+
+define pgrow
+ pgrowx row
+end
+document pgrow
+Pretty print all glyphs in row structure row.
+end
define xtype
xgettype $
diff --git a/src/ChangeLog b/src/ChangeLog
index 5154dc5012e..91694368fe0 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,168 @@
+2006-06-25 Kim F. Storm <storm@cua.dk>
+
+ * s/gnu-linux.h (SIGNALS_VIA_CHARACTERS): Define for Linux kernel
+ version 2.4 and later.
+
+2006-06-24 Chong Yidong <cyd@stupidchicken.com>
+
+ * xfns.c (Fx_create_frame): Set font parameter directly instead of
+ using x_default_parameter, since x_get_args clears the parm alist.
+
+2006-06-24 Eli Zaretskii <eliz@gnu.org>
+
+ * dired.c (directory_files_internal) [WINDOWSNT]: Find files
+ case-insensitively.
+
+2006-06-24 Aidan Kehoe <kehoea@parhasard.net>
+
+ * lread.c (read_escape): When an unknown Unicode code point is
+ encountered as a string or character escape, signal an error.
+
+2006-06-23 Kim F. Storm <storm@cua.dk>
+
+ * .gdbinit (pitx): Dump iterator stack.
+
+ * xdisp.c (handle_composition_prop): Push iterator on stack.
+ (set_iterator_to_next): Pop iterator at end of composition.
+
+2006-06-23 Martin Rudalics <rudalics@gmx.at>
+
+ * fileio.c (Frename_file) [DOS_NT]: Don't try to move directory to
+ itself on DOS_NT platforms, if the old and new names are identical
+ but for the letter-case.
+
+2006-06-21 Kim F. Storm <storm@cua.dk>
+
+ * dispextern.h (struct it): Add `position' member to iterator stack.
+ Rename `pos' member to `current'. Rearrange and add comments.
+
+ * xdisp.c (handle_stop): Set it->ignore_overlay_strings_at_pos_p
+ if we get any overlays.
+ (set_cursor_from_row): Don't clobber `end' if we rescan from
+ start_string.
+ (push_it, pop_it): Save it->position.
+
+2006-06-19 Richard Stallman <rms@gnu.org>
+
+ * window.c (size_window): New arg FIRST_ONLY. All callers changed.
+ (adjust_window_trailing_edge): Specially compute FIRST_PARALLEL
+ for the case of a top-level window and the following minibuffer.
+ Don't exit because of no `next' when there is a parent.
+ Use the FIRST_ONLY feature when resizing following windows.
+
+ * syntax.c (init_syntax_once): Give most control chars' syntax Spunct.
+
+2006-06-17 Kim F. Storm <storm@cua.dk>
+
+ * dispnew.c (update_frame): Check for input pending on entry.
+ (update_window, update_frame_1): Break loop if input is detected.
+
+2006-06-16 Francis Litterio <flitterio@gmail.com>
+
+ * xterm.c (x_check_expected_move, handle_one_xevent)
+ (x_set_offset, x_check_fullscreen): Extensive changes to make
+ frame positioning deterministic under X.
+
+ * xterm.h (x_output): Added members left_before_move and
+ top_before_move. Removed members expected_left and expected_top.
+
+2006-06-16 Kim F. Storm <storm@cua.dk>
+
+ * dispextern.h (struct it): Add union to iterator stack to save
+ image, composition, and stretch specific paramters.
+
+ * xdisp.c (next_overlay_string): Fix assert.
+ (push_it, pop_it): Handle composition and stretch specific values.
+ Only handle it->slice in image (for now).
+ (back_to_previous_visible_line_start): Continue search if newline is
+ part of a compisition. Simplify.
+ (reseat_1): Set it->object to buffer.
+ (set_iterator_to_next): Set it->object to string or buffer, when
+ setting it->method to GET_FROM_STRING or GET_FROM_BUFFER.
+ (next_element_from_composition): Set it->object to buffer if not
+ from string.
+ (set_cursor_from_row): Only save start of string if not already
+ done to handle multiple strings in a row.
+
+ * .gdbinit (pitx): Show composition parameters.
+ (pgx, pg): New commands to print a glyph structure.
+ (pgi, pgn): New commands to print specific/next glyph.
+ (pgrowx, pgrow): New commands to print all glyphs in a row.
+
+2006-06-16 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * macfns.c (Fx_display_mm_height, Fx_display_mm_width)
+ [MAC_OS_X_VERSION_MAX_ALLOWED >= 1030]: Use CGDisplayScreenSize.
+
+ * macterm.c (do_app_resume, do_app_suspend): Remove functions.
+ (mac_tsm_resume, mac_tsm_suspend) [USE_MAC_TSM]: New functions.
+ (mac_handle_window_event, XTread_socket) [USE_MAC_TSM]: Use them.
+ (Vmac_ts_script_language_on_focus) [USE_MAC_TSM]: New variable.
+ (syms_of_macterm) [USE_MAC_TSM]: Defvar it.
+ (saved_ts_language, saved_ts_component) [USE_MAC_TSM]: New variables.
+ (mac_initialize_display_info) [MAC_OSX]: Use Quartz Display
+ Services functions to get size of main display in pixels.
+
+2006-06-14 Chong Yidong <cyd@stupidchicken.com>
+
+ * xdisp.c (back_to_previous_visible_line_start): Reset
+ it->continuation_lines_width.
+
+2006-06-14 Richard Stallman <rms@gnu.org>
+
+ * eval.c (Fdefconst): Mark variable as risky.
+
+ * callproc.c (Fcall_process): Doc fix.
+
+ * window.c (adjust_window_trailing_edge): Don't break out of the loop
+ because there's no next window, if there are parallel windows.
+ Do break out when WINDOW is nil.
+
+2006-06-14 Kim F. Storm <storm@cua.dk>
+
+ * dispextern.h (IT_STACK_SIZE): New macro specifying size of
+ iterator stack (instead of hardcoded number). Increase from 2 to
+ 4 to make room for propertized overlay strings before and after a
+ display string, image or composition.
+ (struct it): Add image_id and method members to iterator stack.
+
+ * xdisp.c (init_from_display_pos): Don't set it->method and
+ overlay_string_index after pop_it. Add asserts.
+ (handle_stop): Look for overlay strings around a display string,
+ image, or composition. Handle properties on those strings.
+ (next_overlay_string): Don't set string, pos or method after pop_it.
+ (get_overlay_strings_1): Split from get_overlay_strings; don't
+ modify it if no overlay strings are found.
+ (get_overlay_strings): Use get_overlay_strings_1. Always set
+ it->string and it->method.
+ (push_it): Push it->image_id and it->method. Push it->object
+ instead of it->string if method is GET_FROM_IMAGE.
+ (pop_it): Pop it->image_id and it->method. Ppo it->object
+ instead of it->string if method is GET_FROM_IMAGE.
+ Reset it->current.string_pos if popped it->string is nil.
+ (reseat_1): Remove comment dated 19 May 2003. It expressed doubt
+ whether a given change was correct; but the change is correct.
+ Clear it->string_from_display_prop_p.
+ (set_iterator_to_next): Rely on it->method and it->image_id from
+ iterator stack, instead of setting them explicitly after pop_it.
+
+ * dispnew.c (sit_for): Undo 2006-06-01 change. Instead, a
+ negative time forces redisplay even when input is available.
+ (Fsit_for): Doc fix.
+
+2006-06-13 Kim F. Storm <storm@cua.dk>
+
+ * dispnew.c: Modify preemptive redisplay to be based on periodic
+ checks for input.
+ (PERIODIC_PREEMPTION_CHECKING): Define to 1 iff EMACS_HAS_USECS.
+ (Vredisplay_preemption_period): New variable.
+ (syms_of_display): DEFVAR_LISP and initialize it.
+ (preemption_period, preemption_next_check): New variables.
+ (update_frame, update_single_window): Initialize them based on
+ Vredisplay_preemption_period if !force_p.
+ (update_window, update_frame_1): Use them to determine when to
+ check for input.
+
2006-06-03 Aidan Kehoe <kehoea@parhasard.net>
* lread.c (read_escape): Provide a Unicode character escape
diff --git a/src/callproc.c b/src/callproc.c
index b2352e9bd55..2f0e569d0c8 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -206,6 +206,10 @@ t (mix it with ordinary output), or a file name string.
Fourth arg DISPLAY non-nil means redisplay buffer as output is inserted.
Remaining arguments are strings passed as command arguments to PROGRAM.
+If executable PROGRAM can't be found as an executable, `call-process'
+signals a Lisp error. `call-process' reports errors in execution of
+the program only through its return and output.
+
If BUFFER is 0, `call-process' returns immediately with value nil.
Otherwise it waits for PROGRAM to terminate
and returns a numeric exit status or a signal description string.
diff --git a/src/dired.c b/src/dired.c
index 8c7c7fd5ac6..8b5d7851765 100644
--- a/src/dired.c
+++ b/src/dired.c
@@ -175,9 +175,15 @@ directory_files_internal (directory, full, match, nosort, attrs, id_format)
#ifdef VMS
bufp = compile_pattern (match, 0,
buffer_defaults.downcase_table, 0, 1);
-#else
+#else /* !VMS */
+# ifdef WINDOWSNT
+ /* Windows users want case-insensitive wildcards. */
+ bufp = compile_pattern (match, 0,
+ buffer_defaults.case_canon_table, 0, 1);
+# else /* !WINDOWSNT */
bufp = compile_pattern (match, 0, Qnil, 0, 1);
-#endif
+# endif /* !WINDOWSNT */
+#endif /* !VMS */
}
/* Note: ENCODE_FILE and DECODE_FILE can GC because they can run
diff --git a/src/dispextern.h b/src/dispextern.h
index ed91d2df76e..6b5705a2865 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -1814,6 +1814,8 @@ enum it_method {
NUM_IT_METHODS
};
+#define IT_STACK_SIZE 4
+
struct it
{
/* The window in which we iterate over current_buffer (or a string). */
@@ -1922,22 +1924,47 @@ struct it
from what we previously had. */
struct iterator_stack_entry
{
- int stop_charpos;
- int face_id;
Lisp_Object string;
- struct display_pos pos;
- int end_charpos;
int string_nchars;
+ int end_charpos;
+ int stop_charpos;
+ int face_id;
+
+ /* Save values specific to a given method. */
+ union {
+ /* method == GET_FROM_IMAGE */
+ struct {
+ Lisp_Object object;
+ struct it_slice slice;
+ int image_id;
+ } image;
+ /* method == GET_FROM_COMPOSITION */
+ struct {
+ Lisp_Object object;
+ int c, len;
+ int cmp_id, cmp_len;
+ } comp;
+ /* method == GET_FROM_STRETCH */
+ struct {
+ Lisp_Object object;
+ } stretch;
+ } u;
+
+ /* current text and display positions. */
+ struct text_pos position;
+ struct display_pos current;
enum glyph_row_area area;
+ enum it_method method;
unsigned multibyte_p : 1;
unsigned string_from_display_prop_p : 1;
unsigned display_ellipsis_p : 1;
- struct it_slice slice;
+
+ /* properties from display property that are reset by another display property. */
Lisp_Object space_width;
- short voffset;
Lisp_Object font_height;
+ short voffset;
}
- stack[2];
+ stack[IT_STACK_SIZE];
/* Stack pointer. */
int sp;
diff --git a/src/dispnew.c b/src/dispnew.c
index c346e94a103..4f63bfa8578 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -192,6 +192,28 @@ struct window *frame_row_to_window P_ ((struct window *, int));
int redisplay_dont_pause;
+/* Define PERIODIC_PREEMPTION_CHECKING to 1, if micro-second timers
+ are supported, so we can check for input during redisplay at
+ regular intervals. */
+#ifdef EMACS_HAS_USECS
+#define PERIODIC_PREEMPTION_CHECKING 1
+#else
+#define PERIODIC_PREEMPTION_CHECKING 0
+#endif
+
+#if PERIODIC_PREEMPTION_CHECKING
+
+/* If a number (float), check for user input every N seconds. */
+
+Lisp_Object Vredisplay_preemption_period;
+
+/* Redisplay preemption timers. */
+
+static EMACS_TIME preemption_period;
+static EMACS_TIME preemption_next_check;
+
+#endif
+
/* Nonzero upon entry to redisplay means do not assume anything about
current contents of actual terminal frame; clear and redraw it. */
@@ -3814,6 +3836,28 @@ update_frame (f, force_p, inhibit_hairy_id_p)
int paused_p;
struct window *root_window = XWINDOW (f->root_window);
+#if PERIODIC_PREEMPTION_CHECKING
+ if (!force_p && NUMBERP (Vredisplay_preemption_period))
+ {
+ EMACS_TIME tm;
+ double p = XFLOATINT (Vredisplay_preemption_period);
+ int sec, usec;
+
+ if (detect_input_pending_ignore_squeezables ())
+ {
+ paused_p = 1;
+ goto do_pause;
+ }
+
+ sec = (int) p;
+ usec = (p - sec) * 1000000;
+
+ EMACS_GET_TIME (tm);
+ EMACS_SET_SECS_USECS (preemption_period, sec, usec);
+ EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
+ }
+#endif
+
if (FRAME_WINDOW_P (f))
{
/* We are working on window matrix basis. All windows whose
@@ -3895,6 +3939,7 @@ update_frame (f, force_p, inhibit_hairy_id_p)
#endif
}
+ do_pause:
/* Reset flags indicating that a window should be updated. */
set_window_update_flags (root_window, 0);
@@ -3949,6 +3994,22 @@ update_single_window (w, force_p)
/* Record that this is not a frame-based redisplay. */
set_frame_matrix_frame (NULL);
+#if PERIODIC_PREEMPTION_CHECKING
+ if (!force_p && NUMBERP (Vredisplay_preemption_period))
+ {
+ EMACS_TIME tm;
+ double p = XFLOATINT (Vredisplay_preemption_period);
+ int sec, usec;
+
+ sec = (int) p;
+ usec = (p - sec) * 1000000;
+
+ EMACS_GET_TIME (tm);
+ EMACS_SET_SECS_USECS (preemption_period, sec, usec);
+ EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
+ }
+#endif
+
/* Update W. */
update_begin (f);
update_window (w, force_p);
@@ -4108,7 +4169,9 @@ update_window (w, force_p)
{
struct glyph_matrix *desired_matrix = w->desired_matrix;
int paused_p;
+#if !PERIODIC_PREEMPTION_CHECKING
int preempt_count = baud_rate / 2400 + 1;
+#endif
extern int input_pending;
extern Lisp_Object do_mouse_tracking;
struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
@@ -4120,8 +4183,13 @@ update_window (w, force_p)
/* Check pending input the first time so that we can quickly return. */
if (redisplay_dont_pause)
force_p = 1;
- else
+#if PERIODIC_PREEMPTION_CHECKING
+ else if (NILP (Vredisplay_preemption_period))
+ force_p = 1;
+#else
+ else if (!force_p)
detect_input_pending_ignore_squeezables ();
+#endif
/* If forced to complete the update, or if no input is pending, do
the update. */
@@ -4193,9 +4261,23 @@ update_window (w, force_p)
detect_input_pending. If it's done too often,
scrolling large windows with repeated scroll-up
commands will too quickly pause redisplay. */
+#if PERIODIC_PREEMPTION_CHECKING
+ if (!force_p)
+ {
+ EMACS_TIME tm, dif;
+ EMACS_GET_TIME (tm);
+ EMACS_SUB_TIME (dif, preemption_next_check, tm);
+ if (EMACS_TIME_NEG_P (dif))
+ {
+ EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
+ if (detect_input_pending_ignore_squeezables ())
+ break;
+ }
+ }
+#else
if (!force_p && ++n_updated % preempt_count == 0)
detect_input_pending_ignore_squeezables ();
-
+#endif
changed_p |= update_window_line (w, vpos,
&mouse_face_overwritten_p);
@@ -5151,11 +5233,16 @@ update_frame_1 (f, force_p, inhibit_id_p)
if (redisplay_dont_pause)
force_p = 1;
+#if PERIODIC_PREEMPTION_CHECKING
+ else if (NILP (Vredisplay_preemption_period))
+ force_p = 1;
+#else
else if (!force_p && detect_input_pending_ignore_squeezables ())
{
pause = 1;
goto do_pause;
}
+#endif
/* If we cannot insert/delete lines, it's no use trying it. */
if (!FRAME_LINE_INS_DEL_OK (f))
@@ -5206,8 +5293,23 @@ update_frame_1 (f, force_p, inhibit_id_p)
}
}
- if ((i - 1) % preempt_count == 0)
+#if PERIODIC_PREEMPTION_CHECKING
+ if (!force_p)
+ {
+ EMACS_TIME tm, dif;
+ EMACS_GET_TIME (tm);
+ EMACS_SUB_TIME (dif, preemption_next_check, tm);
+ if (EMACS_TIME_NEG_P (dif))
+ {
+ EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
+ if (detect_input_pending_ignore_squeezables ())
+ break;
+ }
+ }
+#else
+ if (!force_p && (i - 1) % preempt_count == 0)
detect_input_pending_ignore_squeezables ();
+#endif
update_frame_line (f, i);
}
@@ -6434,15 +6536,22 @@ Lisp_Object
sit_for (sec, usec, reading, display, initial_display)
int sec, usec, reading, display, initial_display;
{
+ int preempt = (sec >= 0) || (sec == 0 && usec >= 0);
+
swallow_events (display);
- if ((detect_input_pending_run_timers (display)
- && !redisplay_dont_pause)
+ if ((detect_input_pending_run_timers (display) && preempt)
|| !NILP (Vexecuting_kbd_macro))
return Qnil;
if (initial_display)
- redisplay_preserve_echo_area (2);
+ {
+ int count = SPECPDL_INDEX ();
+ if (!preempt)
+ specbind (Qredisplay_dont_pause, Qt);
+ redisplay_preserve_echo_area (2);
+ unbind_to (count, Qnil);
+ }
if (sec == 0 && usec == 0)
return Qt;
@@ -6468,8 +6577,7 @@ Redisplay is preempted as always if input arrives, and does not happen
if input is available before it starts.
Value is t if waited the full time with no input arriving.
-Redisplay will occur even when input is available if you bind
-`redisplay-dont-pause' to a non-nil value.
+Redisplay will occur even when input is available if SECONDS is negative.
An obsolete but still supported form is
\(sit-for SECONDS &optional MILLISECONDS NODISP)
@@ -7000,7 +7108,14 @@ See `buffer-display-table' for more information. */);
doc: /* *Non-nil means update isn't paused when input is detected. */);
redisplay_dont_pause = 0;
- /* Initialize `window-system', unless init_display already decided it. */
+#if PERIODIC_PREEMPTION_CHECKING
+ DEFVAR_LISP ("redisplay-preemption-period", &Vredisplay_preemption_period,
+ doc: /* *The period in seconds between checking for input during redisplay.
+If input is detected, redisplay is pre-empted, and the input is processed.
+If nil, never pre-empt redisplay. */);
+ Vredisplay_preemption_period = make_float (0.10);
+#endif
+
#ifdef CANNOT_DUMP
if (noninteractive)
#endif
diff --git a/src/eval.c b/src/eval.c
index 20f29b5f06b..5f8d266ec7b 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -195,9 +195,10 @@ int handling_signal;
Lisp_Object Vmacro_declaration_function;
+extern Lisp_Object Qrisky_local_variable;
static Lisp_Object funcall_lambda P_ ((Lisp_Object, int, Lisp_Object*));
-
+
void
init_eval_once ()
{
@@ -895,6 +896,7 @@ usage: (defconst SYMBOL INITVALUE [DOCSTRING]) */)
tem = Fpurecopy (tem);
Fput (sym, Qvariable_documentation, tem);
}
+ Fput (sym, Qrisky_local_variable, Qt);
LOADHIST_ATTACH (sym);
return sym;
}
diff --git a/src/fileio.c b/src/fileio.c
index b2940d46e9e..e5b81ddfd7b 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -2752,7 +2752,13 @@ This is what happens in interactive use with M-x. */)
CHECK_STRING (newname);
file = Fexpand_file_name (file, Qnil);
- if (!NILP (Ffile_directory_p (newname)))
+ if ((!NILP (Ffile_directory_p (newname)))
+#ifdef DOS_NT
+ /* If the file names are identical but for the case,
+ don't attempt to move directory to itself. */
+ && (NILP (Fstring_equal (Fdowncase (file), Fdowncase (newname))))
+#endif
+ )
newname = Fexpand_file_name (Ffile_name_nondirectory (file), newname);
else
newname = Fexpand_file_name (newname, Qnil);
diff --git a/src/lread.c b/src/lread.c
index 797ae1078fb..8789ad03e1c 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -1949,7 +1949,7 @@ read_escape (readcharfun, stringp, byterep)
while (++count <= unicode_hex_count)
{
c = READCHAR;
- /* isdigit(), isalpha() may be locale-specific, which we don't
+ /* isdigit and isalpha may be locale-specific, which we don't
want. */
if (c >= '0' && c <= '9') i = (i << 4) + (c - '0');
else if (c >= 'a' && c <= 'f') i = (i << 4) + (c - 'a') + 10;
@@ -1962,21 +1962,16 @@ read_escape (readcharfun, stringp, byterep)
}
GCPRO1 (readcharfun);
- lisp_char = call2(intern("decode-char"), intern("ucs"),
- make_number(i));
+ lisp_char = call2 (intern ("decode-char"), intern ("ucs"),
+ make_number (i));
UNGCPRO;
- if (EQ(Qnil, lisp_char))
+ if (NILP (lisp_char))
{
- /* This is ugly and horrible and trashes the user's data. */
- XSETFASTINT (i, MAKE_CHAR (charset_katakana_jisx0201,
- 34 + 128, 46 + 128));
- return i;
- }
- else
- {
- return XFASTINT (lisp_char);
+ error ("Unsupported Unicode code point: U+%x", (unsigned)i);
}
+
+ return XFASTINT (lisp_char);
}
default:
diff --git a/src/macfns.c b/src/macfns.c
index 4345cef2611..a053bc66763 100644
--- a/src/macfns.c
+++ b/src/macfns.c
@@ -3070,11 +3070,20 @@ If omitted or nil, that stands for the selected frame's display. */)
(display)
Lisp_Object display;
{
- /* MAC_TODO: this is an approximation, and only of the main display */
-
struct mac_display_info *dpyinfo = check_x_display_info (display);
+ /* Only of the main display. */
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+ CGSize size;
+
+ BLOCK_INPUT;
+ size = CGDisplayScreenSize (kCGDirectMainDisplay);
+ UNBLOCK_INPUT;
+ return make_number ((int) (size.height + .5f));
+#else
+ /* This is an approximation. */
return make_number ((int) (dpyinfo->height * 25.4 / dpyinfo->resy));
+#endif
}
DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
@@ -3085,11 +3094,20 @@ If omitted or nil, that stands for the selected frame's display. */)
(display)
Lisp_Object display;
{
- /* MAC_TODO: this is an approximation, and only of the main display */
-
struct mac_display_info *dpyinfo = check_x_display_info (display);
+ /* Only of the main display. */
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+ CGSize size;
+
+ BLOCK_INPUT;
+ size = CGDisplayScreenSize (kCGDirectMainDisplay);
+ UNBLOCK_INPUT;
+ return make_number ((int) (size.width + .5f));
+#else
+ /* This is an approximation. */
return make_number ((int) (dpyinfo->width * 25.4 / dpyinfo->resx));
+#endif
}
DEFUN ("x-display-backing-store", Fx_display_backing_store,
diff --git a/src/macterm.c b/src/macterm.c
index b0765069277..19040392aa5 100644
--- a/src/macterm.c
+++ b/src/macterm.c
@@ -8512,6 +8512,9 @@ static Lisp_Object Qtext_input;
static Lisp_Object Qupdate_active_input_area, Qunicode_for_key_event;
static Lisp_Object Vmac_ts_active_input_overlay;
extern Lisp_Object Qbefore_string;
+static Lisp_Object Vmac_ts_script_language_on_focus;
+static ScriptLanguageRecord saved_ts_language;
+static Component saved_ts_component;
#endif
#endif
extern int mac_ready_for_apple_events;
@@ -8861,22 +8864,84 @@ is_emacs_window (WindowPtr win)
return 0;
}
-static void
-do_app_resume ()
-{
#if USE_MAC_TSM
- ActivateTSMDocument (tsm_document_id);
+static OSStatus
+mac_tsm_resume ()
+{
+ OSStatus err;
+ ScriptLanguageRecord slrec, *slptr = NULL;
+
+ err = ActivateTSMDocument (tsm_document_id);
+
+ if (err == noErr)
+ {
+ if (EQ (Vmac_ts_script_language_on_focus, Qt))
+ slptr = &saved_ts_language;
+ else if (CONSP (Vmac_ts_script_language_on_focus)
+ && INTEGERP (XCAR (Vmac_ts_script_language_on_focus))
+ && INTEGERP (XCDR (Vmac_ts_script_language_on_focus)))
+ {
+ slrec.fScript = XINT (XCAR (Vmac_ts_script_language_on_focus));
+ slrec.fLanguage = XINT (XCDR (Vmac_ts_script_language_on_focus));
+ slptr = &slrec;
+ }
+ }
+
+ if (slptr)
+ {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+ err = SetDefaultInputMethodOfClass (saved_ts_component, slptr,
+ kKeyboardInputMethodClass);
+#else
+ err = SetDefaultInputMethod (saved_ts_component, slptr);
#endif
+ if (err == noErr)
+ err = SetTextServiceLanguage (slptr);
+
+ /* Seems to be needed on Mac OS X 10.2. */
+ if (err == noErr)
+ KeyScript (slptr->fScript | smKeyForceKeyScriptMask);
+ }
+
+ return err;
}
-static void
-do_app_suspend ()
+static OSStatus
+mac_tsm_suspend ()
{
-#if USE_MAC_TSM
- DeactivateTSMDocument (tsm_document_id);
+ OSStatus err;
+ ScriptLanguageRecord slrec, *slptr = NULL;
+
+ if (EQ (Vmac_ts_script_language_on_focus, Qt))
+ {
+ err = GetTextServiceLanguage (&saved_ts_language);
+ if (err == noErr)
+ slptr = &saved_ts_language;
+ }
+ else if (CONSP (Vmac_ts_script_language_on_focus)
+ && INTEGERP (XCAR (Vmac_ts_script_language_on_focus))
+ && INTEGERP (XCDR (Vmac_ts_script_language_on_focus)))
+ {
+ slrec.fScript = XINT (XCAR (Vmac_ts_script_language_on_focus));
+ slrec.fLanguage = XINT (XCDR (Vmac_ts_script_language_on_focus));
+ slptr = &slrec;
+ }
+
+ if (slptr)
+ {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+ GetDefaultInputMethodOfClass (&saved_ts_component, slptr,
+ kKeyboardInputMethodClass);
+#else
+ GetDefaultInputMethod (&saved_ts_component, slptr);
#endif
-}
+ }
+ err = DeactivateTSMDocument (tsm_document_id);
+
+ return err;
+}
+#endif
static void
do_apple_menu (SInt16 menu_item)
@@ -9330,12 +9395,12 @@ mac_handle_window_event (next_handler, event, data)
#if USE_MAC_TSM
case kEventWindowFocusAcquired:
result = CallNextEventHandler (next_handler, event);
- err = ActivateTSMDocument (tsm_document_id);
+ err = mac_tsm_resume ();
return err == noErr ? noErr : result;
case kEventWindowFocusRelinquish:
result = CallNextEventHandler (next_handler, event);
- err = DeactivateTSMDocument (tsm_document_id);
+ err = mac_tsm_suspend ();
return err == noErr ? noErr : result;
#endif
}
@@ -10394,10 +10459,12 @@ XTread_socket (sd, expected, hold_quit)
switch ((er.message >> 24) & 0x000000FF)
{
case suspendResumeMessage:
- if ((er.message & resumeFlag) == 1)
- do_app_resume ();
+#if USE_MAC_TSM
+ if (er.message & resumeFlag)
+ mac_tsm_resume ();
else
- do_app_suspend ();
+ mac_tsm_suspend ();
+#endif
break;
case mouseMovedMessage:
@@ -10960,7 +11027,6 @@ void
mac_initialize_display_info ()
{
struct mac_display_info *dpyinfo = &one_mac_display_info;
- GDHandle main_device_handle;
bzero (dpyinfo, sizeof (*dpyinfo));
@@ -10976,37 +11042,29 @@ mac_initialize_display_info ()
strcpy (dpyinfo->mac_id_name, "Mac Display");
#endif
- main_device_handle = LMGetMainDevice();
-
dpyinfo->reference_count = 0;
dpyinfo->resx = 72.0;
dpyinfo->resy = 72.0;
- dpyinfo->color_p = TestDeviceAttribute (main_device_handle, gdDevType);
#ifdef MAC_OSX
/* HasDepth returns true if it is possible to have a 32 bit display,
- but this may not be what is actually used. Mac OSX can do better.
- CGMainDisplayID is only available on OSX 10.2 and higher, but the
- header for CGGetActiveDisplayList says that the first display returned
- is the active one, so we use that. */
+ but this may not be what is actually used. Mac OSX can do better. */
+ dpyinfo->color_p = 1;
+ dpyinfo->n_planes = CGDisplayBitsPerPixel (kCGDirectMainDisplay);
+ dpyinfo->height = CGDisplayPixelsHigh (kCGDirectMainDisplay);
+ dpyinfo->width = CGDisplayPixelsWide (kCGDirectMainDisplay);
+#else
{
- CGDirectDisplayID disp_id[1];
- CGDisplayCount disp_count;
- CGDisplayErr error_code;
-
- error_code = CGGetActiveDisplayList (1, disp_id, &disp_count);
- if (error_code != 0)
- error ("No display found, CGGetActiveDisplayList error %d", error_code);
+ GDHandle main_device_handle = LMGetMainDevice();
- dpyinfo->n_planes = CGDisplayBitsPerPixel (disp_id[0]);
+ dpyinfo->color_p = TestDeviceAttribute (main_device_handle, gdDevType);
+ for (dpyinfo->n_planes = 32; dpyinfo->n_planes > 0; dpyinfo->n_planes >>= 1)
+ if (HasDepth (main_device_handle, dpyinfo->n_planes,
+ gdDevType, dpyinfo->color_p))
+ break;
+ dpyinfo->height = (**main_device_handle).gdRect.bottom;
+ dpyinfo->width = (**main_device_handle).gdRect.right;
}
-#else
- for (dpyinfo->n_planes = 32; dpyinfo->n_planes > 0; dpyinfo->n_planes >>= 1)
- if (HasDepth (main_device_handle, dpyinfo->n_planes,
- gdDevType, dpyinfo->color_p))
- break;
#endif
- dpyinfo->height = (**main_device_handle).gdRect.bottom;
- dpyinfo->width = (**main_device_handle).gdRect.right;
dpyinfo->grabbed = 0;
dpyinfo->root_window = NULL;
dpyinfo->image_cache = make_image_cache ();
@@ -11558,6 +11616,15 @@ order. */);
DEFVAR_LISP ("mac-ts-active-input-overlay", &Vmac_ts_active_input_overlay,
doc: /* Overlay used to display Mac TSM active input area. */);
Vmac_ts_active_input_overlay = Qnil;
+
+ DEFVAR_LISP ("mac-ts-script-language-on-focus", &Vmac_ts_script_language_on_focus,
+ doc: /* *How to change Mac TSM script/language when a frame gets focus.
+If the value is t, the input script and language are restored to those
+used in the last focus frame. If the value is a pair of integers, the
+input script and language codes, which are defined in the Script
+Manager, are set to its car and cdr parts, respectively. Otherwise,
+Emacs doesn't set them and thus follows the system default behavior. */);
+ Vmac_ts_script_language_on_focus = Qnil;
#endif
}
diff --git a/src/s/gnu-linux.h b/src/s/gnu-linux.h
index 4ef3db9f2ea..5d247a1c9c8 100644
--- a/src/s/gnu-linux.h
+++ b/src/s/gnu-linux.h
@@ -52,6 +52,9 @@ Boston, MA 02110-1301, USA. */
#if LINUX_VERSION_CODE >= 0x20000
#define LINUX_MAP_SHARED_DOES_WORK
#endif /* LINUX_VERSION_CODE >= 0x20000 */
+#if LINUX_VERSION_CODE >= 0x20400
+#define LINUX_SIGNALS_VIA_CHARACTERS_DOES_WORK
+#endif /* LINUX_VERSION_CODE >= 0x20400 */
#endif /* HAVE_LINUX_VERSION_H */
#endif /* emacs */
#endif /* NOT_C_CODE */
@@ -247,9 +250,9 @@ Boston, MA 02110-1301, USA. */
#define C_DEBUG_SWITCH
#endif
-/* Let's try this out, just in case.
- Nah. Rik Faith <faith@cs.unc.edu> says it doesn't work well. */
-/* #define SIGNALS_VIA_CHARACTERS */
+#ifdef LINUX_SIGNALS_VIA_CHARACTERS_DOES_WORK
+#define SIGNALS_VIA_CHARACTERS
+#endif
/* Rob Malouf <malouf@csli.stanford.edu> says:
SYSV IPC is standard a standard part of Linux since version 0.99pl10,
diff --git a/src/syntax.c b/src/syntax.c
index 1c8d0debbf3..9af4773a01b 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -3122,6 +3122,20 @@ init_syntax_once ()
Vstandard_syntax_table = Fmake_char_table (Qsyntax_table, temp);
+ /* Control characters should not be whitespace. */
+ temp = XVECTOR (Vsyntax_code_object)->contents[(int) Spunct];
+ for (i = 0; i <= ' ' - 1; i++)
+ SET_RAW_SYNTAX_ENTRY (Vstandard_syntax_table, i, temp);
+ SET_RAW_SYNTAX_ENTRY (Vstandard_syntax_table, 0177, temp);
+
+ /* Except that a few really are whitespace. */
+ temp = XVECTOR (Vsyntax_code_object)->contents[(int) Swhitespace];
+ SET_RAW_SYNTAX_ENTRY (Vstandard_syntax_table, ' ', temp);
+ SET_RAW_SYNTAX_ENTRY (Vstandard_syntax_table, '\t', temp);
+ SET_RAW_SYNTAX_ENTRY (Vstandard_syntax_table, '\n', temp);
+ SET_RAW_SYNTAX_ENTRY (Vstandard_syntax_table, 015, temp);
+ SET_RAW_SYNTAX_ENTRY (Vstandard_syntax_table, 014, temp);
+
temp = XVECTOR (Vsyntax_code_object)->contents[(int) Sword];
for (i = 'a'; i <= 'z'; i++)
SET_RAW_SYNTAX_ENTRY (Vstandard_syntax_table, i, temp);
diff --git a/src/window.c b/src/window.c
index e7f2ed93fd3..f3960b96f2a 100644
--- a/src/window.c
+++ b/src/window.c
@@ -65,7 +65,7 @@ static void window_scroll_pixel_based P_ ((Lisp_Object, int, int, int));
static void window_scroll_line_based P_ ((Lisp_Object, int, int, int));
static int window_min_size_1 P_ ((struct window *, int));
static int window_min_size P_ ((struct window *, int, int, int *));
-static void size_window P_ ((Lisp_Object, int, int, int));
+static void size_window P_ ((Lisp_Object, int, int, int, int, int));
static int freeze_window_start P_ ((struct window *, void *));
static int window_fixed_size_p P_ ((struct window *, int, int));
static void enlarge_window P_ ((Lisp_Object, int, int));
@@ -2828,17 +2828,23 @@ shrink_windows (total, size, nchildren, shrinkable,
/* Set WINDOW's height or width to SIZE. WIDTH_P non-zero means set
WINDOW's width. Resize WINDOW's children, if any, so that they
- keep their proportionate size relative to WINDOW. Propagate
- WINDOW's top or left edge position to children. Delete windows
- that become too small unless NODELETE_P is non-zero.
+ keep their proportionate size relative to WINDOW.
+
+ If FIRST_ONLY is 1, change only the first of WINDOW's children when
+ they are in series. If LAST_ONLY is 1, change only the last of
+ WINDOW's children when they are in series.
+
+ Propagate WINDOW's top or left edge position to children. Delete
+ windows that become too small unless NODELETE_P is non-zero.
If NODELETE_P is 2, that means we do delete windows that are
too small, even if they were too small before! */
static void
-size_window (window, size, width_p, nodelete_p)
+size_window (window, size, width_p, nodelete_p, first_only, last_only)
Lisp_Object window;
int size, width_p, nodelete_p;
+ int first_only, last_only;
{
struct window *w = XWINDOW (window);
struct window *c;
@@ -2913,6 +2919,7 @@ size_window (window, size, width_p, nodelete_p)
if (!NILP (*sideward))
{
+ /* We have a chain of parallel siblings whose size should all change. */
for (child = *sideward; !NILP (child); child = c->next)
{
c = XWINDOW (child);
@@ -2920,9 +2927,45 @@ size_window (window, size, width_p, nodelete_p)
c->left_col = w->left_col;
else
c->top_line = w->top_line;
- size_window (child, size, width_p, nodelete_p);
+ size_window (child, size, width_p, nodelete_p,
+ first_only, last_only);
}
}
+ else if (!NILP (*forward) && last_only)
+ {
+ /* Change the last in a series of siblings. */
+ Lisp_Object last_child;
+ int child_size;
+
+ for (child = *forward; !NILP (child); child = c->next)
+ {
+ c = XWINDOW (child);
+ last_child = child;
+ }
+
+ child_size = XINT (width_p ? c->total_cols : c->total_lines);
+ size_window (last_child,
+ size - old_size + child_size,
+ width_p, nodelete_p, first_only, last_only);
+ }
+ else if (!NILP (*forward) && first_only)
+ {
+ /* Change the first in a series of siblings. */
+ int child_size;
+
+ child = *forward;
+ c = XWINDOW (child);
+
+ if (width_p)
+ c->left_col = w->left_col;
+ else
+ c->top_line = w->top_line;
+
+ child_size = XINT (width_p ? c->total_cols : c->total_lines);
+ size_window (child,
+ size - old_size + child_size,
+ width_p, nodelete_p, first_only, last_only);
+ }
else if (!NILP (*forward))
{
int fixed_size, each, extra, n;
@@ -2930,7 +2973,7 @@ size_window (window, size, width_p, nodelete_p)
int last_pos, first_pos, nchildren, total;
int *new_sizes = NULL;
- /* Determine the fixed-size portion of the this window, and the
+ /* Determine the fixed-size portion of this window, and the
number of child windows. */
fixed_size = nchildren = nfixed = total = 0;
for (child = *forward; !NILP (child); child = c->next, ++nchildren)
@@ -2993,7 +3036,7 @@ size_window (window, size, width_p, nodelete_p)
/* Set new height. Note that size_window also propagates
edge positions to children, so it's not a no-op if we
didn't change the child's size. */
- size_window (child, new_size, width_p, 1);
+ size_window (child, new_size, width_p, 1, first_only, last_only);
/* Remember the bottom/right edge position of this child; it
will be used to set the top/left edge of the next child. */
@@ -3012,7 +3055,7 @@ size_window (window, size, width_p, nodelete_p)
int child_size;
c = XWINDOW (child);
child_size = width_p ? XINT (c->total_cols) : XINT (c->total_lines);
- size_window (child, child_size, width_p, 2);
+ size_window (child, child_size, width_p, 2, first_only, last_only);
}
}
}
@@ -3028,7 +3071,7 @@ set_window_height (window, height, nodelete)
int height;
int nodelete;
{
- size_window (window, height, 0, nodelete);
+ size_window (window, height, 0, nodelete, 0, 0);
}
@@ -3043,7 +3086,7 @@ set_window_width (window, width, nodelete)
int width;
int nodelete;
{
- size_window (window, width, 1, nodelete);
+ size_window (window, width, 1, nodelete, 0, 0);
}
/* Change window heights in windows rooted in WINDOW by N lines. */
@@ -4281,21 +4324,31 @@ adjust_window_trailing_edge (window, delta, horiz_flag)
{
Lisp_Object first_parallel = Qnil;
- p = XWINDOW (window);
- parent = p->parent;
-
- if (NILP (XWINDOW (window)->next))
+ if (NILP (window))
{
+ /* This happens if WINDOW on the previous iteration was
+ at top level of the window tree. */
Fset_window_configuration (old_config);
- error ("No other window following this one");
+ error ("Specified window edge is fixed");
}
+ p = XWINDOW (window);
+ parent = p->parent;
+
/* See if this level has windows in parallel in the specified
direction. If so, set FIRST_PARALLEL to the first one. */
if (horiz_flag)
{
if (! NILP (parent) && !NILP (XWINDOW (parent)->vchild))
first_parallel = XWINDOW (parent)->vchild;
+ else if (NILP (parent) && !NILP (p->next))
+ {
+ /* Handle the vertical chain of main window and minibuffer
+ which has no parent. */
+ first_parallel = window;
+ while (! NILP (XWINDOW (first_parallel)->prev))
+ first_parallel = XWINDOW (first_parallel)->prev;
+ }
}
else
{
@@ -4303,6 +4356,16 @@ adjust_window_trailing_edge (window, delta, horiz_flag)
first_parallel = XWINDOW (parent)->hchild;
}
+ /* If this level's succession is in the desired dimension,
+ and this window is the last one, and there is no higher level,
+ its trailing edge is fixed. */
+ if (NILP (XWINDOW (window)->next) && NILP (first_parallel)
+ && NILP (parent))
+ {
+ Fset_window_configuration (old_config);
+ error ("Specified window edge is fixed");
+ }
+
/* Don't make this window too small. */
if (XINT (CURSIZE (window)) + delta
< (horiz_flag ? window_min_width : window_min_height))
@@ -4326,7 +4389,7 @@ adjust_window_trailing_edge (window, delta, horiz_flag)
we will fail and report an error, above.) */
if (NILP (first_parallel))
{
- if (!NILP (XWINDOW (window)->next))
+ if (!NILP (p->next))
{
/* This may happen for the minibuffer. In that case
the window_deletion_count check below does not work. */
@@ -4339,7 +4402,7 @@ adjust_window_trailing_edge (window, delta, horiz_flag)
XSETINT (CURBEG (p->next),
XINT (CURBEG (p->next)) + delta);
size_window (p->next, XINT (CURSIZE (p->next)) - delta,
- horiz_flag, 0);
+ horiz_flag, 0, 1, 0);
break;
}
}
@@ -4351,7 +4414,7 @@ adjust_window_trailing_edge (window, delta, horiz_flag)
child = XWINDOW (child)->next)
if (! EQ (child, window))
size_window (child, XINT (CURSIZE (child)) + delta,
- horiz_flag, 0);
+ horiz_flag, 0, 0, 1);
window = parent;
}
diff --git a/src/xdisp.c b/src/xdisp.c
index f87f38dc50e..c7e6eda58ca 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -903,6 +903,7 @@ static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
static void compute_line_metrics P_ ((struct it *));
static void run_redisplay_end_trigger_hook P_ ((struct it *));
static int get_overlay_strings P_ ((struct it *, int));
+static int get_overlay_strings_1 P_ ((struct it *, int, int));
static void next_overlay_string P_ ((struct it *));
static void reseat P_ ((struct it *, struct text_pos, int));
static void reseat_1 P_ ((struct it *, struct text_pos, int));
@@ -2896,8 +2897,8 @@ init_from_display_pos (it, w, pos)
also ``processed'' overlay strings at ZV. */
while (it->sp)
pop_it (it);
- it->current.overlay_string_index = -1;
- it->method = GET_FROM_BUFFER;
+ xassert (it->current.overlay_string_index == -1);
+ xassert (it->method == GET_FROM_BUFFER);
if (CHARPOS (pos->pos) == ZV)
it->overlay_strings_at_end_processed_p = 1;
}
@@ -3008,7 +3009,19 @@ handle_stop (it)
if (handled == HANDLED_RECOMPUTE_PROPS)
break;
else if (handled == HANDLED_RETURN)
- return;
+ {
+ /* We still want to show before and after strings from
+ overlays even if the actual buffer text is replaced. */
+ if (!handle_overlay_change_p || it->sp > 1)
+ return;
+ if (!get_overlay_strings_1 (it, 0, 0))
+ return;
+ it->ignore_overlay_strings_at_pos_p = 1;
+ it->string_from_display_prop_p = 0;
+ handle_overlay_change_p = 0;
+ handled = HANDLED_RECOMPUTE_PROPS;
+ break;
+ }
else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
handle_overlay_change_p = 0;
}
@@ -4460,6 +4473,8 @@ handle_composition_prop (it)
}
return HANDLED_RECOMPUTE_PROPS;
}
+
+ push_it (it);
it->method = GET_FROM_COMPOSITION;
it->cmp_id = id;
it->cmp_len = COMPOSITION_LENGTH (prop);
@@ -4529,13 +4544,14 @@ next_overlay_string (it)
int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
pop_it (it);
- xassert (it->stop_charpos >= BEGV
- && it->stop_charpos <= it->end_charpos);
- it->string = Qnil;
+ xassert (it->sp > 0
+ || it->method == GET_FROM_COMPOSITION
+ || (NILP (it->string)
+ && it->method == GET_FROM_BUFFER
+ && it->stop_charpos >= BEGV
+ && it->stop_charpos <= it->end_charpos));
it->current.overlay_string_index = -1;
- SET_TEXT_POS (it->current.string_pos, -1, -1);
it->n_overlay_strings = 0;
- it->method = GET_FROM_BUFFER;
/* If we're at the end of the buffer, record that we have
processed the overlay strings there already, so that
@@ -4791,7 +4807,7 @@ load_overlay_strings (it, charpos)
least one overlay string was found. */
static int
-get_overlay_strings (it, charpos)
+get_overlay_strings_1 (it, charpos, compute_stop_p)
struct it *it;
int charpos;
{
@@ -4813,12 +4829,13 @@ get_overlay_strings (it, charpos)
/* Make sure we know settings in current_buffer, so that we can
restore meaningful values when we're done with the overlay
strings. */
- compute_stop_pos (it);
+ if (compute_stop_p)
+ compute_stop_pos (it);
xassert (it->face_id >= 0);
/* Save IT's settings. They are restored after all overlay
strings have been processed. */
- xassert (it->sp == 0);
+ xassert (!compute_stop_p || it->sp == 0);
push_it (it);
/* Set up IT to deliver display elements from the first overlay
@@ -4830,14 +4847,23 @@ get_overlay_strings (it, charpos)
it->end_charpos = SCHARS (it->string);
it->multibyte_p = STRING_MULTIBYTE (it->string);
it->method = GET_FROM_STRING;
- }
- else
- {
- it->string = Qnil;
- it->current.overlay_string_index = -1;
- it->method = GET_FROM_BUFFER;
+ return 1;
}
+ it->current.overlay_string_index = -1;
+ return 0;
+}
+
+static int
+get_overlay_strings (it, charpos)
+ struct it *it;
+ int charpos;
+{
+ it->string = Qnil;
+ it->method = GET_FROM_BUFFER;
+
+ (void) get_overlay_strings_1 (it, charpos, 1);
+
CHECK_IT (it);
/* Value is non-zero if we found at least one overlay string. */
@@ -4861,19 +4887,38 @@ push_it (it)
{
struct iterator_stack_entry *p;
- xassert (it->sp < 2);
+ xassert (it->sp < IT_STACK_SIZE);
p = it->stack + it->sp;
p->stop_charpos = it->stop_charpos;
xassert (it->face_id >= 0);
p->face_id = it->face_id;
p->string = it->string;
- p->pos = it->current;
+ p->method = it->method;
+ switch (p->method)
+ {
+ case GET_FROM_IMAGE:
+ p->u.image.object = it->object;
+ p->u.image.image_id = it->image_id;
+ p->u.image.slice = it->slice;
+ break;
+ case GET_FROM_COMPOSITION:
+ p->u.comp.object = it->object;
+ p->u.comp.c = it->c;
+ p->u.comp.len = it->len;
+ p->u.comp.cmp_id = it->cmp_id;
+ p->u.comp.cmp_len = it->cmp_len;
+ break;
+ case GET_FROM_STRETCH:
+ p->u.stretch.object = it->object;
+ break;
+ }
+ p->position = it->position;
+ p->current = it->current;
p->end_charpos = it->end_charpos;
p->string_nchars = it->string_nchars;
p->area = it->area;
p->multibyte_p = it->multibyte_p;
- p->slice = it->slice;
p->space_width = it->space_width;
p->font_height = it->font_height;
p->voffset = it->voffset;
@@ -4900,13 +4945,34 @@ pop_it (it)
p = it->stack + it->sp;
it->stop_charpos = p->stop_charpos;
it->face_id = p->face_id;
+ it->current = p->current;
+ it->position = p->position;
it->string = p->string;
- it->current = p->pos;
+ if (NILP (it->string))
+ SET_TEXT_POS (it->current.string_pos, -1, -1);
+ it->method = p->method;
+ switch (it->method)
+ {
+ case GET_FROM_IMAGE:
+ it->image_id = p->u.image.image_id;
+ it->object = p->u.image.object;
+ it->slice = p->u.image.slice;
+ break;
+ case GET_FROM_COMPOSITION:
+ it->object = p->u.comp.object;
+ it->c = p->u.comp.c;
+ it->len = p->u.comp.len;
+ it->cmp_id = p->u.comp.cmp_id;
+ it->cmp_len = p->u.comp.cmp_len;
+ break;
+ case GET_FROM_STRETCH:
+ it->object = p->u.comp.object;
+ break;
+ }
it->end_charpos = p->end_charpos;
it->string_nchars = p->string_nchars;
it->area = p->area;
it->multibyte_p = p->multibyte_p;
- it->slice = p->slice;
it->space_width = p->space_width;
it->font_height = p->font_height;
it->voffset = p->voffset;
@@ -5038,6 +5104,7 @@ back_to_previous_visible_line_start (it)
while (IT_CHARPOS (*it) > BEGV)
{
back_to_previous_line_start (it);
+
if (IT_CHARPOS (*it) <= BEGV)
break;
@@ -5057,37 +5124,47 @@ back_to_previous_visible_line_start (it)
continue;
}
- /* If newline has a display property that replaces the newline with something
- else (image or text), find start of overlay or interval and continue search
- from that point. */
- if (IT_CHARPOS (*it) > BEGV)
- {
- struct it it2 = *it;
- int pos;
- int beg, end;
- Lisp_Object val, overlay;
-
- pos = --IT_CHARPOS (it2);
- --IT_BYTEPOS (it2);
- it2.sp = 0;
- if (handle_display_prop (&it2) == HANDLED_RETURN
- && !NILP (val = get_char_property_and_overlay
- (make_number (pos), Qdisplay, Qnil, &overlay))
- && (OVERLAYP (overlay)
- ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
- : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
- {
- if (beg < BEGV)
- beg = BEGV;
- IT_CHARPOS (*it) = beg;
- IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
- continue;
- }
- }
+ if (IT_CHARPOS (*it) <= BEGV)
+ break;
- break;
+ {
+ struct it it2;
+ int pos;
+ int beg, end;
+ Lisp_Object val, overlay;
+
+ /* If newline is part of a composition, continue from start of composition */
+ if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
+ && beg < IT_CHARPOS (*it))
+ goto replaced;
+
+ /* If newline is replaced by a display property, find start of overlay
+ or interval and continue search from that point. */
+ it2 = *it;
+ pos = --IT_CHARPOS (it2);
+ --IT_BYTEPOS (it2);
+ it2.sp = 0;
+ if (handle_display_prop (&it2) == HANDLED_RETURN
+ && !NILP (val = get_char_property_and_overlay
+ (make_number (pos), Qdisplay, Qnil, &overlay))
+ && (OVERLAYP (overlay)
+ ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
+ : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
+ goto replaced;
+
+ /* Newline is not replaced by anything -- so we are done. */
+ break;
+
+ replaced:
+ if (beg < BEGV)
+ beg = BEGV;
+ IT_CHARPOS (*it) = beg;
+ IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
+ }
}
+ it->continuation_lines_width = 0;
+
xassert (IT_CHARPOS (*it) >= BEGV);
xassert (IT_CHARPOS (*it) == BEGV
|| FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
@@ -5219,15 +5296,11 @@ reseat_1 (it, pos, set_stop_p)
IT_STRING_BYTEPOS (*it) = -1;
it->string = Qnil;
it->method = GET_FROM_BUFFER;
- /* RMS: I added this to fix a bug in move_it_vertically_backward
- where it->area continued to relate to the starting point
- for the backward motion. Bug report from
- Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
- However, I am not sure whether reseat still does the right thing
- in general after this change. */
+ it->object = it->w->buffer;
it->area = TEXT_AREA;
it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
it->sp = 0;
+ it->string_from_display_prop_p = 0;
it->face_before_selective_p = 0;
if (set_stop_p)
@@ -5706,18 +5779,20 @@ set_iterator_to_next (it, reseat_p)
case GET_FROM_COMPOSITION:
xassert (it->cmp_id >= 0 && it->cmp_id < n_compositions);
- if (STRINGP (it->string))
+ xassert (it->sp > 0);
+ pop_it (it);
+ if (it->method == GET_FROM_STRING)
{
IT_STRING_BYTEPOS (*it) += it->len;
IT_STRING_CHARPOS (*it) += it->cmp_len;
- it->method = GET_FROM_STRING;
+ it->object = it->string;
goto consider_string_end;
}
- else
+ else if (it->method == GET_FROM_BUFFER)
{
IT_BYTEPOS (*it) += it->len;
IT_CHARPOS (*it) += it->cmp_len;
- it->method = GET_FROM_BUFFER;
+ it->object = it->w->buffer;
}
break;
@@ -5747,7 +5822,10 @@ set_iterator_to_next (it, reseat_p)
else if (STRINGP (it->string))
it->method = GET_FROM_STRING;
else
- it->method = GET_FROM_BUFFER;
+ {
+ it->method = GET_FROM_BUFFER;
+ it->object = it->w->buffer;
+ }
it->dpvec = NULL;
it->current.dpvec_index = -1;
@@ -5795,9 +5873,8 @@ set_iterator_to_next (it, reseat_p)
&& it->sp > 0)
{
pop_it (it);
- if (STRINGP (it->string))
+ if (it->method == GET_FROM_STRING)
goto consider_string_end;
- it->method = GET_FROM_BUFFER;
}
}
break;
@@ -5809,13 +5886,8 @@ set_iterator_to_next (it, reseat_p)
if the `display' property takes up the whole string. */
xassert (it->sp > 0);
pop_it (it);
- it->image_id = 0;
- if (STRINGP (it->string))
- {
- it->method = GET_FROM_STRING;
- goto consider_string_end;
- }
- it->method = GET_FROM_BUFFER;
+ if (it->method == GET_FROM_STRING)
+ goto consider_string_end;
break;
default:
@@ -6038,6 +6110,7 @@ next_element_from_ellipsis (it)
setting face_before_selective_p. */
it->saved_face_id = it->face_id;
it->method = GET_FROM_BUFFER;
+ it->object = it->w->buffer;
reseat_at_next_visible_line_start (it, 1);
it->face_before_selective_p = 1;
}
@@ -6226,6 +6299,8 @@ next_element_from_composition (it)
: it->current.pos);
if (STRINGP (it->string))
it->object = it->string;
+ else
+ it->object = it->w->buffer;
return 1;
}
@@ -11687,9 +11762,12 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
}
else
{
- string_before_pos = last_pos;
- string_start = glyph;
- string_start_x = x;
+ if (string_start == NULL)
+ {
+ string_before_pos = last_pos;
+ string_start = glyph;
+ string_start_x = x;
+ }
/* Skip all glyphs from string. */
do
{
@@ -11747,25 +11825,25 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
glyph on point by scanning from string_start again. */
Lisp_Object limit;
Lisp_Object string;
+ struct glyph *stop = glyph;
int pos;
limit = make_number (pt_old + 1);
- end = glyph;
glyph = string_start;
x = string_start_x;
string = glyph->object;
pos = string_buffer_position (w, string, string_before_pos);
/* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
because we always put cursor after overlay strings. */
- while (pos == 0 && glyph < end)
+ while (pos == 0 && glyph < stop)
{
string = glyph->object;
- SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
- if (glyph < end)
+ SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
+ if (glyph < stop)
pos = string_buffer_position (w, glyph->object, string_before_pos);
}
- while (glyph < end)
+ while (glyph < stop)
{
pos = XINT (Fnext_single_char_property_change
(make_number (pos), Qdisplay, Qnil, limit));
@@ -11773,13 +11851,13 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
break;
/* Skip glyphs from the same string. */
string = glyph->object;
- SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
+ SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
/* Skip glyphs from an overlay. */
- while (glyph < end
+ while (glyph < stop
&& ! string_buffer_position (w, glyph->object, pos))
{
string = glyph->object;
- SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
+ SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
}
}
diff --git a/src/xfns.c b/src/xfns.c
index 11552a5a9f7..e0cc89c6ebe 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -3207,8 +3207,7 @@ This function is an internal primitive--use `make-frame' instead. */)
if (! STRINGP (font))
font = build_string ("fixed");
- x_default_parameter (f, parms, Qfont, font,
- "font", "Font", RES_TYPE_STRING);
+ x_set_frame_parameters (f, Fcons (Fcons (Qfont, font), Qnil));
}
#ifdef USE_LUCID
diff --git a/src/xterm.c b/src/xterm.c
index 2bfb8a15bb8..975c9c68f39 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -359,7 +359,8 @@ static void x_scroll_bar_report_motion P_ ((struct frame **, Lisp_Object *,
Lisp_Object *, Lisp_Object *,
unsigned long *));
static void x_check_fullscreen P_ ((struct frame *));
-static void x_check_expected_move P_ ((struct frame *));
+static void x_check_expected_move P_ ((struct frame *, int, int));
+static void x_sync_with_move P_ ((struct frame *, int, int, int));
static int handle_one_xevent P_ ((struct x_display_info *, XEvent *,
int *, struct input_event *));
static SIGTYPE x_connection_closed P_ ((Display *, char *));
@@ -6686,11 +6687,8 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
&& GTK_WIDGET_MAPPED (FRAME_GTK_OUTER_WIDGET (f)))
#endif
{
- /* What we have now is the position of Emacs's own window.
- Convert that to the position of the window manager window. */
x_real_positions (f, &f->left_pos, &f->top_pos);
- x_check_expected_move (f);
if (f->want_fullscreen & FULLSCREEN_WAIT)
f->want_fullscreen &= ~(FULLSCREEN_WAIT|FULLSCREEN_BOTH);
}
@@ -8260,8 +8258,11 @@ x_set_offset (f, xoff, yoff, change_gravity)
{
int modified_top, modified_left;
- if (change_gravity > 0)
+ if (change_gravity != 0)
{
+ FRAME_X_OUTPUT (f)->left_before_move = f->left_pos;
+ FRAME_X_OUTPUT (f)->top_before_move = f->top_pos;
+
f->top_pos = yoff;
f->left_pos = xoff;
f->size_hint_flags &= ~ (XNegative | YNegative);
@@ -8279,7 +8280,7 @@ x_set_offset (f, xoff, yoff, change_gravity)
modified_left = f->left_pos;
modified_top = f->top_pos;
- if (FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A)
+ if (change_gravity != 0 && FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A)
{
/* Some WMs (twm, wmaker at least) has an offset that is smaller
than the WM decorations. So we use the calculated offset instead
@@ -8291,13 +8292,26 @@ x_set_offset (f, xoff, yoff, change_gravity)
XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
modified_left, modified_top);
- if (FRAME_VISIBLE_P (f)
- && FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN)
- {
- FRAME_X_OUTPUT (f)->check_expected_move = 1;
- FRAME_X_OUTPUT (f)->expected_top = f->top_pos;
- FRAME_X_OUTPUT (f)->expected_left = f->left_pos;
- }
+ x_sync_with_move (f, f->left_pos, f->top_pos,
+ FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN
+ ? 1 : 0);
+
+ /* change_gravity is non-zero when this function is called from Lisp to
+ programmatically move a frame. In that case, we call
+ x_check_expected_move to discover if we have a "Type A" or "Type B"
+ window manager, and, for a "Type A" window manager, adjust the position
+ of the frame.
+
+ We call x_check_expected_move if a programmatic move occurred, and
+ either the window manager type (A/B) is unknown or it is Type A but we
+ need to compute the top/left offset adjustment for this frame. */
+
+ if (change_gravity != 0 &&
+ (FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN
+ || (FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A
+ && (FRAME_X_OUTPUT (f)->move_offset_left == 0
+ && FRAME_X_OUTPUT (f)->move_offset_top == 0))))
+ x_check_expected_move (f, modified_left, modified_top);
UNBLOCK_INPUT;
}
@@ -8332,37 +8346,96 @@ x_check_fullscreen (f)
}
}
-/* If frame parameters are set after the frame is mapped, we need to move
- the window.
- Some window managers moves the window to the right position, some
- moves the outer window manager window to the specified position.
- Here we check that we are in the right spot. If not, make a second
- move, assuming we are dealing with the second kind of window manager. */
+/* This function is called by x_set_offset to determine whether the window
+ manager interfered with the positioning of the frame. Type A window
+ managers position the surrounding window manager decorations a small
+ amount above and left of the user-supplied position. Type B window
+ managers position the surrounding window manager decorations at the
+ user-specified position. If we detect a Type A window manager, we
+ compensate by moving the window right and down by the proper amount. */
+
static void
-x_check_expected_move (f)
+x_check_expected_move (f, expected_left, expected_top)
struct frame *f;
+ int expected_left;
+ int expected_top;
{
- if (FRAME_X_OUTPUT (f)->check_expected_move)
- {
- int expect_top = FRAME_X_OUTPUT (f)->expected_top;
- int expect_left = FRAME_X_OUTPUT (f)->expected_left;
+ int count = 0, current_left = 0, current_top = 0;
+
+ /* x_real_positions returns the left and top offsets of the outermost
+ window manager window around the frame. */
- if (expect_top != f->top_pos || expect_left != f->left_pos)
+ x_real_positions (f, &current_left, &current_top);
+
+ if (current_left != expected_left || current_top != expected_top)
{
+ /* It's a "Type A" window manager. */
+
+ int adjusted_left;
+ int adjusted_top;
+
FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_A;
- FRAME_X_OUTPUT (f)->move_offset_left = expect_left - f->left_pos;
- FRAME_X_OUTPUT (f)->move_offset_top = expect_top - f->top_pos;
+ FRAME_X_OUTPUT (f)->move_offset_left = expected_left - current_left;
+ FRAME_X_OUTPUT (f)->move_offset_top = expected_top - current_top;
+
+ /* Now fix the mispositioned frame's location. */
- f->left_pos = expect_left;
- f->top_pos = expect_top;
- x_set_offset (f, expect_left, expect_top, 0);
+ adjusted_left = expected_left + FRAME_X_OUTPUT (f)->move_offset_left;
+ adjusted_top = expected_top + FRAME_X_OUTPUT (f)->move_offset_top;
+
+ XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
+ adjusted_left, adjusted_top);
+
+ x_sync_with_move (f, expected_left, expected_top, 0);
}
- else if (FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN)
+ else
+ /* It's a "Type B" window manager. We don't have to adjust the
+ frame's position. */
+
FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_B;
+}
+
+
+/* Wait for XGetGeometry to return up-to-date position information for a
+ recently-moved frame. Call this immediately after calling XMoveWindow.
+ If FUZZY is non-zero, then LEFT and TOP are just estimates of where the
+ frame has been moved to, so we use a fuzzy position comparison instead
+ of an exact comparison. */
+
+static void
+x_sync_with_move (f, left, top, fuzzy)
+ struct frame *f;
+ int left, top, fuzzy;
+{
+ int count = 0;
+
+ while (count++ < 50)
+ {
+ int current_left = 0, current_top = 0;
+
+ /* In theory, this call to XSync only needs to happen once, but in
+ practice, it doesn't seem to work, hence the need for the surrounding
+ loop. */
+
+ XSync (FRAME_X_DISPLAY (f), False);
+ x_real_positions (f, &current_left, &current_top);
+
+ if (fuzzy)
+ {
+ /* The left fuzz-factor is 10 pixels. The top fuzz-factor is 40
+ pixels. */
- /* Just do this once */
- FRAME_X_OUTPUT (f)->check_expected_move = 0;
+ if (abs (current_left - left) <= 10 && abs (current_top - top) <= 40)
+ return;
}
+ else if (current_left == left && current_top == top)
+ return;
+ }
+
+ /* As a last resort, just wait 0.5 seconds and hope that XGetGeometry
+ will then return up-to-date position info. */
+
+ wait_reading_process_output (0, 500000, 0, 0, Qnil, NULL, 0);
}
diff --git a/src/xterm.h b/src/xterm.h
index 03d7b630d65..4580f3c0744 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -639,18 +639,14 @@ struct x_output
FocusOut and LeaveNotify clears EXPLICIT/IMPLICIT. */
int focus_state;
- /* The latest move we made to FRAME_OUTER_WINDOW. Saved so we can
- compensate for type A WMs (see wm_type in dpyinfo above). */
- int expected_top;
- int expected_left;
-
/* The offset we need to add to compensate for type A WMs. */
int move_offset_top;
int move_offset_left;
- /* Nonzero if we have made a move and needs to check if the WM placed us
- at the right position. */
- int check_expected_move;
+ /* The frame's left/top offsets before we call XMoveWindow. See
+ x_check_expected_move. */
+ int left_before_move;
+ int top_before_move;
};
#define No_Cursor (None)