-
Notifications
You must be signed in to change notification settings - Fork 3
/
notes.txt
226 lines (224 loc) · 14.9 KB
/
notes.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
_shift,^shift = press shift, release shift?
- begin when key down, end when key up?
- <mode>.<action> = <key combo>
- normal-mode.to.normal-mode=_ctrl,^ctrl,_ctrl,^ctrl
- normal-mode.to.temp-normal-mode=_ctrl,^ctrl
- temp-normal-mode.to.normal-mode=_ctrl,^ctrl
- normal-mode.press-left=_shift
- normal-mode.release-left=^shift
- normal-mode.start-move-left=_leftarrow
- normal-mode.stop-move-left=^leftarrow
- normal-mode.mouse-acceleration, wheel.acceleration
- normal-mode.indicator.color=red
- temp-normal-mode.timeout.duration=1s # automatically changes mode if no key combo was detected during 1s and no action is currently running (e.g. move-up)
- temp-normal-mode.timeout.mode=normal-mode
- temp-normal-mode.oneshot.mode=normal-mode # once an action has run (e.g. move-up), mode changes automatically
- Can assign multiple combo to same action
- normal-mode.press-left=_lshift
- normal-mode.press-left=_rshift
- Can assign one combo to multiple actions
- normal-mode.to.normal-mode=_leftarrow,^leftarrow,_leftarrow
- normal-mode.start-move-left=_leftarrow,^leftarrow,_leftarrow
- Non-last keys involved in a combo should not be eaten
- Reason is Up, Up: if only press single up, the Up,Up combo should not eat the first Up
- The last key event of the combo should be eaten
- In _ctrl,_/ the / should be eaten only if ctrl was pressed (i.e. combo is being prepared)
- Ctrl-A,B == _ctrl _a ^ctrl ^a _b and _ctrl _a ^a ^ctrl _b
- Could do complex combo like hold ctrl, then a, then a again: _ctrl _a ^a _a ^a
- combo timeout = time after which we stop waiting for a combo to be completed (150ms,?)
- A combo has to be non-broken (no unknown key presses), with at most 150ms between keys
- Large timeout to allow Ctrl, wait, Z. Or special __ctrl to indicate no timeout. Or no timeout at all?
- Should a keyevent unrelated to a combo break the combo preparation? Yes.
- Released event cannot be eaten if Pressed event was not eaten, otherwise apps will bug
-- Need user to specify which event should not be eaten (eaten by normal)
- Should a reached combo reset the preparation (no combo accumulation)? No. Maybe. No.
-- Imagine Ctrl+up/down moves the mouse. We want to be able to hold Ctrl, (wait long) then up/down
- This should be done with a mode (enabled with Ctrl)
- _arrow,^arrow,_arrow should enable mouse mode and move up
- Done by defining move-up in both normal-mode and normal-mode
- _arrow,^arrow,_arrow,^arrow,(some time)_arrow should enable mouse mode then move up
- _arrow,^arrow,_arrow,^arrow,_arrow should enable mouse mode then scroll up
- Combo(List<KeyAction>), KeyAction(Key, KeyState=PRESSED,RELEASED)
- KeyEvent(time, action)
- Preparation(List<KeyEvent> events)
- Reset when last key event is not a prefix of any combo
- Preparation.isPrefixOf(Combo)
- Speed should not change when overlapping press-left/press-right. Speed set to 0 when all released.
- On overlaps (press-left/press-right), last action wins (need a stack push/pop)
- ^{shift up|shift down} +rightctrl mean shift and up, and shift down should not be pressed when
this combo (+rightctrl) starts
- getkeystate to reset pressed keys after 10s
- On windows lock screen, I hit space then enter the pin. Space press is recorded by the app but the
corresponding release is never received, never removed from currentlyPressedKeys. This blocks the app.
- toggle logging?
- teleport key should use current display size percentage: not if we go from one screen to another
- Name it move-left-by instead of teleport-left
- mouse.move-by-offset=300
- vimium-like hint (warpd), keynav-like grid?
- Move mouse to center of focused app?
- Hide cursor after 5s
- uncluttered-normal-mode.hide-cursor.enabled+idle-duration
- timeout.duration -> idle-duration
- Add timeout.enabled
- Rename OsManager to Platform
- Check LLKHF_INJECTED?
- Min/max values for grid row/column count
- Do not inherit SwitchMode commands with mode.extend
- Keynav grid (2 rows x 2 columns grid)
- Grid could have arbitrary number of rows/columns (for snapping), but the grid cuts and shifts are done on 2x2
- Snap instead of grid?
- Reset/Show grid to full screen, fixed-size around current mouse position, around focused window
- create-full-screen-grid, create-active-window-grid, create-follow-mouse-grid
- grid.follow-mouse-grid-width/height
- press rightctrl -> temp-snap-mode
- temp-snap-mode -> idle timeout 0.2s -> grid-mode
- temp-snap-mode -> arrow key -> perm-snap-mode
- press rightctrl -> snap-mode -> release rightctrl -> normal-mode
- temp-snap-mode -> quick release rightctrl -> normal-mode
- grid-mode -> release rightctrl -> normal-mode
- If leftctrl also pressed then focused window grid, if leftshift then around current pos
- also moves mouse to grid center: move-to-grid-center-when-created=true
- Hide grid (cannot disable a grid?)
-- If try to use grid commands while grid is hidden/not initialized, create a new full screen grid
- Snap to grid lines (mouse can be outside grid) snap-left
- Half (cut in half) grid in a direction (shrink-grid-top/bottom/left/right)
- arrow keys
- Also moves to grid center automatically: move-to-grid-center-when-cut=true
- Shift grid: move-grid-top
- arrow keys with rightctrl
- move-to-grid-center-when-shifted
- If grid already touches screen edge, then move grid to closest screen
- Resize too fullscreen if grid bigger than new screen
- Teleport forward to +300px is snapping to (or moving-grid) the follow-mouse grid?
- The corresponding grid window should be movable to a neighbor screen
+ Exit gracefully when exception thrown (e.g. infinite switch mode loop)
- Rename shift-grid to move-grid
- Put back update() in IndicatorManager for updating the color
- When moving/snapping grid to edge of screen, check if there is a screen containing grid center
- If not, keep grid in current screen
- mouse-follows-grid-center should not initially synchronize the mouse
- _{rightctrl} move-to-grid-center: does not work for modes triggered after idle timeout
- mouse-follows-grid-center-except-when-grid-created?
- synchronization=mouse-follows-grid-center / grid-center-follows-mouse / mouse-and-grid-center-unsynchronized
- grid.type->area = active-screen 1.0 1.0, active-window 1.0 1.0
- Rename snapRow/ColumnCount to row/ColumnCount
+ IndicatorManager should listen for mouse position and give it to WindowsIndicator
- Hints
- Grid hints (hints on the current grid, which can be a fullscreen or active window or around mouse grid)
- Screen hints = one-hint-per-screen-mode (one per screen)
- Grid type: active-screen (instead of full screen) and all-screens
- all-screens: WindowsOverlay.setGrid(List<Grid>)
- One hint per grid cell
- Screen selection = all-screens grid with row/column count 1
- In all screen grid, cannot move grid or cut grid (but can snap)
- Hint selection is like cutting the grid to a specific cell
- mode.grid.end.shrink-count = 2 to have 2-phase hint selection
- grid.end.next-mode
- Or: mode.grid.next-next-mode-after-cut=smaller-grid-around-cursor-mode
- switch-to-next-mode-after-grid-cut=new-mode
- mode.switch-next-mode-after-hint-selected-=...
- or mode.to.new-mode=once-hint-selected
- Regular hint = active-screen-hints-mode = active-screen grid with row/column count 20 20
- grid.row-count=hint-key-count
- If hint key count == row and column count, then 2-key hints in order (aa, ab, ac, etc.)
- If hint key count > hint count (e.g. screen selection) then 1-key hints
- Else: Find hintLength, hintCount = hintKeyCount^hintLength >= rowCount*columnCount
- grid.hint-enabled=false/true
- Split hint into its own class HintManager
- hint.area=active-screen, active-window, all-screens
- Give a chance to _{} ^{} combos when mode switched? No
- Dragging: normal-mode -> press left -> hint mode (handles left release key) -> normal-mode
+ Update hint windows when screens changed?
+ Hint undo key could be a combo instead of a key
- History (positions previously selected through hints)
- hint.save-position-after-selection=true
- save-position=+leftalt +leftalt
- clear-position-history=+leftalt +leftalt +leftalt
- grid.area/row-count -> grid.layout=position-history | active-screen 0.99 0.99 2(rowCount) 2
- Grid with variable-size rows and columns
- Each historical position is the center of one cell
- Compute the midpoints between consecutive hint positions, that is the cell width/height
- Or one mini 1x1 grid per historical position
- normal-mode -> idle-mode
+ Rename Mouse, Wheel, etc. to Mouse/Wheel/...Configuration
+ mode.blinking-mouse.enabled/visible-duration/invisible-duration
- previous-mode is not great. mode.save-to-mode-history=true?
- previous-mode-from-history-stack
- push-mode-to-history-stack=true
- Change pause-combo-processing-when-mode-activated to when-mode-exited and simplify absolute-snap-mode
- Remove it completely? Ignore switch-mode combo if mode has already been changed?
- Is grid follows mouse useful? Should it be replaced with jump-forward command
and jump-forward-screen-percent?
- Make mouse-follows-grid-center the default, need grid.enabled?
- Or Move to grid center command
++ Zoom mode? Useful for 2-stage hint?
+ Configuration for indicator offset
- Check mode reference tree
+ Improve error handling in config parser
+ Wrap all parseBoolean/... into try catch that log the error with the property key and value
- hint.type -> hint.type=grid .area=active-screen/... hint.area-width-percent, .row-count
- hint.type = position-history
- grid.area
- Remove extend? Replace with absolute-snap-mode.indicator=temp-absolute-snap-mode.indicator
- start-move-up -> start-move.up/down/... (block that can be copied), stop-move.up/down/...
- Allow all mode.Xxx to be copied, but cannot chain them (the copy source cannot, itself, copy from another mode)
- Remove enabled fields like HintMeshConfiguration.enabled?
- Prevent duplicate property keys in configuration files
- Fix undo key which is undoing all
- No UI (just a command line app that loads the configuration from a file)
- Seamlessly move mouse across screens (like mouseable does)
- Configuration file is automatically reloaded when changes are saved to it
- Can have an indicator next to the mouse (or not), with different colors for when idling, moving, pressing buttons, and scrolling
- The indicator re-positions itself around the mouse when the mouse is close to the edges of the screen so that it stays visible
- You can move the mouse from one screen to the next seamlessly (like mouseable). warpd does not allow that as far as I know.
- You can move from one screen to the next using a single hint per screen (warpd calls that the screen selection mode).
- Configuration of keys is done in terms of key press and key release events, and whether the key events should be passed onto other apps or not.
This allows for defining advanced key combos, but at the cost of added complexity of the configuration file
- Distinguish between left and right alt/ctrl/shift keys (they are called them leftalt, rightalt, leftctrl, etc.)
- All keys are treated the same way, meaning that for example, you can implement
"hold capslock then press enter" and "hold Z then press X" combos
just like you would implement a "hold alt then press X" combo
- I made an effort to not interfere with other apps using shortcuts. For example,
if "hold alt then press X" is used to switch to a hint mode, that key combo should not be triggered
if the user holds not only alt but another key (e.g. alt and ctrl).
Similarly, "press then release alt twice in a row" would not prevent another app from using a shortcut that uses alt like "hold alt then press Y"
- Keyboard layout-aware
- Instead of saying "left arrow means move left", the user has to say both
"pressing left arrow means start moving left" and "releasing left arrow means stop moving left"
- Examples of more advanced combos: "hold alt for 1 second" (I personally use that for the clear position history command),
"press then release alt twice in a row".
- Each command (e.g. start-move.left, stop-move.left, press.middle) is triggered by one or more key combos
- The same key combo can be used to trigger multiple commands.
- Multiple key combos can be used to trigger the same command.
- The user defines modes. There is only one predefined mode, the "idle-mode" which has no key combos defined
(i.e. this is the "mousemaster-is-disabled mode").
- Each mode has its own (command -> key combo) map.
- Each mode can have its own mouse and wheel configuration (initial velocity, max velocity, acceleration).
This can be used to create "slow" and "fast" modes.
- A timeout can be set on a mode to switch to another mode after some idle time
(this can be used for disabling mousemaster after a while, or hiding the indicator after a while)
- This way of defining key combos and modes can be used to implement "toggle dragging",
- Chain commands: for example, if your snap to screen edge combo is "hold ctrl then press arrow key", you can snap left/right without releasing ctrl
- Grids: regular keynav-style grids (warpd has them, mouseable doesn't)
- A grid can cover the active screen or the active window
- A grid size can be 0-100% of the active screen/window: I personally use 99% to give the grid an offset
- A grid can follow the mouse: this can be used for implementing mouseable-style "teleport the mouse forward at +300 pixels"
- Hints: regular Vimium-like hints
- A hint grid can cover the active screen, the active window, or all screens (that last one is used for screen selection hints)
- Can automatically trigger a mouse click after a hint is selected
- Position history: multi-screen position history hints (I believe warpd has position history hints for a single screen only)
- The two major differences with mouseable and warpd are the way key combos are defined
(key presses and key releases instead of "just keys"), and the "create your own modes" approach.
A mode is not restricted to "just normal mouse movements", "just grid" or "just hints".
- The configuration of mousemaster is significantly more complex than warpd/mouseable, mostly because you have to think in terms of key presses and key releases.
It's a tradeoff and I've traded configuration simplicity for more flexibility.
I've added a lot of debug logs that are useful for understanding what is going on when creating or debugging a configuration file
- It's Windows only, I have not looked at making it cross-platform simply because I don't have an incentive for doing so
(all my desktops are Windows based). Besides, it is possible that the Linux and macOS APIs offer less control than the Windows API when it
comes to handling mouse and keyboard events, and for that reason some of the features of mousemaster may not currently be implementable in Linux and macOS.
+ idle-mode.to.hibernate-mode=_{firefox.exe | chrome.exe}
hibernate-mode.to.idle-mode=^{firefox.exe chrome.exe}
or
app-alias.hibernateapp=firefox.exe chrome.exe
idle-mode.to.hibernate-mode=_{hibernateapp}
hibernate-mode.to.idle-mode=^{hibernateapp}