reworked refreshing from stump, readme, presentations

Removed the patched stumpwm::eval-command function and instead hung a
refresh function on the event hook in stumpwm.

moved highlighting of current window/group into the present method.

added a lock to the redisplay to function to (hopefully) cut down on
freezes/hanging of the mode line.

rewrote goals and TODO portion of the readme.
This commit is contained in:
Nathan Shostek 2021-02-11 21:17:24 +01:00
parent 41098bd809
commit 9341d8d6f4
5 changed files with 47 additions and 73 deletions

View file

@ -2,7 +2,7 @@
#+AUTHOR: Shozo «szos at posteo dot net»
* CLIM Mode Line
This is a project to write a dock using CLIM inspired by the emacs and stumpwm mode lines.
This is a project to write a dock using CLIM inspired by the emacs and StumpWM mode lines.
** Usage
Currently the (imo) best way to utilize this modeline is to launch StumpWM as normal and then start a swank/slynk server and connect to it. From the repl evaluate
@ -22,24 +22,13 @@
At this point the mode line should pop up.
- NB! If you kill the mode line process/thread, the built in stumpwm mode line wont return. To kill and restart the clim mode line interrupt the ~run-mode-line~ fuction we ran in our second repl (via =C-c C-c=) and abort the evaluation, then run the stumpwm command ~restart-soft~. This should bring back the built in mode line, and you can follow the steps above to reopen the clim mode line. If you dont have access to the second repl, you can evaluate the following in any repl connected to the image· ~(clim-mode-line::com-quit)~
* Design Goals
The goal of this system is to suppland the built in stumpwm mode line and input line. To this end there are three general layouts/display items we need to make:
1. we need a pane to display everything
- this is pretty easy, we already have it. its just an application pane we draw text to
2. We need an execute-extended-command pane
- this can be harder to implement. Its made easier by the fact that we wont have to wrap lines, but complicated by the fact that we need to accept arguments to some commands. Hopefully theres a built in modeline pane in drei or esa.
3. We need to accept arguments and prompt the user.
- This is probably the hardest part. What I think is the best course of action, is when accepting an extended command (think stumpwm colon commands) that takes arguments, we want to create a pop-up to accept them, and we want that pop up to not be managed by stumpwm and not relinquish focus to any other windows (aside from the mode line) until its finished getting the arguments. For example, we press =C-t ;= to open up the modeline execute-extended-command layout. we type in =Move Window To Group=, and a popup appears, asking us for the window and the group, while simultaneously the windows and groups in the mode line become active (through presentations) and clicking on them will satisfy that specific argument to the command we entered. Alternatively, we could type the window (name/number/class/title/etc) and the group (name/number/etc) in the popup, and then press meta-RET to submit it.
* Goals
The initial goal is to get a mode line esq application written in CLIM, which doesnt hang, and allows for CLIM commands to be dispatched via clicking on elements in the mode line.
After that is completed, we can evaluate adding in a command reading system through the mode line.
* Todo List
** TODO Fix drag and drop translator
Drag and drop translator needs fixing, it is unclear why the second argument fails to be aquired.
** TODO Update on window map/unmap
We want to update the frame whenever a map/unmap event occurs. This should probably be developed as a stumpwm mode line replacement and not a standalone dock/panel. Thus we can say with certainty that the mode line process will be within the same lisp image as stumpwm, and we can use stumpwm directly, and update the mode line directly from stumpwm. This also lets us get an idea of various other aspects, such as groups, heads, etc.
** TODO Fix Presentation Types
Presentation types need to be fleshed out. What we want to have happen is, for example, if
we define a command to move a window to a group, we want to be able to control-click on a window to select it, then click on a group and the window gets sent to that group. This is the same purpose as the drag and drop translator, but we want both working so we can define different behaviores for dragging vs clicking/keystrokes etc.
** TODO Fix Commands
Commands arent functioning currently.
** TODO Solve Threading Issues
It is unclear whether crashes are caused by threading issues. This needs to be investigated and solved.

View file

@ -11,7 +11,7 @@
:display-function 'clim-mode-line-display-function
;; :width 1920
;; :height 10
:incremental-redisplay t
;; :incremental-redisplay t
:scroll-bars nil
:borders nil)
;; We should add an execute-extended-command, and switch to a layout containing that when
@ -42,9 +42,15 @@
(setf *mode-line-active* t)
(run-frame-top-level frame)))
(defun redisplay-clim-mode-line (&optional (ml (find-application-frame 'clim-mode-line :create nil :activate nil)))
(when ml
(redisplay-frame-panes ml :force-p t)))
(defvar *redisplay-mode-line-lock* (bt:make-lock "cml-lock"))
(defun redisplay-clim-mode-line (&optional (ml (find-application-frame
'clim-mode-line
:create nil
:activate nil)))
(bt:with-lock-held (*redisplay-mode-line-lock*)
(when ml
(redisplay-frame-panes ml :force-p t))))
(defmethod clime:find-frame-type ((frame clim-mode-line))
"this method sets the window type via clim-clx::adopt-frame as defined below."

View file

@ -6,10 +6,7 @@
(loop for group in (stumpwm::sort-groups (stumpwm:current-screen))
with current = (stumpwm:current-group)
do (slim:cell
(if (eql group current)
(with-drawing-options (pane :ink +red+)
(present group 'stumpwm::group :stream pane :single-box t))
(present group 'stumpwm::group :stream pane :single-box t))))
(present group 'stumpwm::group :stream pane :single-box t)))
(slim:cell (format pane "]")))
(defun format-windows (frame pane)
@ -17,13 +14,11 @@
(slim:cell (format pane "["))
(loop for window in (stumpwm::sort-windows (stumpwm:current-group))
with current = (stumpwm:current-window)
do (slim:cell (if (eql window current)
(with-drawing-options (pane :ink +red+)
(present window 'stumpwm::window :stream pane
:single-box t))
(present window 'stumpwm::window :stream pane
:single-box t))))
(slim:cell (format pane "]")))
do (slim:cell (present window 'stumpwm::window :stream pane
:single-box t)))
(slim:cell (format pane "]"))
;; (slim:cell (format pane "Current Window: ~A" (stumpwm:current-window)))
)
(defun format-mode-line (frame pane)
"As the default mode line formatting function, format-mode-line walks through the list of active
@ -31,7 +26,6 @@ formatters and calls them within the appropriate row/column configuration. "
(let ((flists (if (functionp (car *mode-line-active-formatters*))
(list *mode-line-active-formatters*)
*mode-line-active-formatters*)))
;; (dragging-output (pane)) ; useful?
(slim:with-table (pane)
(loop for flist in flists
do (slim:row

View file

@ -1,5 +1,8 @@
(in-package :clim-mode-line)
(defvar *current-group-color* +red+)
(defvar *current-window-color* +red+)
;;; Presentation Methods
(define-presentation-method present
@ -7,12 +10,20 @@
(let ((str (string-trim '(#\space) (stumpwm::format-expand
stumpwm::*window-formatters*
stumpwm::*window-format*
window))))
(format stream "~A" str)))
window)))
(curwin (stumpwm:current-window)))
(if (eq curwin window)
(with-drawing-options (stream :ink *current-window-color*)
(format stream "~A" str))
(format stream "~A" str))))
(define-presentation-method present
(group (type stumpwm::group) stream view &key)
(format stream "~A" (stumpwm:group-name group)))
(let ((curgrp (stumpwm:current-group)))
(if (eq curgrp group)
(with-drawing-options (stream :ink *current-group-color*)
(format stream "~A" (stumpwm:group-name group)))
(format stream "~A" (stumpwm:group-name group)))))
;;; Commands
@ -54,9 +65,7 @@
(define-clim-mode-line-command (com-delete-window)
((window stumpwm::window))
(stumpwm:delete-window window)
;; (redisplay-clim-mode-line)
(window-refresh (find-pane-named *application-frame* 'display)))
(stumpwm:delete-window window))
(define-clim-mode-line-command (com-kill-window)
((window stumpwm::window))

View file

@ -1,36 +1,12 @@
(in-package :stumpwm)
;;; We want to redisplay our clim mode line every time a command is run.
;;; We want to redisplay our clim mode line every time a command is run.
(defun eval-command (cmd &optional interactivep)
"exec cmd and echo the result."
(labels ((parse-and-run-command (input)
(let* ((arg-line (make-argument-line :string input
:start 0))
(cmd (argument-pop arg-line)))
(let ((*interactivep* interactivep))
(call-interactively cmd arg-line)))))
(multiple-value-bind (result error-p)
;; this fancy footwork lets us grab the backtrace from where the
;; error actually happened.
(restart-case
(handler-bind
((error (lambda (c)
(invoke-restart 'eval-command-error
(format nil "^B^1*Error In Command '^b~a^B': ^n~A~a"
cmd c (if *show-command-backtrace*
(backtrace-string) ""))))))
(parse-and-run-command cmd))
(eval-command-error (err-text)
:interactive (lambda () nil)
(values err-text t)))
;; interactive commands update the modeline
(update-all-mode-lines)
(defun refresh-clim-mode-line-hook-fn (&rest ignore)
(declare (ignore ignore))
(handler-case
(clim-mode-line::redisplay-clim-mode-line)
(cond ((stringp result)
(if error-p
(message-no-timeout "~a" result)
(message "~a" result)))
((eq result :abort)
(unless *suppress-abort-messages*
(message "Abort.")))))))
(error () nil)))
(add-hook *event-processing-hook* 'refresh-clim-mode-line-hook-fn)