CLIM mail archive


Still trying to get typed user input while reading commands

I am still trying to read a string that a user types in while also
reading commands.  The behavior I want is the user can type some
input and use the pointer to enter commands or presentation-actions.
The problem seems to be that there is really only one stream per frame
manager so when you read a command you cannot read anything else.

Currently, I have a separate frame running in a separate process.
However, when One of my frames tries to read a command, the other
cannot read characters from the stream.  All of the characters go to
the stream that the first frame is reading a command on, the command
reader looks at it, decides it is not a command and throws it away.
It does not matter which window the mouse is in.  The following
program demonstrates this behavior.

The only way I can make this work is by fooling clim into generating a
new frame manager.  The way I do this is by running lisp remotely
under emacs that sets up the display variable so that it runs on my
console.  I then ask clim to find a frame manager with the home machine
as the display for the port.  This way each process gets its own frame
manager and the front-end does not grab the user's input.

This behavior seems to preclude doing anything other than reading
commands and executing them.  Am I missing something?

Nathaniel G. Martin           Department of Computer Science       University of Rochester
(716) 275-4198                Rochester, NY  14627-0226

(defun TEST ()
   (setq *fe-frame*
    (CLIM:make-application-frame 'front-end
				 :width 1100
				 :height 800))))

(CLIM:define-application-frame FRONT-END ()
  (:menu-bar t)
  (:panes (front-end-display :application))
  (:layouts (:default front-end-display)))

(defmethod CLIM:DEFAULT-FRAME-TOP-LEVEL ((frame front-end)
					 &key command-parser
					      (prompt "Enter Utterancs"))
  ;; Loops getting a command.  Read-frame-command will time after a second.
  (unless (eq (CLIM:frame-state frame) :enabled)
    (CLIM:enable-frame frame))
    (let* ((*standard-output* (CLIM:get-frame-pane frame 'front-end-display))
	   (*standard-input* (CLIM:get-frame-pane frame 'front-end-display))
	    (or (CLIM:frame-query-io frame) *standard-input*))
	    (or (CLIM:frame-error-output frame) *standard-output*)))
	(CLIM:catch-abort-gestures ("Return to ~A command level"
			       (CLIM:frame-pretty-name frame))
	  (let ((command
		 (CLIM:read-frame-command frame :stream *standard-output*)))
	    (when command
	      (CLIM:execute-frame-command frame command)))

(define-front-end-command (COM-QUIT :menu "Quit") ()
  ;; A single command for read-frame-command to read from the menu
  (CLIM:frame-exit CLIM:*application-frame*))

(defmethod CLIM:READ-FRAME-COMMAND ((frame front-end) &key stream)
  ;; Times out reading a command so I can do some processing inside
  ;; the top-level loop when no command is entered.
  (MP:with-timeout (1)
    (CLIM:read-command (CLIM:frame-command-table frame)
		       :stream stream)))

(defmethod CLIM:RUN-FRAME-TOP-LEVEL :around ((frame front-end)
					     &key &allow-other-keys)
  ;; When you start the front end frame, start a user input frame in a
  ;; different process
  (let* ((user-frame
	  (CLIM:make-application-frame 'user-input))
	   `(:name "Select a Window" 
	   #'CLIM:run-frame-top-level user-frame)))
    (when user-input-process
      (MP:process-kill user-input-process))))

(CLIM:define-application-frame USER-INPUT ()
  (:geometry :left 200 :top 850 :width 1100 :height 100)
  (:panes (input-pane :application))
  (:layouts (default input-pane)))

(defmethod CLIM:DEFAULT-FRAME-TOP-LEVEL ((frame user-input)
					 &key command-parser
					      (prompt "Enter Utterancs"))
  ;; Loops accepting a string.  Will not work because
  ;; read-frame-command from the other frame, the other process grabs
  ;; all the characters from the stream and throws them away.
  (unless (eq (CLIM:frame-state frame) :enabled)
    (CLIM:enable-frame frame))
      (let* ((*standard-output* (CLIM:get-frame-pane frame 'input-pane))
	     (*standard-input* (CLIM:get-frame-pane frame 'input-pane))
	      (or (CLIM:frame-query-io frame) *standard-input*))
	      (or (CLIM:frame-error-output frame) *standard-output*)))
	  (CLIM:catch-abort-gestures ("Return to ~A command level"
				 (frame-pretty-name frame))
	    (let ((stream *standard-input*))
	      (CLIM:accept 'string
			   '(#\return #\newline)
			   :stream stream))
	    (terpri stream))

Main Index | Thread Index