mirror of
https://github.com/stumpwm/stumpwm.git
synced 2026-09-10 07:26:20 -04:00
Updated clickable area processing to allow nested areas.
This commit is contained in:
parent
c456632ac2
commit
44ebc9bf5d
116
color.lisp
116
color.lisp
|
|
@ -332,64 +332,64 @@ string."
|
|||
"Renders STRING-OR-PARTS to the pixmap in CC. Returns the height and width of
|
||||
the rendered line as two values. The returned width is the value of X plus the
|
||||
rendered width."
|
||||
(let* ((parts (if (stringp string-or-parts)
|
||||
(parse-color-string string-or-parts)
|
||||
string-or-parts))
|
||||
(height (max-font-height parts cc))
|
||||
(current-on-click nil))
|
||||
(loop
|
||||
for (part . rest) on parts
|
||||
for font-height-difference = (- height
|
||||
(font-height (ccontext-font cc)))
|
||||
for y-to-center = (floor (/ font-height-difference 2))
|
||||
if (stringp part)
|
||||
do (draw-image-glyphs
|
||||
(ccontext-px cc)
|
||||
(ccontext-gc cc)
|
||||
(ccontext-font cc)
|
||||
draw-x (+ y y-to-center (font-ascent (ccontext-font cc)))
|
||||
part
|
||||
:translate #'translate-id
|
||||
:size 16)
|
||||
(incf draw-x (text-line-width (ccontext-font cc)
|
||||
part
|
||||
:translate #'translate-id))
|
||||
else
|
||||
do (case (first part)
|
||||
((:on-click)
|
||||
(when ml
|
||||
(setf current-on-click (list draw-x (cadr part) (cddr part)))))
|
||||
((:on-click-end)
|
||||
(when ml
|
||||
(register-ml-boundaries-with-id
|
||||
ml
|
||||
(first current-on-click)
|
||||
draw-x
|
||||
y
|
||||
(+ y y-to-center (font-ascent (ccontext-font cc)))
|
||||
(second current-on-click)
|
||||
(third current-on-click))
|
||||
(setf current-on-click nil)))
|
||||
((:>)
|
||||
(let ((xbeg (- (xlib:drawable-width (ccontext-px cc))
|
||||
x
|
||||
(rendered-string-size rest cc))))
|
||||
;; Register a sentinel on click boundary to prevent overlapping
|
||||
;; renders from being clickable (eg if a formatter before :> is
|
||||
;; larger than the space available for it).
|
||||
(when ml
|
||||
(register-ml-boundaries-with-id ml xbeg most-positive-fixnum
|
||||
y
|
||||
(+ y y-to-center (font-ascent
|
||||
(ccontext-font
|
||||
cc)))
|
||||
:ml-on-click-do-nothing
|
||||
nil))
|
||||
(render-string rest cc xbeg y :ml ml))
|
||||
(loop-finish))
|
||||
(otherwise
|
||||
(apply #'apply-color cc (first part) (rest part)))))
|
||||
(values height draw-x)))
|
||||
(macrolet ((register (thing)
|
||||
`(let ((top ,thing))
|
||||
(when top
|
||||
(register-ml-boundaries-with-id ml
|
||||
(first top)
|
||||
draw-x
|
||||
y
|
||||
(+ y y-to-center
|
||||
(font-ascent
|
||||
(ccontext-font cc)))
|
||||
(second top)
|
||||
(third top))))))
|
||||
(let* ((parts (if (stringp string-or-parts)
|
||||
(parse-color-string string-or-parts)
|
||||
string-or-parts))
|
||||
(height (max-font-height parts cc))
|
||||
(current-on-click nil))
|
||||
(loop
|
||||
for (part . rest) on parts
|
||||
for font-height-difference = (- height
|
||||
(font-height (ccontext-font cc)))
|
||||
for y-to-center = (floor (/ font-height-difference 2))
|
||||
if (stringp part)
|
||||
do (draw-image-glyphs
|
||||
(ccontext-px cc)
|
||||
(ccontext-gc cc)
|
||||
(ccontext-font cc)
|
||||
draw-x (+ y y-to-center (font-ascent (ccontext-font cc)))
|
||||
part
|
||||
:translate #'translate-id
|
||||
:size 16)
|
||||
(incf draw-x (text-line-width (ccontext-font cc)
|
||||
part
|
||||
:translate #'translate-id))
|
||||
else
|
||||
do (case (first part)
|
||||
((:on-click)
|
||||
(when ml
|
||||
(push (list draw-x (cadr part) (cddr part)) current-on-click)))
|
||||
((:on-click-end)
|
||||
(when ml
|
||||
(register (pop current-on-click))))
|
||||
((:>)
|
||||
(let ((xbeg (- (xlib:drawable-width (ccontext-px cc))
|
||||
x
|
||||
(rendered-string-size rest cc))))
|
||||
;; Register a sentinel on click boundary to prevent overlapping
|
||||
;; renders from being clickable (eg if a formatter before :> is
|
||||
;; larger than the space available for it).
|
||||
(when ml
|
||||
(loop for top = (pop current-on-click)
|
||||
while top
|
||||
do (register top)))
|
||||
(render-string rest cc xbeg y :ml ml))
|
||||
(loop-finish))
|
||||
(otherwise
|
||||
(apply #'apply-color cc (first part) (rest part)))))
|
||||
(values height draw-x))))
|
||||
|
||||
(defun render-strings (cc padx pady strings highlights &key ml)
|
||||
(let* ((gc (ccontext-gc cc))
|
||||
|
|
|
|||
|
|
@ -333,7 +333,8 @@ timer.")
|
|||
()
|
||||
:ml ml)
|
||||
(when (mode-line-new-bounds ml)
|
||||
(setf (mode-line-on-click-bounds ml) (mode-line-new-bounds ml)))))
|
||||
(setf (mode-line-on-click-bounds ml)
|
||||
(reverse (mode-line-new-bounds ml))))))
|
||||
(handler-case
|
||||
(when (or force (not (string= (mode-line-contents ml) str)))
|
||||
(resize-and-render str))
|
||||
|
|
|
|||
|
|
@ -2027,10 +2027,12 @@ color variables.
|
|||
@node Mode-line Interaction, , Mode-line, Mode-line
|
||||
@section 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.
|
||||
use of the color formatters @code{:on-click} and
|
||||
@code{: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
|
||||
@code{check-for-ml-press} from the hook @var{*mode-line-click-hook*}.
|
||||
|
|
@ -2049,7 +2051,7 @@ example of a click-to-focus function and its registration:
|
|||
@end example
|
||||
|
||||
This defines a function that focuses a window based upon its X11 window
|
||||
ID, and registers it under the ID @code{:ML-ON-CLICK-FOCUS-WINDOW}. Here
|
||||
ID, and registers it under the ID @code{:ml-on-click-focus-window}. Here
|
||||
is an example of a mode line formatter that makes use of this function:
|
||||
|
||||
@example
|
||||
|
|
@ -2078,14 +2080,23 @@ space seperated and clickable."
|
|||
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:
|
||||
arguments provided to @code{:on-click} will be read but not
|
||||
evaluated. The string generated will look like so:
|
||||
|
||||
@example
|
||||
"^(:on-click :ml-on-click-focus-window 308242)window text^(:on-click-end)"
|
||||
@end example
|
||||
|
||||
If one wished for right click to delete the window, then the following
|
||||
Clickable text can be nested, in which case the innermost clickable text
|
||||
will take precendent. In the following example @code{:id2} will be
|
||||
dispatched when clicking @code{2}, but @code{:id1} will be dispatched
|
||||
when clicking @code{1} and @code{3}:
|
||||
|
||||
@example
|
||||
"^(:on-click :id1)1^(:on-click :id2)2^(:on-click-end)3^(:on-click-end)"
|
||||
@end example
|
||||
|
||||
If one wished for right click to delete windows, then the following
|
||||
example could be placed in the .stumpwmrc:
|
||||
|
||||
@example
|
||||
|
|
|
|||
Loading…
Reference in a new issue