[ I cross-post this to xemacs-beta so Greg can see it. All of my
future patches intended for the distribution will be sent to
xemacs-patches. ]
This defines the new `set-frame-focus' function, as well as the new
macros we discussed.
src/ChangeLog:
1998-05-03 Hrvoje Niksic <hniksic(a)srce.hr>
* frame.c (Fset_frame_focus): New function.
1998-05-03 Hrvoje Niksic <hniksic(a)srce.hr>
* x-toolbar.el (toolbar-info): Use `set-frame-focus' where
appropriate.
* lisp-mode.el: Update lisp-indent-function for
save-selected-frame and with-selected-frame.
* gnuserv.el (gnuserv-edit-files): Use set-frame-focus instead of
select-frame.
* frame.el (save-selected-frame): New macro.
(with-selected-frame): Ditto.
(other-frame): Use `set-frame-focus'.
--- etc/NEWS.orig Sun May 3 02:55:37 1998
+++ etc/NEWS Sun May 3 03:01:42 1998
@@ -186,12 +186,28 @@
change, the maximum buffer size on 32-bit machines is bumped from 128M
to 1G. This setting will be the default in a future XEmacs version.
-** When the variable focus-follows-mouse is non-nil, `select-frame' no
-longer permanently selects a different frame. The frame selection is
-temporary and is reverted when the current command terminates, much
-like the buffer selected by `set-buffer'. The `other-frame' command
-(`C-x 5 o') is unaffected by `focus-follows-mouse', and its behaviour
-is unchanged.
+** Frame focus management changes.
+
+*** When the variable focus-follows-mouse is non-nil, `select-frame'
+no longer permanently selects a different frame. The frame selection
+is temporary and is reverted when the current command terminates, much
+like the buffer selected by `set-buffer'. This is the same as in FSF
+Emacs.
+
+*** The new function `set-frame-focus' sets the window system focus to
+FRAME (and selects it), regardless of the value of
+`focus-follows-mouse'. Doing this is not well behaved, so be
+absolutely sure that you want this.
+
+The code that uses `select-frame' only to get the window manager focus
+should be changed to use `set-frame-focus' instead, so that they keep
+working when `focus-follows-mouse' is non-nil.
+
+*** The special forms `save-selected-frame' and `with-selected-frame'
+can now be used to temporarily change selected frame.
+
+*** The behavior of `other-frame' command (`C-x 5 o') is unaffected by
+these changes.
** It is now possible to build XEmacs with LDAP support
You need to install a LDAP library first. The following have been
--- src/frame.c.orig Sun May 3 01:58:40 1998
+++ src/frame.c Sun May 3 03:10:33 1998
@@ -657,6 +657,22 @@
update_frame_window_mirror (f);
}
+DEFUN ("set-frame-focus", Fset_frame_focus, 1, 1, 0, /*
+Select FRAME and give it the window system focus.
+This function is not affected by the value of `focus-follows-mouse'.
+*/
+ (frame))
+{
+ CHECK_LIVE_FRAME (frame);
+
+ MAYBE_DEVMETH (XDEVICE (FRAME_DEVICE (XFRAME (frame))), focus_on_frame,
+ (XFRAME (frame)));
+ /* This will get happen by the time we receive the next event
+ anyway, but it is safer to do it immediately. */
+ Fselect_frame (frame);
+ return Qnil;
+}
+
DEFUN ("select-frame", Fselect_frame, 1, 1, 0, /*
Select the frame FRAME.
Subsequent editing commands apply to its selected window.
@@ -665,15 +681,13 @@
function is called.
Note that this does not actually cause the window-system focus to
-be set to this frame, or the select-frame-hook or deselect-frame-hook
+be set to this frame, or the `select-frame-hook' or `deselect-frame-hook'
to be run, until the next time that XEmacs is waiting for an event.
Also note that when focus-follows-mouse is non-nil, the frame
selection is temporary and is reverted when the current command
terminates, much like the buffer selected by `set-buffer'. In order
-to effect a permanent focus change in this case, bind
-focus-follows-mouse to nil, select the frame you want, and do
-a (sit-for 0) within the scope of the binding.
+to effect a permanent focus change, use `set-frame-focus'.
*/
(frame))
{
@@ -3052,6 +3066,7 @@
#if 0 /* FSFmacs */
DEFSUBR (Fignore_event);
#endif
+ DEFSUBR (Fset_frame_focus);
DEFSUBR (Fselect_frame);
DEFSUBR (Fselected_frame);
DEFSUBR (Factive_minibuffer_window);
--- lisp/x-toolbar.el.orig Sun May 3 03:02:31 1998
+++ lisp/x-toolbar.el Sun May 3 03:08:48 1998
@@ -271,7 +271,7 @@
(t
;; However, if the frame already exists, and the user
;; clicks on info, it's OK to raise it.
- (select-frame toolbar-info-frame)
+ (set-frame-focus toolbar-info-frame)
(raise-frame toolbar-info-frame)))
(when (frame-iconified-p toolbar-info-frame)
(deiconify-frame toolbar-info-frame)))
--- lisp/lisp-mode.el.orig Sun May 3 03:03:35 1998
+++ lisp/lisp-mode.el Sun May 3 03:03:53 1998
@@ -757,6 +757,8 @@
(put 'unwind-protect 'lisp-indent-function 1)
(put 'save-current-buffer 'lisp-indent-function 0)
(put 'with-current-buffer 'lisp-indent-function 1)
+(put 'save-selected-frame 'lisp-indent-function 0)
+(put 'with-selected-frame 'lisp-indent-function 1)
(put 'with-temp-file 'lisp-indent-function 1)
(put 'with-temp-buffer 'lisp-indent-function 0)
(put 'with-output-to-string 'lisp-indent-function 0)
--- lisp/gnuserv.el.orig Sun May 3 02:53:46 1998
+++ lisp/gnuserv.el Sun May 3 02:53:59 1998
@@ -446,7 +446,8 @@
;; Visit all the listed files.
(while list
(let ((line (caar list)) (path (cdar list)))
- (select-frame frame)
+ ;(select-frame frame)
+ (set-frame-focus frame)
;; Visit the file.
(funcall (if view
gnuserv-view-file-function
--- lisp/frame.el.orig Sun May 3 02:08:55 1998
+++ lisp/frame.el Sun May 3 02:52:57 1998
@@ -519,13 +519,10 @@
This command selects the frame ARG steps away in that order.
A negative ARG moves in the opposite order.
-This command ignores the value of `focus-follows-mouse'."
+This sets the window system focus, regardless of
+`focus-follows-mouse'."
(interactive "p")
- (let ((frame (selected-frame))
- (old-focus-follows-mouse focus-follows-mouse)
- ;; Allow selecting another frame even when
- ;; focus-follows-mouse is true.
- (focus-follows-mouse nil))
+ (let ((frame (selected-frame)))
(while (> arg 0)
(setq frame (next-frame frame 'visible-nomini))
(setq arg (1- arg)))
@@ -533,11 +530,8 @@
(setq frame (previous-frame frame 'visible-nomini))
(setq arg (1+ arg)))
(raise-frame frame)
- (select-frame frame)
- ;; Allow the focus change to be processed while
- ;; focus-follows-mouse is nil.
- (and old-focus-follows-mouse
- (sit-for 0))
+ ;; This will also select the frame.
+ (set-frame-focus frame)
;this is a bad idea; you should in general never warp the
;pointer unless the user asks for this. Furthermore,
;our version of `set-mouse-position' takes a window,
@@ -549,6 +543,33 @@
))
;; XEmacs-added utility functions
+
+(defmacro save-selected-frame (&rest body)
+ "Execute forms in BODY, then restore the selected frame.
+The value returned is the value of the last form in BODY.
+
+The frame selection is not accompanied by changes to the actual window
+manager focus and is not affected by the value of `focus-follows-mouse'.
+See also `with-selected-frame'."
+ (let ((old-frame (gensym "ssf")))
+ `(let ((,old-frame (selected-frame))
+ ;; This is necessary, in case code within BODY invokes
+ ;; (next-event).
+ (focus-follows-mouse t))
+ (unwind-protect
+ (progn ,@body)
+ (select-frame ,old-frame)))))
+
+(defmacro with-selected-frame (frame &rest body)
+ "Execute forms in BODY with FRAME as the selected frame.
+The value returned is the value of the last form in BODY.
+
+The frame selection is not accompanied by changes to the actual window
+manager focus and is not affected by the value of `focus-follows-mouse'.
+See also `with-selected-frame'."
+ `(save-selected-frame
+ (select-frame ,frame)
+ ,@body))
; this is in C in FSFmacs
(defun frame-list ()
--
Hrvoje Niksic <hniksic(a)srce.hr> | Student at FER Zagreb, Croatia
--------------------------------+--------------------------------
I'm a Lisp variable -- bind me!