How to set the focus to a specific pane, in CLIM?

64 views Asked by At

At startup, tagger-app should give the input focus to pane2 text-field. How can I do this?

(cl:eval-when (:compile-toplevel :load-toplevel :execute)
  (ql:quickload :mcclim))

(defpackage :tagger
  (:use #:clim-lisp #:clim))

(in-package :tagger)

(define-application-frame tagger-app () ()

  (:panes
      (pane1 :text-field)
      (pane2 :text-field))

  (:layouts
     (default
       (vertically ()
         (labelling (:label "Pane 1") pane1)
         (labelling (:label "Pane 2") pane2)))))

(defun run-tagger-app ()
  (run-frame-top-level (make-application-frame 'tagger-app)))

(run-tagger-app)

I tried to study the CLIM documentation, but there are too much details.

2

There are 2 answers

1
Massimo Zaniboni On

jackdaniel, one of McCLIM maintainers, answered on #CLIM IRC group in this way

(defmethod clim:run-frame-top-level :before
  ((app tagger-app) &key)
  (clim:stream-set-input-focus (find-pane-named app 'pane1)))

Note the usage of :before, instead of :after, because run-frame-top-level is not a "normal" method, returning immediately a result, but it is an always running loop (as the name run-... suggests), that will terminate when the frame passed as argument is closed.

2
John Carroll On

You could do the following

(defmethod run-frame-top-level :before ((frame tagger-app) &key &allow-other-keys)
  (let ((pane2 (find-pane-named frame 'pane2)))
    (when pane2
      (setf (port-keyboard-input-focus (port frame)) pane2))))

If pane2 were a stream pane then the solution would be a bit simpler (you could specialize frame-standard-input) – but it's not.