diff options
| author | Karoly Lorentey | 2004-01-12 16:36:35 +0000 |
|---|---|---|
| committer | Karoly Lorentey | 2004-01-12 16:36:35 +0000 |
| commit | 990e879437236fc76e827d6191899c117f01fd99 (patch) | |
| tree | e3a10d3d851886e39fe0accf24079874cbaf1063 | |
| parent | 7f19e125070fa016bcfad660febf19f1a84adb76 (diff) | |
| parent | bcb6b6b8b1a7bc1f724bb0b5ba3306c760d97c35 (diff) | |
| download | emacs-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/NEWS | 13 | ||||
| -rw-r--r-- | lisp/calendar/appt.el | 12 | ||||
| -rw-r--r-- | lispref/ChangeLog | 13 | ||||
| -rw-r--r-- | lispref/searching.texi | 169 | ||||
| -rw-r--r-- | lwlib/ChangeLog | 28 | ||||
| -rw-r--r-- | lwlib/lwlib-Xaw.c | 17 | ||||
| -rw-r--r-- | lwlib/lwlib-Xlw.c | 31 | ||||
| -rw-r--r-- | lwlib/lwlib-Xm.c | 33 | ||||
| -rw-r--r-- | lwlib/xlwmenu.c | 109 | ||||
| -rw-r--r-- | lwlib/xlwmenu.h | 3 | ||||
| -rw-r--r-- | lwlib/xlwmenuP.h | 1 | ||||
| -rw-r--r-- | src/ChangeLog | 10 | ||||
| -rw-r--r-- | src/xmenu.c | 22 |
13 files changed, 344 insertions, 117 deletions
| @@ -481,6 +481,13 @@ command. | |||
| 481 | On the other hand, the size of the thumb does not represent the actual | 481 | On the other hand, the size of the thumb does not represent the actual |
| 482 | amount of text shown any more (only a crude approximation of it). | 482 | amount 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 | ||
| 486 | be 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 |
| 486 | disabled by customizing the variable `use-file-dialog'. | 493 | disabled by customizing the variable `use-file-dialog'. |
| @@ -946,6 +953,12 @@ count backward from the end of the year. | |||
| 946 | This can be controlled through the variables `diary-header-line-flag' | 953 | This can be controlled through the variables `diary-header-line-flag' |
| 947 | and `diary-header-line-format'. | 954 | and `diary-header-line-format'. |
| 948 | 955 | ||
| 956 | +++ | ||
| 957 | ** The procedure for activating appointment reminders has changed: use | ||
| 958 | the new function `appt-activate'. The new variable | ||
| 959 | `appt-display-format' controls how reminders are displayed, replacing | ||
| 960 | appt-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. | ||
| 84 | To be detected, the diary entry must have the format described in the | ||
| 85 | documentation 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 \ | ||
| 91 | variable `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 @@ | |||
| 1 | 2004-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 | |||
| 1 | 2004-01-07 Luc Teirlinck <teirllm@auburn.edu> | 14 | 2004-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 | |||
| 90 | search is repeated that many times (each time starting at the end of the | 90 | search is repeated that many times (each time starting at the end of the |
| 91 | previous time's match). If these successive searches succeed, the | 91 | previous time's match). If these successive searches succeed, the |
| 92 | function succeeds, moving point and returning its new value. Otherwise | 92 | function succeeds, moving point and returning its new value. Otherwise |
| 93 | the search fails, leaving point where it started. | 93 | the 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 | |||
| 143 | an error if the search fails. If @var{noerror} is @code{t}, then it | 144 | an error if the search fails. If @var{noerror} is @code{t}, then it |
| 144 | returns @code{nil} instead of signaling an error. If @var{noerror} is | 145 | returns @code{nil} instead of signaling an error. If @var{noerror} is |
| 145 | neither @code{nil} nor @code{t}, it moves point to @var{limit} (or the | 146 | neither @code{nil} nor @code{t}, it moves point to @var{limit} (or the |
| 146 | end of the buffer) and returns @code{nil}. | 147 | end of the accessible portion of the buffer) and returns @code{nil}. |
| 147 | 148 | ||
| 148 | If @var{repeat} is non-@code{nil}, then the search is repeated that many | 149 | If @var{repeat} is non-@code{nil}, then the search is repeated that many |
| 149 | times. Point is positioned at the end of the last match. | 150 | times. 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 | ||
| 294 | You can also include character ranges in a character alternative, by | 295 | You can also include character ranges in a character alternative, by |
| 295 | writing the starting and ending characters with a @samp{-} between them. | 296 | writing the starting and ending characters with a @samp{-} between them. |
| 296 | Thus, @samp{[a-z]} matches any lower-case @acronym{ASCII} letter. Ranges may be | 297 | Thus, @samp{[a-z]} matches any lower-case @acronym{ASCII} letter. |
| 297 | intermixed freely with individual characters, as in @samp{[a-z$%.]}, | 298 | Ranges may be intermixed freely with individual characters, as in |
| 298 | which matches any lower case @acronym{ASCII} letter or @samp{$}, @samp{%} or | 299 | @samp{[a-z$%.]}, which matches any lower case @acronym{ASCII} letter |
| 299 | period. | 300 | or @samp{$}, @samp{%} or period. |
| 300 | 301 | ||
| 301 | Note that the usual regexp special characters are not special inside a | 302 | Note that the usual regexp special characters are not special inside a |
| 302 | character alternative. A completely different set of characters is | 303 | character 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 |
| 361 | is a special character that matches the empty string, but only at the | 362 | When matching a buffer, @samp{^} matches the empty string, but only at the |
| 362 | beginning of a line in the text being matched. Otherwise it fails to | 363 | beginning of a line in the text being matched (or the beginning of the |
| 363 | match anything. Thus, @samp{^foo} matches a @samp{foo} that occurs at | 364 | accessible portion of the buffer). Otherwise it fails to match |
| 364 | the beginning of a line. | 365 | anything. Thus, @samp{^foo} matches a @samp{foo} that occurs at the |
| 366 | beginning of a line. | ||
| 365 | 367 | ||
| 366 | When matching a string instead of a buffer, @samp{^} matches at the | 368 | When matching a string instead of a buffer, @samp{^} matches at the |
| 367 | beginning of the string or after a newline character. | 369 | beginning 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 |
| 375 | is similar to @samp{^} but matches only at the end of a line. Thus, | 377 | is 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. | 378 | end of the accessible portion of the buffer). Thus, @samp{x+$} |
| 379 | matches a string of one @samp{x} or more at the end of a line. | ||
| 377 | 380 | ||
| 378 | When matching a string instead of a buffer, @samp{$} matches at the end | 381 | When matching a string instead of a buffer, @samp{$} matches at the end |
| 379 | of the string or before a newline character. | 382 | of the string or before a newline character. |
| @@ -542,7 +545,7 @@ purposes of an ordinary group (controlling the nesting of other | |||
| 542 | operators), but it does not get a number, so you cannot refer back to | 545 | operators), but it does not get a number, so you cannot refer back to |
| 543 | its value with @samp{\@var{digit}}. | 546 | its value with @samp{\@var{digit}}. |
| 544 | 547 | ||
| 545 | Shy groups are particulary useful for mechanically-constructed regular | 548 | Shy groups are particularly useful for mechanically-constructed regular |
| 546 | expressions because they can be added automatically without altering the | 549 | expressions because they can be added automatically without altering the |
| 547 | numbering of any ordinary, non-shy groups. | 550 | numbering of any ordinary, non-shy groups. |
| 548 | 551 | ||
| @@ -567,6 +570,10 @@ composed of two identical halves. The @samp{\(.*\)} matches the first | |||
| 567 | half, which may be anything, but the @samp{\1} that follows must match | 570 | half, which may be anything, but the @samp{\1} that follows must match |
| 568 | the same exact text. | 571 | the same exact text. |
| 569 | 572 | ||
| 573 | If a @samp{\( @dots{} \)} construct matches more than once (which can | ||
| 574 | happen, for instance, if it is followed by @samp{*}), only the last | ||
| 575 | match is recorded. | ||
| 576 | |||
| 570 | If a particular grouping construct in the regular expression was never | 577 | If a particular grouping construct in the regular expression was never |
| 571 | matched---for instance, if it appears inside of an alternative that | 578 | matched---for instance, if it appears inside of an alternative that |
| 572 | wasn't used, or inside of a repetition that repeated zero times---then | 579 | wasn'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, |
| 613 | they don't use up any characters---but whether they match depends on the | 620 | they don't use up any characters---but whether they match depends on the |
| 614 | context. | 621 | context. For all, the beginning and end of the accessible portion of |
| 622 | the buffer are treated as if they were the actual beginning and end of | ||
| 623 | the 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) |
| 640 | regardless of what text appears next to it. | 649 | regardless 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 |
| 644 | matches the empty string, but @emph{not} at the beginning or | 653 | matches the empty string, but @emph{not} at the beginning or |
| 645 | end of a word. | 654 | end 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 |
| 649 | matches the empty string, but only at the beginning of a word. | 658 | matches 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 |
| 651 | word-constituent character follows. | 660 | word-constituent character follows. |
| 652 | 661 | ||
| 653 | @item \> | 662 | @item \> |
| 654 | @cindex @samp{\>} in regexp | 663 | @cindex @samp{\>} in regexp |
| 655 | matches the empty string, but only at the end of a word. @samp{\>} | 664 | matches the empty string, but only at the end of a word. @samp{\>} |
| 656 | matches at the end of the buffer only if the contents end with a | 665 | matches at the end of the buffer (or string) only if the contents end |
| 657 | word-constituent character. | 666 | with 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 |
| 672 | sentence together with any whitespace that follows. It is the value of | 681 | recognize the end of a sentence together with any whitespace that |
| 673 | the variable @code{sentence-end}. | 682 | follows. It was used as the variable @code{sentence-end}. (Its value |
| 683 | nowadays contains alternatives for @samp{.}, @samp{?} and @samp{!} in | ||
| 684 | other 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 |
| 676 | spaces from tab characters. The string constant begins and ends with a | 687 | spaces 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 | |||
| 679 | tab and @samp{\n} for a newline. | 690 | tab 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 |
| 686 | In contrast, if you evaluate the variable @code{sentence-end}, you | 697 | In contrast, if you evaluate this string, you will see the following: |
| 687 | will see the following: | ||
| 688 | 698 | ||
| 689 | @example | 699 | @example |
| 690 | @group | 700 | @group |
| 691 | sentence-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 [.?!] |
| 705 | The first part of the pattern is a character alternative that matches | 715 | The first part of the pattern is a character alternative that matches |
| 706 | any one of three characters: period, question mark, and exclamation | 716 | any one of three characters: period, question mark, and exclamation |
| 707 | mark. The match must begin with one of these three characters. | 717 | mark. The match must begin with one of these three characters. (This |
| 718 | is the one point where the new value of @code{sentence-end} differs | ||
| 719 | from the old. The new value also lists sentence ending | ||
| 720 | non-@acronym{ASCII} characters.) | ||
| 708 | 721 | ||
| 709 | @item []\"')@}]* | 722 | @item []\"')@}]* |
| 710 | The second part of the pattern matches any closing braces and quotation | 723 | The 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 |
| 766 | This function returns an efficient regular expression that will match | 779 | This function returns an efficient regular expression that will match |
| 767 | any of the strings @var{strings}. This is useful when you need to make | 780 | any of the strings in the list @var{strings}. This is useful when you |
| 768 | matching or searching as fast as possible---for example, for Font Lock | 781 | need to make matching or searching as fast as possible---for example, |
| 769 | mode. | 782 | for Font Lock mode. |
| 770 | 783 | ||
| 771 | If the optional argument @var{paren} is non-@code{nil}, then the | 784 | If the optional argument @var{paren} is non-@code{nil}, then the |
| 772 | returned regular expression is always enclosed by at least one | 785 | returned regular expression is always enclosed by at least one |
| 773 | parentheses-grouping construct. | 786 | parentheses-grouping construct. If @var{paren} is @code{words}, then |
| 787 | that construct is additionally surrounded by @samp{\<} and @samp{\>}. | ||
| 774 | 788 | ||
| 775 | This simplified definition of @code{regexp-opt} produces a | 789 | This simplified definition of @code{regexp-opt} produces a |
| 776 | regular expression which is equivalent to the actual value | 790 | regular 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 |
| 790 | This function returns the total number of grouping constructs | 804 | This function returns the total number of grouping constructs |
| 791 | (parenthesized expressions) in @var{regexp}. | 805 | (parenthesized expressions) in @var{regexp}. (This does not include |
| 806 | shy 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 |
| 833 | buffer) and returns @code{nil}. | 848 | accessible portion of the buffer) and returns @code{nil}. |
| 834 | 849 | ||
| 835 | In the following example, point is initially before the @samp{T}. | 850 | In the following example, point is initially before the @samp{T}. |
| 836 | Evaluating the search call moves point to the end of that line (between | 851 | Evaluating 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 | |||
| 866 | beginning is as close as possible to the starting point. If | 881 | beginning 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 |
| 868 | match whose end is as close as possible. However, in fact it finds the | 883 | match whose end is as close as possible. However, in fact it finds the |
| 869 | match whose beginning is as close as possible. The reason for this is that | 884 | match whose beginning is as close as possible (and yet ends before the |
| 870 | matching a regular expression at a given spot always works from | 885 | starting point). The reason for this is that matching a regular |
| 871 | beginning to end, and starts at a specified beginning position. | 886 | expression at a given spot always works from beginning to end, and |
| 887 | starts at a specified beginning position. | ||
| 872 | 888 | ||
| 873 | A true mirror-image of @code{re-search-forward} would require a special | 889 | A true mirror-image of @code{re-search-forward} would require a special |
| 874 | feature for matching regular expressions from end to beginning. It's | 890 | feature 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 | |||
| 1069 | commands. It searches for occurrences of @var{from-string} in the | 1085 | commands. It searches for occurrences of @var{from-string} in the |
| 1070 | text between positions @var{start} and @var{end} and replaces some or | 1086 | text between positions @var{start} and @var{end} and replaces some or |
| 1071 | all of them. If @var{start} is @code{nil} (or omitted), point is used | 1087 | all of them. If @var{start} is @code{nil} (or omitted), point is used |
| 1072 | instead, and the buffer's end is used for @var{end}. | 1088 | instead, and the end of the buffer's accessible portion is used for |
| 1089 | @var{end}. | ||
| 1073 | 1090 | ||
| 1074 | If @var{query-flag} is @code{nil}, it replaces all | 1091 | If @var{query-flag} is @code{nil}, it replaces all |
| 1075 | occurrences; otherwise, it asks the user what to do about each one. | 1092 | occurrences; 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 | ||
| 1091 | If @var{repeat-count} is non-@code{nil}, it should be an integer. Then | 1108 | If @var{repeat-count} is non-@code{nil}, it should be an integer. Then |
| 1092 | it specifies how many times to use each of the strings in the | 1109 | it 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 | ||
| 1095 | If @var{from-string} contains upper-case letters, then | 1112 | If @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. | |||
| 1099 | Normally, the keymap @code{query-replace-map} defines the possible user | 1116 | Normally, the keymap @code{query-replace-map} defines the possible user |
| 1100 | responses for queries. The argument @var{map}, if non-@code{nil}, is a | 1117 | responses for queries. The argument @var{map}, if non-@code{nil}, is a |
| 1101 | keymap to use instead of @code{query-replace-map}. | 1118 | keymap to use instead of @code{query-replace-map}. |
| 1119 | |||
| 1120 | @strong{Usage note:} Do not use this function in your own programs | ||
| 1121 | unless you want to do something very similar to what | ||
| 1122 | @code{query-replace} does, including setting the mark and possibly | ||
| 1123 | querying the user. For most purposes a simple loop like, for | ||
| 1124 | instance: | ||
| 1125 | |||
| 1126 | @example | ||
| 1127 | (while (re-search-forward "foo[ \t]+bar" nil t) | ||
| 1128 | (replace-match "foobar")) | ||
| 1129 | @end example | ||
| 1130 | |||
| 1131 | @noindent | ||
| 1132 | is preferable. It runs faster and avoids side effects, such as | ||
| 1133 | setting the mark. @xref{Replacing Match,, Replacing the Text that | ||
| 1134 | Matched}, 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 | ||
| 1207 | If you did the last search in a buffer, you should specify @code{nil} | 1240 | If you did the last search in a buffer, you should specify @code{nil} |
| 1208 | for @var{string}. Then @code{replace-match} does the replacement by | 1241 | for @var{string} and make sure that the current buffer when you call |
| 1209 | editing 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 |
| 1210 | and returns @code{t}. | 1243 | matching. Then @code{replace-match} does the replacement by editing |
| 1244 | the buffer; it leaves point at the end of the replacement text, and | ||
| 1245 | returns @code{t}. | ||
| 1211 | 1246 | ||
| 1212 | If you did the search in a string, pass the same string as @var{string}. | 1247 | If you did the search in a string, pass the same string as @var{string}. |
| 1213 | Then @code{replace-match} does the replacement by constructing and | 1248 | Then @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 |
| 1240 | matched the @var{n}th subexpression in the original regexp. | 1275 | matched the @var{n}th subexpression in the original regexp. |
| 1241 | Subexpressions are those expressions grouped inside @samp{\(@dots{}\)}. | 1276 | Subexpressions are those expressions grouped inside @samp{\(@dots{}\)}. |
| 1277 | If 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 |
| 1397 | write the entire match data, all at once. | 1433 | write the entire match data, all at once. |
| 1398 | 1434 | ||
| 1399 | @defun match-data | 1435 | @defun match-data &optional integers reuse |
| 1400 | This function returns a newly constructed list containing all the | 1436 | This function returns a newly constructed list containing all the |
| 1401 | information on what text the last search matched. Element zero is the | 1437 | information on what text the last search matched. Element zero is the |
| 1402 | position of the beginning of the match for the whole expression; element | 1438 | position of the beginning of the match for the whole expression; element |
| @@ -1420,8 +1456,20 @@ number {\mathsurround=0pt $2n+1$} | |||
| 1420 | corresponds to @code{(match-end @var{n})}. | 1456 | corresponds to @code{(match-end @var{n})}. |
| 1421 | 1457 | ||
| 1422 | All the elements are markers or @code{nil} if matching was done on a | 1458 | All the elements are markers or @code{nil} if matching was done on a |
| 1423 | buffer, and all are integers or @code{nil} if matching was done on a | 1459 | buffer and all are integers or @code{nil} if matching was done on a |
| 1424 | string with @code{string-match}. | 1460 | string with @code{string-match}. If @var{integers} is |
| 1461 | non-@code{nil}, then all elements are integers or @code{nil}, even if | ||
| 1462 | matching was done on a buffer. Also, @code{match-beginning} and | ||
| 1463 | @code{match-end} always return integers or @code{nil}. | ||
| 1464 | |||
| 1465 | If @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 | ||
| 1468 | have the right length. If it is not long enough to contain the match | ||
| 1469 | data, it is extended. If it is too long, the length of @var{reuse} | ||
| 1470 | stays 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 | ||
| 1472 | much garbage, that would later have to be collected. | ||
| 1425 | 1473 | ||
| 1426 | As always, there must be no possibility of intervening searches between | 1474 | As always, there must be no possibility of intervening searches between |
| 1427 | the call to a search function and the call to @code{match-data} that is | 1475 | the 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{} |
| 1476 | This macro executes @var{body}, saving and restoring the match | 1524 | This macro executes @var{body}, saving and restoring the match |
| 1477 | data around it. | 1525 | data 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 | |||
| 1544 | searching functions used in Lisp code. | 1593 | searching functions used in Lisp code. |
| 1545 | 1594 | ||
| 1546 | @defopt case-replace | 1595 | @defopt case-replace |
| 1547 | This variable determines whether the replacement functions should | 1596 | This variable determines whether the higher level replacement |
| 1548 | preserve case. If the variable is @code{nil}, that means to use the | 1597 | functions should preserve case. If the variable is @code{nil}, that |
| 1549 | replacement text verbatim. A non-@code{nil} value means to convert the | 1598 | means to use the replacement text verbatim. A non-@code{nil} value |
| 1550 | case of the replacement text according to the text being replaced. | 1599 | means to convert the case of the replacement text according to the |
| 1600 | text being replaced. | ||
| 1551 | 1601 | ||
| 1552 | This variable is used by passing it as an argument to the function | 1602 | This 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 |
| 1601 | This is the regular expression for recognizing the beginning of a line | 1651 | This is the regular expression for recognizing the beginning of a line |
| 1602 | that starts @emph{or} separates paragraphs. The default value is | 1652 | that 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 |
| 1604 | newline, or form feed (after its left margin). | 1654 | whitespace 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 |
| 1608 | This is the regular expression describing the end of a sentence. (All | 1658 | This is the regular expression describing the end of a sentence. (All |
| 1609 | paragraph boundaries also end sentences, regardless.) The default value | 1659 | paragraph boundaries also end sentences, regardless.) The (slightly |
| 1610 | is: | 1660 | simplified) 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 | ||
| 1616 | This means a period, question mark or exclamation mark, followed | 1666 | This means a period, question mark or exclamation mark (the actual |
| 1617 | optionally by a closing parenthetical character, followed by tabs, | 1667 | default value also lists their alternatives in other character sets), |
| 1618 | spaces or new lines. | 1668 | followed optionally by a closing parenthetical character, followed by |
| 1669 | tabs, spaces or new lines. | ||
| 1619 | 1670 | ||
| 1620 | For a detailed explanation of this regular expression, see @ref{Regexp | 1671 | For a detailed explanation of this regular expression, see @ref{Regexp |
| 1621 | Example}. | 1672 | Example}. |
diff --git a/lwlib/ChangeLog b/lwlib/ChangeLog index f41b323c04c..3b69d955392 100644 --- a/lwlib/ChangeLog +++ b/lwlib/ChangeLog | |||
| @@ -1,3 +1,31 @@ | |||
| 1 | 2004-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 | |||
| 1 | 2003-05-22 Dave Love <fx@gnu.org> | 29 | 2003-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 | ||
| 278 | static char overrideTrans[] = | 278 | static char overrideTrans[] = |
| 279 | "<Message>WM_PROTOCOLS: lwlib_delete_dialog()"; | 279 | "<Message>WM_PROTOCOLS: lwlib_delete_dialog()"; |
| 280 | /* Dialogs pop down on any key press */ | ||
| 281 | static char dialogOverride[] = | ||
| 282 | "<KeyPress>: lwlib_delete_dialog()"; | ||
| 280 | static void wm_delete_window(); | 283 | static void wm_delete_window(); |
| 281 | static XtActionsRec xaw_actions [] = { | 284 | static 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 | ||
| 513 | static void | 518 | static void |
| 514 | wm_delete_window (shell, closure, call_data) | 519 | wm_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. */ | ||
| 1039 | static void | ||
| 1040 | dialog_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 */ |
| 1039 | static Widget | 1066 | static Widget |
| 1040 | make_dialog (name, parent, pop_up_p, shell_title, icon_name, text_input_slot, | 1067 | make_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(); | |||
| 197 | static void Key(); | 197 | static void Key(); |
| 198 | static void Nothing(); | 198 | static void Nothing(); |
| 199 | static int separator_height __P ((enum menu_separator)); | 199 | static int separator_height __P ((enum menu_separator)); |
| 200 | static void pop_up_menu __P ((XlwMenuWidget, XButtonPressedEvent *)); | ||
| 201 | |||
| 200 | 202 | ||
| 201 | static XtActionsRec | 203 | static XtActionsRec |
| 202 | xlwMenuActionsList [] = | 204 | xlwMenuActionsList [] = |
| @@ -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 | ||
| 2047 | widget_value * | 2056 | static widget_value * |
| 2048 | find_first_selectable (mw, item) | 2057 | find_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 | ||
| 2064 | widget_value * | 2075 | static widget_value * |
| 2065 | find_next_selectable (mw, item) | 2076 | find_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 | ||
| 2096 | widget_value * | 2110 | static widget_value * |
| 2097 | find_prev_selectable (mw, item) | 2111 | find_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 | ||
| 2165 | static void | 2200 | void |
| 2166 | Left (w, ev, params, num_params) | 2201 | Left (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 | ||
| 2200 | static void | 2240 | void |
| 2201 | Right (w, ev, params, num_params) | 2241 | Right (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 */ |
| 2308 | void | 2353 | static void |
| 2309 | pop_up_menu (mw, event) | 2354 | pop_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 | ||
| 54 | extern WidgetClass xlwMenuWidgetClass; | 54 | extern WidgetClass xlwMenuWidgetClass; |
| 55 | 55 | ||
| 56 | void | ||
| 57 | pop_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 @@ | |||
| 1 | 2004-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 | |||
| 1 | 2004-01-11 Jan Dj,Ad(Brv <jan.h.d@swipnet.se> | 11 | 2004-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 |
| 1129 | static void | 1130 | static void |
| 1130 | popup_get_selection (initial_event, dpyinfo, id, do_timers) | 1131 | popup_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 | } |