### 7.1 Mode-line Interaction ¶

Mode line formatters can register sections of text to be clickable by use of the color formatters `:on-click` and `:on-click-end`. Any text enclosed by these formatters has its bounds saved, and when the mode line recieves a button press event these bounds are checked against to find a clickable area, whose registered function is then called. These formatters can be thought of as similar to XML tags.

To disable the on-click behavior, remove the function `check-for-ml-press` from the hook *mode-line-click-hook*.

To call a function by click the function must first be registered. The function must take at least one argument, the button code. Here is an example of a click-to-focus function and its registration:

    (defun ml-on-click-focus-window (code id &rest rest)
      (declare (ignore code rest))
      (when-let ((window (window-by-id id)))
        (focus-all window)))

    (register-ml-on-click-id :ml-on-click-focus-window #'ml-on-click-focus-window)

This defines a function that focuses a window based upon its X11 window ID, and registers it under the ID `:ml-on-click-focus-window`. Here is an example of a mode line formatter that makes use of this function:

    (add-screen-mode-line-formatter #\i 'fmt-head-window-list-clickable)
    (defun fmt-head-window-list-clickable (ml)
      "Using *window-format*, return a 1 line list of the windows,
    space seperated and clickable."
      (flet ((fmt-w (w)
               (let ((str (format-expand *window-formatters*
                                         *window-format*
                                         w)))
                 (format-with-on-click-id (if (eq w (current-window))
                                              (fmt-highlight str)
                                              str)
                                          :ml-on-click-focus-window
                                          (window-id w)))))

        (format nil "~{~a~^ ~}"

                (mapcar #'fmt-w
                        (sort1 (head-windows (mode-line-current-group ml)
                                             (mode-line-head ml))
                               #'< :key #'window-number)))))

In the above formatter, every windows expansion is wrapped in a :on-click/end pair, which takes the ID we registered as the function to call and the window ID as an argument to be passed to its function. The arguments provided to `:on-click` will be read but not evaluated. The string generated will look like so:

    "^(:on-click :ml-on-click-focus-window 308242)window text^(:on-click-end)"

Clickable text can be nested, in which case the innermost clickable text will take precendent. In the following example `:id2` will be dispatched when clicking `2`, but `:id1` will be dispatched when clicking `1` and `3`:

    "^(:on-click :id1)1^(:on-click :id2)2^(:on-click-end)3^(:on-click-end)"

If one wished for right click to delete windows, then the following example could be placed in the .stumpwmrc:

    (labels ((ml-on-click-focus-or-delete-window (code id &rest rest)
               (declare (ignore rest))
               (when-let ((window (window-by-id id)))
                 (let ((button (decode-button-code code)))
                   (case button
                     ((:left-button)
                      (focus-all window))
                     ((:right-button)
                      (delete-window window)))))))
      (register-ml-on-click-id :ml-on-click-focus-window
                               #'ml-on-click-focus-or-delete-window))

This will replace the `:ml-on-click-focus-window` function, and all uses of `:on-click` formatters referring to `:ml-on-click-focus-window` will use the new function.

Function: register-ml-on-click-id id fn ¶

  Register FN with ID, to be used by the :on-click mode line color formatter.

Function: format-with-on-click-id string id &rest arguments ¶

  Wrap STRING in :on-click and :on-click-end color formatters, using ID as the id to call when clicked and ARGUMENTS as the arguments to pass to the ID’s function. STRING may not contain the :> color formatter, but may contain any other color formatters.