Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mousegrid: implement grid-based mouse navigation #24811

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from

Conversation

windo
Copy link

@windo windo commented Jan 12, 2025

Add 2 modes of "grid-based" mouse cursor movement schemes:

  1. Specifying an absolute x-y coordinate using 26-character alphabet
  2. Iteratively picking a 3x3 direction to zoom in towards

Both of these pose as an absolute positiong digitizer.

Description

Complements mouse keys by allowing for moving the cursor to the right part of the screen rapidly.

I've only just implemented the alphabet-based method so I haven't tried to use that mode very much yet. But I have used the direction-based method lightly over the past weeks and in some cases I prefer it over reaching for an actual pointing device. So I think something like this could be pretty nice.

See the documentation for an overview of how to use this.

Types of Changes

  • Core
  • Bugfix
  • New feature
  • Enhancement/optimization
  • Keyboard (addition or update)
  • Keymap/layout (addition or update)
  • Documentation

Issues Fixed or Closed by This PR

Checklist

  • My code follows the code style of this project: C, Python
  • I have read the PR Checklist document and have made the appropriate changes.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • I have tested the changes and verified that they work and don't break anything (as well as I can manage).

Add 2 modes of "grid-based" mouse cursor movement schemes:

1. Specifying an absolute x-y coordinate using 26-character alphabet
2. Iteratively picking a 3x3 direction to zoom in towards

Both of these pose as an absolute positiong digitizer.
@github-actions github-actions bot added core documentation dd Data Driven Changes labels Jan 12, 2025
@zvecr zvecr changed the base branch from master to develop January 12, 2025 21:33
@windo
Copy link
Author

windo commented Jan 13, 2025

All the keys definitiely don't need to be in the basic range (I wasn't sure how to define keys at all, so this is just what I got working first) and maybe some actions (NEAR and ANIMATE) perhaps are not as needed or can just exist as APIs to be called from custom keys users set up for themselves.

I haven't added any tests, but happy to add some if it looks like this feature might be worth merging.

Copy link
Member

@tzarc tzarc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This set of changes will do for now, will do another pass once addressed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will need to be 0.0.7 as this version of keycodes is already locked-in on master. You'll need another file, keycodes_0.0.7.hjson with content {} too.

@@ -0,0 +1,116 @@
{
"keycodes": {
"0x00E8": {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's start these at a higher keycode range -- this low is a bit too close to pure USB HID keycodes.
Perhaps starting at 0x77C0?

|0 |`MG_L` |`MG_C`|`MG_R` |
|+1|`MG_BL`|`MG_B`|`MG_BR`|

In first interation, the whole screen is divided into a 3x3 grid to pick from, while second iteration picks within the 3x3 subgrid of the "quadrant" picked in the first iteration.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically we'd need to be a 2x2 grid for quadrants to work as a term. Given that the grid size is configurable, perhaps we swap to segments?

Suggested change
In first interation, the whole screen is divided into a 3x3 grid to pick from, while second iteration picks within the 3x3 subgrid of the "quadrant" picked in the first iteration.
In first interation, the whole screen is divided into a 3x3 grid to pick from, while second iteration picks within the 3x3 subgrid of the segment picked in the first iteration.


In first interation, the whole screen is divided into a 3x3 grid to pick from, while second iteration picks within the 3x3 subgrid of the "quadrant" picked in the first iteration.

Since the "quadrants" are not visualized on screen while navigating, if a movement target is kind of between two quadrants, it can be difficult to tell which one is the "correct" coordinate.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Since the "quadrants" are not visualized on screen while navigating, if a movement target is kind of between two quadrants, it can be difficult to tell which one is the "correct" coordinate.
Since the segments aren't displayed on screen while navigating, it can be difficult to determine which segment is 'correct' when a movement target spans two segments.


Since the "quadrants" are not visualized on screen while navigating, if a movement target is kind of between two quadrants, it can be difficult to tell which one is the "correct" coordinate.

In order to be forgiving of some inaccuracy, the default configuration leaves a little bit of buffer by zooming in slightly less than would be required for the 1/9th of the "quadrant". This means that for slightly inaccurate path can still reach the target but may require an extra keystroke.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
In order to be forgiving of some inaccuracy, the default configuration leaves a little bit of buffer by zooming in slightly less than would be required for the 1/9th of the "quadrant". This means that for slightly inaccurate path can still reach the target but may require an extra keystroke.
The default configuration accounts for some inaccuracy by zooming in slightly less than what would be required for exactly 1/9th-sized segments. This allows slightly inaccurate paths to still reach the target, though it may require an extra keystroke.

// Little bit of overlap when using directional grid to further refine cursor
// position.
#ifndef MG_ALPHABET_RESCALE_MULTIPLIER
# define MG_ALPHABET_RESCALE_MULTIPLIER 2.0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# define MG_ALPHABET_RESCALE_MULTIPLIER 2.0
# define MG_ALPHABET_RESCALE_MULTIPLIER 2.0f

}

void cancel_animation(void) {
animation_since = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
animation_since = 0;
cancel_deferred_exec(animation_token);

default:
dx = 0;
dy = 0;
animation_since = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
animation_since = 0;
cancel_animation();

Comment on lines +89 to +93
if (animation_since == 0) {
// Animation has been cancelled.
return 0;
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (animation_since == 0) {
// Animation has been cancelled.
return 0;
}

Comment on lines +43 to +44
// Little bit of overlap when using directional grid to further refine cursor
// position.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please describe this value's usage a bit more:

Suggested change
// Little bit of overlap when using directional grid to further refine cursor
// position.
// Little bit of overlap when using directional grid to further refine cursor
// position. Lower values mean XXXXXXX, higher values mean YYYYYY.

@tzarc
Copy link
Member

tzarc commented Jan 15, 2025

Also, bunch of build failures due to:

quantum/keyboard.c:495:5: error: implicit declaration of function 'mousegrid_init' [-Wimplicit-function-declaration]
  495 |     mousegrid_init();
      |     ^~~~~~~~~~~~~~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core dd Data Driven Changes documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants