[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