The reason is tooltips for buttons that lie along the left or bottom
edge of the app window. Since adding tooltips I noticed that the tooltip
on the 'next' button (which lies all down the right margin of the
window) would continue to be visible after the mouse moves off the
window. It turns out that LÖVE doesn't disable the mouse position
somehow after it goes off screen. It just remains at 0 or width-1 or
height-1.
Why was I not seeing the same issue with the 'previous' button? Kinda by
happy accident. The checks in button.lua were comparing using < and >,
not <= or >=. And the x coordinate when the mouse goes off window is 0.
So the quick solution is to remove one px of clickable area from the
bottom and right. It doesn't seem too hacky; the icon switches to
resizing the window anyway when you're _right_ at the border.
I'm also focusing now on the fact that pixel values in LÖVE go from 0 to
width-1 in spite of Lua's 1-based indexing in most places.
Hopefully this is easy to remember from left to right:
- run is F1
- stop is F2
- hide/show is F3
- save is F4
- load is F5
There are also tooltips to introduce these shortcuts to newcomers.
Most of the shortcuts are only enabled when code is visible. In keeping
with existing conventions for mouse events, we leave most event handlers
for the script when code is hidden. The only exception is 'F3' to show
code. So if you want to use a shortcut 'k' when code is hidden, you have
to instead use 'F3 k F3'.
This is all tentative and open to change. But I'll probably grow more
reluctant to change the shortcuts in a few weeks or months.
This is compatible with Javascript, and it also seems like a better
default; when people forget to think about return values in click
handlers, they should be consumed.
Symptom: a test (test_click_to_create_drawing) started randomly failing
after I inserted a `return` 2 commits ago.
Cause: my tests call edit.draw, but button handlers only get cleared in
app.draw. So my tests weren't clearing button handlers, and every call
to edit.draw was accumulating states. Still unclear why those were going
to different state objects after the `return`, but anyway. I'm not going
to understand every last thing that happens when things go wrong, just
guarantee they can't go wrong. And the way to do that is to decentralize
button handlers to each state that receives them.
The State object in buttons.lua doesn't have to be Editor_state. It just
has to be some table that provides a Schelling Point for shared state.