emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/hyperbole 1aec56c 27/53: Added drags between frames and


From: Robert Weiner
Subject: [elpa] externals/hyperbole 1aec56c 27/53: Added drags between frames and outside Emacs, new mode-line drags, dired item drags,
Date: Wed, 15 Nov 2017 22:47:03 -0500 (EST)

branch: externals/hyperbole
commit 1aec56c5d6c3c1a45877a7ea3eaaccffc1573f69
Author: Bob Weiner <address@hidden>
Commit: Bob Weiner <address@hidden>

    Added drags between frames and outside Emacs, new mode-line drags, dired 
item drags,
      hyperbole.el commentary, texinfo @findex and @vindex implicit buttons, 
hycontrol
      frame quadrant movement by virtual numeric keypad, greater hycontrol 
WINDOW/FRAME
      commonality, hycontrol rapid frame percentage resizing along a single 
edge, improved
      smart key help
    
    2017-10-16  Bob Weiner  <address@hidden>
    
    * hib-debbugs.el (debbugs-query:at-p): eliminated match of #id-number and 
always required
       'bug' or similar prefix so there is no ambiguity with social references 
including
       git #commit-number.
    
    * hmouse-drv.el (hkey-help): Updated to handle call-interactively actions 
and 'or'ed action
        intelligently when printing action documentation.
    
    2017-10-15  Bob Weiner  <address@hidden>
    
    * hmouse-drv.el (action-key-depress-position, assist-key-depress-position): 
Added to
        test whether or not last Action Mouse Key event was a mouse click 
(non-drag event).
    
    2017-10-14  Bob Weiner  <address@hidden>
    
    * hmouse-drv.el (hmouse-window-at-absolute-pixel-position): Added optional 
Python script,
        topwin, for macOS window-system only.  It determines the topmost 
application window at
        the given position and returns the application name, so Emacs can tell 
if its frame is
        obscured by another application or not.
                    (hmouse-verify-release-window-flag): Added so can turn off 
use of the macOS
        Python script when desired since it slows Smart Key action handling at 
least 1/3 of a
        second.
    
    * hycontrol.el (hycontrol-frames): Changed = command call to set-frame-size 
to use pixel
        dimensions rather than chars/lines for better accuracy.
        (hycontrol-window-to-new-frame): Same.
    
    * hui-menu.el (hui-menu-key-binding-item): Added.
    
    * hmouse-drv.el (hmouse-set-point): Fixed to return a posn object as a 
fallback, i.e. what
        event-start and event-end return; previously, had returned point as a 
marker in this case.
        Keyboard-based emulation of mouse drags via hkey-operate had been 
broken; this fixed it.
    * hui-window.el (hmouse-x-coord, hmouse-y-coord): Updated to accept a posn.
                    (hmouse-modeline-event-p): Ignored case where args is a 
posn or point-marker,
        not an event.
    
    2017-10-13  Bob Weiner  <address@hidden>
    
    * hversion.el (hyperb:window-sys-term): Emacs set-frame-parameter does not 
return the value, so
        this function was always returning nil.  Fixed it to return what the 
doc says it does.
    
    * hycontrol.el (hycontrol-frame-at-left-p, hycontrol-frame-at-top-p, 
hycontrol-frame-at-right-p,
        hycontrol-frame-at-bottom-p): Added.
        (hycontrol-frame-expand-to-*): Rewrote these: first they expand a frame 
to a particular edge;
          then the next invocation when already at that edge, cuts that frame 
dimension in half from the
          opposite side (or to any percentage specified as an argument), 
leaving the particular edge fixed.
          Renamed to hycontrol-frame-resize-to-*.  This allows both rapid 
expansion and contraction of
          frames with just 4 keys whenever needed.
        (hycontrol-frame-resize-percentage, hycontrol-frame-resize-arg): Added 
as support functions.
        (hycontrol-frame-edges): Added to ensure outer edges of frames are 
always used.
        (hycontrol-frames): Added arg as a 0-100 percentage for i,j,k,m 
commands.
        (hycontrol-windows): Added same c (cycle frame positions), i,j,k,m keys 
and numeric
           keypad keys to here.
        (hycontrol-frames/windows): Added p (virtual numeric keypad) to allow 
keyboard-based frame
           quadrant movement when a numeric keypad is not available.  This can 
be interrupted
           with a q to return to the control menu or a C-g to abort the control 
menu.
    
    * hui-window.el (hmouse-horizontal-action-drag): Replaced doc typo of 
'vertical' with 'horizontal'.
    
    * DEMO (Help buffers): Added description of how to get help for Smart Mouse 
Key-only events.
    
    * hycontrol.el (hycontrol-windows, hycontrol-frames): In window-control 
mode, changed {f}
        to clone window to new frame without deleting the source window to 
match similar
        Action Key drag from window/modeline to outside of any Emacs window.  
Added {F} to clone but
        delete the source window.  Added these 2 bindings to frame-control mode 
too.  Documented
        in Hyperbole manual.
    
        Expanded control help to 4 lines, added = command to equalize sizes of 
windows/frames,
        added f/F commands.
    
    * hibtypes.el (texinfo-ref): Added doc display for Emacs Lisp @findex 
(function) and @vindex
       (variable) entries.  Changed so does nothing if function or variable is 
unbound.
       Updated its doc string and doc in the Hyperbole manual.
    
    * hmouse-drv.el (hkey-help): Changed to print "WHICH WILL:" rather than 
"WHICH:" when the first
        word of the doc string does not end in an 's', e.g. "Display this" 
instead of "Displays this".
    
    * hui-window.el (hmouse-release-left-edge): Noted that left edge mode-line 
clicks must be on the
        first blank character of the mode-line because Emacs overrides the 
Smart Mouse Key bindings
        immediately after that position.  Noted in Hyperbole manual as well.
    
    * Makefile (version): Added hyperbole.el to version check.
      hyperbole.el: Updated the Commentary with a description of Hyperbole in 
case the Emacs package
        system or a user looks here for it.
    
    * hycontrol.el (hycontrol-clone-window-to-new-frame): Added and used in 
hmouse-alist.
    
    2017-10-12  Bob Weiner  <address@hidden>
    
    * hycontrol.el (hycontrol-window-to-frame): Renamed to 
hycontrol-window-to-new-frame.
                   (hycontrol-keep-window-flag): Added: When non-nil (default 
is nil), leave
        original window when tear off window to another frame.
    
    * hui-window.el (hmouse-emacs-modeline-event-p, hmouse-modeline-event-p): 
Added.
        (hmouse-modeline-depress, hmouse-modeline-release): Simplified and 
speeded up for GNU Emacs.
        (action-key-modeline, assist-key-modeline):
      man/hyperbole.texi (Modeline Clicks and Drags): Updated with new modeline 
buffer id click actions.
      man/hkey-help.txt: Updated with most new drag and click actions.
    
    * hywconfig.el: Changed all (called-interactively-p 'interactive) to 
(called-interactively-p)
        so will work if called interactively from one of the Smart Key lists.
    
    * DEMO: Fixed a number of small issues with implicit buttons therein.
    
    * hui-window.el (hmouse-drag-diagonally, hmouse-drag-horizontally, 
hmouse-drag-vertically):
        Added explicit test that press and release are in the same window.
        (hmouse-drag-item-to-display, hmouse-item-to-window): Added dired 
support.
        (hmouse-pulse-flag): Disabled by default due to sluggishness and 
improper visuals at times.
        (hmouse-map-modes-to-form, hmouse-drag-item-mode-forms): Added.
        (hmouse-drag-item-to-display, hmouse-item-to-window): Updated to use 
the new variable,
           hmouse-drag-item-mode-forms so users can add new modes for named 
item drags.
    
    * hui-window.el (hmouse-drag-between-frames): Added and used in 
hmouse-alist.
                    (hmouse-alist): Added modeline drags between frames and 
outside of Emacs.
        Added window drags outside of any window (outside of Emacs).
                    (hmouse-clone-window-to-frame): Added and used in 
hmouse-alist.
      man/hkey-help.txt: Updated with latest modeline and between window drag 
movements.
    
    2017-10-11  Bob Weiner  <address@hidden>
    
    * hycontrol.el (hycontrol-window-to-frame): Modified in the case of only 
one window in the frame,
        then clone the window into a new frame.  This allows you to create a 
bunch of tiled frames
        when in Window Control mode.  Also made this an autoload and called in 
"hui-window" within
        hmouse-alist.
    
    * hui-window.el (hmouse-drag-outside-all-windows): Added to handle the case 
where a drag release is
        outside of any Emacs window or frame and used in hmouse-alist.
    
    * hmouse-drv.el (hmouse-vertical-line-spacing): Added and used to compute 
vertical character positions.
                    (hmouse-key-release-window-emacs): Renamed to 
hmouse-key-release-window and used in
        hmouse-function to set action/assist-key-release-window accurately.
                    (hmouse-function): Fixed so 
action/assist-key-release-prev-point is set properly,
        before point is set to the location of the mouse button release.
    
    * hui-window.el (hmouse-drag-thing): Fixed to handle when release location 
is outside Emacs and
        end-point is nil.
                    (hmouse-drag-same-window): Added and used in horizontal and 
vertical drag tests.
    
    * hmouse-key.el (hmouse-update-smart-keys): Extended to also re-initialize 
Smart Key bindings.
    
    * hmouse-drv.el (smart-scroll-up): Removed 's' from the end of verbs in all 
function comments,
       e.g. scroll window instead of scrolls window, for consistency within the 
file.
       (hmouse-window-at-absolute-pixel-position, hmouse-window-coordinates): 
Added to compute the
          actual window and location of the release of a mouse drag which Emacs 
does not compute.
          Proper top-to-bottom listing of frames is available only in Emacs 26 
and above.  For
          prior versions, the ordering of the frames returned is not 
guaranteed, so the frame
          whose window is returned may not be the uppermost.
    
       (hmouse-key-release-window-emacs, hmouse-key-release-args-emacs): 
Updated to use new window
          of release functions.  Now drags between frames work properly.
---
 Changes            | 152 +++++++++++++++++
 DEMO               |  71 ++++----
 Makefile           |   2 +-
 hib-debbugs.el     |   7 +-
 hib-social.el      |   8 +-
 hibtypes.el        |  16 +-
 hmouse-drv.el      | 372 ++++++++++++++++++++++++++++++----------
 hmouse-key.el      |   3 +-
 hui-menu.el        |  26 +--
 hui-window.el      | 487 ++++++++++++++++++++++++++++++++++++-----------------
 hversion.el        |   5 +-
 hycontrol.el       | 287 +++++++++++++++++++++++--------
 hyperbole.el       |  56 +++++-
 hywconfig.el       |  10 +-
 man/hkey-help.txt  |  18 +-
 man/hyperbole.texi |  44 +++--
 16 files changed, 1161 insertions(+), 403 deletions(-)

diff --git a/Changes b/Changes
index 90f7461..35cebdb 100644
--- a/Changes
+++ b/Changes
@@ -1,3 +1,155 @@
+2017-10-16  Bob Weiner  <address@hidden>
+
+* hib-debbugs.el (debbugs-query:at-p): eliminated match of #id-number and 
always required
+   'bug' or similar prefix so there is no ambiguity with social references 
including
+   git #commit-number.
+
+* hmouse-drv.el (hkey-help): Updated to handle call-interactively actions and 
'or'ed action
+    intelligently when printing action documentation.
+
+2017-10-15  Bob Weiner  <address@hidden>
+
+* hmouse-drv.el (action-key-depress-position, assist-key-depress-position): 
Added to
+    test whether or not last Action Mouse Key event was a mouse click 
(non-drag event).
+
+2017-10-14  Bob Weiner  <address@hidden>
+
+* hmouse-drv.el (hmouse-window-at-absolute-pixel-position): Added optional 
Python script,
+    topwin, for macOS window-system only.  It determines the topmost 
application window at
+    the given position and returns the application name, so Emacs can tell if 
its frame is
+    obscured by another application or not.
+                (hmouse-verify-release-window-flag): Added so can turn off use 
of the macOS
+    Python script when desired since it slows Smart Key action handling at 
least 1/3 of a
+    second. 
+
+* hycontrol.el (hycontrol-frames): Changed = command call to set-frame-size to 
use pixel
+    dimensions rather than chars/lines for better accuracy.
+    (hycontrol-window-to-new-frame): Same.
+
+* hui-menu.el (hui-menu-key-binding-item): Added.
+
+* hmouse-drv.el (hmouse-set-point): Fixed to return a posn object as a 
fallback, i.e. what 
+    event-start and event-end return; previously, had returned point as a 
marker in this case.
+    Keyboard-based emulation of mouse drags via hkey-operate had been broken; 
this fixed it.
+* hui-window.el (hmouse-x-coord, hmouse-y-coord): Updated to accept a posn.
+                (hmouse-modeline-event-p): Ignored case where args is a posn 
or point-marker,
+    not an event.
+
+2017-10-13  Bob Weiner  <address@hidden>
+
+* hversion.el (hyperb:window-sys-term): Emacs set-frame-parameter does not 
return the value, so
+    this function was always returning nil.  Fixed it to return what the doc 
says it does.
+
+* hycontrol.el (hycontrol-frame-at-left-p, hycontrol-frame-at-top-p, 
hycontrol-frame-at-right-p,
+    hycontrol-frame-at-bottom-p): Added.
+    (hycontrol-frame-expand-to-*): Rewrote these: first they expand a frame to 
a particular edge;
+      then the next invocation when already at that edge, cuts that frame 
dimension in half from the
+      opposite side (or to any percentage specified as an argument), leaving 
the particular edge fixed.
+      Renamed to hycontrol-frame-resize-to-*.  This allows both rapid 
expansion and contraction of
+      frames with just 4 keys whenever needed.
+    (hycontrol-frame-resize-percentage, hycontrol-frame-resize-arg): Added as 
support functions.
+    (hycontrol-frame-edges): Added to ensure outer edges of frames are always 
used.
+    (hycontrol-frames): Added arg as a 0-100 percentage for i,j,k,m commands.
+    (hycontrol-windows): Added same c (cycle frame positions), i,j,k,m keys 
and numeric
+       keypad keys to here.
+    (hycontrol-frames/windows): Added p (virtual numeric keypad) to allow 
keyboard-based frame
+       quadrant movement when a numeric keypad is not available.  This can be 
interrupted
+       with a q to return to the control menu or a C-g to abort the control 
menu.
+
+* hui-window.el (hmouse-horizontal-action-drag): Replaced doc typo of 
'vertical' with 'horizontal'.
+
+* DEMO (Help buffers): Added description of how to get help for Smart Mouse 
Key-only events.
+
+* hycontrol.el (hycontrol-windows, hycontrol-frames): In window-control mode, 
changed {f}
+    to clone window to new frame without deleting the source window to match 
similar
+    Action Key drag from window/modeline to outside of any Emacs window.  
Added {F} to clone but
+    delete the source window.  Added these 2 bindings to frame-control mode 
too.  Documented
+    in Hyperbole manual.
+
+    Expanded control help to 4 lines, added = command to equalize sizes of 
windows/frames,
+    added f/F commands.
+
+* hibtypes.el (texinfo-ref): Added doc display for Emacs Lisp @findex 
(function) and @vindex
+   (variable) entries.  Changed so does nothing if function or variable is 
unbound.
+   Updated its doc string and doc in the Hyperbole manual.
+
+* hmouse-drv.el (hkey-help): Changed to print "WHICH WILL:" rather than 
"WHICH:" when the first
+    word of the doc string does not end in an 's', e.g. "Display this" instead 
of "Displays this".
+
+* hui-window.el (hmouse-release-left-edge): Noted that left edge mode-line 
clicks must be on the
+    first blank character of the mode-line because Emacs overrides the Smart 
Mouse Key bindings
+    immediately after that position.  Noted in Hyperbole manual as well.
+
+* Makefile (version): Added hyperbole.el to version check.
+  hyperbole.el: Updated the Commentary with a description of Hyperbole in case 
the Emacs package
+    system or a user looks here for it.
+
+* hycontrol.el (hycontrol-clone-window-to-new-frame): Added and used in 
hmouse-alist.
+
+2017-10-12  Bob Weiner  <address@hidden>
+
+* hycontrol.el (hycontrol-window-to-frame): Renamed to 
hycontrol-window-to-new-frame.
+               (hycontrol-keep-window-flag): Added: When non-nil (default is 
nil), leave
+    original window when tear off window to another frame.
+
+* hui-window.el (hmouse-emacs-modeline-event-p, hmouse-modeline-event-p): 
Added.
+    (hmouse-modeline-depress, hmouse-modeline-release): Simplified and speeded 
up for GNU Emacs.
+    (action-key-modeline, assist-key-modeline):
+  man/hyperbole.texi (Modeline Clicks and Drags): Updated with new modeline 
buffer id click actions.
+  man/hkey-help.txt: Updated with most new drag and click actions.
+
+* hywconfig.el: Changed all (called-interactively-p 'interactive) to 
(called-interactively-p)
+    so will work if called interactively from one of the Smart Key lists.
+
+* DEMO: Fixed a number of small issues with implicit buttons therein.
+
+* hui-window.el (hmouse-drag-diagonally, hmouse-drag-horizontally, 
hmouse-drag-vertically):
+    Added explicit test that press and release are in the same window.
+    (hmouse-drag-item-to-display, hmouse-item-to-window): Added dired support.
+    (hmouse-pulse-flag): Disabled by default due to sluggishness and improper 
visuals at times.
+    (hmouse-map-modes-to-form, hmouse-drag-item-mode-forms): Added.
+    (hmouse-drag-item-to-display, hmouse-item-to-window): Updated to use the 
new variable,
+       hmouse-drag-item-mode-forms so users can add new modes for named item 
drags.
+
+* hui-window.el (hmouse-drag-between-frames): Added and used in hmouse-alist.
+                (hmouse-alist): Added modeline drags between frames and 
outside of Emacs.
+    Added window drags outside of any window (outside of Emacs).
+                (hmouse-clone-window-to-frame): Added and used in hmouse-alist.
+  man/hkey-help.txt: Updated with latest modeline and between window drag 
movements.
+
+2017-10-11  Bob Weiner  <address@hidden>
+
+* hycontrol.el (hycontrol-window-to-frame): Modified in the case of only one 
window in the frame,
+    then clone the window into a new frame.  This allows you to create a bunch 
of tiled frames
+    when in Window Control mode.  Also made this an autoload and called in 
"hui-window" within
+    hmouse-alist.
+
+* hui-window.el (hmouse-drag-outside-all-windows): Added to handle the case 
where a drag release is
+    outside of any Emacs window or frame and used in hmouse-alist.
+
+* hmouse-drv.el (hmouse-vertical-line-spacing): Added and used to compute 
vertical character positions.
+                (hmouse-key-release-window-emacs): Renamed to 
hmouse-key-release-window and used in
+    hmouse-function to set action/assist-key-release-window accurately.
+                (hmouse-function): Fixed so 
action/assist-key-release-prev-point is set properly,
+    before point is set to the location of the mouse button release.
+
+* hui-window.el (hmouse-drag-thing): Fixed to handle when release location is 
outside Emacs and
+    end-point is nil.
+                (hmouse-drag-same-window): Added and used in horizontal and 
vertical drag tests.
+
+* hmouse-key.el (hmouse-update-smart-keys): Extended to also re-initialize 
Smart Key bindings.
+
+* hmouse-drv.el (smart-scroll-up): Removed 's' from the end of verbs in all 
function comments,
+   e.g. scroll window instead of scrolls window, for consistency within the 
file.
+   (hmouse-window-at-absolute-pixel-position, hmouse-window-coordinates): 
Added to compute the
+      actual window and location of the release of a mouse drag which Emacs 
does not compute.
+      Proper top-to-bottom listing of frames is available only in Emacs 26 and 
above.  For
+      prior versions, the ordering of the frames returned is not guaranteed, 
so the frame
+      whose window is returned may not be the uppermost.
+
+   (hmouse-key-release-window-emacs, hmouse-key-release-args-emacs): Updated 
to use new window
+      of release functions.  Now drags between frames work properly.
+
 2017-10-10  Bob Weiner  <address@hidden>
 
 * hyperbole.el (after-init-time): Added hyperb:init to the end of 
after-init-hook;
diff --git a/DEMO b/DEMO
index 9b3e7ea..8907a32 100644
--- a/DEMO
+++ b/DEMO
@@ -123,6 +123,14 @@ current context; {C-u C-h A} displays the same kind of 
help for the Assist
 Key.  Only a capital A will work, so be sure to press shift.  Try these
 help commands.
 
+You can also see what mouse-only events like mode-line clicks and drags across
+frames will do.  Depress the Smart Mouse Key you are interested in at
+a location, then while holding it down, depress the other Smart Mouse Key, move
+to any release point and then release both keys.  The help displayed will show
+you exactly what will happen in that context.  Try this for the Action Mouse 
Key
+by dragging horizontally at least 10 characters in this buffer and depressing
+the Assist Mouse Key before you finish the drag.
+
 Any buffer whose name ends in `Help*' is presumed to be a temporary buffer
 that you want to inspect and then remove from view.  If you press either the
 Action or Assist Key at the end of a help buffer, the buffer is buried from
@@ -201,7 +209,7 @@ command to return to this DEMO later.
 An incredibly powerful feature of Hyperbole is known as implicit buttons,
 i.e. a specific format of text within a buffer that Hyperbole recognizes as a
 button and lets you activate.  Hyperbole recognizes these by context and does
-require much of any specialized markup.
+not require any specialized markup.
 
 Note that you must press a Smart Key on the first line of an implicit button
 to utilize it if it spans multiple lines and always press on a regular
@@ -211,7 +219,7 @@ used to select groups of text.
 Hyperbole has many built-in implicit button types, a number of which you will
 see here, and allows you to create your own.  Once a type is known, you can
 embed an infinite number of buttons of that type within your text simply by
-typing them.  Let's look at some of these buttontypes and how you can use
+typing them.  Let's look at some of these button types and how you can use
 them.
 
 ** Key Sequence Buttons
@@ -251,7 +259,7 @@ Any existing absolute or relative pathname (whether doubly 
quoted or not)
 acts as an implicit button that either displays the referenced path within a
 buffer, passes it to an external viewer program, or runs a function that
 operates upon the path.  These are `pathname' implicit buttons.  For example,
-activate "HY-ABOUT".  HY-ABOUT or `HY-ABOUT' would work as well or
+activate "HY-ABOUT".  HY-ABOUT or `HY-ABOUT' would work as well.   Or try
 "~/.emacs".  Pathname implicit buttons provide one example of how Hyperbole
 can improve your working environment without requiring any work from you.
 
@@ -260,8 +268,8 @@ can improve your working environment without requiring any 
work from you.
 If you want to display a path at a specific line number and optionally column
 number, then add each number preceded by a colon at the end of the path.
 For example, "HY-ABOUT:10" displays HY-ABOUT at line 10, the second
-paragraph, with point at the start of the line.  "HY-ABOUT:18:7" shows the
-first numbered item on line 18 at column 7, where the text starts.
+paragraph, with point at the start of the line.  "HY-ABOUT:17:7" shows the
+first numbered item on line 17 at column 7, where the text starts.
 
 *** HTML Markdown and Emacs Outline Hash Links
 
@@ -444,15 +452,16 @@ includes your system information.
 An Action Key press on a social media hashtag or username reference at point
 displays the web page associated with the reference at the associated
 service.  References are of the form:
-[facebook|instagram|address@hidden<hashtag-or-username> or
-[fb|in|address@hidden<hashtag-or-username>.  If no service is given, it 
defaults to
-the value of @code{hibtypes-social-default-service} which is initially
-"twitter".
+[facebook|instagram|address@hidden<hashtag-or-username> or
+[fb|in|address@hidden<hashtag-or-username>.  If the service is omitted and 
there
+is no other usage of a hash reference without a prefix in the buffer, then
+the service defaults to the value of `hibtypes-social-default-service',
+which is initially "twitter".
 
-So all of the following make the same hashtag reference: #gnu twitter#gnu
-tw#gnu and display the page for tweets with that hashtag.  Similarly,
address@hidden or address@hidden would display the page for the user lostart
-at instagram.  Try pressing the Action Key on these if you like.
+For example, these make the same hashtag reference: twitter#gnu or tw#gnu
+and display the page for tweets with that hashtag.  Similarly, address@hidden 
or
address@hidden would display the page for the user lostart at instagram.
+Try pressing the Action Key on these if you like.
 
 The file "hib-social.el" has more details on this.
 
@@ -478,7 +487,7 @@ of the git commit hash code:
 An Action Key press on the first commit reference above works because
 user, project and commit hash code are all included.  The second and
 third versions require the setup of default values, as explained in
-"(hyperbole)github-reference".
+the commentary near the top of "hib-social.el".
 
 ** Git (Local) References
 
@@ -494,11 +503,9 @@ on your local system, then you can activate all of the 
following buttons.
 
 The first four examples work anywhere regardless of the buffer since Hyperbole
 locates all git repositories for you by repository/project name.  If you set a
-default project (see "(hyperbole)git-reference"), then the last example will
-work anywhere as well.
+default project, then the last example will work anywhere as well.
 
-** Grep, Occurrence, Debugger and Compiler Error Buttons, and Cscope Analyzer
-   Lines
+** Grep, Occurrence, Debugger and Compiler Error Buttons, and Cscope Analyzer 
Lines
 
 The output of `grep -n', the UNIX line pattern matcher, can be activated as
 buttons that jump to each matched line within its source file; use {M-x grep
@@ -510,7 +517,7 @@ along with GDB breakpoint listing lines also link to source 
lines.
 
 {C-h h f o} or {M-x occur RET} (find matches in a single buffer) and {C-h h f
 m} or {M-x moccur RET} (find matches across multiple buffers and files) also
-produce implicit button output that displays associated source lines.
+produce implicit button output that display associated source lines.
 
 If you have the Cscope C/C++ code analyzer from the AT&T Toolchest and have
 loaded the cscope.el library add-on for GNU Emacs, then the output lines
@@ -519,14 +526,15 @@ source lines.  Cscope goes beyond the basic Emacs tags 
facility to allow you
 to see the callers of a function and the functions called by a specific
 routine.
 
-Many of these `find a line' features exist in the Hyperbole Find/ menu.  Give
-it a try, e.g. to filter a file to just lines that don't match a pattern.
+Many of these find-a-line features exist in the Hyperbole Find/ menu,
+{C-h h f}.  Give it a try for fast access to complex file line filters,
+e.g. filter a file to just lines that don't match a pattern (RemoveLines).
 
 ** Annotated Bibliography Buttons
 
-Here's a use of an annotated bibliography reference implicit button which
-allows you to see a bibliography entry such as [FSF 16] when you activate the
-button between brackets.
+Annotated Bibliography references such as [FSF 16] may be embedded in any file
+and activated with the Action Key to find the reference at the end of the file.
+Try that one by pressing between the square brackets.
 
 ** Completion Selection
 
@@ -539,8 +547,8 @@ displayed.  Test this technique with a {C-x C-f} 
(find-file) and then a {?}.
 
 ** Hyperbole Source Buttons
 
-If you ask for help with the Assist Key or {C-u C-h A} from within the [FSF
-16] button, the first line of the help buffer will look like this:
+If you ask for help with the Assist Key or {C-u C-h A} from within the
+[FSF 16] button, the first line of the help buffer will look like this:
 
 @loc> "DEMO"
 
@@ -985,12 +993,11 @@ behavior.
 
 * Epilog
 
-We hope you have enjoyed this introduction to Hyperbole and see how it can
-help you as an every-ready sidekick as you work with information every day.
-Explore the Hyperbole menus to learn more interactively.  For reference, the
-Hyperbole Manual has more detail about the many things that Hyperbole does
-when you are ready to dive deeper.  Read it online with the GNU Info reader
-at "(hyperbole)Top".
+We hope you have enjoyed this introduction to Hyperbole. It can be your
+every-ready sidekick in your daily information work.  Explore the Hyperbole
+menus to learn more interactively.  For reference, the Hyperbole Manual, has
+more detail about the many things that Hyperbole does when you are ready to
+dive deeper.  Read it online with the GNU Info reader at "(hyperbole)Top".
 
 
 * References
diff --git a/Makefile b/Makefile
index 4e508d1..16b14fc 100644
--- a/Makefile
+++ b/Makefile
@@ -242,7 +242,7 @@ TAGS: $(EL_TAGS)
 version: doc
        @ echo ""
        @ echo "Any fgrep output means the version number has not been updated 
in that file."
-       fgrep -L $(HYPB_VERSION) Makefile HY-ABOUT HY-ANNOUNCE 
HY-ANNOUNCE-SHORT HY-NEWS README.md hversion.el hyperbole-pkg.el 
man/hyperbole.texi man/version.texi
+       fgrep -L $(HYPB_VERSION) Makefile HY-ABOUT HY-ANNOUNCE 
HY-ANNOUNCE-SHORT HY-NEWS README.md hversion.el hyperbole.el hyperbole-pkg.el 
man/hyperbole.texi man/version.texi
        @ echo ""
 
 # Build the Info, HTML and Postscript versions of the user manual and 
README.md.html.
diff --git a/hib-debbugs.el b/hib-debbugs.el
index 6d221ba..88fe952 100644
--- a/hib-debbugs.el
+++ b/hib-debbugs.el
@@ -27,7 +27,6 @@
 ;;   queries when pressed within any of the following buffer text
 ;;   formats (with point prior to any attribute):
 ;;
-;;      #id-number
 ;;      bug#id-number, bug# id-number, bug #id-number, or bug id-number
 ;;      bug?attr1=val1&attr2=val2&attr3=val3
 ;;      bug#id-number?attr1=val1&attr2=val2&attr3=val3
@@ -205,10 +204,12 @@ If this is a query with attributes, then (match-string 3) 
= \"?\" and (match-str
          (skip-chars-backward " \t\n\r\f")
          (skip-chars-backward "bugdiseBUGDISE#") ;; bug, debbugs or issue
          ;; Allow for bug#222?package=hyperbole&severity=high as well as
-         ;; bug222, bug#222, or #222.
+         ;; bug222, or bug#222.
          (or (looking-at "[ \t\n\r\f]*\\(bug#?\\|debbugs#?\\|issue#?\\)[ 
\t\n\r\f]*#?\\([1-9][0-9]*\\)?\\(\\?\\)\\([a-z=&0-9%;()]+\\)")
              (looking-at "[ \t\n\r\f]*\\(bug#?\\|debbugs#?\\|issue#?\\)[ 
\t\n\r\f]*#?\\([1-9][0-9]*\\)[\].,;?!\)\>\}]?\\([ \t\n\r\f]\\|\\'\\)")
-             (looking-at "[ \t\n\r\f]*\\(bug\\|debbugs\\|issue\\)?[ 
\t\n\r\f]*#\\([1-9][0-9]*\\)[\].,;?!\)\>\}]?\\([ \t\n\r\f]\\|\\'\\)"))))))
+             ;; Ignore matches like  #222, so this is not confused with 
"hib-social.el" social references.
+             ;; (looking-at "[ \t\n\r\f]*\\(bug\\|debbugs\\|issue\\)?[ 
\t\n\r\f]*#\\([1-9][0-9]*\\)[\].,;?!\)\>\}]?\\([ \t\n\r\f]\\|\\'\\)")
+             )))))
 
 (defun debbugs-query:status (id)
   "Pretty prints to standard-output the status attributes of debbugs ID (a 
positive integer).
diff --git a/hib-social.el b/hib-social.el
index 9ecec0a..ac46cc5 100644
--- a/hib-social.el
+++ b/hib-social.el
@@ -16,11 +16,11 @@
 ;;   When the referent is a web page, this calls the function given by
 ;;   `hibtypes-social-display-function' to display it, initially set to 
`browse-url'.
 ;;
-;;   A hashtag reference is either: 
[facebook|github|git|instagram|twitter]?#<hashtag>
-;;   or using 2-letter service abbreviations: [fb|gh|gt|in|tw]?#<hashtag>.
+;;   A hashtag reference is either: 
[facebook|github|git|instagram|twitter]#<hashtag>
+;;   or using 2-letter service abbreviations: [fb|gh|gt|in|tw]#<hashtag>.
 ;;
-;;   A username reference is either: 
[facebook|github|instagram|twitter]?@<username>
-;;   or [fb|gh|in|tw]?@<username>.
+;;   A username reference is either: 
[facebook|github|instagram|twitter]@<username>
+;;   or [fb|gh|in|tw]@<username>.
 ;;
 ;;   If the social media service is not given, it defaults to the value of
 ;;   `hibtypes-social-default-service', initially set to \"twitter\".
diff --git a/hibtypes.el b/hibtypes.el
index e294827..65b365d 100644
--- a/hibtypes.el
+++ b/hibtypes.el
@@ -832,13 +832,13 @@ any buffer attached to a file in `hyrolo-file-list', or 
any buffer with
 ;;; ========================================================================
 
 (defib texinfo-ref ()
-  "Displays Texinfo, Info node or help associated with Texinfo node, menu 
item, @xref, @pxref, @ref, @code or @var at point.
+  "Displays Texinfo, Info node or help associated with Texinfo node, menu 
item, @xref, @pxref, @ref, @code, @findex, @var or @vindex at point.
 If point is within the braces of a cross-reference, the associated
 Info node is shown.  If point is to the left of the braces but after
 the @ symbol and the reference is to a node within the current
 Texinfo file, then the Texinfo node is shown.
 
-For @code and @var references, the associated documentation string is 
displayed."
+For @code, @findex, @var and @vindex references, the associated documentation 
string is displayed."
   (if (memq major-mode '(texinfo-mode para-mode))
       (let ((opoint (point))
            (bol (save-excursion (beginning-of-line) (point))))
@@ -851,10 +851,16 @@ For @code and @var references, the associated 
documentation string is displayed.
              ;; Show doc for any Emacs Lisp identifier references,
              ;; marked with @code{} or @var{}.
              ((save-excursion
-                (and (search-backward "@" bol t) (looking-at 
"@\\(code\\|var\\){\\([^\} \t\n\r]+\\)}")
+                (and (search-backward "@" bol t)
+                     (or (looking-at "@\\(code\\|var\\){\\([^\} \t\n\r]+\\)}")
+                         (looking-at "@\\(findex\\|vindex\\)[ ]+\\([^\} 
\t\n\r]+\\)"))
                      (>= (match-end 2) opoint)))
-              (hact 'link-to-elisp-doc
-                    (intern (ibut:label-set (match-string 2) (match-beginning 
2) (match-end 2)))))
+              (let ((type-str (match-string 1))
+                    (symbol (intern-soft (ibut:label-set (match-string 2) 
(match-beginning 2) (match-end 2)))))
+                (when (and symbol (pcase type-str
+                                    ((or "code" "findex") (fboundp symbol))
+                                    ((or "var" "vindex") (boundp symbol))))
+                  (hact 'link-to-elisp-doc symbol))))
              ;; If at an @node and point is within a node name reference
              ;; other than the current node, display it.
              ((save-excursion
diff --git a/hmouse-drv.el b/hmouse-drv.el
index 49b29d2..c3f2f65 100644
--- a/hmouse-drv.el
+++ b/hmouse-drv.el
@@ -28,6 +28,14 @@
 ;;; Public variables
 ;;; ************************************************************************
 
+(defvar hmouse-verify-release-window-flag t
+  "When non-nil under the macOS window system, verifies the application of 
top-most window.
+Forces a window system check at a screen position that the top-most
+window there is an Emacs frame or treats the location as outside Emacs,
+even though an Emacs frame may be below the top-most window.
+
+See function `hmouse-window-at-absolute-pixel-position' for more details.")
+
 (defvar action-key-depressed-flag nil "t while Action Key is depressed.")
 (defvar assist-key-depressed-flag nil "t while Assist Key is depressed.")
 (defvar action-key-depress-args nil
@@ -51,6 +59,11 @@ This is set to nil when the depress is on an inactive 
minibuffer.")
 (defvar assist-key-release-window nil
   "The last window in which the Assist Key was released or nil.")
 
+(defvar action-key-depress-position nil
+  "The last screen position at which the Action Key was depressed or nil.")
+(defvar assist-key-depress-position nil
+  "The last screen position at which the Assist Key was depressed or nil.")
+
 (defvar action-key-depress-prev-point nil
   "Marker at point prior to last Action Key depress.
 Note that this may be a buffer different than where the depress occurs.")
@@ -114,6 +127,7 @@ This permits the Smart Keys to behave as paste keys.")
        action-key-depress-args (hmouse-set-point args)
        action-key-depress-window (or (hmouse-depress-inactive-minibuffer-p 
args)
                                      (selected-window))
+       action-key-depress-position (mouse-absolute-pixel-position)
        action-key-release-args nil
        action-key-release-window nil
        action-key-release-prev-point nil)
@@ -130,6 +144,7 @@ This permits the Smart Keys to behave as paste keys.")
        assist-key-depress-args (hmouse-set-point args)
        assist-key-depress-window (or (hmouse-depress-inactive-minibuffer-p 
args)
                                      (selected-window))
+       assist-key-depress-position (mouse-absolute-pixel-position)
        assist-key-release-args nil
        assist-key-release-window nil
        assist-key-release-prev-point nil)
@@ -206,7 +221,7 @@ Any ARGS will be passed to `hmouse-function'."
 (defun action-key ()
   "Use one key to perform functions that vary by context.
 If no matching context is found, the default function set with
-the `action-key-default-function' variable is run.  Returns t
+the `action-key-default-function' variable is run.  Return t
 unless the `action-key-default-function' variable is not bound to
 a valid function."
   (interactive)
@@ -234,7 +249,7 @@ a valid function."
 (defun assist-key ()
   "Use one key to perform functions that vary by context.
 If no matching context is found, the default function set with
-the `assist-key-default-function' variable is run.  Returns
+the `assist-key-default-function' variable is run.  Return
 non-nil unless `assist-key-default-function' variable is not
 bound to a valid function."
   (interactive)
@@ -260,7 +275,7 @@ bound to a valid function."
        t)))
 
 (defun hkey-either (arg)
-  "Executes `action-key' or with non-nil ARG executes `assist-key'."
+  "Execute `action-key' or with non-nil ARG execute `assist-key'."
   (interactive "P")
   (if arg (assist-key) (action-key)))
 
@@ -285,7 +300,7 @@ bound to a valid function."
 (defun hkey-execute (assist-flag)
   "Evaluate Action Key form (or Assist Key form with ASSIST-FLAG non-nil) for 
first non-nil predicate from `hkey-alist'.
 Non-nil ASSIST-FLAG means evaluate second form, otherwise evaluate first form.
-Returns non-nil iff a non-nil predicate is found."
+Return non-nil iff a non-nil predicate is found."
   ;; Keep in mind that hkey-alist may be set to hmouse-alist here, with 
additional predicates.
   (let ((hkey-forms hkey-alist)
        (pred-value) (hkey-action) hkey-form pred)
@@ -303,10 +318,10 @@ Returns non-nil iff a non-nil predicate is found."
 (defun hkey-help (&optional assist-flag)
   "Display help for the Action Key command in current context.
 With optional ASSIST-FLAG non-nil, display help for the Assist Key command.
-Returns non-nil iff associated help documentation is found."
+Return non-nil iff associated help documentation is found."
   (interactive "P")
   (let ((hkey-forms hkey-alist)
-       (hkey-form) (pred-value) (call) (cmd-sym) (doc))
+       hkey-form pred-value call calls cmd-sym doc)
     (while (and (null pred-value) (setq hkey-form (car hkey-forms)))
       (or (setq pred-value (eval (car hkey-form)))
          (setq hkey-forms (cdr hkey-forms))))
@@ -314,13 +329,20 @@ Returns non-nil iff associated help documentation is 
found."
        (setq call (if assist-flag (cdr (cdr hkey-form))
                     (car (cdr hkey-form)))
              cmd-sym (car call))
-      (setq cmd-sym
-           (if assist-flag assist-key-default-function 
action-key-default-function)
+      (setq cmd-sym (if assist-flag assist-key-default-function 
action-key-default-function)
            call cmd-sym))
+    (if (and (consp call) (eq (car call) 'call-interactively))
+       (if (consp (cadr call))
+           (setq cmd-sym (if (memq (caadr call) '(function quote))
+                             (cadadr call) 
+                           (caadr call)))))
+    (setq calls (if (and (consp call) (eq (car call) 'or))
+                   (mapcar #'car (cdr call))
+                 (list cmd-sym)))
+
     (setq hkey-help-msg
          (if (and cmd-sym (symbolp cmd-sym))
              (progn
-               (setq doc (documentation cmd-sym))
                (let* ((condition (car hkey-form))
                       (temp-buffer-show-hook
                         (lambda (buf)
@@ -351,15 +373,26 @@ Returns non-nil iff associated help documentation is 
found."
                      (or condition
                          "there is no matching context"))
                    (terpri)
-                   (princ "CALLS ") (princ call)
-                   (if doc (progn (princ " WHICH:") (terpri) (terpri)
-                                  (princ doc)))
-                   (if (memq cmd-sym '(hui:hbut-act hui:hbut-help))
-                       (progn
-                         (princ (format "\n\nBUTTON SPECIFICS:\n\n%s\n"
-                                        (actype:doc 'hbut:current t)))
-                         (hattr:report
-                           (nthcdr 2 (hattr:list 'hbut:current)))))
+
+                   (mapcar (lambda (c)
+                             (if (> (length calls) 1)
+                                 ;; Is an 'or' set of calls
+                                 (princ "'OR' "))
+                             (princ "CALLS ") (princ (list c))
+                             (when (setq doc (documentation c))
+                               (princ " WHICH")
+                               (princ (if (string-match 
"\\`[a-zA-Z]*[a-rt-zA-RT-Z]+s[ [:punct:]]" doc)
+                                          ":" " WILL:"))
+                               (terpri) (terpri)
+                               (princ (replace-regexp-in-string "^" "  " doc))
+                               (terpri) (terpri)))
+                           calls)
+
+                   (when (memq cmd-sym '(hui:hbut-act hui:hbut-help))
+                     (princ (format "BUTTON SPECIFICS:\n\n%s\n"
+                                    (actype:doc 'hbut:current t)))
+                     (hattr:report
+                      (nthcdr 2 (hattr:list 'hbut:current))))
                    (terpri)
                    ))
                "")
@@ -369,7 +402,7 @@ Returns non-nil iff associated help documentation is found."
 
 (defun hkey-assist-help ()
   "Display doc associated with Assist Key command in current context.
-Returns non-nil iff associated documentation is found."
+Return non-nil iff associated documentation is found."
   (interactive)
   (hkey-help 'assist))
 
@@ -380,8 +413,8 @@ Returns non-nil iff associated documentation is found."
 
 ;;;###autoload
 (defun hkey-help-hide (&optional kill window)
-  "Optionally KILLs current buffer (default is bury) and quits WINDOW.
-Restores frame to configuration prior to help buffer display.
+  "Optionally KILL current buffer (default is bury) and quit WINDOW.
+Restore frame to configuration prior to help buffer display.
 Point must be in a help buffer.  See `hkey-quit-window' for additional
 details."
   (interactive "P")
@@ -405,9 +438,9 @@ details."
 
 ;;;###autoload
 (defun hkey-help-show (&optional buffer current-window)
-  "Saves prior window configuration if BUFFER displays help.  Displays BUFFER.
+  "Save prior window configuration if BUFFER displays help.  Display BUFFER.
 
-Optional second arg CURRENT-WINDOW non-nil forces display of buffer within
+With optional second arg CURRENT-WINDOW non-nil, force display of buffer within
 the current window.  By default, it is displayed according to the setting of
 `hpath:display-where'."
   (if (bufferp buffer) (setq buffer (buffer-name buffer)))
@@ -448,10 +481,10 @@ the current window.  By default, it is displayed 
according to the setting of
        (select-window (get-buffer-window completion-reference-buffer t)))))
 
 (defun hkey-mouse-help (assist-flag args)
-  "If a Smart Key help flag is set and the other Smart Key is not down, shows 
help.
+  "If a Smart Key help flag is set and the other Smart Key is not down, show 
help.
 Takes two args:  ASSIST-FLAG should be non-nil iff command applies to the 
Assist Key.
 ARGS is a list of arguments passed to `hmouse-function'.
-Returns t if help is displayed, nil otherwise."
+Return t if help is displayed, nil otherwise."
   (let ((help-shown)
        (other-key-released (not (if assist-flag
                                     action-key-depressed-flag
@@ -473,7 +506,7 @@ Returns t if help is displayed, nil otherwise."
        t))))
 
 (defun hkey-operate (&optional arg)
-  "Uses the keyboard to emulate Smart Mouse Key drag actions.
+  "Use the keyboard to emulate Smart Mouse Key drag actions.
 Each invocation alternates between starting a drag and ending it.
 Optional prefix ARG non-nil means emulate Assist Key rather than the
 Action Key.
@@ -501,8 +534,8 @@ Only works when running under a window system, not from a 
dumb terminal."
       )))
 
 (defun hkey-summarize (&optional current-window)
-  "Displays smart key operation summary in help buffer.
-Optional arg CURRENT-WINDOW non-nil forces display of buffer within
+  "Display smart key operation summary in help buffer.
+With optional arg CURRENT-WINDOW non-nil, force display of buffer within
 the current window.  By default, it is displayed in another window."
   (interactive)
   (let* ((doc-file (hypb:hkey-help-file))
@@ -542,40 +575,198 @@ With optional ARG, override them iff ARG is positive."
         (not (minibuffer-window-active-p window))
         window)))
 
-(defun hmouse-key-release-window-emacs (pos)
-  "Returns window of current mouse position POS if in a window, else nil.
-POS must be the result of calling (mouse-position)."
-  (ignore-errors (window-at (cadr pos) (cddr pos) (car pos))))
+;; Based on code from subr.el.
+(defun hmouse-vertical-line-spacing (frame)
+  "Return any extra vertical spacing in pixels between text lines or 0 if 
none."
+  (let ((spacing (when (display-graphic-p frame)
+                   (or (with-current-buffer (window-buffer 
(frame-selected-window frame))
+                         line-spacing)
+                      (frame-parameter frame 'line-spacing)))))
+    (cond ((floatp spacing)
+          (setq spacing (truncate (* spacing (frame-char-height frame)))))
+         ((null spacing)
+          (setq spacing 0)))
+    spacing))
+
+(defun hmouse-window-at-absolute-pixel-position (&optional position 
release-flag)
+  "Return the top-most Emacs window at optional POSITION ((x . y) in absolute 
pixels) or mouse position.
+If POSITION is not in a window, return nil.  Considers all windows on
+the same display as the selected frame.
+
+If optional RELEASE-FLAG is non-nil, this is part of a Smart Key
+release computation, so optimize window selection based on the depress
+window already computed.
+
+If the selected frame is a graphical macOS window and
+`hmouse-verity-release-window-flag' is non-nil, then return the
+top-most Emacs window only if it is the top-most application window at
+the position (not below another application's window)."
+  (interactive)
+  (setq position (or position (mouse-absolute-pixel-position)))
+  ;; Proper top-to-bottom listing of frames is available only in Emacs
+  ;; 26 and above.  For prior versions, the ordering of the frames
+  ;; returned is not guaranteed, so the frame whose window is returned
+  ;; may not be the uppermost.
+  (let* ((top-to-bottom-frames (if (fboundp 'frame-list-z-order)
+                                  (frame-list-z-order)
+                                (frame-list)))
+        (pos-x (car position))
+        (pos-y (cdr position))
+        edges left top right bottom
+        frame
+        in-frame
+        window)
+    ;; First find top-most frame containing position.
+    (while (and (not in-frame) top-to-bottom-frames)
+      (setq frame (car top-to-bottom-frames)
+           top-to-bottom-frames (cdr top-to-bottom-frames))
+      ;; Check that in-frame is valid with frame-live-p since under macOS
+      ;; when position is outside a frame, in-frame could be invalid and
+      ;; frame-visible-p would trigger an error in that case.
+      (when (and (frame-live-p frame) (frame-visible-p frame))
+       (setq edges (frame-edges frame)
+             left   (nth 0 edges)
+             top    (nth 1 edges)
+             right  (nth 2 edges)
+             bottom (nth 3 edges))
+       (when (and (>= pos-x left) (<= pos-x right)
+                  (>= pos-y top)  (<= pos-y bottom))
+         (setq in-frame frame))))
+    ;; If in-frame is found, find which of its windows contains
+    ;; position and return that.  The window-at call below requires
+    ;; character coordinates relative to in-frame, so compute them.
+    (when in-frame
+      (let ((depress-position (and release-flag (if assist-flag
+                                                   assist-key-depress-position
+                                                 action-key-depress-position)))
+           (depress-window  (and release-flag (if assist-flag
+                                                  assist-key-depress-window
+                                                action-key-depress-window))))
+       (if (and release-flag depress-window (equal position depress-position))
+           ;; This was a click, so we know that the frame of the click
+           ;; is topmost on screen or the mouse events would not have
+           ;; been routed to Emacs.  Reuse saved window of depress rather
+           ;; then running possibly expensive computation to find the
+           ;; topmost application window.
+           (setq window depress-window)
+         (let ((char-x (/ (- pos-x left) (frame-char-width in-frame)))
+               (line-y (/ (- pos-y top) (+ (frame-char-height in-frame)
+                                           (hmouse-vertical-line-spacing 
in-frame)))))
+           (setq window (window-at char-x line-y in-frame)))
+         ;;
+         ;; Even if in-frame is found, under click-to-focus external window
+         ;; managers, Emacs may have received the drag release event when
+         ;; in-frame was covered by an external application's window.
+         ;; Emacs presently has no way to handle this.  However, for the
+         ;; macOS window system only, Hyperbole has a Python script, topwin, 
which
+         ;; computes the application of the topmost window at the point of 
release.
+         ;; If that is Emacs, then we have the right window and nothing need be
+         ;; done; otherwise, set window to nil and return.
+         ;;
+         (when (and hmouse-verify-release-window-flag
+                    window (eq (window-system) 'ns))
+           (let ((topwin (executable-find "topwin"))
+                 (case-fold-search t)
+                 topmost-app)
+             (when (and topwin (file-executable-p topwin))
+               (setq topmost-app (shell-command-to-string
+                                  (format "topwin %d %d" pos-x pos-y)))
+               (cond ((string-match "emacs" topmost-app)) ; In an Emacs frame, 
do nothing.
+                     ((or (equal topmost-app "")
+                          ;; Any non-Emacs app window
+                          (string-match "\\`\\[" topmost-app))
+                      ;; Outside of any Emacs frame
+                      (setq window nil))
+                     (t                ; topwin error message
+                      ;; Setup of the topwin script is somewhat complicated,
+                      ;; so don't trigger an error just because of it.  But
+                      ;; display a message so the user knows something happened
+                      ;; when topwin encounters an error.
+                      (message "(Hyperbole): topwin Python script error: %s" 
topmost-app)))))))))
+
+    (when (called-interactively-p 'interactive)
+      (message "%s at absolute pixel position %s"
+              (or window "No Emacs window") position))
+    window))
+
+(defun hmouse-window-coordinates (&optional event)
+  "Return a list (window (x-chars . y-chars)) for optional EVENT.
+Always ignores EVENT coordinates and uses current mouse position.
+The area of the EVENT is utilized. If EVENT is not given and the
+free variable `assist-flag' is non-nil, EVENT is set to
+`assist-key-release-args', otherwise, `action-key-release-args'.
+
+The coordinates x-chars and y-chars are relative character
+coordinates within the window.  If POSITION is not in a live
+window, return nil.  Considers all windows on the selected frame's display."
+  (interactive)
+  (unless (eventp event)
+    (setq event (if assist-flag assist-key-release-args 
action-key-release-args)))
+  (let* ((position (mouse-absolute-pixel-position))
+        (pos-x (car position))
+        (pos-y (cdr position))
+        (window (hmouse-window-at-absolute-pixel-position position t))
+        (edges (when (window-live-p window) (window-edges window t t t)))
+        left top right bottom
+        frame)
+    (when edges
+      (setq left   (nth 0 edges)
+           top    (nth 1 edges)
+           right  (nth 2 edges)
+           bottom (nth 3 edges))
+      (when (or (and event (eq (posn-area (event-start event)) 'mode-line))
+               (and (>= pos-x left) (<= pos-x right)
+                    (>= pos-y top)  (<= pos-y bottom)))
+       ;; If position is in a live window, compute position's character
+       ;; coordinates within the window and return the window with these
+       ;; coordinates.
+       (setq frame (window-frame window)
+             pos-x (round (/ (- pos-x left) (frame-char-width frame)))
+             pos-y (round (/ (- pos-y top)  (+ (frame-char-height frame)
+                                               (hmouse-vertical-line-spacing 
frame)))))))
+    (when (called-interactively-p 'interactive)
+      (message "%s at %s coordinates (%s . %s)"
+              (if edges window "No live Emacs window")
+              (if frame "character" "absolute pixel")
+              pos-x pos-y))
+    (when edges (list window (cons pos-x pos-y)))))
+
+(defun hmouse-key-release-window ()
+  "Return the window of the current mouse position if any, else nil."
+  (ignore-errors (hmouse-window-at-absolute-pixel-position nil t)))
 
 (defun hmouse-key-release-args-emacs (event)
+  "For GNU Emacs, return a possibly modified version of EVENT as a list.
+For mouse drags and double and triple clicks, remove any depress location,
+compute the actual release location and include that."
   (if (integerp event)
       (list event)
     (let ((ev-type-str (and (listp event) (symbol-name (car event)))))
-      (cond ((or (and ev-type-str
-                     (string-match "\\(double\\|triple\\)-mouse" ev-type-str))
-                (not (= (length event) 3)))
-            event)
-           ((and ev-type-str (string-match "drag-mouse" ev-type-str)
-                 ;; end of drag event; if drag crossed frames, the location
-                 ;; will contain a frame and some relative coordinates;
-                 ;; change to window of release and window's character 
coordinates
-                 ;; if within a window
-                 (let ((pos (event-end event))
-                       mouse-pos coords window)
-                   (when (and (framep (posn-window pos))
-                              (setq mouse-pos (mouse-position)
-                                    coords (cdr mouse-pos)
-                                    window (hmouse-key-release-window-emacs 
mouse-pos)))
-                     (setcar pos window)
-                     (setcar (nthcdr 2 pos) coords)))
-                 ;; always fall through cond
-                 nil))
-           ;; Remove depress coordinates and send only release coordinates.
-           (t (list (car event) (nth 2 event)))))))
-
+      (if (or (and ev-type-str
+                  (string-match "\\(double\\|triple\\)-mouse" ev-type-str))
+             (not (= (length event) 3)))
+         event
+       (let ((pos (event-end event))
+             coords window-and-char-coords)
+         (when (and ev-type-str (string-match "drag-mouse" ev-type-str)
+                    ;; end of drag event; If drag crossed frames, the location
+                    ;; will contain the frame of the depress point and
+                    ;; some relative coordinates; change these to the window of
+                    ;; release and window's character coordinates if within a 
window
+                    ;; and to nil if outside of Emacs (as best we can tell).
+                    (framep (posn-window pos)))
+           (setq window-and-char-coords (hmouse-window-coordinates event)
+                 window (car window-and-char-coords)
+                 coords (cadr window-and-char-coords))
+           ;; Modify the values in the event-end structure even if no
+           ;; valid window was found.
+           (setcar pos window)
+           (setcar (nthcdr 2 pos) coords)))
+       ;; Remove depress coordinates and send only original release 
coordinates.
+       (list (car event) (nth 2 event))))))
 
 (defun hmouse-save-region (&optional frame)
-  "Saves any active region within the current buffer.
+  "Save any active region within the current buffer.
 Under InfoDock and XEmacs, `zmacs-region' must be t; under GNU Emacs,
 `transient-mark-mode' must be t or the function does nothing."
   (if (cond
@@ -605,8 +796,8 @@ Under InfoDock and XEmacs, `zmacs-region' must be t; under 
GNU Emacs,
 ;; assume this is no longer a problem in 2016 but have this note here
 ;; in case it is.
 (defun hmouse-set-point (args)
-  "Sets point to Smart Key press/release location given by ARGS.
-Returns argument list including x and y frame coordinates in characters and
+  "Set point to Smart Key press/release location given by ARGS.
+Return argument list including x and y frame coordinates in characters and
 lines or if ARGS is null and there is no graphical window system,
 return current point as a marker."
   (and (car args) (listp (car args)) (setq args (car args)))
@@ -621,10 +812,10 @@ return current point as a marker."
                            (+ (nth 1 args) (nth 0 (window-edges win)))
                            (+ (nth 2 args) (nth 1 (window-edges win))))))
                   (t args)))
-    (point-marker)))
+    (posn-at-point)))
 
 (defun hmouse-set-point-at (set-point-arg-list)
-  "Sets point to cursor position using SET-POINT-ARG-LIST and returns t.
+  "Set point to cursor position using SET-POINT-ARG-LIST and returns t.
 If 'hmouse-set-point-command' is not bound to a function, this does nothing
 and returns nil."
   (if (fboundp hmouse-set-point-command)
@@ -642,7 +833,7 @@ line to bottom of window.  Repeated presses then scroll up 
or down a
 windowful.  Nil value instead ignores current line and always scrolls up or
 down a windowful."))
 
-;; The smart keys scroll buffers when pressed at the ends of lines.
+;; The smart keys scroll buffers when pressed at the end of lines.
 ;; These next two functions do the scrolling and keep point at the end
 ;; of line to simplify repeated scrolls when using keyboard smart keys.
 ;;
@@ -652,39 +843,40 @@ down a windowful."))
 ;; t is returned whenever scrolling is performed.
 
 (defun hmouse-function (func assist-flag set-point-arg-list)
-  "Executes FUNC for Action Key (Assist Key with ASSIST-FLAG non-nil) and sets 
point from SET-POINT-ARG-LIST.
+  "Execute FUNC for Action Key (Assist Key with ASSIST-FLAG non-nil) and set 
point from SET-POINT-ARG-LIST.
 FUNC may be nil in which case no function is called.
 SET-POINT-ARG-LIST is passed to the call of the command bound to
-`hmouse-set-point-command'.  Returns nil if `hmouse-set-point-command' variable
+`hmouse-set-point-command'.  Return nil if `hmouse-set-point-command' variable
 is not bound to a valid function."
-  (if (fboundp hmouse-set-point-command)
-      (let ((release-args (hmouse-set-point set-point-arg-list)))
-       (if assist-flag
-           (setq assist-key-release-window (selected-window)
-                 assist-key-release-args release-args
-                 assist-key-release-prev-point (point-marker))
-         (setq action-key-release-window (selected-window)
-               action-key-release-args release-args
-               action-key-release-prev-point (point-marker)))
-       (and (eq major-mode 'br-mode)
-            (setq action-mouse-key-prev-window 
-                  (if (br-in-view-window-p)
-                      (save-window-excursion
-                        (br-next-listing-window)
-                        (selected-window))
-                    (selected-window))))
-       (setq action-mouse-key-prefix-arg current-prefix-arg)
-       (when func
-         (funcall func)
-         (setq action-mouse-key-prev-window nil
-               action-mouse-key-prefix-arg nil))
-       t)))
+  (when (fboundp hmouse-set-point-command)
+    (if assist-flag
+       (setq assist-key-release-window (hmouse-key-release-window)
+             assist-key-release-prev-point (point-marker))
+      (setq action-key-release-window (hmouse-key-release-window)
+           action-key-release-prev-point (point-marker)))
+    (and (eq major-mode 'br-mode)
+        (setq action-mouse-key-prev-window 
+              (if (br-in-view-window-p)
+                  (save-window-excursion
+                    (br-next-listing-window)
+                    (selected-window))
+                (selected-window))))
+    (setq action-mouse-key-prefix-arg current-prefix-arg)
+    (let ((release-args (hmouse-set-point set-point-arg-list)))
+      (if assist-flag
+         (setq assist-key-release-args release-args)
+       (setq action-key-release-args release-args)))
+    (when func
+      (funcall func)
+      (setq action-mouse-key-prev-window nil
+           action-mouse-key-prefix-arg nil))
+    t))
 
 (defun smart-scroll-down ()
-  "Scrolls down according to value of smart-scroll-proportional.
+  "Scroll down according to value of smart-scroll-proportional.
 If smart-scroll-proportional is nil or if point is on the bottom window line,
-scrolls down (backward) a windowful.  Otherwise, tries to bring current line
-to bottom of window.  Leaves point at end of line and returns t if scrolled,
+scroll down (backward) a windowful.  Otherwise, try to bring current line
+to the bottom of the window.  Leave point at end of line and return t if 
scrolled,
 nil if not."
   (interactive)
   (let ((rtn t))
@@ -706,10 +898,10 @@ nil if not."
     rtn))
 
 (defun smart-scroll-up ()
-  "Scrolls up according to value of smart-scroll-proportional.
+  "Scroll up according to value of smart-scroll-proportional.
 If smart-scroll-proportional is nil or if point is on the top window line,
-scrolls up (forward) a windowful.  Otherwise, tries to bring current line to
-top of window.  Leaves point at end of line and returns t if scrolled, nil if
+scroll up (forward) a windowful.  Otherwise, tyr to bring current line to
+the top of the window.  Leave point at end of line and return t if scrolled, 
nil if
 not."
   (interactive)
   (let ((rtn t))
diff --git a/hmouse-key.el b/hmouse-key.el
index 158f4ef..397ebe9 100644
--- a/hmouse-key.el
+++ b/hmouse-key.el
@@ -144,10 +144,11 @@ mouse key the Paste Key instead of the Action Key."
       (error "(hmouse-toggle-bindings): `%s' is empty."
             (if hmouse-bindings-flag 'hmouse-previous-bindings 
'hmouse-bindings)))))
 
-;; Define function to reload Smart Key actions after a source code change.
+;; Define function to reload Smart Key bindings and actions after a source 
code change.
 (defun hmouse-update-smart-keys ()
   "Reloads the contexts and actions associated with the Smart Keys after any 
programmatic changes are made."
   (interactive)
+  (hkey-initialize)
   (makunbound 'hkey-alist)
   (makunbound 'hmouse-alist)
   (let ((load-prefer-newer t))
diff --git a/hui-menu.el b/hui-menu.el
index 637e22e..0d2da90 100644
--- a/hui-menu.el
+++ b/hui-menu.el
@@ -122,6 +122,10 @@ Return t if cutoff, else nil."
                        '("----" "----")))))
         rest-of-menu)))
 
+(defun hui-menu-key-binding-item (item-name command)
+  "Return a key binding menu item string built from ITEM-NAME and COMMAND."
+  (format "%-30s {%s}" item-name (key-description (car (where-is-internal 
command)))))
+
 ;; Dynamically compute submenus for Screen menu
 (defun hui-menu-screen (_ignored)
   (list
@@ -194,17 +198,19 @@ Return t if cutoff, else nil."
             hpath:find-file-urls-mode
             :style toggle
             :selected hpath:find-file-urls-mode]
-           "----"
-           ("Change-Key-Bindings"
-            ["Action-Key"              (hui:bind-key #'hkey-either) t]         
   ;; {M-RET}
-            ["Button-Rename-Key"       (hui:bind-key #'hui:ebut-rename) t]     
   ;; {C-c C-r}
-            ["Drag-Emulation-Key"      (hui:bind-key #'hkey-operate) t]        
   ;; {M-o}
-            ["Hyperbole-Menu-Key"      (hui:bind-key #'hyperbole) t]           
   ;; {C-h h}
-            ["Mark-Thing-Key"          (hui:bind-key #'hui-select-thing) t]    
   ;; {C-c C-m}
-            ["Smart-Help-Key"          (hui:bind-key #'hkey-help) t]           
   ;; {C-h A}
-            ["Windows-Control-Key"     (hui:bind-key #'hycontrol-windows) t]   
   ;; {C-C \}
-            )
            "----")
+         (list (list "Change-Key-Bindings"
+                     (vector (hui-menu-key-binding-item "Action-Key"          
'hkey-either)       '(hui:bind-key #'hkey-either)
+                             :key-sequence "M-RET"
+                             :selected t)            ;; {M-RET}
+                     (vector (hui-menu-key-binding-item "Button-Rename-Key"   
'hui:ebut-rename)   '(hui:bind-key #'hui:ebut-rename) t)        ;; {C-c C-r}
+                     (vector (hui-menu-key-binding-item "Drag-Emulation-Key"  
'hkey-operate)      '(hui:bind-key #'hkey-operate) t)           ;; {M-o}
+                     (vector (hui-menu-key-binding-item "Hyperbole-Menu-Key"  
'hyperbole)         '(hui:bind-key #'hyperbole) t)              ;; {C-h h}
+                     (vector (hui-menu-key-binding-item "Mark-Thing-Key"      
'hui-select-thing)  '(hui:bind-key #'hui-select-thing) t)       ;; {C-c C-m}
+                     (vector (hui-menu-key-binding-item "Smart-Help-Key"      
'hkey-help)         '(hui:bind-key #'hkey-help) t)              ;; {C-h A}
+                     (vector (hui-menu-key-binding-item "Windows-Control-Key" 
'hycontrol-windows) '(hui:bind-key #'hycontrol-windows) t)      ;; {C-C \}
+                     ))
+         '("----")
          (list (cons "Display-Referents-in"
                      (mapcar (lambda (sym)
                                (vector
diff --git a/hui-window.el b/hui-window.el
index 6ab475e..9cacbdc 100644
--- a/hui-window.el
+++ b/hui-window.el
@@ -4,7 +4,7 @@
 ;;
 ;; Orig-Date:    21-Sep-92
 ;;
-;; Copyright (C) 1991-2016  Free Software Foundation, Inc.
+;; Copyright (C) 1992-2017  Free Software Foundation, Inc.
 ;; See the "HY-COPY" file for license information.
 ;;
 ;; This file is part of GNU Hyperbole.
@@ -13,29 +13,41 @@
 ;;
 ;;   Must be loaded AFTER hmouse-alist has been defined in "hui-mouse.el".
 ;;
-;;   Handles drags in same window or across windows and modeline depresses.
+;;   Handles drags in same window or across windows and modeline presses.
 ;;
 ;; What drags and modeline presses do.  (Note that a `thing' is a
-;; delimited expression, such as a string, list or markup language tag
-;; pair).
-;; 
==============================================================================
+;; delimited expression, such as a string, list or markup language tag pair).
+;; 
======================================================================================================
 ;;                                              Smart Keys
-;; Context                         Action Key                 Assist Key
-;; 
==============================================================================
-;; Drag from thing start or end    Yank thing at release      Kill thing and 
yank at release
+;; Context                         Action Key                  Assist Key
+;; 
======================================================================================================
+;; Drag from thing start or end    Yank thing at release       Kill thing and 
yank at release
+;;
 ;; Drag from shared window side
-;;   or from left of scroll bar    Resize window width        <- same
-;; Modeline depress & wind release Resize window height       <- same
+;;   or from left of scroll bar    Resize window width         <- same
+;;
+;; Drag buffer/file menu item      Display buffer/file there   Swap window 
buffers
+;;   to another window
+;; Other drag between windows      Create/modify a link but    Swap window 
buffers
+;; Drag buffer/file menu item      Display buffer/file
+;;   outside of Emacs                in a new frame            Move window to 
a new frame
+;;
+;; Modeline or other window drag   Clone window to a new frame Move window to 
a new frame
+;;   outside of Emacs              
+;; Modeline drag to another frame  Clone window to other frame Move window to 
other frame  
+;; Modeline depress & wind release Resize window height        <- same
 ;; Click in modeline
-;;     Left window edge            Bury buffer                Unbury bottom 
buffer
-;;     Right window edge           Info                       Smart Key Summary
-;;     Otherwise                   Action Key Modeline Hook   Assist Key 
Modeline Hook
-;; Drag between windows            Create/modify a link but   Swap window 
buffers
-;; Drag in a window, region active Error, not allowed         Error, not 
allowed
-;; Drag horizontally in a window   Split window below         Delete window
-;; Drag vertically in a window     Split window side-by-side  Delete window
-;; Drag diagonally in a window     Save window-config         Restore 
window-config from ring
-;; Active region exists            Yank region at release     Kill region and 
yank at release
+;;     Left modeline edge          Bury buffer                 Unbury bottom 
buffer
+;;     Right modeline edge         Info                        Smart Key 
Summary
+;;     Buffer ID                   Dired on buffer's dir       Next buffer
+;;     Other blank area            Action Key modeline hook    Assist Key 
modeline hook
+;;
+;; Drag in a window, region active Error, not allowed          Error, not 
allowed
+;; Drag horizontally in a window   Split window below          Delete window
+;; Drag vertically in a window     Split window side-by-side   Delete window
+;; Drag diagonally in a window     Save window-config          Restore 
window-config from ring
+;;
+;; Active region exists            Yank region at release      Kill region and 
yank at release
 
 ;;; Code:
 ;;; ************************************************************************
@@ -43,6 +55,7 @@
 ;;; ************************************************************************
 
 (eval-when-compile (defvar assist-flag nil)) ;; Silences free variable 
compiler warnings
+(require 'hycontrol)
 ;; For momentary highlighting of buffer/file item lines.
 (require 'pulse nil t)
 
@@ -74,7 +87,34 @@ of screen control commands."
   :type 'function
   :group 'hyperbole-keys)
 
-(defcustom hmouse-pulse-flag t
+(defun hmouse-map-modes-to-form (mode-forms)
+  "Maps over a sequence of (major-mode(s) form-to-eval) lists; returns items 
with a single major-mode in the car, (major-mode form-to-eval)."
+  (apply 'nconc
+        (mapcar (lambda (modes-form)
+                  (if (sequencep (car modes-form))
+                      (mapcar (lambda (mode) (cons mode (cdr modes-form)))
+                              (car modes-form))
+                    (list modes-form)))
+                mode-forms)))
+
+(defvar hmouse-drag-item-mode-forms
+  (hmouse-map-modes-to-form
+  '((Buffer-menu-mode (Buffer-menu-buffer t))
+    (ibuffer-mode (ibuffer-current-buffer t))
+    (helm-major-mode (helm-get-selection (current-buffer)))
+    ;; Note how multiple major modes may be grouped with a single form for 
item getting.
+    ((dired-mode vc-dired-mode wdired-mode) (dired-get-filename nil t))))
+  "List of (major-mode lisp-form) lists.
+The car of an item must be a major-mode symbol.  The cadr of an item
+is a Lisp form to evaluate to get the item name at point (typically a
+buffer, file or directory name whose contents will be displayed in the
+drag release window.")
+
+
+;; !!! Disable this by default because it is rather slow and the referent
+;; pulsing is not working properly.  Wait until these issues are
+;; resolved before enabling this by default.
+(defcustom hmouse-pulse-flag nil
   "When non-nil (the default) and when display supports visual pulsing, then 
pulse lines and buffers when an Action Key drag is used to place a buffer or 
file in a window."
   :type 'boolean
   :group 'hyperbole-keys)
@@ -123,12 +163,19 @@ of screen control commands."
                 ((hmouse-yank-region) . (hmouse-kill-and-yank-region)))
                ((hmouse-drag-window-side) .
                 ((hmouse-resize-window-side) . (hmouse-resize-window-side)))
+               ;; Modeline drag between frames
+               ((and (hmouse-modeline-depress) (hmouse-drag-between-frames)) .
+                ((hmouse-clone-window-to-frame) . 
(hmouse-move-window-to-frame)))
+               ;; Modeline drag that ends outside of Emacs
+               ((and (hmouse-modeline-depress) 
(hmouse-drag-outside-all-windows)) .
+                ((hycontrol-clone-window-to-new-frame) . 
(hycontrol-window-to-new-frame)))
+               ;; Other Modeline click or drag
                ((hmouse-modeline-depress) .
                 ((action-key-modeline) . (assist-key-modeline)))
                ((hmouse-drag-between-windows) .
                 ;; Note that `hui:link-directly' uses any active
                 ;; region as the label of the button to create.
-                ((or (hmouse-drag-item-to-window) (hui:link-directly)) . 
(hmouse-swap-buffers)))
+                ((or (hmouse-drag-item-to-display) (hui:link-directly)) . 
(hmouse-swap-buffers)))
                ((hmouse-drag-region-active) .
                 ((hmouse-drag-not-allowed) . (hmouse-drag-not-allowed)))
                ((setq hkey-value (hmouse-drag-horizontally)) .
@@ -136,8 +183,13 @@ of screen control commands."
                ((hmouse-drag-vertically) .
                 ((hmouse-vertical-action-drag) . 
(hmouse-vertical-assist-drag)))
                ((setq hkey-value (hmouse-drag-diagonally)) .
-                ((hywconfig-ring-save) . (hywconfig-yank-pop
-                                          (prefix-numeric-value 
current-prefix-arg))))
+                ((call-interactively #'hywconfig-ring-save) .
+                 (call-interactively #'hywconfig-yank-pop)))
+               ;; Window drag that ends outside of Emacs
+               ((hmouse-drag-outside-all-windows) .
+                ((or (hmouse-drag-item-to-display)
+                     (hycontrol-clone-window-to-new-frame)) .
+                 (hycontrol-window-to-new-frame)))
                ;;
                ;; Now since this is not a drag and if there was an active
                ;; region prior to when the Action or Assist Key was
@@ -236,6 +288,8 @@ Delimited constructs include lists, comments, strings,
                       (end-point (smart-point-of-coords release-args)))
                   ;; Ignore this, if it is a click or if drag end point is 
within the thing to operate upon
                   (not (and (eq start-buf end-buf)
+                            start-point
+                            end-point
                             (/= start-point end-point)
                             (setq marked-thing (hui-select-delimited-thing))
                             (>= end-point (min (point) (mark)))
@@ -314,6 +368,19 @@ Signals an error if the buffer is read-only."
     (select-window (if assist-flag assist-key-release-window 
action-key-release-window))
     (hmouse-insert-region)))
 
+(defun hmouse-drag-between-frames ()
+  "Returns non-nil if last Action Key depress and release were in different 
frames.
+If free variable `assist-flag' is non-nil, uses Assist Key."
+  (if assist-flag
+      (and (window-valid-p assist-key-depress-window)
+          (window-valid-p assist-key-release-window)
+          (not (eq (window-frame assist-key-depress-window)
+                   (window-frame assist-key-release-window))))
+    (and (window-valid-p action-key-depress-window)
+        (window-valid-p action-key-release-window)
+        (not (eq (window-frame action-key-depress-window)
+                 (window-frame action-key-release-window))))))
+
 (defun hmouse-drag-between-windows ()
   "Returns non-nil if last Action Key depress and release were in different 
windows.
 If free variable `assist-flag' is non-nil, uses Assist Key."
@@ -324,11 +391,34 @@ If free variable `assist-flag' is non-nil, uses Assist 
Key."
     (and action-key-depress-window action-key-release-window
         (not (eq action-key-depress-window action-key-release-window)))))
 
-(defun hmouse-drag-item-to-window ()
-  "Depress on a buffer name in Buffer-menu or ibuffer mode and release in 
another window in which to display the buffer.
-Return t unless source is not a buffer menu mode, then nil."
-  (let ((mode (cdr (assq 'major-mode (buffer-local-variables (window-buffer 
action-key-depress-window))))))
-    (when (memq mode '(Buffer-menu-mode ibuffer-mode helm-major-mode))
+(defun hmouse-drag-same-window ()
+  "Returns non-nil if last Action Key depress and release were in the same 
window.
+If free variable `assist-flag' is non-nil, uses Assist Key."
+  (if assist-flag
+      (and assist-key-depress-window assist-key-release-window
+          (eq assist-key-depress-window assist-key-release-window))
+    (and action-key-depress-window action-key-release-window
+        (eq action-key-depress-window action-key-release-window))))
+
+(defun hmouse-drag-outside-all-windows ()
+  "Returns non-nil if last Action Key release was outside of an Emacs window.
+If free variable `assist-flag' is non-nil, uses Assist Key."
+  (null (if assist-flag
+           assist-key-release-window
+         action-key-release-window)))
+
+(defun hmouse-drag-item-to-display ()
+  "Depress on a buffer name in Buffer-menu/ibuffer-mode or on a file/directory 
in dired and release in another window in which to display the item.
+If depress is on an item and release is outside Emacs, the item is displayed 
in a new frame.
+Return t unless source buffer is not one of these modes or point is not on an 
item, then nil.
+
+See `hmouse-drag-item-mode-forms' for how to allow for draggable items from 
other modes."
+  (let* ((buf (and action-key-depress-window (window-buffer 
action-key-depress-window)))
+        (mode (and buf (cdr (assq 'major-mode (buffer-local-variables buf))))))
+    (when (and buf (with-current-buffer buf
+                    ;; Point must be on an item, not after one
+                    (not (looking-at "\\s-*$")))
+              (memq mode (mapcar #'car hmouse-drag-item-mode-forms)))
       (hmouse-item-to-window)
       t)))
 
@@ -337,85 +427,88 @@ Return t unless source is not a buffer menu mode, then 
nil."
 If free variable `assist-flag' is non-nil, uses Assist Key.
 Value returned is nil if not a diagonal drag, or one of the following symbols
 depending on the direction of the drag: southeast, southwest, northwest, 
northeast."
-  (let ((last-depress-x) (last-release-x)
-       (last-depress-y) (last-release-y))
-    (if assist-flag
-       (setq last-depress-x (hmouse-x-coord assist-key-depress-args)
-             last-release-x (hmouse-x-coord assist-key-release-args)
-             last-depress-y (hmouse-y-coord assist-key-depress-args)
-             last-release-y (hmouse-y-coord assist-key-release-args))
-      (setq last-depress-x (hmouse-x-coord action-key-depress-args)
-           last-release-x (hmouse-x-coord action-key-release-args)
-           last-depress-y (hmouse-y-coord action-key-depress-args)
-           last-release-y (hmouse-y-coord action-key-release-args)))
-    (and last-depress-x last-release-x last-depress-y last-release-y
-        (>= (- (max last-depress-x last-release-x)
-               (min last-depress-x last-release-x))
-            hmouse-x-diagonal-sensitivity)
-        (>= (- (max last-depress-y last-release-y)
-               (min last-depress-y last-release-y))
-            hmouse-y-diagonal-sensitivity)
-        (cond
-          ((< last-depress-x last-release-x)
-           (if (< last-depress-y last-release-y)
-               'southeast 'northeast))
-          (t (if (< last-depress-y last-release-y)
-                 'southwest 'northwest))))))
+  (when (hmouse-drag-same-window)
+    (let ((last-depress-x) (last-release-x)
+         (last-depress-y) (last-release-y))
+      (if assist-flag
+         (setq last-depress-x (hmouse-x-coord assist-key-depress-args)
+               last-release-x (hmouse-x-coord assist-key-release-args)
+               last-depress-y (hmouse-y-coord assist-key-depress-args)
+               last-release-y (hmouse-y-coord assist-key-release-args))
+       (setq last-depress-x (hmouse-x-coord action-key-depress-args)
+             last-release-x (hmouse-x-coord action-key-release-args)
+             last-depress-y (hmouse-y-coord action-key-depress-args)
+             last-release-y (hmouse-y-coord action-key-release-args)))
+      (and last-depress-x last-release-x last-depress-y last-release-y
+          (>= (- (max last-depress-x last-release-x)
+                 (min last-depress-x last-release-x))
+              hmouse-x-diagonal-sensitivity)
+          (>= (- (max last-depress-y last-release-y)
+                 (min last-depress-y last-release-y))
+              hmouse-y-diagonal-sensitivity)
+          (cond
+           ((< last-depress-x last-release-x)
+            (if (< last-depress-y last-release-y)
+                'southeast 'northeast))
+           (t (if (< last-depress-y last-release-y)
+                  'southwest 'northwest)))))))
 
 (defun hmouse-drag-horizontally ()
   "Returns non-nil iff last Action Key use was a horizontal drag within a 
single window.
 If free variable `assist-flag' is non-nil, uses Assist Key.
 Value returned is nil if not a horizontal drag, 'left if drag moved left or
 'right otherwise."
-  (let ((last-depress-x) (last-release-x)
-       (last-depress-y) (last-release-y))
-    (if assist-flag
-       (setq last-depress-x (hmouse-x-coord assist-key-depress-args)
-             last-release-x (hmouse-x-coord assist-key-release-args)
-             last-depress-y (hmouse-y-coord assist-key-depress-args)
-             last-release-y (hmouse-y-coord assist-key-release-args))
-      (setq last-depress-x (hmouse-x-coord action-key-depress-args)
-           last-release-x (hmouse-x-coord action-key-release-args)
-           last-depress-y (hmouse-y-coord action-key-depress-args)
-           last-release-y (hmouse-y-coord action-key-release-args)))
-    (and last-depress-x last-release-x last-depress-y last-release-y
-        (>= (- (max last-depress-x last-release-x)
-               (min last-depress-x last-release-x))
-            hmouse-x-drag-sensitivity)
-        ;; Don't want to register vertical drags here, so ensure any
-        ;; vertical movement was less than the vertical drag sensitivity.
-        (< (- (max last-depress-y last-release-y)
-              (min last-depress-y last-release-y))
-           hmouse-y-drag-sensitivity)
-        (if (< last-depress-x last-release-x) 'right 'left))))
+  (when (hmouse-drag-same-window)
+    (let ((last-depress-x) (last-release-x)
+         (last-depress-y) (last-release-y))
+      (if assist-flag
+         (setq last-depress-x (hmouse-x-coord assist-key-depress-args)
+               last-release-x (hmouse-x-coord assist-key-release-args)
+               last-depress-y (hmouse-y-coord assist-key-depress-args)
+               last-release-y (hmouse-y-coord assist-key-release-args))
+       (setq last-depress-x (hmouse-x-coord action-key-depress-args)
+             last-release-x (hmouse-x-coord action-key-release-args)
+             last-depress-y (hmouse-y-coord action-key-depress-args)
+             last-release-y (hmouse-y-coord action-key-release-args)))
+      (and last-depress-x last-release-x last-depress-y last-release-y
+          (>= (- (max last-depress-x last-release-x)
+                 (min last-depress-x last-release-x))
+              hmouse-x-drag-sensitivity)
+          ;; Don't want to register vertical drags here, so ensure any
+          ;; vertical movement was less than the vertical drag sensitivity.
+          (< (- (max last-depress-y last-release-y)
+                (min last-depress-y last-release-y))
+             hmouse-y-drag-sensitivity)
+          (if (< last-depress-x last-release-x) 'right 'left)))))
 
 (defun hmouse-drag-vertically ()
   "Returns non-nil iff last Action Key use was a vertical drag within a single 
window.
 If free variable `assist-flag' is non-nil, uses Assist Key.
 Value returned is nil if not a vertical line drag, 'up if drag moved up or
 'down otherwise."
-  (let ((last-depress-x) (last-release-x)
-       (last-depress-y) (last-release-y))
-    (if assist-flag
-       (setq last-depress-x (hmouse-x-coord assist-key-depress-args)
-             last-release-x (hmouse-x-coord assist-key-release-args)
-             last-depress-y (hmouse-y-coord assist-key-depress-args)
-             last-release-y (hmouse-y-coord assist-key-release-args))
-      (setq last-depress-x (hmouse-x-coord action-key-depress-args)
-           last-release-x (hmouse-x-coord action-key-release-args)
-           last-depress-y (hmouse-y-coord action-key-depress-args)
-           last-release-y (hmouse-y-coord action-key-release-args)))
-    (and last-depress-x last-release-x last-depress-y last-release-y
-        (>= (- (max last-depress-y last-release-y)
-               (min last-depress-y last-release-y))
-            hmouse-y-drag-sensitivity)
-        ;; Don't want to register horizontal drags here, so ensure any
-        ;; horizontal movement was less than or equal to the horizontal drag
-        ;; sensitivity.
-        (<= (- (max last-depress-x last-release-x)
-               (min last-depress-x last-release-x))
-            hmouse-x-drag-sensitivity)
-        (if (< last-depress-y last-release-y) 'down 'up))))
+  (when (hmouse-drag-same-window)
+    (let ((last-depress-x) (last-release-x)
+         (last-depress-y) (last-release-y))
+      (if assist-flag
+         (setq last-depress-x (hmouse-x-coord assist-key-depress-args)
+               last-release-x (hmouse-x-coord assist-key-release-args)
+               last-depress-y (hmouse-y-coord assist-key-depress-args)
+               last-release-y (hmouse-y-coord assist-key-release-args))
+       (setq last-depress-x (hmouse-x-coord action-key-depress-args)
+             last-release-x (hmouse-x-coord action-key-release-args)
+             last-depress-y (hmouse-y-coord action-key-depress-args)
+             last-release-y (hmouse-y-coord action-key-release-args)))
+      (and last-depress-x last-release-x last-depress-y last-release-y
+          (>= (- (max last-depress-y last-release-y)
+                 (min last-depress-y last-release-y))
+              hmouse-y-drag-sensitivity)
+          ;; Don't want to register horizontal drags here, so ensure any
+          ;; horizontal movement was less than or equal to the horizontal drag
+          ;; sensitivity.
+          (<= (- (max last-depress-x last-release-x)
+                 (min last-depress-x last-release-x))
+              hmouse-x-drag-sensitivity)
+          (if (< last-depress-y last-release-y) 'down 'up)))))
 
 (defun hmouse-drag-window-side ()
   "Returns non-nil if Action Key was dragged from a window side divider.
@@ -464,7 +557,7 @@ Beeps and prints message if the window cannot be split 
further."
           (message "(hmouse-vertical-assist-drag): A single window cannot be 
deleted."))))
 
 (defun hmouse-horizontal-action-drag ()
-  "Handles an Action Key vertical drag within a window: adds a window below 
this one.
+  "Handles an Action Key horizontal drag within a window: adds a window below 
this one.
 Beeps and prints message if the window cannot be split further."
   (interactive)
   (condition-case ()
@@ -607,10 +700,16 @@ Ignores minibuffer window."
     (sit-for 0.3)))
 
 (defun hmouse-item-to-window ()
-  "Displays buffer or file menu item at Action Key depress in window of Action 
Key release.
-If depress is on the top fixed header line, moves the menu buffer to the 
release window."
+  "Displays buffer or file menu item at Action Key depress at the location of 
Action Key release.
+Release location may be an Emacs window or outside of Emacs in which case a 
new frame with a
+single window is created to display the item.
+
+If depress is on the top fixed header line or to the right of any item, this 
moves the menu
+buffer itself to the release location."
   (let* ((w1 action-key-depress-window)
-        (w2 action-key-release-window)
+        ;; Release may be outside of an Emacs window in which case,
+        ;; create a new frame and window.
+        (w2 (or action-key-release-window (frame-selected-window 
(hycontrol-make-frame))))
         (buf-name)
         (w1-ref))
     (when (and w1 w2)
@@ -623,26 +722,19 @@ If depress is on the top fixed header line, moves the 
menu buffer to the release
                            (hmouse-pulse-buffer)
                            (bury-buffer))
                   ;; Otherwise, move the current menu item to the release 
window.
-                  (setq w1-ref (cond ((eq major-mode 'Buffer-menu-mode)
-                                      (Buffer-menu-buffer t))
-                                     ((eq major-mode 'ibuffer-mode)
-                                      (ibuffer-current-buffer t))
-                                     ((eq major-mode 'helm-major-mode)
-                                      ;; Returns item string
-                                      (helm-get-selection (current-buffer)))
-                                     (t nil)))
+                  (setq w1-ref (eval (cadr (assq major-mode 
hmouse-drag-item-mode-forms))))
                   (when w1-ref (hmouse-pulse-line))))
        (select-window w2)))
     (unwind-protect
        (cond ((not w1-ref)
-              (error "(hmouse-item-to-window): Last depress was not within a 
window."))
+              (error "(hmouse-item-to-window): Action Mouse Key item drag must 
start in a live window"))
              ((buffer-live-p w1-ref)
               (set-window-buffer w2 w1-ref)
               (hmouse-pulse-buffer))
              ((and (stringp w1-ref) (file-readable-p w1-ref))
               (set-window-buffer w2 (find-file-noselect w1-ref))
               (hmouse-pulse-buffer))
-             (t (error "(hmouse-item-to-window): Cannot find or read `%s'." 
w1-ref)))
+             (t (error "(hmouse-item-to-window): Cannot find or read `%s'" 
w1-ref)))
       ;; If helm is active, end in the minibuffer window.
       (if (smart-helm-alive-p)
          (smart-helm-to-minibuffer)))))
@@ -650,21 +742,26 @@ If depress is on the top fixed header line, moves the 
menu buffer to the release
 (defun action-key-modeline ()
   "Handles Action Key depresses on a window mode line.
 If the Action Key is:
- (1) clicked on left edge of a window's modeline,
-     window's buffer is buried (placed at bottom of buffer list);
+ (1) clicked on the first blank character of a window's modeline,
+     the window's buffer is buried (placed at bottom of buffer list);
  (2) clicked on right edge of a window's modeline,
      the Info buffer is displayed, or if already displayed and the
      modeline clicked belongs to a window displaying Info, the Info
      buffer is hidden;
- (3) clicked anywhere in the middle of a window's modeline,
+ (3) clicked on the buffer id of a window's modeline, dired is run
+     on the current directory, replacing the window's buffer;
+     successive clicks walk up the directory tree
+ (4) clicked anywhere in the middle of a window's modeline,
      the function given by `action-key-modeline-function' is called;
- (4) dragged vertically from modeline to within a window,
+ (5) dragged vertically from modeline to within a window,
      the modeline is moved to point of key release, thereby resizing
      its window and potentially its vertical neighbors."
   (let ((w (smart-window-of-coords action-key-depress-args)))
     (if w (select-window w))
     (cond ((hmouse-modeline-click)
-          (cond ((hmouse-release-left-edge)  (bury-buffer))
+          (cond ((hmouse-emacs-at-modeline-buffer-id-p)
+                 (dired-jump))
+                ((hmouse-release-left-edge) (bury-buffer))
                 ((hmouse-release-right-edge)
                  (if (eq major-mode 'Info-mode)
                      (Info-exit)
@@ -675,22 +772,26 @@ If the Action Key is:
 (defun assist-key-modeline ()
   "Handles Assist Key depresses on a window mode line.
 If the Assist Key is:
- (1) clicked on left edge of a window's modeline,
+ (1) clicked on the first blank character of a window's modeline,
      bottom buffer in buffer list is unburied and placed in window;
  (2) clicked on right edge of a window's modeline,
      the summary of Smart Key behavior is displayed, or if already
      displayed and the modeline clicked belongs to a window displaying
      the summary, the summary buffer is hidden;
- (3) clicked anywhere in the middle of a window's modeline,
+ (3) clicked on the buffer id of a window's modeline,
+     the next buffer in sequence is displayed in the window
+ (4) clicked anywhere in the middle of a window's modeline,
      the function given by `assist-key-modeline-function' is called;
- (4) dragged vertically from modeline to within a window,
+ (5) dragged vertically from modeline to within a window,
      the modeline is moved to point of key release, thereby resizing
      its window and potentially its vertical neighbors."
   (let ((buffers)
        (w (smart-window-of-coords assist-key-depress-args)))
     (if w (select-window w))
     (cond ((hmouse-modeline-click)
-          (cond ((hmouse-release-left-edge)
+          (cond ((hmouse-emacs-at-modeline-buffer-id-p)
+                 (next-buffer))
+                ((hmouse-release-left-edge)
                  (if (fboundp 'last)
                      (switch-to-buffer (car (last (buffer-list))))
                    (setq buffers (buffer-list))
@@ -708,33 +809,57 @@ If the Assist Key is:
   ;; So just check that release was in modeline.
   (hmouse-modeline-release))
 
+(defun hmouse-emacs-modeline-event-p (event)
+  "GNU Emacs: Returns non-nil if EVENT happened on a window mode line."
+  (eq (posn-area (event-start event)) 'mode-line))
+
+(defun hmouse-modeline-event-p (args)
+  "Returns non-nil if event ARGS happened on a window mode line."
+    (when (and (hyperb:window-system) args
+              (not (posnp args))
+              (not (markerp args)))
+      (cond
+       ;; Modern GNU Emacs
+       ((hmouse-emacs-modeline-event-p args))
+       ;; XEmacs
+       ((fboundp 'event-over-modeline-p)
+       (event-over-modeline-p args))
+       ;; Early Emacs
+       (t
+       (let* ((w (smart-window-of-coords args))
+              (mode-ln (if w (nth 3 (window-edges w))))
+              (last-press-y (hmouse-y-coord args)))
+         ;; Mode-line is always 1 less than the bottom of the window, unless it
+         ;; is a minibuffer window which does not have a modeline.
+         (if (not (eq w (minibuffer-window))) (setq mode-ln (1- mode-ln)))
+         (and last-press-y mode-ln (= last-press-y mode-ln)))))))
+
 (defun hmouse-modeline-depress ()
   "Returns non-nil if Action Key was depressed on a window mode line.
 If free variable `assist-flag' is non-nil, uses Assist Key."
-  (let ((args (if assist-flag assist-key-depress-args
+  (let ((args (if assist-flag
+                 assist-key-depress-args
                action-key-depress-args)))
-    (if (and (hyperb:window-system) args)
-       (if (fboundp 'event-over-modeline-p)
-           (event-over-modeline-p args)
-         (let* ((w (smart-window-of-coords args))
-                (mode-ln (if w (nth 3 (window-edges w))))
-                (last-press-y (hmouse-y-coord args)))
-           ;; Mode-line is always 1 less than the bottom of the window, unless 
it
-           ;; is a minibuffer window which does not have a modeline.
-           (if (not (eq w (minibuffer-window))) (setq mode-ln (1- mode-ln)))
-           (and last-press-y mode-ln (= last-press-y mode-ln)))))))
+    (hmouse-modeline-event-p args)))
 
 (defun hmouse-modeline-release ()
   "Returns non-nil if Smart Key was released on a window mode line."
-  (let ((args (if assist-flag assist-key-release-args
+  (let ((args (if assist-flag
+                 assist-key-release-args
                action-key-release-args)))
-    (if (and (hyperb:window-system) args)
-       (if (fboundp 'event-over-modeline-p)
-           (event-over-modeline-p args)
-         (let* ((w (smart-window-of-coords args))
-                (mode-ln (and w (1- (nth 3 (window-edges w)))))
-                (last-press-y (hmouse-y-coord args)))
-           (and last-press-y mode-ln (= last-press-y mode-ln)))))))
+    (hmouse-modeline-event-p args)))
+
+(defun hmouse-emacs-at-modeline-buffer-id-p ()
+  "GNU Emacs: Return t if mouse position is within the buffer name field of 
the current window's mode-line, else nil."
+  (when hyperb:emacs-p
+    (let* ((coords (hmouse-window-coordinates)) ;; in characters
+          (x-coord (caadr coords))
+          (mode-line-string (and (integerp x-coord) (>= x-coord 0) 
(format-mode-line mode-line-format)))
+          (keymap (and mode-line-string
+                       (<= x-coord (1- (length mode-line-string)))
+                       (plist-get (text-properties-at x-coord 
mode-line-string) 'local-map))))
+      (when keymap
+       (eq (lookup-key keymap [mode-line mouse-1]) 
'mode-line-previous-buffer)))))
 
 (defun hmouse-modeline-resize-window ()
   "Resizes window whose mode line was depressed on by the last Smart Key.
@@ -781,10 +906,53 @@ of the Smart Key."
                         (error nil)))
                   (select-window owind))))))))
 
+(defun hmouse-clone-window-to-frame (&optional always-delete-flag)
+  (let ((hycontrol-keep-window-flag t))
+    (hmouse-move-window-to-frame)))
+
+;; Derived from Emacs mouse.el.
+(defun hmouse-move-window-to-frame (&optional always-delete-flag)
+  "Move the selected window to the right of the window of Action Key release.
+If free variable `assist-flag' is non-nil, uses Assist Key release instead.
+
+If optional ALWAYS-DELETE-FLAG is non-nil, delete the source window
+after copying it to the other frame; otherwise, if there is only one
+window in the source frame or if free variable `hycontrol-keep-window-flag'
+is non-nil, leave the original window and just clone it into the new frame."
+  (interactive)
+  (let ((depress-window (if assist-flag
+                           assist-key-depress-window
+                         action-key-depress-window))
+       (release-window (if assist-flag
+                           assist-key-release-window
+                         action-key-release-window))
+       buf)
+    (cond ((or (window-minibuffer-p depress-window)
+              (window-minibuffer-p release-window))
+          (beep)
+          (minibuffer-message "(Hyperbole): Select a non-minibuffer window"))
+         (t
+          ;; Give temporary modes such as isearch a chance to turn off.
+          (run-hooks 'mouse-leave-buffer-hook)
+          (setq buf (window-buffer depress-window))
+          (with-selected-window release-window
+            (split-window-horizontally)
+            (other-window 1)
+            (switch-to-buffer buf nil t))
+          (with-selected-frame (window-frame depress-window)
+            (unless (or hycontrol-keep-window-flag
+                        (and (not always-delete-flag) (one-window-p t)))
+              (delete-window depress-window)))))))
+
 (defun hmouse-release-left-edge ()
   "Returns non-nil if last Smart Key release was at left window edge.
 `hmouse-edge-sensitivity' value determines how near to actual edge the
-release must be."
+release must be.
+
+GNU Emacs mode-line key bindings override the Smart Mouse Key bindings
+immediately after the first blank mode-line character position.  Therefore,
+mode-line left edge clicks must be on the first blank character of the
+mode-line regardless of the setting of `hmouse-edge-sensitivity'."
   (let ((args (if assist-flag assist-key-release-args
                 action-key-release-args))
        window-left last-release-x)
@@ -912,14 +1080,19 @@ of the Smart Key."
                 (hypb:goto-marker args)
                 (current-column))
             (eval (cdr (assoc (hyperb:window-system)
-                              '(("emacs" . (if (eventp args)
-                                               (let ((w-or-f (posn-window 
(event-start args))))
-                                                 (if (framep w-or-f)
-                                                     (setq w-or-f 
(frame-selected-window w-or-f)))
-                                                 (+ (car (posn-col-row
-                                                          (event-start args)))
-                                                    (nth 0 (window-edges 
w-or-f))))
-                                             (car args)))
+                              '(("emacs" . (cond ((eventp args)
+                                                  (let ((w-or-f (posn-window 
(event-start args))))
+                                                    (if (framep w-or-f)
+                                                        (setq w-or-f 
(frame-selected-window w-or-f)))
+                                                    (+ (car (posn-col-row 
(event-start args)))
+                                                       (nth 0 (window-edges 
w-or-f)))))
+                                                 ((posnp args)
+                                                  (let ((w-or-f (posn-window 
args)))
+                                                    (if (framep w-or-f)
+                                                        (setq w-or-f 
(frame-selected-window w-or-f)))
+                                                    (+ (car (posn-col-row 
args)))
+                                                       (nth 0 (window-edges 
w-or-f))))
+                                                 (t (car args))))
                                 ("xemacs" .  (if (eventp args)
                                                  (event-x args)
                                                (car args)))
@@ -931,14 +1104,20 @@ of the Smart Key."
 (defun hmouse-y-coord (args)
   "Returns y coordinate in frame lines from window system dependent ARGS."
   (let ((y (eval (cdr (assoc (hyperb:window-system)
-                            '(("emacs" . (if (eventp args)
-                                             (let ((w-or-f (posn-window 
(event-start args))))
-                                               (if (framep w-or-f)
-                                                   (setq w-or-f 
(frame-selected-window w-or-f)))
-                                               (+ (cdr (posn-col-row
-                                                        (event-start args)))
-                                                  (nth 1 (window-edges 
w-or-f))))
-                                           (cdr args)))
+                            '(("emacs" . (cond ((eventp args)
+                                                (let ((w-or-f (posn-window 
(event-start args))))
+                                                  (if (framep w-or-f)
+                                                      (setq w-or-f 
(frame-selected-window w-or-f)))
+                                                  (+ (cdr (posn-col-row
+                                                           (event-start args)))
+                                                     (nth 1 (window-edges 
w-or-f)))))
+                                               ((posnp args)
+                                                (let ((w-or-f (posn-window 
args)))
+                                                  (if (framep w-or-f)
+                                                      (setq w-or-f 
(frame-selected-window w-or-f)))
+                                                  (+ (cdr (posn-col-row args))
+                                                     (nth 1 (window-edges 
w-or-f)))))
+                                               (t (cdr args))))
                               ("xemacs" .  (if (eventp args)
                                                (event-y args)
                                              (cdr args)))
diff --git a/hversion.el b/hversion.el
index db0092e..35dfcaa 100644
--- a/hversion.el
+++ b/hversion.el
@@ -126,7 +126,7 @@ Where a part in the term-type is delimited by a `-' or  an 
`_'."
                          ;; the selected frame has mouse support,
                          ;; then there is a window system to support.
                          (display-mouse-p))
-                     ;; X11, NEXTSTEP (DPS), or OS/2 Presentation Manager (PM)
+                     ;; X11, macOS, NEXTSTEP (DPS), or OS/2 Presentation 
Manager (PM)
                      (cond (hyperb:emacs-p "emacs")
                            ((featurep 'xemacs)  "xemacs")
                            (t                "xterm")))
@@ -137,7 +137,8 @@ Where a part in the term-type is delimited by a `-' or  an 
`_'."
                      "next")
                     )))
     (set-frame-parameter frame 'hyperb:window-system
-                        (and term (substring term 0 (string-match "[-_]" 
term))))))
+                        (and term (setq term (substring term 0 (string-match 
"[-_]" term)))))
+    term))
 
 (defun hyperb:window-system (&optional frame)
   "Returns the string name for window system or term type under which the 
selected frame is running.
diff --git a/hycontrol.el b/hycontrol.el
index dc0e894..4a2fcc2 100644
--- a/hycontrol.el
+++ b/hycontrol.el
@@ -4,7 +4,7 @@
 ;;
 ;; Orig-Date:     1-Jun-16 at 15:35:36
 ;;
-;; Copyright (C) 2016  Free Software Foundation, Inc.
+;; Copyright (C) 2016-2017  Free Software Foundation, Inc.
 ;; See the "HY-COPY" file for license information.
 ;;
 ;; This file is part of GNU Hyperbole.
@@ -68,6 +68,11 @@
 ;;; Public variables
 ;;; ************************************************************************
 
+(defcustom hycontrol-keep-window-flag nil
+  "*When non-nil (default is nil), leave original window when tear off window 
to another frame."
+  :type 'boolean
+  :group 'hyperbole-screen)
+
 (defcustom hycontrol-maximum-units 1000
   "*Maximum units setting allowed for hycontrol commands.
 The unit counter resets to the last digit entered whenever this value is 
exceeded."
@@ -83,7 +88,8 @@ It's value is an (x-offset . y-offset) pair in pixels."
   :group 'hyperbole-screen)
 
 (defvar hycontrol-screen-offset-alist
-  '(((1920 . 1080) . (10 0 68 0)) ; 24" iMac / HD display
+  '(((1920 . 1080) . (10 0 68 0)) ; 24" iMac HD display
+    ((2560 . 1440) . (15 0 88 0)) ; 27" iMac HD display
     (t . (0 0 0 0)))
   "*Alist of (screen-predicate . (top-offset right-offset bottom-offset 
left-offset) pairs.
 Offsets are integers given in pixels.  The offsets associated with the first
@@ -163,10 +169,10 @@ set to 1.  If it is > `hycontrol-maximum-units', it is 
set to
            (message
             (concat
              "FRAME: (h=heighten, s=shorten, w=widen, n=narrow, %%/H/W=screen 
%%age, arrow=move frame) by %d unit%s, .=clear units\n"
-             ;; "c=cycle to edges, keypad=to edges, d/^/D=delete/iconify 
frame/others, o/O=other win/frame, [/]=create frame, (/)=save/restore fconfig\n"
-             "c=cycle to edges, keypad=to edges, d/D=delete frame/others, 
o/O=other win/frame, [/]=create frame, (/)=save/restore fconfig\n"
-             "i/j/k/m=expand to edges, -=min frame, +=max frame, 
u/b/~=un/bury/swap bufs, Z/z=zoom in/out, t=to win control, q=quit")
-            ;; No room to include this binding in the message: ==frames same 
size
+             ;; d/^/D=delete/iconify frame/others - iconify left out due to 
some bug on macOS (see comment near ^ below)
+             "d/D=delete frame/others, o/O=other win/frame, [/]=create frame, 
(/)=save/restore fconfig\n"
+             "f/F=clone/move win to new frame, -/+=minimize/maximize frame, 
==frames same size, u/b/~=un/bury/swap bufs\n"
+             "Frame to edges: c=cycle, i/j/k/m=expand/contract, 
p/num-keypad=move; z/Z=zoom out/in, t=to WINDOW:, q=quit")
             arg
             (if (= arg 1) "" "s"))
            (condition-case ()
@@ -182,20 +188,26 @@ set to 1.  If it is > `hycontrol-maximum-units', it is 
set to
                   ((eq e ?c) (hycontrol-frame-to-screen-edges))
                   ((eq e ?d) (delete-frame))
                   ((eq e ?D) (hycontrol-delete-other-frames))
+                  ((eq e ?f) (hycontrol-clone-window-to-new-frame))
+                  ((eq e ?F) (hycontrol-window-to-new-frame))
                   ((eq e ?\C-g) (keyboard-quit))
                   ((eq e ?%) (hycontrol-frame-percentage-of-screen arg))
                   ((eq e ?H) (hycontrol-frame-height-percentage-of-screen arg))
                   ((eq e ?W) (hycontrol-frame-width-percentage-of-screen arg))
                   ((eq e ?h) (set-frame-height nil (+ (frame-height) arg)))
-                  ((eq e ?i) (hycontrol-frame-expand-to-top))
-                  ((eq e ?j) (hycontrol-frame-expand-to-left))
-                  ((eq e ?k) (hycontrol-frame-expand-to-right))
-                  ((eq e ?m) (hycontrol-frame-expand-to-bottom))
+                  ((eq e ?i) (setq arg (hycontrol-frame-resize-to-top arg)))
+                  ((eq e ?j) (setq arg (hycontrol-frame-resize-to-left arg)))
+                  ((eq e ?k) (setq arg (hycontrol-frame-resize-to-right arg)))
+                  ((eq e ?l) (lower-frame))
+                  ((eq e ?m) (setq arg (hycontrol-frame-resize-to-bottom arg)))
                   ((eq e ?n) (set-frame-width nil (- (frame-width) arg)))
                   ((eq e ?o) (setq w (selected-window)) (other-window arg) (if 
(eq w (selected-window)) (other-window 1)))
                   ((eq e ?O) (setq w (selected-window)) (other-frame arg) (if 
(eq w (selected-window)) (other-frame 1)))
-                  ;; ((memq e (list ?q (aref (kbd "<escape>") 0))) (throw 
'done t))
+                  ;; Numeric keypad emulation for keyboards that lack one.
+                  ((eq e ?p) (hycontrol-virtual-numeric-keypad arg))
+                  ;; Don't use expr to the right; it prevents ESC use as Meta: 
((memq e (list ?q (aref (kbd "<escape>") 0))) (throw 'done t))
                   ((eq e ?q) (throw 'done t))
+                  ((eq e ?r) (raise-frame))
                   ((eq e ?s) (set-frame-height nil (- (frame-height) arg)))
                   ((eq e ?t) (throw 'done nil))
                   ((eq e ?u) (unbury-buffer))
@@ -205,9 +217,8 @@ set to 1.  If it is > `hycontrol-maximum-units', it is set 
to
                   ((memq e '(?\[ ?\])) (hycontrol-make-frame))
                   ((eq e ?\() (call-interactively 
'hycontrol-save-frame-configuration))
                   ((eq e ?\)) (hycontrol-restore-frame-configuration))
-                  ;; Something in this command's event handling slows down
-                  ;; frame iconification under Mac OS X 100-fold, so
-                  ;; don't enable it until this issue is resolved.
+                  ;; Something in this command's event handling when used 
within HyControl's event loop slows down
+                  ;; frame iconification under macOS 100-fold, so don't enable 
it until this issue is resolved.
                   ;; ((eq e ?^)  (iconify-frame))
                   ((eq e ?~) (or (hycontrol-frame-swap-buffers) 
(hycontrol-window-swap-buffers)
                                  (hycontrol-user-error debug "(HyControl): 
There must be only two windows on screen to swap buffers.")))
@@ -216,7 +227,7 @@ set to 1.  If it is > `hycontrol-maximum-units', it is set 
to
                   ((eq e ?=)
                    (and (> (length (visible-frame-list)) 1)
                         (y-or-n-p "Resize all other frames to the size of the 
selected frame?")
-                        (mapc (lambda (f) (set-frame-size f (frame-width) 
(frame-height))) (visible-frame-list))))
+                        (mapc (lambda (f) (set-frame-size f 
(frame-pixel-width) (frame-pixel-height) t)) (visible-frame-list))))
                   ((eq e ?\C-u)
                    (setq arg (* arg 4))
                    (if (> arg hycontrol-maximum-units) (setq arg 4)))
@@ -261,8 +272,8 @@ set to 1.  If it is > `hycontrol-maximum-units', it is set 
to
             (concat
              "WINDOW: (h=heighten, s=shorten, w=widen, n=narrow, arrow=move 
frame) by %d unit%s, .=clear units\n"
              "d/D=delete win/others, o/O=other win/frame, [/]=split win 
atop/sideways, (/)=save/restore wconfig\n"
-             "f=win to own frame, -=min win,+=max win, u/b/~=un/bury/swap 
bufs, Z/z=zoom in/out, t=to frame control, q=quit")
-            ;; No room to include this binding in the message: ==wins same size
+             "f/F=clone/move win to new frame, -/+=minimize/maximize win, 
==wins same size, u/b/~=un/bury/swap bufs\n"
+             "Frame to edges: c=cycle, i/j/k/m=expand/contract, 
p/num-keypad=move; z/Z=zoom out/in, t=to FRAME:, q=quit")
             arg
             (if (= arg 1) "" "s"))
            (condition-case ()
@@ -271,18 +282,29 @@ set to 1.  If it is > `hycontrol-maximum-units', it is 
set to
                  (cond
                   ((memq e '(up down left right))
                    (hycontrol-move-frame e arg))
+                  ((memq e '(kp-0 kp-1 kp-2 kp-3 kp-4 kp-5 kp-6 kp-7 kp-8 
kp-9))
+                   (hycontrol-numeric-keypad e arg))
                   ((eq e ?.) (setq arg 0)) ;; Clear arg
                   ((eq e ?b) (bury-buffer))
-                  ;; ((memq e '(?d ?^)) (delete-window))
+                  ((eq e ?c) (hycontrol-frame-to-screen-edges))
                   ((eq e ?d) (delete-window))
                   ((eq e ?D) (hycontrol-delete-other-windows))
-                  ((eq e ?f) (hycontrol-window-to-frame))
+                  ((eq e ?f) (hycontrol-clone-window-to-new-frame))
+                  ((eq e ?F) (hycontrol-window-to-new-frame))
                   ((eq e ?\C-g) (keyboard-quit))
                   ((eq e ?h) (enlarge-window arg))
+                  ;; Allow frame resizing even when in window control
+                  ;; mode because it may be used often.
+                  ((eq e ?i) (setq arg (hycontrol-frame-resize-to-top arg)))
+                  ((eq e ?j) (setq arg (hycontrol-frame-resize-to-left arg)))
+                  ((eq e ?k) (setq arg (hycontrol-frame-resize-to-right arg)))
+                  ((eq e ?m) (setq arg (hycontrol-frame-resize-to-bottom arg)))
                   ((eq e ?n) (shrink-window-horizontally arg))
                   ((eq e ?o) (setq w (selected-window)) (other-window arg) (if 
(eq w (selected-window)) (other-window 1)))
                   ((eq e ?O) (setq w (selected-window)) (other-frame arg) (if 
(eq w (selected-window)) (other-frame 1)))
-                  ;; ((memq e (list ?q (aref (kbd "<escape>") 0))) (throw 
'done t))
+                  ;; Numeric keypad emulation for keyboards that lack one.
+                  ((eq e ?p) (hycontrol-virtual-numeric-keypad arg))
+                  ;; Don't use expr to the right; it prevents ESC use as Meta: 
((memq e (list ?q (aref (kbd "<escape>") 0))) (throw 'done t))
                   ((eq e ?q) (throw 'done t))
                   ((eq e ?s) (shrink-window arg))
                   ((eq e ?t) (throw 'done nil))
@@ -349,6 +371,20 @@ nothing and return nil."
 
 ;;; Frame Relocation Commands
 
+(defconst hycontrol--vnk-string
+  "(Virtual   7 8 9   Enter a digit to
+ Numeric   4 5 6   move the frame
+ Keypad)   1 2 3   to that quadrant"
+  "HyControl prompt string for virtual numeric keypad (emulate keypad when not 
available)")
+
+(defun hycontrol-virtual-numeric-keypad (arg)
+  (catch 'quit
+    (while (and (setq e (read-char hycontrol--vnk-string))
+               (not (when (memq e '(?q ?\C-g)) (throw 'quit nil)))
+               (or (not (numberp e)) (< e ?0) (> e ?9)))
+      (beep))
+    (hycontrol-numeric-keypad (- e ?0) arg)))
+
 (defun hycontrol-frame-to-screen-edges (&optional arg)
   "Cycle the selected frame's position clockwise through the middle of edges 
and corners of the screen; once per call.
 With an optional arg of 0, just reset the cycle position to 0."
@@ -459,39 +495,106 @@ With an optional arg of 0, just reset the cycle position 
to 0."
                      hycontrol-screen-top-offset))
 
 ;;; Frame Resizing Commands
-(defun hycontrol-frame-expand-to-bottom ()
-  "Expand the selected frame to the bottom of the screen, allowing for 
hycontrol-screen-*-offsets."
-  (interactive)
+(defun hycontrol-frame-resize-percentage (arg)
+  "ARG should be between 0 and 100.  0 means don't resize (return 1).
+1 is the default value which means cut the frame along the given dimension
+in half (return 0.5).  2-100 is converted to a percentage to multiply by.
+Over 100 is set to 100.  Under 0 is set to 0.  Floats between 0 and 1
+are taken as percentages and used.  Other floats are rounded.
+non-integer arguments are ignored and the default value is used."
+  (cond ((integerp arg)
+        (cond 
+          ((= arg 0) 1)
+          ((= arg 1) 0.5)
+          ((and (> arg 1) (<= arg 100)) (/ arg 100.0))
+          ((< arg 0) 0)
+          ((> arg 100) 1)))
+       ((floatp arg)
+        (if (and (<= 0.0 arg) (<= arg 1.0))
+            arg
+          (hycontrol-frame-resize-percentage (round arg))))
+       (t (hycontrol-frame-resize-percentage 1))))
+
+(defun hycontrol-frame-resize-arg (arg)
+  "Inverse result of `hycontrol-frame-resize-percentage' to provide feedback 
on any argument value adjustment."
+  (pcase arg
+    (0 0)
+    (1 1)
+    (50 1)
+    ;; Arg must be a percentage, scale it so not fractional.
+    ((pred numberp) (round (* arg 100)))
+    (_ 1)))
+
+(defun hycontrol-frame-resize-to-bottom (&optional arg)
+  "Expand the selected frame to the bottom of the screen, allowing for 
hycontrol-screen-*-offsets.
+If already at the bottom, adjust its height to ARG percent of the screen (50% 
by default
+if ARG is 1 or nil) but keep it at the bottom of the screen."
+  (interactive "p")
+  (setq arg (hycontrol-frame-resize-percentage arg))
   (let ((frame-resize-pixelwise t))
-    (set-frame-height nil (- (display-pixel-height) (cdr (frame-position)) 
hycontrol-screen-bottom-offset)
-                     nil t)))
-
-(defun hycontrol-frame-expand-to-left ()
-  "Expand the selected frame to the left of the screen, allowing for 
hycontrol-screen-*-offsets."
-  (interactive)
+    (if (hycontrol-frame-at-bottom-p)
+       ;; Reduce frame height to ARG percent, keeping bottom side fixed.
+       (set-frame-height nil (floor (* (frame-pixel-height) arg))
+                         nil t)
+      ;; Expand frame height all the way to the bottom, keeping top side fixed.
+      (set-frame-height nil (- (display-pixel-height) (cdr (frame-position)) 
hycontrol-screen-bottom-offset)
+                       nil t))
+    (hycontrol-frame-to-bottom))
+  (hycontrol-frame-resize-arg arg))
+
+(defun hycontrol-frame-resize-to-left (&optional arg)
+  "Expand the selected frame to the left of the screen, allowing for 
hycontrol-screen-*-offsets.
+If already at the left, adjust its width to ARG percent of the screen (50% by 
default
+if ARG is 1 or nil) but keep it at the left of the screen."
+  (interactive "p")
+  (setq arg (hycontrol-frame-resize-percentage arg))
   (let ((frame-resize-pixelwise t))
-    (set-frame-width nil (round (- (+ (hycontrol-frame-width) (car 
(frame-position)))
-                                  (* 2.5 (frame-scroll-bar-width))
-                                  hycontrol-screen-left-offset))
-                    nil t)
-    (set-frame-position nil hycontrol-screen-left-offset (cdr 
(frame-position)))))
-
-(defun hycontrol-frame-expand-to-right ()
-  "Expand the selected frame to the right of the screen, allowing for 
hycontrol-screen-*-offsets."
-  (interactive)
+    (if (hycontrol-frame-at-left-p)
+       ;; Reduce frame width to ARG percent, keeping left side fixed.
+       (set-frame-width nil (floor (* (frame-pixel-width) arg)) nil t)
+      ;; Expand frame width all the way to the left, keeping right side fixed.
+      (set-frame-width nil (round (- (+ (hycontrol-frame-width) (car 
(frame-position)))
+                                    (* 2.5 (frame-scroll-bar-width))
+                                    hycontrol-screen-left-offset))
+                      nil t))
+    (hycontrol-frame-to-left))
+  (hycontrol-frame-resize-arg arg))
+
+(defun hycontrol-frame-resize-to-right (&optional arg)
+  "Expand the selected frame to the right of the screen, allowing for 
hycontrol-screen-*-offsets.
+If already at the right, adjust its width to ARG percent of the screen (50% by 
default
+if ARG is 1 or nil) but keep it at the right of the screen."
+  (interactive "p")
+  (setq arg (hycontrol-frame-resize-percentage arg))
   (let ((frame-resize-pixelwise t))
-    (set-frame-width nil (round (- (display-pixel-width) (car (frame-position))
-                                  (* 2.5 (frame-scroll-bar-width))
-                                  hycontrol-screen-right-offset))
-                    nil t)))
+    (if (hycontrol-frame-at-right-p)
+       ;; Reduce frame width to ARG percent, keeping right side fixed.
+       (set-frame-width nil (floor (* (frame-pixel-width) arg)) nil t)
+      ;; Expand frame width all the way to the right, keeping left side fixed.
+      (set-frame-width nil (round (- (display-pixel-width) (car 
(frame-position))
+                                    (* 2.5 (frame-scroll-bar-width))
+                                    hycontrol-screen-right-offset))
+                      nil t))
+    (hycontrol-frame-to-right))
+  (hycontrol-frame-resize-arg arg))
   
-(defun hycontrol-frame-expand-to-top ()
-  "Expand the selected frame to the top of the screen, allowing for 
hycontrol-screen-*-offsets."
-  (interactive)
-  (let ((frame-resize-pixelwise t))
-    (set-frame-height nil (- (+ (cdr (frame-position)) 
(hycontrol-frame-height)) hycontrol-screen-top-offset)
-                     nil t)
-    (set-frame-position nil (car (frame-position)) 
hycontrol-screen-top-offset)))
+(defun hycontrol-frame-resize-to-top (&optional arg)
+  "Expand the selected frame to the top of the screen, allowing for 
hycontrol-screen-*-offsets.
+If already at the top, adjust its height to ARG percent of the screen (50% by 
default
+if ARG is 1 or nil) but keep it at the top of the screen."
+  (interactive "p")
+  (setq arg (hycontrol-frame-resize-percentage arg))
+  (let ((frame-resize-pixelwise t)
+       (top (nth 1 (hycontrol-frame-edges))))
+    (if (hycontrol-frame-at-top-p)
+       ;; Reduce frame height to ARG percent, keeping top side fixed.
+       (set-frame-height nil (floor (* (frame-pixel-height) arg)) nil t)
+      ;; Expand frame height all the way to the top, keeping bottom side fixed.
+      (set-frame-height nil (- (+ (cdr (frame-position)) 
(hycontrol-frame-height)) hycontrol-screen-top-offset)
+                       nil t))
+    (hycontrol-frame-to-top))
+  (hycontrol-frame-resize-arg arg))
+
 
 (defun hycontrol-frame-minimize-lines ()
   "Shrink the frame to its approximate smallest number of lines to display all 
existing windows."
@@ -504,11 +607,6 @@ With an optional arg of 0, just reset the cycle position 
to 0."
            (window-list nil 'nomini)))
     (set-frame-height nil l)))
 
-(defun hycontrol-frame-height-percentage-of-screen (percent)
-  "Resize the selected frame's height to be approximately PERCENT of the 
screen."
-  (interactive "nResize frame height to be this percent of the screen (1-100): 
")
-  (hycontrol-frame-percentage-of-screen percent 'height))
-
 (defun hycontrol-frame-percentage-of-screen (percent &optional dimension)
   "Resize the selected frame to be approximately PERCENT of the screen.
 PERCENT may be given as a decimal percentage or a number between 0 and 100.
@@ -536,6 +634,11 @@ width to affect only that dimension."
                                 t))))
     (error "(hycontrol-frame-fraction-of-screen): `%s', must be a percent 
value between 0 and 100." percent)))
 
+(defun hycontrol-frame-height-percentage-of-screen (percent)
+  "Resize the selected frame's height to be approximately PERCENT of the 
screen."
+  (interactive "nResize frame height to be this percent of the screen (1-100): 
")
+  (hycontrol-frame-percentage-of-screen percent 'height))
+
 (defun hycontrol-frame-width-percentage-of-screen (percent)
   "Resize the selected frame's width to be approximately PERCENT of the 
screen."
   (interactive "nResize frame width to be this percent of the screen (1-100): 
")
@@ -572,25 +675,36 @@ Do nothing and return nil if there are not precisely two 
windows."
       t)))
 
 ;; Derived from Emacs mouse.el.
-(defun hycontrol-window-to-frame ()
-  "Delete the selected window, and create a new frame displaying its buffer."
+;;;###autoload
+(defun hycontrol-window-to-new-frame ()
+  "Create a new frame sized to match the selected window and with its buffer.
+If there is only one window in the source frame or if 
`hycontrol-keep-window-flag'
+is non-nil, leave the original window and just clone it into the new frame."
   (interactive)
   (let ((w (selected-window))
        buf)
     (cond ((window-minibuffer-p w)
           (beep)
           (minibuffer-message "(Hyperbole): Select a non-minibuffer window"))
-         ((one-window-p t)
-          (beep)
-          (minibuffer-message "(Hyperbole): Selected window is already in its 
own frame"))
          (t
           ;; Give temporary modes such as isearch a chance to turn off.
           (run-hooks 'mouse-leave-buffer-hook)
           (setq buf (window-buffer w))
-          (delete-window w)
           (display-buffer-pop-up-frame buf nil)
-          (set-frame-position nil (+ (car hycontrol-frame-offset) (car 
(frame-position)))
-                              (+ (cdr hycontrol-frame-offset) (cdr 
(frame-position))))))))
+          (set-frame-position nil (+ (car hycontrol-frame-offset)
+                                     (car (frame-position (window-frame w))))
+                              (+ (cdr hycontrol-frame-offset)
+                                 (cdr (frame-position (window-frame w)))))
+          (set-frame-size nil (window-size w t t) (window-size w nil t) t)
+          (with-selected-frame (window-frame w)
+            (unless (or hycontrol-keep-window-flag (one-window-p t))
+              (delete-window w)))))))
+
+;;;###autoload
+(defun hycontrol-clone-window-to-new-frame ()
+  "Create a new frame sized to match the selected window and with its buffer."
+  (let ((hycontrol-keep-window-flag t))
+    (hycontrol-window-to-new-frame)))
 
 ;;; Screen Offsets - Set once when this file is loaded; 
`hycontrol-set-screen-offsets' resets them.
 (defun hycontrol-display-screen-offsets ()
@@ -670,17 +784,52 @@ See its documentation for more information."
         (key-description e))
        (t e)))
 
+(defsubst hycontrol-frame-edges (&optional frame)
+  "Return the outermost edges of optional or selected FRAME."
+  (frame-edges frame 'native-edges))
+
 (defun hycontrol-frame-height (&optional frame)
   "Return the height of optional FRAME or the selected frame.  This includes 
all graphical window manager decorations.
 Under a graphical window system, this is in pixels; otherwise, it is in 
characters."
-    (- (nth 3 (frame-edges frame 'outer-edges))
-       (nth 1 (frame-edges frame 'outer-edges))))
+    (- (nth 3 (hycontrol-frame-edges frame))
+       (nth 1 (hycontrol-frame-edges frame))))
 
 (defun hycontrol-frame-width (&optional frame)
   "Return the height of optional FRAME or the selected frame.  This includes 
all graphical window manager decorations.
 Under a graphical window system, this is in pixels; otherwise, it is in 
characters."
-    (- (nth 2 (frame-edges frame 'outer-edges))
-       (nth 0 (frame-edges frame 'outer-edges))))
+    (- (nth 2 (hycontrol-frame-edges frame))
+       (nth 0 (hycontrol-frame-edges frame))))
+
+
+;; Frame Resizing Support
+(defconst hycontrol-screen-offset-sensitivity 12
+  "Number of pixels a frame dimension can be off from its screen-offset and 
still be considered at the screen edge.")
+
+(defun hycontrol-frame-at-left-p ()
+  "Return non-nil if selected frame's left edge is at the left edge of the 
screen sans `hycontrol-screen-left-offset'."
+  (<= (- (nth 0 (hycontrol-frame-edges)) hycontrol-screen-left-offset)
+      hycontrol-screen-offset-sensitivity))
+
+(defun hycontrol-frame-at-top-p ()
+  "Return non-nil if selected frame's bottom is at the top of the screen sans 
`hycontrol-screen-top-offset'."
+  (<= (- (nth 1 (hycontrol-frame-edges)) hycontrol-screen-top-offset
+        ;; Under macOS, frames are automatically offset vertically by
+        ;; the height of the global menubar, so account for that.
+        (if (eq system-type 'darwin) 23 0))
+      hycontrol-screen-offset-sensitivity))
+
+(defun hycontrol-frame-at-right-p ()
+  "Return non-nil if selected frame's right edge is at the right edge of the 
screen sans `hycontrol-screen-right-offset'."
+  (<= (- (display-pixel-width) (nth 2 (hycontrol-frame-edges)) 
hycontrol-screen-right-offset)
+      hycontrol-screen-offset-sensitivity))
+
+(defun hycontrol-frame-at-bottom-p ()
+  "Return non-nil if selected frame's bottom is at the bottom of the screen 
sans `hycontrol-screen-bottom-offset'."
+  (<= (- (display-pixel-height) (nth 3 (hycontrol-frame-edges)) 
hycontrol-screen-bottom-offset
+        ;; Under macOS, frames are automatically offset vertically by
+        ;; the height of the global menubar, so account for that.
+        (if (eq system-type 'darwin) -23 0))
+      hycontrol-screen-offset-sensitivity))
 
 ;; Frame Zoom Support
 (defun hycontrol-frame-zoom (zoom-func arg max-msgs)
@@ -757,7 +906,11 @@ It is offset from the selected frame by 
`hycontrol-frame-offset' (x . y) pixels.
         (set-frame-position nil (+ x pixels) y)))))
 
 (defun hycontrol-numeric-keypad (e _arg)
-  (let ((num (- (aref (symbol-name e) 3) ?0)))
+  "Move the selected frame to a screen location based on the location of the 
last pressed numeric keypad key."
+  (let ((num (if (integerp e)
+                e
+              ;; kp-<num> symbol
+              (- (aref (symbol-name e) 3) ?0))))
     (funcall
      (nth num '(nil hycontrol-frame-to-bottom-left 
hycontrol-frame-to-bottom-center hycontrol-frame-to-bottom-right
                hycontrol-frame-to-left-center hycontrol-frame-to-center 
hycontrol-frame-to-right-center
diff --git a/hyperbole.el b/hyperbole.el
index 848e3d1..1b9de00 100644
--- a/hyperbole.el
+++ b/hyperbole.el
@@ -1,6 +1,6 @@
 ;;; hyperbole.el --- GNU Hyperbole: The Everyday Hypertextual Information 
Manager
 
-;; Copyright (C) 1992-2016  Free Software Foundation, Inc.
+;; Copyright (C) 1992-2017  Free Software Foundation, Inc.
 
 ;; Author:           Bob Weiner
 ;; Maintainer:       Bob Weiner <address@hidden> and Mats Lidell 
<address@hidden>
@@ -18,15 +18,55 @@
 
 ;;; Commentary:
 ;;
-;;   See the "INSTALL" file for installation instructions and the
-;;   "README" file for general information.
+;; GNU Hyperbole (pronounced Ga-new Hi-per-bo-lee), or just Hyperbole, is an
+;; easy-to-use, yet powerful and programmable hypertextual information
+;; management system implemented as a GNU Emacs package.  It offers rapid views
+;; and interlinking of all kinds of textual information, utilizing Emacs for
+;; editing.  It can dramatically increase your productivity and greatly reduce
+;; the number of keyboard/mouse keys you'll need to work efficiently.
+;; 
+;; Hyperbole lets you:
+;; 
+;; 1. Quickly create hyperlink buttons either from the keyboard or by dragging
+;; between a source and destination window with a mouse button depressed.
+;; Later activate buttons by pressing/clicking on them or by giving the name of
+;; the button.
+;; 
+;; 2. Activate many kinds of `implicit buttons' recognized by context within
+;; text buffers, e.g. URLs, grep output lines, and git commits.  A single key
+;; or mouse button automatically does the right thing in dozens of contexts;
+;; just press and go.
+;; 
+;; 3. Build outlines with multi-level numbered outline nodes, e.g. 1.4.8.6,
+;; that all renumber automatically as any node or tree is moved in the
+;; outline. Each node also has a permanent hyperlink anchor that you can
+;; reference from any other node;
+;; 
+;; 4. Manage all your contacts quickly with hierarchical categories and embed
+;; hyperlinks within each entry. Or create an archive of documents with
+;; hierarchical entries and use the same search mechanism to quickly find any
+;; matching entry;
+;; 
+;; 5. Use single keys to easily manage your Emacs windows or frames and quickly
+;; retrieve saved window and frame configurations;
+;; 
+;; 6. Search for things in your current buffers, in a directory tree or across
+;; major web search engines with the touch of a few keys.
+;; 
+;; The common thread in all these features is making retrieval, management and
+;; display of information fast and easy. That is Hyperbole's purpose.
+;; 
+;; ----
 ;;
-;;   There is no need to manually edit this file unless there are specific
-;;   customizations you would like to make, such as whether a Hyperbole
-;;   Action Mouse Key is bound to the middle mouse button.  (See the
-;;   call of the function, `hmouse-install', below).
+;; See the "INSTALL" file for installation instructions and the "README" file
+;; for general information.
 ;;
-;;   Other site-specific customizations belong in "hsettings.el".
+;; There is no need to manually edit this file unless there are specific
+;; customizations you would like to make, such as whether a Hyperbole Action
+;; Mouse Key is bound to the middle mouse button.  (See the call of the
+;; function, `hmouse-install', below).
+;;
+;; Other site-specific customizations belong in "hsettings.el".
 
 ;;; Code:
 ;;; ************************************************************************
diff --git a/hywconfig.el b/hywconfig.el
index 271ed4b..b05f710 100644
--- a/hywconfig.el
+++ b/hywconfig.el
@@ -82,13 +82,13 @@ NAME, confirms whether or not to replace it."
       (error "(hywconfig-add-by-name): `name' argument is not a string: %s" 
name))
   (let ((set:equal-op  (lambda (key elt) (equal key (car elt))))
        (wconfig-names (hywconfig-get-names)))
-    (if (or (not (called-interactively-p 'interactive))
+    (if (or (not (called-interactively-p))
            (not (set:member name wconfig-names))
            (y-or-n-p
             (format "Replace existing `%s' window configuration: " name)))
        (progn (hywconfig-set-names (set:replace name 
(current-window-configuration)
                                                 wconfig-names))
-              (if (called-interactively-p 'interactive)
+              (if (called-interactively-p)
                   (message
                    (substitute-command-keys
                     (format "Window configuration `%s' saved.  Use 
{\\[hywconfig-restore-by-name]} to restore." name))))))))
@@ -104,7 +104,7 @@ NAME, confirms whether or not to replace it."
         (error "(hywconfig-delete-by-name): `name' argument is not a string: 
%s" name))
        (t (let ((set:equal-op (lambda (key elt) (equal key (car elt)))))
             (hywconfig-set-names (set:remove name (hywconfig-get-names)))
-            (if (called-interactively-p 'interactive)
+            (if (called-interactively-p)
                 (message "Window configuration `%s' has been deleted." 
name))))))
 
 ;;;###autoload
@@ -119,7 +119,7 @@ NAME, confirms whether or not to replace it."
        (t (let ((wconfig (set:get name (hywconfig-get-names))))
             (if wconfig
                 (progn (hywconfig-set-window-configuration wconfig)
-                       (if (called-interactively-p 'interactive)
+                       (if (called-interactively-p)
                            (message "Window configuration `%s' is now active." 
name)))
               (error "(hywconfig-restore-by-name): No window configuration for 
this frame named `%s'" name))))))
 
@@ -148,7 +148,7 @@ Then deletes this new configuration from the ring."
 Use {\\[hywconfig-yank-pop]} to restore it at a later time."
   (interactive)
   (ring-insert (hywconfig-get-ring) (current-window-configuration))
-  (if (called-interactively-p 'interactive)
+  (if (called-interactively-p)
       (message
        (substitute-command-keys
        "Window configuration saved.  Use {\\[hywconfig-yank-pop]} to 
restore."))))
diff --git a/man/hkey-help.txt b/man/hkey-help.txt
index cbbb8f1..b4e9c4d 100644
--- a/man/hkey-help.txt
+++ b/man/hkey-help.txt
@@ -31,19 +31,29 @@ Mouse-only Control
   Drag from shared window side
     or from left of scroll bar  Resizes window width       <- same
 
-  Modeline press+wind release   Resizes window height      <- same
-  Click in modeline
+  Drag between windows from     Displays buffer/file in    Swaps window buffers
+    buffer/file menu item         window of button release 
+  Other drag between windows    Creates/modifies a link    Swaps window buffers
+  Drag to outside Emacs from    Displays buffer/file in    Moves window to new 
frame
+    buffer/file menu item         a new frame
+
+  Modeline or other window drag
+    outside of Emacs            Clones window to new frame Moves window to new 
frame
+  Modeline drag to other frame  Clones window to frame     Moves window to 
frame
+  Modeline depress+wind release Resizes window height      <- same
+  Modeline Click
     Left modeline edge          Buries current buffer      Unburies bottom 
buffer
     Right modeline edge         Info manual browser        Smart Key summary
+    Buffer ID                   Dired on buffer's dir      Next buffer
     Other blank area            Action Key modeline hook   Assist Key modeline 
hook
                                   Show/Hide Buffer Menu      Popup Jump & 
Manage Menu
 
-  Drag between windows          Creates/modifies a link    Swaps wind buffers
   Drag in window, region active Error, not allowed         Error, not allowed
   Horizontal drag in a window   Splits window below        Deletes window
   Vertical drag in a window     Splits window side-by-side Deletes window
   Diagonal drag in a window     Saves wconfig              Restores wconfig 
from ring
-  Active region exists          Yanks sexp at release      Kills & yanks sexp 
at release
+
+  Active region exists          Yanks region at release    Kills & yanks 
region at release
 
 Hyperbole Key Press/Click in Special Modes
   Emacs Push Button             Activates button           Button help
diff --git a/man/hyperbole.texi b/man/hyperbole.texi
index a433425..e023b5e 100644
--- a/man/hyperbole.texi
+++ b/man/hyperbole.texi
@@ -1023,14 +1023,14 @@ signatures.  GNUS is a news and mail reader."
 @cindex cross-reference, Texinfo
 @item texinfo-ref
 Displays Texinfo, Info node or help associated with Texinfo node, menu
-item, @@xref, @@pxref, @@ref, @@code or @@var at point.  If point is
-within the braces of a cross-reference, the associated Info node is
+item, @@xref, @@pxref, @@ref, @@code, @@findex, @@var or @@vindex at point.
+If point is within the braces of a cross-reference, the associated Info node is
 shown.  If point is to the left of the braces but after the @@ symbol and
 the reference is to a node within the current Texinfo file, then the
 Texinfo node is shown.
 
-For @@code and @@var references, the associated documentation string
-is displayed.
+For @@code, @@findex, @@var and @@vindex references, the associated 
documentation
+string is displayed.
 
 @findex ibtypes mail-address
 @cindex e-mail address
@@ -2938,8 +2938,11 @@ based on mode.
 
 @kindex screen, f
 @kitem f
-In WINDOW mode, delete the selected window and redisplay its buffer in a
-new frame.
+Delete the selected window and redisplay its buffer in a new frame.
address@hidden screen, F
address@hidden F
+Clone the selected window into a new frame.
+
 
 @kindex screen, i
 @kindex screen, j
@@ -2956,9 +2959,9 @@ Respects the pixel edge offsets returned by
 
 @kindex screen, =
 @kitem =
-Make the current frame's windows or all frames approximately the same
-size based on mode.  In FRAME mode, all visible frames are set to the
-size of the selected frame.
+After confirmation, in WINDOW mode, make the current frame's windows
+approximately the same size.  In FRAME mode, make all visible frames
+the size of the selected frame.
 
 @kindex screen, -
 @kitem -
@@ -6861,28 +6864,35 @@ a vertical scroll bar:
 @group
 If depressed within a window mode line:
   ACTION KEY
-     (1) clicked on the left edge of a window's modeline, the window's
-         buffer is buried (placed at the bottom of the buffer list);
+     (1) clicked on the first blank character of a window's modeline,
+         the window's buffer is buried (placed at the bottom of the
+         buffer list);
      (2) clicked on the right edge of a window's modeline, the Info
          buffer is displayed, or if it is already displayed and the
          modeline clicked upon belongs to a window displaying Info,
          the Info buffer is hidden;
-     (3) clicked anywhere within the middle of a window's modeline,
+     (3) clicked on the buffer id of a window's modeline, dired is run
+         on the current directory, replacing the window's buffer;
+         successive clicks walk up the directory tree
+     (4) clicked anywhere within the middle of a window's modeline,
          the function given by `action-key-modeline-function' is called;
-     (4) dragged vertically from a modeline to within a window, the
+     (5) dragged vertically from a modeline to within a window, the
          modeline is moved to the point of the drag release, thereby
          resizing its window and potentially its vertically neighboring
          windows.
   ASSIST KEY
-     (1) clicked on the left edge of a window's modeline, the bottom
-         buffer in the buffer list is unburied and placed in the window;
+     (1) clicked on the first blank character of a window's modeline,
+         the bottom buffer in the buffer list is unburied and placed in
+         the window;
      (2) clicked on the right edge of a window's modeline, the summary
          of Smart Key behavior is displayed, or if it is already
          displayed and the modeline clicked upon belongs to a window
          displaying the summary, the summary buffer is hidden;
-     (3) clicked anywhere within the middle of a window's modeline,
+     (3) clicked on the buffer id of a window's modeline, the next
+         buffer in sequence is displayed in the window
+     (4) clicked anywhere within the middle of a window's modeline,
          the function given by `assist-key-modeline-function' is called;
-     (4) dragged vertically from a modeline to within a window, the
+     (5) dragged vertically from a modeline to within a window, the
          modeline is moved to the point of the drag release, thereby
          resizing its window and potentially its vertically neighboring
          windows.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]