[mcclim-cvs] CVS update: mcclim/Backends/beagle/input/events.lisp
Duncan Rose
drose at common-lisp.net
Tue May 17 20:12:38 UTC 2005
Update of /project/mcclim/cvsroot/mcclim/Backends/beagle/input
In directory common-lisp.net:/tmp/cvs-serv27747/beagle/input
Modified Files:
events.lisp
Log Message:
Fixed annoying (and long term) issue with key focus. Focus is
now (or at least, appears to now be) set correctly.
Updated README.txt accordingly.
Date: Tue May 17 22:12:37 2005
Author: drose
Index: mcclim/Backends/beagle/input/events.lisp
diff -u mcclim/Backends/beagle/input/events.lisp:1.2 mcclim/Backends/beagle/input/events.lisp:1.3
--- mcclim/Backends/beagle/input/events.lisp:1.2 Tue May 17 19:51:14 2005
+++ mcclim/Backends/beagle/input/events.lisp Tue May 17 22:12:37 2005
@@ -28,7 +28,7 @@
#||
-$Id: events.lisp,v 1.2 2005/05/17 17:51:14 drose Exp $
+$Id: events.lisp,v 1.3 2005/05/17 20:12:37 drose Exp $
All these are copied pretty much from CLX/port.lisp
@@ -302,24 +302,17 @@
(sheet (%beagle-port-lookup-sheet-for-view *beagle-port* (send window 'content-view))))
;; We don't get exposure notifications when the window has a (Cocoa) backing store.
(cond
- ;; I'm not sure this is right; we need to find the sheet in the hierarchy of this window
- ;; that can accept key events. Can there be multiple sheets this counts for? I'd guess
- ;; so, in which case how do we know which one to set as port key focus? Suspect we can
- ;; only know this by tracking the last view that can be key that received a mouse down?
- ;; *Should* be able to do this by doing a :hit-test on the content view of the receiving
- ;; window after manually grabbing the pointer coordinates.
((send (send notification 'name) :is-equal-to-string #@"NSWindowDidBecomeKeyNotification")
(setf return-event nil)
(when (send window 'is-visible) ; only do if window is on-screen...
- ;; NB: this isn't in the right coordinate system! Convert screen -> content view coords.
- (slet ((pointer-loc (send (@class ns-event) 'mouse-location))
- (loc-in-window (send window :convert-screen-to-base pointer-loc)))
- (let* ((content-view (send window 'content-view))
- (target-view (send content-view :hit-test loc-in-window))
- (target-sheet (%beagle-port-lookup-sheet-for-view *beagle-port* target-view)))
- (unless (null target-sheet)
- (format *debug-io* "Setting focus in *beagle-port* onto (hopefully correct) sheet: ~S~%" target-sheet)
- (%set-port-keyboard-focus target-sheet *beagle-port*))))))
+ (let* ((content-view (send window 'content-view))
+ (target-sheet (%beagle-port-lookup-sheet-for-view *beagle-port* content-view))
+ (frame (pane-frame target-sheet))
+ ;; Works out which sheet *should* be the focus, not which is currently...
+ ;; or at least, so I think.
+ (focus (climi::keyboard-input-focus frame)))
+ (unless (null target-sheet)
+ (setf (port-keyboard-input-focus *beagle-port*) focus)))))
((send (send notification 'name) :is-equal-to-string #@"NSWindowDidExposeNotification")
(setf return-event
(make-instance 'window-repaint-event :timestamp (incf timestamp)
@@ -703,19 +696,28 @@
;;; (oops, we lose the timestamp here.)
;;; Cocoa note: the Frame (NSWindow) must be made key for us to receive events; but they
-;;; must then be sent to the Sheet that has focus.
+;;; must then be sent to the Sheet that has focus. Whilst there are Cocoa mechanisms to
+;;; do this, it's probably best to let CLIM decide on the appropriate sheet and we just
+;;; send all key events to it.
-;;; NB. when the method was renamed it appears that the argument order was also changed.
(defmethod %set-port-keyboard-focus ((port beagle-port) focus &key timestamp)
(declare (ignore timestamp))
- (let ((mirror (sheet-mirror focus)))
- (when mirror
- (let ((window (send mirror 'window)))
- (when window
- (setf (beagle-port-key-focus port) focus)
- (if (send window 'is-key-window)
- (send window :order-front nil)
- (send window :make-key-and-order-front nil)))))))
+ (if (eq (beagle-port-key-focus port) focus)
+ (format *trace-output* "Attempt to set keyboard focus on sheet ~a which already has focus.~%"
+ focus)
+ (let ((mirror (sheet-mirror focus)))
+ (if (null mirror)
+ (format *trace-output* "Attempt to set keyboard focus on sheet ~a which has no mirror!~%"
+ focus)
+ (let ((window (send mirror 'window)))
+ (if (eql window (%null-ptr))
+ (format *trace-output* "Attempt to set keyboard focus on sheet ~a with no NSWindow!~%"
+ focus)
+ (progn
+ (setf (beagle-port-key-focus port) focus)
+ (unless (send window 'is-key-window)
+ (send window 'make-key-window)))))))))
+
;;; Not sure we need to do this... apparently we do. I have stopped flushing
;;; the window after every drawing op, and now things don't get output
More information about the Mcclim-cvs
mailing list