aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaroly Lorentey2004-01-12 16:36:35 +0000
committerKaroly Lorentey2004-01-12 16:36:35 +0000
commit990e879437236fc76e827d6191899c117f01fd99 (patch)
treee3a10d3d851886e39fe0accf24079874cbaf1063
parent7f19e125070fa016bcfad660febf19f1a84adb76 (diff)
parentbcb6b6b8b1a7bc1f724bb0b5ba3306c760d97c35 (diff)
downloademacs-990e879437236fc76e827d6191899c117f01fd99.tar.gz
emacs-990e879437236fc76e827d6191899c117f01fd99.zip
Merged in changes from CVS HEAD
Patches applied: * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-32 Update from CVS git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-57
-rw-r--r--etc/NEWS13
-rw-r--r--lisp/calendar/appt.el12
-rw-r--r--lispref/ChangeLog13
-rw-r--r--lispref/searching.texi169
-rw-r--r--lwlib/ChangeLog28
-rw-r--r--lwlib/lwlib-Xaw.c17
-rw-r--r--lwlib/lwlib-Xlw.c31
-rw-r--r--lwlib/lwlib-Xm.c33
-rw-r--r--lwlib/xlwmenu.c109
-rw-r--r--lwlib/xlwmenu.h3
-rw-r--r--lwlib/xlwmenuP.h1
-rw-r--r--src/ChangeLog10
-rw-r--r--src/xmenu.c22
13 files changed, 344 insertions, 117 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 60068811a59..aae7f497103 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -481,6 +481,13 @@ command.
481On the other hand, the size of the thumb does not represent the actual 481On the other hand, the size of the thumb does not represent the actual
482amount of text shown any more (only a crude approximation of it). 482amount of text shown any more (only a crude approximation of it).
483 483
484---
485** The pop up menus for Lucid now stay up if you do a fast click and can
486be navigated with the arrow keys (like Gtk+ and W32).
487
488---
489** Dialogs for Lucid/Athena and Lesstif/Motif pops down when pressing ESC.
490
484+++ 491+++
485** The file selection dialog for Gtk+, W32 and Motif/Lesstif can be 492** The file selection dialog for Gtk+, W32 and Motif/Lesstif can be
486disabled by customizing the variable `use-file-dialog'. 493disabled by customizing the variable `use-file-dialog'.
@@ -946,6 +953,12 @@ count backward from the end of the year.
946This can be controlled through the variables `diary-header-line-flag' 953This can be controlled through the variables `diary-header-line-flag'
947and `diary-header-line-format'. 954and `diary-header-line-format'.
948 955
956+++
957** The procedure for activating appointment reminders has changed: use
958the new function `appt-activate'. The new variable
959`appt-display-format' controls how reminders are displayed, replacing
960appt-issue-message, appt-visible, and appt-msg-window.
961
949** VC Changes 962** VC Changes
950 963
951*** The key C-x C-q no longer checks files in or out, it only changes 964*** The key C-x C-q no longer checks files in or out, it only changes
diff --git a/lisp/calendar/appt.el b/lisp/calendar/appt.el
index 825bd936475..8a92ef614ce 100644
--- a/lisp/calendar/appt.el
+++ b/lisp/calendar/appt.el
@@ -79,6 +79,18 @@
79 79
80 80
81;;;###autoload 81;;;###autoload
82(defcustom appt-issue-message t
83 "*Non-nil means check for appointments in the diary buffer.
84To be detected, the diary entry must have the format described in the
85documentation of the function `appt-check'."
86 :type 'boolean
87 :group 'appt)
88
89(make-obsolete-variable 'appt-issue-message
90 "use the function `appt-activate', and the \
91variable `appt-display-format' instead." "21.4")
92
93;;;###autoload
82(defcustom appt-message-warning-time 12 94(defcustom appt-message-warning-time 12
83 "*Time in minutes before an appointment that the warning begins." 95 "*Time in minutes before an appointment that the warning begins."
84 :type 'integer 96 :type 'integer
diff --git a/lispref/ChangeLog b/lispref/ChangeLog
index 62fb3e10307..7e1a96db78d 100644
--- a/lispref/ChangeLog
+++ b/lispref/ChangeLog
@@ -1,3 +1,16 @@
12004-01-11 Luc Teirlinck <teirllm@auburn.edu>
2
3 * searching.texi: Various small changes in addition to the
4 following.
5 (Regexp Example): Adapt to new value of `sentence-end'.
6 (Regexp Functions): The PAREN argument to `regexp-opt' can be
7 `words'.
8 (Search and Replace): Add usage note for `perform-replace'.
9 (Entire Match Data): Mention INTEGERS and REUSE arguments to
10 `match-data'.
11 (Standard Regexps): Update for new values of `paragraph-start'
12 and `sentence-end'.
13
12004-01-07 Luc Teirlinck <teirllm@auburn.edu> 142004-01-07 Luc Teirlinck <teirllm@auburn.edu>
2 15
3 * files.texi (Saving Buffers): Clarify descriptions of 16 * files.texi (Saving Buffers): Clarify descriptions of
diff --git a/lispref/searching.texi b/lispref/searching.texi
index ab5abecc7d0..94edaae6734 100644
--- a/lispref/searching.texi
+++ b/lispref/searching.texi
@@ -90,7 +90,8 @@ If @var{repeat} is supplied (it must be a positive number), then the
90search is repeated that many times (each time starting at the end of the 90search is repeated that many times (each time starting at the end of the
91previous time's match). If these successive searches succeed, the 91previous time's match). If these successive searches succeed, the
92function succeeds, moving point and returning its new value. Otherwise 92function succeeds, moving point and returning its new value. Otherwise
93the search fails, leaving point where it started. 93the search fails, with results depending on the value of
94@var{noerror}, as described above.
94@end deffn 95@end deffn
95 96
96@deffn Command search-backward string &optional limit noerror repeat 97@deffn Command search-backward string &optional limit noerror repeat
@@ -143,7 +144,7 @@ If @var{noerror} is @code{nil}, then @code{word-search-forward} signals
143an error if the search fails. If @var{noerror} is @code{t}, then it 144an error if the search fails. If @var{noerror} is @code{t}, then it
144returns @code{nil} instead of signaling an error. If @var{noerror} is 145returns @code{nil} instead of signaling an error. If @var{noerror} is
145neither @code{nil} nor @code{t}, it moves point to @var{limit} (or the 146neither @code{nil} nor @code{t}, it moves point to @var{limit} (or the
146end of the buffer) and returns @code{nil}. 147end of the accessible portion of the buffer) and returns @code{nil}.
147 148
148If @var{repeat} is non-@code{nil}, then the search is repeated that many 149If @var{repeat} is non-@code{nil}, then the search is repeated that many
149times. Point is positioned at the end of the last match. 150times. Point is positioned at the end of the last match.
@@ -168,8 +169,8 @@ regexps; the following section says how to search for them.
168 169
169@menu 170@menu
170* Syntax of Regexps:: Rules for writing regular expressions. 171* Syntax of Regexps:: Rules for writing regular expressions.
171* Regexp Functions:: Functions for operating on regular expressions.
172* Regexp Example:: Illustrates regular expression syntax. 172* Regexp Example:: Illustrates regular expression syntax.
173* Regexp Functions:: Functions for operating on regular expressions.
173@end menu 174@end menu
174 175
175@node Syntax of Regexps 176@node Syntax of Regexps
@@ -293,10 +294,10 @@ matches @samp{cr}, @samp{car}, @samp{cdr}, @samp{caddaar}, etc.
293 294
294You can also include character ranges in a character alternative, by 295You can also include character ranges in a character alternative, by
295writing the starting and ending characters with a @samp{-} between them. 296writing the starting and ending characters with a @samp{-} between them.
296Thus, @samp{[a-z]} matches any lower-case @acronym{ASCII} letter. Ranges may be 297Thus, @samp{[a-z]} matches any lower-case @acronym{ASCII} letter.
297intermixed freely with individual characters, as in @samp{[a-z$%.]}, 298Ranges may be intermixed freely with individual characters, as in
298which matches any lower case @acronym{ASCII} letter or @samp{$}, @samp{%} or 299@samp{[a-z$%.]}, which matches any lower case @acronym{ASCII} letter
299period. 300or @samp{$}, @samp{%} or period.
300 301
301Note that the usual regexp special characters are not special inside a 302Note that the usual regexp special characters are not special inside a
302character alternative. A completely different set of characters is 303character alternative. A completely different set of characters is
@@ -358,10 +359,11 @@ the handling of regexps in programs such as @code{grep}.
358 359
359@item @samp{^} 360@item @samp{^}
360@cindex beginning of line in regexp 361@cindex beginning of line in regexp
361is a special character that matches the empty string, but only at the 362When matching a buffer, @samp{^} matches the empty string, but only at the
362beginning of a line in the text being matched. Otherwise it fails to 363beginning of a line in the text being matched (or the beginning of the
363match anything. Thus, @samp{^foo} matches a @samp{foo} that occurs at 364accessible portion of the buffer). Otherwise it fails to match
364the beginning of a line. 365anything. Thus, @samp{^foo} matches a @samp{foo} that occurs at the
366beginning of a line.
365 367
366When matching a string instead of a buffer, @samp{^} matches at the 368When matching a string instead of a buffer, @samp{^} matches at the
367beginning of the string or after a newline character. 369beginning of the string or after a newline character.
@@ -372,8 +374,9 @@ beginning of the regular expression, or after @samp{\(} or @samp{\|}.
372@item @samp{$} 374@item @samp{$}
373@cindex @samp{$} in regexp 375@cindex @samp{$} in regexp
374@cindex end of line in regexp 376@cindex end of line in regexp
375is similar to @samp{^} but matches only at the end of a line. Thus, 377is similar to @samp{^} but matches only at the end of a line (or the
376@samp{x+$} matches a string of one @samp{x} or more at the end of a line. 378end of the accessible portion of the buffer). Thus, @samp{x+$}
379matches a string of one @samp{x} or more at the end of a line.
377 380
378When matching a string instead of a buffer, @samp{$} matches at the end 381When matching a string instead of a buffer, @samp{$} matches at the end
379of the string or before a newline character. 382of the string or before a newline character.
@@ -542,7 +545,7 @@ purposes of an ordinary group (controlling the nesting of other
542operators), but it does not get a number, so you cannot refer back to 545operators), but it does not get a number, so you cannot refer back to
543its value with @samp{\@var{digit}}. 546its value with @samp{\@var{digit}}.
544 547
545Shy groups are particulary useful for mechanically-constructed regular 548Shy groups are particularly useful for mechanically-constructed regular
546expressions because they can be added automatically without altering the 549expressions because they can be added automatically without altering the
547numbering of any ordinary, non-shy groups. 550numbering of any ordinary, non-shy groups.
548 551
@@ -567,6 +570,10 @@ composed of two identical halves. The @samp{\(.*\)} matches the first
567half, which may be anything, but the @samp{\1} that follows must match 570half, which may be anything, but the @samp{\1} that follows must match
568the same exact text. 571the same exact text.
569 572
573If a @samp{\( @dots{} \)} construct matches more than once (which can
574happen, for instance, if it is followed by @samp{*}), only the last
575match is recorded.
576
570If a particular grouping construct in the regular expression was never 577If a particular grouping construct in the regular expression was never
571matched---for instance, if it appears inside of an alternative that 578matched---for instance, if it appears inside of an alternative that
572wasn't used, or inside of a repetition that repeated zero times---then 579wasn't used, or inside of a repetition that repeated zero times---then
@@ -611,7 +618,9 @@ matches any character whose category is not @var{c}.
611 618
612 The following regular expression constructs match the empty string---that is, 619 The following regular expression constructs match the empty string---that is,
613they don't use up any characters---but whether they match depends on the 620they don't use up any characters---but whether they match depends on the
614context. 621context. For all, the beginning and end of the accessible portion of
622the buffer are treated as if they were the actual beginning and end of
623the buffer.
615 624
616@table @samp 625@table @samp
617@item \` 626@item \`
@@ -636,25 +645,25 @@ end of a word. Thus, @samp{\bfoo\b} matches any occurrence of
636@samp{foo} as a separate word. @samp{\bballs?\b} matches 645@samp{foo} as a separate word. @samp{\bballs?\b} matches
637@samp{ball} or @samp{balls} as a separate word.@refill 646@samp{ball} or @samp{balls} as a separate word.@refill
638 647
639@samp{\b} matches at the beginning or end of the buffer 648@samp{\b} matches at the beginning or end of the buffer (or string)
640regardless of what text appears next to it. 649regardless of what text appears next to it.
641 650
642@item \B 651@item \B
643@cindex @samp{\B} in regexp 652@cindex @samp{\B} in regexp
644matches the empty string, but @emph{not} at the beginning or 653matches the empty string, but @emph{not} at the beginning or
645end of a word. 654end of a word, nor at the beginning or end of the buffer (or string).
646 655
647@item \< 656@item \<
648@cindex @samp{\<} in regexp 657@cindex @samp{\<} in regexp
649matches the empty string, but only at the beginning of a word. 658matches the empty string, but only at the beginning of a word.
650@samp{\<} matches at the beginning of the buffer only if a 659@samp{\<} matches at the beginning of the buffer (or string) only if a
651word-constituent character follows. 660word-constituent character follows.
652 661
653@item \> 662@item \>
654@cindex @samp{\>} in regexp 663@cindex @samp{\>} in regexp
655matches the empty string, but only at the end of a word. @samp{\>} 664matches the empty string, but only at the end of a word. @samp{\>}
656matches at the end of the buffer only if the contents end with a 665matches at the end of the buffer (or string) only if the contents end
657word-constituent character. 666with a word-constituent character.
658@end table 667@end table
659 668
660@kindex invalid-regexp 669@kindex invalid-regexp
@@ -668,9 +677,11 @@ an @code{invalid-regexp} error is signaled.
668@comment node-name, next, previous, up 677@comment node-name, next, previous, up
669@subsection Complex Regexp Example 678@subsection Complex Regexp Example
670 679
671 Here is a complicated regexp, used by Emacs to recognize the end of a 680 Here is a complicated regexp which was formerly used by Emacs to
672sentence together with any whitespace that follows. It is the value of 681recognize the end of a sentence together with any whitespace that
673the variable @code{sentence-end}. 682follows. It was used as the variable @code{sentence-end}. (Its value
683nowadays contains alternatives for @samp{.}, @samp{?} and @samp{!} in
684other character sets.)
674 685
675 First, we show the regexp as a string in Lisp syntax to distinguish 686 First, we show the regexp as a string in Lisp syntax to distinguish
676spaces from tab characters. The string constant begins and ends with a 687spaces from tab characters. The string constant begins and ends with a
@@ -679,17 +690,16 @@ string, @samp{\\} for a backslash as part of the string, @samp{\t} for a
679tab and @samp{\n} for a newline. 690tab and @samp{\n} for a newline.
680 691
681@example 692@example
682"[.?!][]\"')@}]*\\($\\| $\\|\t\\| \\)[ \t\n]*" 693"[.?!][]\"')@}]*\\($\\| $\\|\t\\|@ @ \\)[ \t\n]*"
683@end example 694@end example
684 695
685@noindent 696@noindent
686In contrast, if you evaluate the variable @code{sentence-end}, you 697In contrast, if you evaluate this string, you will see the following:
687will see the following:
688 698
689@example 699@example
690@group 700@group
691sentence-end 701"[.?!][]\"')@}]*\\($\\| $\\|\t\\|@ @ \\)[ \t\n]*"
692 @result{} "[.?!][]\"')@}]*\\($\\| $\\| \\| \\)[ 702 @result{} "[.?!][]\"')@}]*\\($\\| $\\| \\|@ @ \\)[
693]*" 703]*"
694@end group 704@end group
695@end example 705@end example
@@ -704,7 +714,10 @@ deciphered as follows:
704@item [.?!] 714@item [.?!]
705The first part of the pattern is a character alternative that matches 715The first part of the pattern is a character alternative that matches
706any one of three characters: period, question mark, and exclamation 716any one of three characters: period, question mark, and exclamation
707mark. The match must begin with one of these three characters. 717mark. The match must begin with one of these three characters. (This
718is the one point where the new value of @code{sentence-end} differs
719from the old. The new value also lists sentence ending
720non-@acronym{ASCII} characters.)
708 721
709@item []\"')@}]* 722@item []\"')@}]*
710The second part of the pattern matches any closing braces and quotation 723The second part of the pattern matches any closing braces and quotation
@@ -764,13 +777,14 @@ whitespace:
764 777
765@defun regexp-opt strings &optional paren 778@defun regexp-opt strings &optional paren
766This function returns an efficient regular expression that will match 779This function returns an efficient regular expression that will match
767any of the strings @var{strings}. This is useful when you need to make 780any of the strings in the list @var{strings}. This is useful when you
768matching or searching as fast as possible---for example, for Font Lock 781need to make matching or searching as fast as possible---for example,
769mode. 782for Font Lock mode.
770 783
771If the optional argument @var{paren} is non-@code{nil}, then the 784If the optional argument @var{paren} is non-@code{nil}, then the
772returned regular expression is always enclosed by at least one 785returned regular expression is always enclosed by at least one
773parentheses-grouping construct. 786parentheses-grouping construct. If @var{paren} is @code{words}, then
787that construct is additionally surrounded by @samp{\<} and @samp{\>}.
774 788
775This simplified definition of @code{regexp-opt} produces a 789This simplified definition of @code{regexp-opt} produces a
776regular expression which is equivalent to the actual value 790regular expression which is equivalent to the actual value
@@ -788,7 +802,8 @@ regular expression which is equivalent to the actual value
788 802
789@defun regexp-opt-depth regexp 803@defun regexp-opt-depth regexp
790This function returns the total number of grouping constructs 804This function returns the total number of grouping constructs
791(parenthesized expressions) in @var{regexp}. 805(parenthesized expressions) in @var{regexp}. (This does not include
806shy groups.)
792@end defun 807@end defun
793 808
794@node Regexp Search 809@node Regexp Search
@@ -830,7 +845,7 @@ error is signaled. If @var{noerror} is @code{t},
830@code{re-search-forward} does nothing and returns @code{nil}. If 845@code{re-search-forward} does nothing and returns @code{nil}. If
831@var{noerror} is neither @code{nil} nor @code{t}, then 846@var{noerror} is neither @code{nil} nor @code{t}, then
832@code{re-search-forward} moves point to @var{limit} (or the end of the 847@code{re-search-forward} moves point to @var{limit} (or the end of the
833buffer) and returns @code{nil}. 848accessible portion of the buffer) and returns @code{nil}.
834 849
835In the following example, point is initially before the @samp{T}. 850In the following example, point is initially before the @samp{T}.
836Evaluating the search call moves point to the end of that line (between 851Evaluating the search call moves point to the end of that line (between
@@ -866,9 +881,10 @@ simple mirror images. @code{re-search-forward} finds the match whose
866beginning is as close as possible to the starting point. If 881beginning is as close as possible to the starting point. If
867@code{re-search-backward} were a perfect mirror image, it would find the 882@code{re-search-backward} were a perfect mirror image, it would find the
868match whose end is as close as possible. However, in fact it finds the 883match whose end is as close as possible. However, in fact it finds the
869match whose beginning is as close as possible. The reason for this is that 884match whose beginning is as close as possible (and yet ends before the
870matching a regular expression at a given spot always works from 885starting point). The reason for this is that matching a regular
871beginning to end, and starts at a specified beginning position. 886expression at a given spot always works from beginning to end, and
887starts at a specified beginning position.
872 888
873A true mirror-image of @code{re-search-forward} would require a special 889A true mirror-image of @code{re-search-forward} would require a special
874feature for matching regular expressions from end to beginning. It's 890feature for matching regular expressions from end to beginning. It's
@@ -1069,7 +1085,8 @@ This function is the guts of @code{query-replace} and related
1069commands. It searches for occurrences of @var{from-string} in the 1085commands. It searches for occurrences of @var{from-string} in the
1070text between positions @var{start} and @var{end} and replaces some or 1086text between positions @var{start} and @var{end} and replaces some or
1071all of them. If @var{start} is @code{nil} (or omitted), point is used 1087all of them. If @var{start} is @code{nil} (or omitted), point is used
1072instead, and the buffer's end is used for @var{end}. 1088instead, and the end of the buffer's accessible portion is used for
1089@var{end}.
1073 1090
1074If @var{query-flag} is @code{nil}, it replaces all 1091If @var{query-flag} is @code{nil}, it replaces all
1075occurrences; otherwise, it asks the user what to do about each one. 1092occurrences; otherwise, it asks the user what to do about each one.
@@ -1090,7 +1107,7 @@ get the replacement text. This function is called with two arguments:
1090 1107
1091If @var{repeat-count} is non-@code{nil}, it should be an integer. Then 1108If @var{repeat-count} is non-@code{nil}, it should be an integer. Then
1092it specifies how many times to use each of the strings in the 1109it specifies how many times to use each of the strings in the
1093@var{replacements} list before advancing cyclicly to the next one. 1110@var{replacements} list before advancing cyclically to the next one.
1094 1111
1095If @var{from-string} contains upper-case letters, then 1112If @var{from-string} contains upper-case letters, then
1096@code{perform-replace} binds @code{case-fold-search} to @code{nil}, and 1113@code{perform-replace} binds @code{case-fold-search} to @code{nil}, and
@@ -1099,6 +1116,22 @@ it uses the @code{replacements} without altering the case of them.
1099Normally, the keymap @code{query-replace-map} defines the possible user 1116Normally, the keymap @code{query-replace-map} defines the possible user
1100responses for queries. The argument @var{map}, if non-@code{nil}, is a 1117responses for queries. The argument @var{map}, if non-@code{nil}, is a
1101keymap to use instead of @code{query-replace-map}. 1118keymap to use instead of @code{query-replace-map}.
1119
1120@strong{Usage note:} Do not use this function in your own programs
1121unless you want to do something very similar to what
1122@code{query-replace} does, including setting the mark and possibly
1123querying the user. For most purposes a simple loop like, for
1124instance:
1125
1126@example
1127(while (re-search-forward "foo[ \t]+bar" nil t)
1128 (replace-match "foobar"))
1129@end example
1130
1131@noindent
1132is preferable. It runs faster and avoids side effects, such as
1133setting the mark. @xref{Replacing Match,, Replacing the Text that
1134Matched}, for a description of @code{replace-match}.
1102@end defun 1135@end defun
1103 1136
1104@defvar query-replace-map 1137@defvar query-replace-map
@@ -1205,9 +1238,11 @@ was matched by the last search. It replaces that text with
1205@var{replacement}. 1238@var{replacement}.
1206 1239
1207If you did the last search in a buffer, you should specify @code{nil} 1240If you did the last search in a buffer, you should specify @code{nil}
1208for @var{string}. Then @code{replace-match} does the replacement by 1241for @var{string} and make sure that the current buffer when you call
1209editing the buffer; it leaves point at the end of the replacement text, 1242@code{replace-match} is the one in which you did the searching or
1210and returns @code{t}. 1243matching. Then @code{replace-match} does the replacement by editing
1244the buffer; it leaves point at the end of the replacement text, and
1245returns @code{t}.
1211 1246
1212If you did the search in a string, pass the same string as @var{string}. 1247If you did the search in a string, pass the same string as @var{string}.
1213Then @code{replace-match} does the replacement by constructing and 1248Then @code{replace-match} does the replacement by constructing and
@@ -1239,6 +1274,7 @@ part of one of the following sequences:
1239@samp{\@var{n}}, where @var{n} is a digit, stands for the text that 1274@samp{\@var{n}}, where @var{n} is a digit, stands for the text that
1240matched the @var{n}th subexpression in the original regexp. 1275matched the @var{n}th subexpression in the original regexp.
1241Subexpressions are those expressions grouped inside @samp{\(@dots{}\)}. 1276Subexpressions are those expressions grouped inside @samp{\(@dots{}\)}.
1277If the @var{n}th subexpression never matched, an empty string is substituted.
1242 1278
1243@item @samp{\\} 1279@item @samp{\\}
1244@cindex @samp{\} in replacement 1280@cindex @samp{\} in replacement
@@ -1396,7 +1432,7 @@ character of the buffer counts as 1.)
1396 The functions @code{match-data} and @code{set-match-data} read or 1432 The functions @code{match-data} and @code{set-match-data} read or
1397write the entire match data, all at once. 1433write the entire match data, all at once.
1398 1434
1399@defun match-data 1435@defun match-data &optional integers reuse
1400This function returns a newly constructed list containing all the 1436This function returns a newly constructed list containing all the
1401information on what text the last search matched. Element zero is the 1437information on what text the last search matched. Element zero is the
1402position of the beginning of the match for the whole expression; element 1438position of the beginning of the match for the whole expression; element
@@ -1420,8 +1456,20 @@ number {\mathsurround=0pt $2n+1$}
1420corresponds to @code{(match-end @var{n})}. 1456corresponds to @code{(match-end @var{n})}.
1421 1457
1422All the elements are markers or @code{nil} if matching was done on a 1458All the elements are markers or @code{nil} if matching was done on a
1423buffer, and all are integers or @code{nil} if matching was done on a 1459buffer and all are integers or @code{nil} if matching was done on a
1424string with @code{string-match}. 1460string with @code{string-match}. If @var{integers} is
1461non-@code{nil}, then all elements are integers or @code{nil}, even if
1462matching was done on a buffer. Also, @code{match-beginning} and
1463@code{match-end} always return integers or @code{nil}.
1464
1465If @var{reuse} is non-@code{nil}, it should be a list. In that case,
1466@code{match-data} stores the match data in @var{reuse}. That is,
1467@var{reuse} is destructively modified. @var{reuse} does not need to
1468have the right length. If it is not long enough to contain the match
1469data, it is extended. If it is too long, the length of @var{reuse}
1470stays the same, but the elements that were not used are set to
1471@code{nil}. The purpose of this feature is to avoid producing too
1472much garbage, that would later have to be collected.
1425 1473
1426As always, there must be no possibility of intervening searches between 1474As always, there must be no possibility of intervening searches between
1427the call to a search function and the call to @code{match-data} that is 1475the call to a search function and the call to @code{match-data} that is
@@ -1474,7 +1522,8 @@ that shows the problem that arises if you fail to save the match data:
1474 1522
1475@defmac save-match-data body@dots{} 1523@defmac save-match-data body@dots{}
1476This macro executes @var{body}, saving and restoring the match 1524This macro executes @var{body}, saving and restoring the match
1477data around it. 1525data around it. The return value is the value of the last form in
1526@var{body}.
1478@end defmac 1527@end defmac
1479 1528
1480 You could use @code{set-match-data} together with @code{match-data} to 1529 You could use @code{set-match-data} together with @code{match-data} to
@@ -1544,10 +1593,11 @@ for an upper case letter only. But this has nothing to do with the
1544searching functions used in Lisp code. 1593searching functions used in Lisp code.
1545 1594
1546@defopt case-replace 1595@defopt case-replace
1547This variable determines whether the replacement functions should 1596This variable determines whether the higher level replacement
1548preserve case. If the variable is @code{nil}, that means to use the 1597functions should preserve case. If the variable is @code{nil}, that
1549replacement text verbatim. A non-@code{nil} value means to convert the 1598means to use the replacement text verbatim. A non-@code{nil} value
1550case of the replacement text according to the text being replaced. 1599means to convert the case of the replacement text according to the
1600text being replaced.
1551 1601
1552This variable is used by passing it as an argument to the function 1602This variable is used by passing it as an argument to the function
1553@code{replace-match}. @xref{Replacing Match}. 1603@code{replace-match}. @xref{Replacing Match}.
@@ -1600,22 +1650,23 @@ spaces, tabs, and form feeds (after its left margin).
1600@defvar paragraph-start 1650@defvar paragraph-start
1601This is the regular expression for recognizing the beginning of a line 1651This is the regular expression for recognizing the beginning of a line
1602that starts @emph{or} separates paragraphs. The default value is 1652that starts @emph{or} separates paragraphs. The default value is
1603@w{@code{"[@ \t\n\f]"}}, which matches a line starting with a space, tab, 1653@w{@code{"\f\\|[ \t]*$"}}, which matches a line containing only
1604newline, or form feed (after its left margin). 1654whitespace or starting with a form feed (after its left margin).
1605@end defvar 1655@end defvar
1606 1656
1607@defvar sentence-end 1657@defvar sentence-end
1608This is the regular expression describing the end of a sentence. (All 1658This is the regular expression describing the end of a sentence. (All
1609paragraph boundaries also end sentences, regardless.) The default value 1659paragraph boundaries also end sentences, regardless.) The (slightly
1610is: 1660simplified) default value is:
1611 1661
1612@example 1662@example
1613"[.?!][]\"')@}]*\\($\\| $\\|\t\\| \\)[ \t\n]*" 1663"[.?!][]\"')@}]*\\($\\| $\\|\t\\|@ @ \\)[ \t\n]*"
1614@end example 1664@end example
1615 1665
1616This means a period, question mark or exclamation mark, followed 1666This means a period, question mark or exclamation mark (the actual
1617optionally by a closing parenthetical character, followed by tabs, 1667default value also lists their alternatives in other character sets),
1618spaces or new lines. 1668followed optionally by a closing parenthetical character, followed by
1669tabs, spaces or new lines.
1619 1670
1620For a detailed explanation of this regular expression, see @ref{Regexp 1671For a detailed explanation of this regular expression, see @ref{Regexp
1621Example}. 1672Example}.
diff --git a/lwlib/ChangeLog b/lwlib/ChangeLog
index f41b323c04c..3b69d955392 100644
--- a/lwlib/ChangeLog
+++ b/lwlib/ChangeLog
@@ -1,3 +1,31 @@
12004-01-12 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
2
3 * xlwmenuP.h (_XlwMenu_part): Added top_depth.
4
5 * xlwmenu.h: Removed declaration of pop_up_menu
6
7 * xlwmenu.c (Start): Get correct time if time in event is CurrentTime.
8 (find_first_selectable, find_next_selectable)
9 (find_prev_selectable): Add parameter skip_no_call_data to skip
10 over items with no call data (popup menu titles).
11 (Down, Up): Compare old_depth to top_depth instead of 2.
12 Pass True to find_*_selectable:s new parameter if this is a popup menu.
13 (Left, Right): Compare old_depth to top_depth instead of 2.
14 Pass 0 to find_*_selectable:s new parameter.
15 (pop_up_menu): Set top_depth to 1 for pop up menus and 2 for
16 menu bar menus, to enable keyboard traversal of popups.
17
18 * lwlib-Xm.c (dialog_key_cb): New function.
19 (make_dialog): Add event handlers to dialog_key_cb for key press
20 so we can pop down on ESC.
21
22 * lwlib-Xlw.c (xlw_popup_menu): Replace call to pop_up_menu with
23 XtCallActionProc ("start"). Use a full XEvent since "start" copies it.
24
25 * lwlib-Xaw.c (make_dialog): Add override so dialog pops down
26 on ESC.
27 (wm_delete_window): If widget isn't a shell, use the parent.
28
12003-05-22 Dave Love <fx@gnu.org> 292003-05-22 Dave Love <fx@gnu.org>
2 30
3 * xlwmenu.c: Include lisp.h, not ../src/lisp.h. 31 * xlwmenu.c: Include lisp.h, not ../src/lisp.h.
diff --git a/lwlib/lwlib-Xaw.c b/lwlib/lwlib-Xaw.c
index 7f37596457f..867193c7cc8 100644
--- a/lwlib/lwlib-Xaw.c
+++ b/lwlib/lwlib-Xaw.c
@@ -277,6 +277,9 @@ xaw_pop_instance (instance, up)
277 277
278static char overrideTrans[] = 278static char overrideTrans[] =
279 "<Message>WM_PROTOCOLS: lwlib_delete_dialog()"; 279 "<Message>WM_PROTOCOLS: lwlib_delete_dialog()";
280/* Dialogs pop down on any key press */
281static char dialogOverride[] =
282 "<KeyPress>: lwlib_delete_dialog()";
280static void wm_delete_window(); 283static void wm_delete_window();
281static XtActionsRec xaw_actions [] = { 284static XtActionsRec xaw_actions [] = {
282 {"lwlib_delete_dialog", wm_delete_window} 285 {"lwlib_delete_dialog", wm_delete_window}
@@ -333,6 +336,8 @@ make_dialog (name, parent, pop_up_p, shell_title, icon_name, text_input_slot, ra
333 336
334 ac = 0; 337 ac = 0;
335 dialog = XtCreateManagedWidget (name, dialogWidgetClass, shell, av, ac); 338 dialog = XtCreateManagedWidget (name, dialogWidgetClass, shell, av, ac);
339 override = XtParseTranslationTable (dialogOverride);
340 XtOverrideTranslations (dialog, override);
336 341
337 bc = 0; 342 bc = 0;
338 button = 0; 343 button = 0;
@@ -511,8 +516,8 @@ xaw_generic_callback (widget, closure, call_data)
511} 516}
512 517
513static void 518static void
514wm_delete_window (shell, closure, call_data) 519wm_delete_window (w, closure, call_data)
515 Widget shell; 520 Widget w;
516 XtPointer closure; 521 XtPointer closure;
517 XtPointer call_data; 522 XtPointer call_data;
518{ 523{
@@ -520,7 +525,13 @@ wm_delete_window (shell, closure, call_data)
520 Cardinal nkids; 525 Cardinal nkids;
521 int i; 526 int i;
522 Widget *kids = 0; 527 Widget *kids = 0;
523 Widget widget; 528 Widget widget, shell;
529
530 if (XtIsSubclass (w, dialogWidgetClass))
531 shell = XtParent (w);
532 else
533 shell = w;
534
524 if (! XtIsSubclass (shell, shellWidgetClass)) 535 if (! XtIsSubclass (shell, shellWidgetClass))
525 abort (); 536 abort ();
526 XtVaGetValues (shell, XtNnumChildren, &nkids, NULL); 537 XtVaGetValues (shell, XtNnumChildren, &nkids, NULL);
diff --git a/lwlib/lwlib-Xlw.c b/lwlib/lwlib-Xlw.c
index d0800e0ca0e..248e4e8be74 100644
--- a/lwlib/lwlib-Xlw.c
+++ b/lwlib/lwlib-Xlw.c
@@ -180,6 +180,7 @@ xlw_create_popup_menu (instance)
180 XtAddCallback (widget, XtNselect, pick_hook, (XtPointer)instance); 180 XtAddCallback (widget, XtNselect, pick_hook, (XtPointer)instance);
181 XtAddCallback (widget, XtNhighlightCallback, highlight_hook, 181 XtAddCallback (widget, XtNhighlightCallback, highlight_hook,
182 (XtPointer)instance); 182 (XtPointer)instance);
183
183 return popup_shell; 184 return popup_shell;
184} 185}
185 186
@@ -251,7 +252,6 @@ xlw_popup_menu (widget, event)
251 Widget widget; 252 Widget widget;
252 XEvent *event; 253 XEvent *event;
253{ 254{
254 XButtonPressedEvent dummy;
255 XlwMenuWidget mw; 255 XlwMenuWidget mw;
256 256
257 if (!XtIsShell (widget)) 257 if (!XtIsShell (widget))
@@ -260,21 +260,24 @@ xlw_popup_menu (widget, event)
260 mw = (XlwMenuWidget)((CompositeWidget)widget)->composite.children [0]; 260 mw = (XlwMenuWidget)((CompositeWidget)widget)->composite.children [0];
261 261
262 if (event) 262 if (event)
263 pop_up_menu (mw, (XButtonPressedEvent*) event); 263 XtCallActionProc ((Widget) mw, "start", event, NULL, 0);
264 else 264 else
265 { 265 {
266 dummy.type = ButtonPress; 266 XEvent dummy;
267 dummy.serial = 0; 267 XButtonPressedEvent *bd = &dummy.xbutton;
268 dummy.send_event = 0; 268
269 dummy.display = XtDisplay (widget); 269 bd->type = ButtonPress;
270 dummy.window = XtWindow (XtParent (widget)); 270 bd->serial = 0;
271 dummy.time = CurrentTime; 271 bd->send_event = 0;
272 dummy.button = 0; 272 bd->display = XtDisplay (widget);
273 XQueryPointer (dummy.display, dummy.window, &dummy.root, 273 bd->window = XtWindow (XtParent (widget));
274 &dummy.subwindow, &dummy.x_root, &dummy.y_root, 274 bd->time = CurrentTime;
275 &dummy.x, &dummy.y, &dummy.state); 275 bd->button = 0;
276 276 XQueryPointer (bd->display, bd->window, &bd->root,
277 pop_up_menu (mw, &dummy); 277 &bd->subwindow, &bd->x_root, &bd->y_root,
278 &bd->x, &bd->y, &bd->state);
279
280 XtCallActionProc ((Widget) mw, "start", &dummy, NULL, 0);
278 } 281 }
279} 282}
280 283
diff --git a/lwlib/lwlib-Xm.c b/lwlib/lwlib-Xm.c
index f63d13c85ee..e57fa57f939 100644
--- a/lwlib/lwlib-Xm.c
+++ b/lwlib/lwlib-Xm.c
@@ -1035,6 +1035,33 @@ activate_button (widget, closure, call_data)
1035 1035
1036/* creation functions */ 1036/* creation functions */
1037 1037
1038/* Called for key press in dialogs. Used to pop down dialog on ESC. */
1039static void
1040dialog_key_cb (widget, closure, event, continue_to_dispatch)
1041 Widget widget;
1042 XtPointer closure;
1043 XEvent *event;
1044 Boolean *continue_to_dispatch;
1045{
1046 KeySym sym = 0;
1047 Modifiers modif_ret;
1048
1049 XtTranslateKeycode (event->xkey.display, event->xkey.keycode, 0,
1050 &modif_ret, &sym);
1051
1052 if (sym == osfXK_Cancel)
1053 {
1054 Widget w = *((Widget *) closure);
1055
1056 while (w && ! XtIsShell (w))
1057 w = XtParent (w);
1058
1059 if (XtIsShell (w)) XtPopdown (w);
1060 }
1061
1062 *continue_to_dispatch = TRUE;
1063}
1064
1038/* dialogs */ 1065/* dialogs */
1039static Widget 1066static Widget
1040make_dialog (name, parent, pop_up_p, shell_title, icon_name, text_input_slot, 1067make_dialog (name, parent, pop_up_p, shell_title, icon_name, text_input_slot,
@@ -1123,6 +1150,8 @@ make_dialog (name, parent, pop_up_p, shell_title, icon_name, text_input_slot,
1123 XtSetArg(al[ac], XmNmarginWidth, 10); ac++; 1150 XtSetArg(al[ac], XmNmarginWidth, 10); ac++;
1124 XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++; 1151 XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
1125 children [n_children] = XmCreatePushButton (row, button_name, al, ac); 1152 children [n_children] = XmCreatePushButton (row, button_name, al, ac);
1153 XtAddEventHandler (children [n_children],
1154 KeyPressMask, False, dialog_key_cb, result);
1126 1155
1127 if (i == 0) 1156 if (i == 0)
1128 { 1157 {
@@ -1149,6 +1178,9 @@ make_dialog (name, parent, pop_up_p, shell_title, icon_name, text_input_slot,
1149 XtSetArg(al[ac], XmNmarginWidth, 10); ac++; 1178 XtSetArg(al[ac], XmNmarginWidth, 10); ac++;
1150 XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++; 1179 XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
1151 children [n_children] = XmCreatePushButton (row, button_name, al, ac); 1180 children [n_children] = XmCreatePushButton (row, button_name, al, ac);
1181 XtAddEventHandler (children [n_children],
1182 KeyPressMask, False, dialog_key_cb, result);
1183
1152 if (! button) button = children [n_children]; 1184 if (! button) button = children [n_children];
1153 n_children++; 1185 n_children++;
1154 } 1186 }
@@ -1491,6 +1523,7 @@ xm_create_dialog (instance)
1491 1523
1492 XtAddCallback (widget, XmNpopdownCallback, xm_nosel_callback, 1524 XtAddCallback (widget, XmNpopdownCallback, xm_nosel_callback,
1493 (XtPointer) instance); 1525 (XtPointer) instance);
1526
1494 return widget; 1527 return widget;
1495} 1528}
1496 1529
diff --git a/lwlib/xlwmenu.c b/lwlib/xlwmenu.c
index 917181226c7..973fc6ec5d5 100644
--- a/lwlib/xlwmenu.c
+++ b/lwlib/xlwmenu.c
@@ -197,6 +197,8 @@ static void Select();
197static void Key(); 197static void Key();
198static void Nothing(); 198static void Nothing();
199static int separator_height __P ((enum menu_separator)); 199static int separator_height __P ((enum menu_separator));
200static void pop_up_menu __P ((XlwMenuWidget, XButtonPressedEvent *));
201
200 202
201static XtActionsRec 203static XtActionsRec
202xlwMenuActionsList [] = 204xlwMenuActionsList [] =
@@ -2004,6 +2006,13 @@ Start (w, ev, params, num_params)
2004 if (!mw->menu.popped_up) 2006 if (!mw->menu.popped_up)
2005 { 2007 {
2006 menu_post_event = *ev; 2008 menu_post_event = *ev;
2009 /* If event is set to CurrentTime, get the last known time stamp.
2010 This is for calculating if (popup) menus should stay up after
2011 a fast click. */
2012 if (menu_post_event.xbutton.time == CurrentTime)
2013 menu_post_event.xbutton.time
2014 = XtLastTimestampProcessed (XtDisplay (w));
2015
2007 pop_up_menu (mw, (XButtonPressedEvent*) ev); 2016 pop_up_menu (mw, (XButtonPressedEvent*) ev);
2008 } 2017 }
2009 else 2018 else
@@ -2044,15 +2053,17 @@ Nothing (w, ev, params, num_params)
2044{ 2053{
2045} 2054}
2046 2055
2047widget_value * 2056static widget_value *
2048find_first_selectable (mw, item) 2057find_first_selectable (mw, item, skip_no_call_data)
2049 XlwMenuWidget mw; 2058 XlwMenuWidget mw;
2050 widget_value *item; 2059 widget_value *item;
2060 int skip_no_call_data;
2051{ 2061{
2052 widget_value *current = item; 2062 widget_value *current = item;
2053 enum menu_separator separator; 2063 enum menu_separator separator;
2054 2064
2055 while (lw_separator_p (current->name, &separator, 0) || !current->enabled) 2065 while (lw_separator_p (current->name, &separator, 0) || !current->enabled
2066 || (skip_no_call_data && !current->call_data))
2056 if (current->next) 2067 if (current->next)
2057 current=current->next; 2068 current=current->next;
2058 else 2069 else
@@ -2061,8 +2072,8 @@ find_first_selectable (mw, item)
2061 return current; 2072 return current;
2062} 2073}
2063 2074
2064widget_value * 2075static widget_value *
2065find_next_selectable (mw, item) 2076find_next_selectable (mw, item, skip_no_call_data)
2066 XlwMenuWidget mw; 2077 XlwMenuWidget mw;
2067 widget_value *item; 2078 widget_value *item;
2068{ 2079{
@@ -2070,7 +2081,8 @@ find_next_selectable (mw, item)
2070 enum menu_separator separator; 2081 enum menu_separator separator;
2071 2082
2072 while (current->next && (current=current->next) && 2083 while (current->next && (current=current->next) &&
2073 (lw_separator_p (current->name, &separator, 0) || !current->enabled)) 2084 (lw_separator_p (current->name, &separator, 0) || !current->enabled
2085 || (skip_no_call_data && !current->call_data)))
2074 ; 2086 ;
2075 2087
2076 if (current == item) 2088 if (current == item)
@@ -2079,7 +2091,9 @@ find_next_selectable (mw, item)
2079 return current; 2091 return current;
2080 current = mw->menu.old_stack [mw->menu.old_depth - 2]->contents; 2092 current = mw->menu.old_stack [mw->menu.old_depth - 2]->contents;
2081 2093
2082 while (lw_separator_p (current->name, &separator, 0) || !current->enabled) 2094 while (lw_separator_p (current->name, &separator, 0)
2095 || !current->enabled
2096 || (skip_no_call_data && !current->call_data))
2083 { 2097 {
2084 if (current->next) 2098 if (current->next)
2085 current=current->next; 2099 current=current->next;
@@ -2093,15 +2107,16 @@ find_next_selectable (mw, item)
2093 return current; 2107 return current;
2094} 2108}
2095 2109
2096widget_value * 2110static widget_value *
2097find_prev_selectable (mw, item) 2111find_prev_selectable (mw, item, skip_no_call_data)
2098 XlwMenuWidget mw; 2112 XlwMenuWidget mw;
2099 widget_value *item; 2113 widget_value *item;
2100{ 2114{
2101 widget_value *current = item; 2115 widget_value *current = item;
2102 widget_value *prev = item; 2116 widget_value *prev = item;
2103 2117
2104 while ((current=find_next_selectable (mw, current)) != item) 2118 while ((current=find_next_selectable (mw, current, skip_no_call_data))
2119 != item)
2105 { 2120 {
2106 if (prev == current) 2121 if (prev == current)
2107 break; 2122 break;
@@ -2120,15 +2135,23 @@ Down (w, ev, params, num_params)
2120{ 2135{
2121 XlwMenuWidget mw = (XlwMenuWidget) w; 2136 XlwMenuWidget mw = (XlwMenuWidget) w;
2122 widget_value* selected_item = mw->menu.old_stack [mw->menu.old_depth - 1]; 2137 widget_value* selected_item = mw->menu.old_stack [mw->menu.old_depth - 1];
2138 int popup_menu_p = mw->menu.top_depth == 1;
2123 2139
2124 /* Inside top-level menu-bar? */ 2140 /* Inside top-level menu-bar? */
2125 if (mw->menu.old_depth == 2) 2141 if (mw->menu.old_depth == mw->menu.top_depth)
2126 /* When <down> in the menu-bar is pressed, display the corresponding 2142 /* When <down> in the menu-bar is pressed, display the corresponding
2127 sub-menu and select the first selectable menu item there. */ 2143 sub-menu and select the first selectable menu item there.
2128 set_new_state (mw, find_first_selectable (mw, selected_item->contents), mw->menu.old_depth); 2144 If this is a popup menu, skip items with zero call data (title of
2145 the popup). */
2146 set_new_state (mw,
2147 find_first_selectable (mw,
2148 selected_item->contents,
2149 popup_menu_p),
2150 mw->menu.old_depth);
2129 else 2151 else
2130 /* Highlight next possible (enabled and not separator) menu item. */ 2152 /* Highlight next possible (enabled and not separator) menu item. */
2131 set_new_state (mw, find_next_selectable (mw, selected_item), mw->menu.old_depth - 1); 2153 set_new_state (mw, find_next_selectable (mw, selected_item, popup_menu_p),
2154 mw->menu.old_depth - 1);
2132 2155
2133 remap_menubar (mw); 2156 remap_menubar (mw);
2134} 2157}
@@ -2142,27 +2165,39 @@ Up (w, ev, params, num_params)
2142{ 2165{
2143 XlwMenuWidget mw = (XlwMenuWidget) w; 2166 XlwMenuWidget mw = (XlwMenuWidget) w;
2144 widget_value* selected_item = mw->menu.old_stack [mw->menu.old_depth - 1]; 2167 widget_value* selected_item = mw->menu.old_stack [mw->menu.old_depth - 1];
2168 int popup_menu_p = mw->menu.top_depth == 1;
2145 2169
2146 /* Inside top-level menu-bar? */ 2170 /* Inside top-level menu-bar? */
2147 if (mw->menu.old_depth == 2) 2171 if (mw->menu.old_depth == mw->menu.top_depth)
2148 { 2172 {
2149 /* FIXME: this is tricky. <up> in the menu-bar should select the 2173 /* FIXME: this is tricky. <up> in the menu-bar should select the
2150 last selectable item in the list. So we select the first 2174 last selectable item in the list. So we select the first
2151 selectable one and find the previous selectable item. Is there 2175 selectable one and find the previous selectable item. Is there
2152 a better way? */ 2176 a better way? */
2153 set_new_state (mw, find_first_selectable (mw, selected_item->contents), mw->menu.old_depth); 2177 /* If this is a popup menu, skip items with zero call data (title of
2178 the popup). */
2179 set_new_state (mw,
2180 find_first_selectable (mw,
2181 selected_item->contents,
2182 popup_menu_p),
2183 mw->menu.old_depth);
2154 remap_menubar (mw); 2184 remap_menubar (mw);
2155 selected_item = mw->menu.old_stack [mw->menu.old_depth - 1]; 2185 selected_item = mw->menu.old_stack [mw->menu.old_depth - 1];
2156 set_new_state (mw, find_prev_selectable (mw, selected_item), mw->menu.old_depth - 1); 2186 set_new_state (mw,
2187 find_prev_selectable (mw,
2188 selected_item,
2189 popup_menu_p),
2190 mw->menu.old_depth - 1);
2157 } 2191 }
2158 else 2192 else
2159 /* Highlight previous (enabled and not separator) menu item. */ 2193 /* Highlight previous (enabled and not separator) menu item. */
2160 set_new_state (mw, find_prev_selectable (mw, selected_item), mw->menu.old_depth - 1); 2194 set_new_state (mw, find_prev_selectable (mw, selected_item, popup_menu_p),
2195 mw->menu.old_depth - 1);
2161 2196
2162 remap_menubar (mw); 2197 remap_menubar (mw);
2163} 2198}
2164 2199
2165static void 2200void
2166Left (w, ev, params, num_params) 2201Left (w, ev, params, num_params)
2167 Widget w; 2202 Widget w;
2168 XEvent *ev; 2203 XEvent *ev;
@@ -2173,31 +2208,36 @@ Left (w, ev, params, num_params)
2173 widget_value* selected_item = mw->menu.old_stack [mw->menu.old_depth - 1]; 2208 widget_value* selected_item = mw->menu.old_stack [mw->menu.old_depth - 1];
2174 2209
2175 /* Inside top-level menu-bar? */ 2210 /* Inside top-level menu-bar? */
2176 if (mw->menu.old_depth == 2) 2211 if (mw->menu.old_depth == mw->menu.top_depth)
2177 /* When <left> in the menu-bar is pressed, display the previous item on 2212 /* When <left> in the menu-bar is pressed, display the previous item on
2178 the menu-bar. If the current item is the first one, highlight the 2213 the menu-bar. If the current item is the first one, highlight the
2179 last item in the menubar (probably Help). */ 2214 last item in the menubar (probably Help). */
2180 set_new_state (mw, find_prev_selectable (mw, selected_item), mw->menu.old_depth - 1); 2215 set_new_state (mw, find_prev_selectable (mw, selected_item, 0),
2216 mw->menu.old_depth - 1);
2181 else if (mw->menu.old_depth == 1 2217 else if (mw->menu.old_depth == 1
2182 && selected_item->contents) /* Is this menu item expandable? */ 2218 && selected_item->contents) /* Is this menu item expandable? */
2183 { 2219 {
2184 set_new_state (mw, selected_item->contents, mw->menu.old_depth); 2220 set_new_state (mw, selected_item->contents, mw->menu.old_depth);
2185 remap_menubar (mw); 2221 remap_menubar (mw);
2186 selected_item = mw->menu.old_stack [mw->menu.old_depth - 1]; 2222 selected_item = mw->menu.old_stack [mw->menu.old_depth - 1];
2187 if (!selected_item->enabled && find_first_selectable (mw, selected_item)) 2223 if (!selected_item->enabled && find_first_selectable (mw,
2188 set_new_state (mw, find_first_selectable (mw, selected_item), mw->menu.old_depth - 1); 2224 selected_item,
2225 0))
2226 set_new_state (mw, find_first_selectable (mw, selected_item, 0),
2227 mw->menu.old_depth - 1);
2189 } 2228 }
2190 2229
2191 else 2230 else
2192 { 2231 {
2193 pop_new_stack_if_no_contents (mw); 2232 pop_new_stack_if_no_contents (mw);
2194 set_new_state (mw, mw->menu.old_stack [mw->menu.old_depth - 2], mw->menu.old_depth - 2); 2233 set_new_state (mw, mw->menu.old_stack [mw->menu.old_depth - 2],
2234 mw->menu.old_depth - 2);
2195 } 2235 }
2196 2236
2197 remap_menubar (mw); 2237 remap_menubar (mw);
2198} 2238}
2199 2239
2200static void 2240void
2201Right (w, ev, params, num_params) 2241Right (w, ev, params, num_params)
2202 Widget w; 2242 Widget w;
2203 XEvent *ev; 2243 XEvent *ev;
@@ -2208,23 +2248,28 @@ Right (w, ev, params, num_params)
2208 widget_value* selected_item = mw->menu.old_stack [mw->menu.old_depth - 1]; 2248 widget_value* selected_item = mw->menu.old_stack [mw->menu.old_depth - 1];
2209 2249
2210 /* Inside top-level menu-bar? */ 2250 /* Inside top-level menu-bar? */
2211 if (mw->menu.old_depth == 2) 2251 if (mw->menu.old_depth == mw->menu.top_depth)
2212 /* When <right> in the menu-bar is pressed, display the next item on 2252 /* When <right> in the menu-bar is pressed, display the next item on
2213 the menu-bar. If the current item is the last one, highlight the 2253 the menu-bar. If the current item is the last one, highlight the
2214 first item (probably File). */ 2254 first item (probably File). */
2215 set_new_state (mw, find_next_selectable (mw, selected_item), mw->menu.old_depth - 1); 2255 set_new_state (mw, find_next_selectable (mw, selected_item, 0),
2256 mw->menu.old_depth - 1);
2216 else if (selected_item->contents) /* Is this menu item expandable? */ 2257 else if (selected_item->contents) /* Is this menu item expandable? */
2217 { 2258 {
2218 set_new_state (mw, selected_item->contents, mw->menu.old_depth); 2259 set_new_state (mw, selected_item->contents, mw->menu.old_depth);
2219 remap_menubar (mw); 2260 remap_menubar (mw);
2220 selected_item = mw->menu.old_stack [mw->menu.old_depth - 1]; 2261 selected_item = mw->menu.old_stack [mw->menu.old_depth - 1];
2221 if (!selected_item->enabled && find_first_selectable (mw, selected_item)) 2262 if (!selected_item->enabled && find_first_selectable (mw,
2222 set_new_state (mw, find_first_selectable (mw, selected_item), mw->menu.old_depth - 1); 2263 selected_item,
2264 0))
2265 set_new_state (mw, find_first_selectable (mw, selected_item, 0),
2266 mw->menu.old_depth - 1);
2223 } 2267 }
2224 else 2268 else
2225 { 2269 {
2226 pop_new_stack_if_no_contents (mw); 2270 pop_new_stack_if_no_contents (mw);
2227 set_new_state (mw, mw->menu.old_stack [mw->menu.old_depth - 2], mw->menu.old_depth - 2); 2271 set_new_state (mw, mw->menu.old_stack [mw->menu.old_depth - 2],
2272 mw->menu.old_depth - 2);
2228 } 2273 }
2229 2274
2230 remap_menubar (mw); 2275 remap_menubar (mw);
@@ -2305,7 +2350,7 @@ Select (w, ev, params, num_params)
2305 2350
2306 2351
2307 /* Special code to pop-up a menu */ 2352 /* Special code to pop-up a menu */
2308void 2353static void
2309pop_up_menu (mw, event) 2354pop_up_menu (mw, event)
2310 XlwMenuWidget mw; 2355 XlwMenuWidget mw;
2311 XButtonPressedEvent* event; 2356 XButtonPressedEvent* event;
@@ -2349,6 +2394,7 @@ pop_up_menu (mw, event)
2349 display_menu (mw, 0, False, NULL, NULL, NULL, NULL, NULL); 2394 display_menu (mw, 0, False, NULL, NULL, NULL, NULL, NULL);
2350 mw->menu.windows [0].x = x + borderwidth; 2395 mw->menu.windows [0].x = x + borderwidth;
2351 mw->menu.windows [0].y = y + borderwidth; 2396 mw->menu.windows [0].y = y + borderwidth;
2397 mw->menu.top_depth = 1; /* Popup menus don't have a bar so top is 1 */
2352 } 2398 }
2353 else 2399 else
2354 { 2400 {
@@ -2359,6 +2405,7 @@ pop_up_menu (mw, event)
2359 /* notes the absolute position of the menubar window */ 2405 /* notes the absolute position of the menubar window */
2360 mw->menu.windows [0].x = ev->xmotion.x_root - ev->xmotion.x; 2406 mw->menu.windows [0].x = ev->xmotion.x_root - ev->xmotion.x;
2361 mw->menu.windows [0].y = ev->xmotion.y_root - ev->xmotion.y; 2407 mw->menu.windows [0].y = ev->xmotion.y_root - ev->xmotion.y;
2408 mw->menu.top_depth = 2;
2362 } 2409 }
2363 2410
2364#ifdef emacs 2411#ifdef emacs
diff --git a/lwlib/xlwmenu.h b/lwlib/xlwmenu.h
index 3057998d17a..c1f37b5617b 100644
--- a/lwlib/xlwmenu.h
+++ b/lwlib/xlwmenu.h
@@ -53,9 +53,6 @@ typedef struct _XlwMenuClassRec *XlwMenuWidgetClass;
53 53
54extern WidgetClass xlwMenuWidgetClass; 54extern WidgetClass xlwMenuWidgetClass;
55 55
56void
57pop_up_menu __P ((XlwMenuWidget, XButtonPressedEvent*));
58
59#endif /* _XlwMenu_h */ 56#endif /* _XlwMenu_h */
60 57
61/* arch-tag: 0c019735-d61b-4080-be85-4fdd6e50ae07 58/* arch-tag: 0c019735-d61b-4080-be85-4fdd6e50ae07
diff --git a/lwlib/xlwmenuP.h b/lwlib/xlwmenuP.h
index c3e62830184..f6aa0f4a58c 100644
--- a/lwlib/xlwmenuP.h
+++ b/lwlib/xlwmenuP.h
@@ -47,6 +47,7 @@ typedef struct _XlwMenu_part
47 unsigned free_bottom_shadow_color_p : 1; 47 unsigned free_bottom_shadow_color_p : 1;
48 48
49 /* State of the XlwMenu */ 49 /* State of the XlwMenu */
50 int top_depth;
50 int old_depth; 51 int old_depth;
51 widget_value** old_stack; 52 widget_value** old_stack;
52 int old_stack_length; 53 int old_stack_length;
diff --git a/src/ChangeLog b/src/ChangeLog
index 8b6160fb5eb..9c21defd658 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,13 @@
12004-01-12 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
2
3 * xmenu.c (popup_get_selection): Check new parameter down_on_keypress
4 if a key press should pop down. Only pop down if a key is pressed
5 outside the menu/dialog.
6 (create_and_show_popup_menu): Pass 0 for down_on_keypress to
7 popup_get_selection.
8 (create_and_show_dialog): Pass 1 for down_on_keypress to
9 popup_get_selection.
10
12004-01-11 Jan Dj,Ad(Brv <jan.h.d@swipnet.se> 112004-01-11 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
2 12
3 * alloc.c (allocate_vectorlike): Surround calls to mallopt with 13 * alloc.c (allocate_vectorlike): Surround calls to mallopt with
diff --git a/src/xmenu.c b/src/xmenu.c
index 3a2b75bfdea..2ca6e247e12 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -1121,17 +1121,19 @@ on the left of the dialog box and all following items on the right.
1121 and x-popup-dialog; it is not used for the menu bar. 1121 and x-popup-dialog; it is not used for the menu bar.
1122 1122
1123 If DO_TIMERS is nonzero, run timers. 1123 If DO_TIMERS is nonzero, run timers.
1124 If DOWN_ON_KEYPRESS is nonzero, pop down if a key is pressed.
1124 1125
1125 NOTE: All calls to popup_get_selection should be protected 1126 NOTE: All calls to popup_get_selection should be protected
1126 with BLOCK_INPUT, UNBLOCK_INPUT wrappers. */ 1127 with BLOCK_INPUT, UNBLOCK_INPUT wrappers. */
1127 1128
1128#ifdef USE_X_TOOLKIT 1129#ifdef USE_X_TOOLKIT
1129static void 1130static void
1130popup_get_selection (initial_event, dpyinfo, id, do_timers) 1131popup_get_selection (initial_event, dpyinfo, id, do_timers, down_on_keypress)
1131 XEvent *initial_event; 1132 XEvent *initial_event;
1132 struct x_display_info *dpyinfo; 1133 struct x_display_info *dpyinfo;
1133 LWLIB_ID id; 1134 LWLIB_ID id;
1134 int do_timers; 1135 int do_timers;
1136 int down_on_keypress;
1135{ 1137{
1136 XEvent event; 1138 XEvent event;
1137 1139
@@ -1167,15 +1169,20 @@ popup_get_selection (initial_event, dpyinfo, id, do_timers)
1167 event.xbutton.state = 0; 1169 event.xbutton.state = 0;
1168#endif 1170#endif
1169 } 1171 }
1170 /* If the user presses a key, deactivate the menu. 1172 /* If the user presses a key that doesn't go to the menu,
1173 deactivate the menu.
1171 The user is likely to do that if we get wedged. 1174 The user is likely to do that if we get wedged.
1172 This is mostly for Lucid, Motif pops down the menu on ESC. */ 1175 All toolkits now pop down menus on ESC.
1176 For dialogs however, the focus may not be on the dialog, so
1177 in that case, we pop down. */
1173 else if (event.type == KeyPress 1178 else if (event.type == KeyPress
1179 && down_on_keypress
1174 && dpyinfo->display == event.xbutton.display) 1180 && dpyinfo->display == event.xbutton.display)
1175 { 1181 {
1176 KeySym keysym = XLookupKeysym (&event.xkey, 0); 1182 KeySym keysym = XLookupKeysym (&event.xkey, 0);
1177 if (!IsModifierKey (keysym)) 1183 if (!IsModifierKey (keysym)
1178 popup_activated_flag = 0; 1184 && x_any_window_to_frame (dpyinfo, event.xany.window) != NULL)
1185 popup_activated_flag = 0;
1179 } 1186 }
1180 1187
1181 x_dispatch_event (&event, event.xany.display); 1188 x_dispatch_event (&event, event.xany.display);
@@ -2448,7 +2455,7 @@ create_and_show_popup_menu (f, first_wv, x, y, for_click)
2448 popup_activated_flag = 1; 2455 popup_activated_flag = 1;
2449 2456
2450 /* Process events that apply to the menu. */ 2457 /* Process events that apply to the menu. */
2451 popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), menu_id, 0); 2458 popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), menu_id, 0, 0);
2452 2459
2453 /* fp turned off the following statement and wrote a comment 2460 /* fp turned off the following statement and wrote a comment
2454 that it is unnecessary--that the menu has already disappeared. 2461 that it is unnecessary--that the menu has already disappeared.
@@ -2842,7 +2849,8 @@ create_and_show_dialog (f, first_wv)
2842 Fcons (make_number (dialog_id >> (fact)), 2849 Fcons (make_number (dialog_id >> (fact)),
2843 make_number (dialog_id & ~(-1 << (fact))))); 2850 make_number (dialog_id & ~(-1 << (fact)))));
2844 2851
2845 popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), dialog_id, 1); 2852 popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f),
2853 dialog_id, 1, 1);
2846 2854
2847 unbind_to (count, Qnil); 2855 unbind_to (count, Qnil);
2848 } 2856 }