Giter VIP home page Giter VIP logo

scoot's Introduction

Scoot

Meet Scoot, your friendly cursor teleportation and actuation tool.

Scoot helps you efficiently move your mouse cursor, using keyboard shortcuts!

For updates, follow @mjrusso on Twitter.

build status

Scoot, MacOS Cursor Actuator


Scoot App Icon

Scoot is a tiny utility app that provides fast, keyboard-driven control over the mouse pointer. Scoot lets you move your mouse—and click and drag, too—all from the comfort of your keyboard.

Scoot supports two primary navigation modes: element-based, and grid-based.

  • Element-based navigation: MacOS accessibility APIs are used to find user interface elements, such as buttons and links, on the user's screen. (In this mode, Scoot will look for elements in the focused window of the frontmost app.) Here, for example, Scoot has identified the only link on the page ("More information..."), and assigned it the key sequence "aa":

Scoot using the element-based navigation mode

  • Grid-based navigation: all connected screens are subdivided into a grid of equally-sized cells.

Scoot using the grid-based navigation mode

Each location is identified by a unique character sequence, making each element (or cell) uniquely addressable with the keyboard — simply type the associated key sequence to teleport your mouse cursor to that location.

Scoot also supports moving the mouse cursor using text editing keyboard shortcuts that you're likely already familiar with (specifically, those for moving the insertion point). Scoot supports standard MacOS text editing shortcuts, as well as Emacs and vi keybindings. For a full breakdown, see the usage documentation.

There's also a supplementary usage mode:

  • Freestyle: a freeform usage mode that offers no special navigation assistance. It's like using the grid-based navigation mode, but without bringing up the grid.

Freestyle mode is particularly handy for those cases where you want to quickly nudge the cursor using the (re-purposed) text editing keyboard shortcuts, and would prefer to not have the grid or element-based views on screen.

About

  • This project started as an experiment: an attempt to craft a keyboard-driven mouse movement utility that's efficient, and (more importantly) that users will actually want to use. It has met that bar, at least for the primary author. (Scoot may not be for you, and that's totally fine!)

  • Scoot is not intended to replace the mouse or trackpad entirely. It's here to augment them.

  • Scoot runs on MacOS 11 (Big Sur), and 12 (Monterey).

  • Scoot is an AppKit app, written in Swift. (There's still some Carbon in here, too! Yes, really.)

  • Scoot complements mouse-related accessibility tools that ship as part of MacOS, such as Mouse Keys and other accessibility shortcuts, in addition to mouse emulation provided via keyboard firmware (QMK, for example).

Usage

To activate Scoot in the element-based navigation mode, use the ⇧⌘J global keyboard shortcut. Alternatively, to activate Scoot in the grid-based navigation mode, use the ⇧⌘K global keyboard shortcut. And for freestyle mode, use the ⇧⌘L global keyboard shortcut. (These shortcuts can be customized.)

As long as Scoot is running, any of these hotkeys will bring the app to the foreground, and activate the requested mode.

When Scoot is in the foreground:

  • You can jump directly to a cell (a UI element, or a location in the grid, depending on the active navigation mode). Each cell is marked with a label (e.g. “aaa”, “aas”, “aad”); type the characters, one letter at a time, and, as soon as a complete sequence is entered, the mouse cursor will move directly to the center of the corresponding cell. (This approach, including the use of a char-based decision tree, is heavily inspired by avy.)

    • If you make a mistake while entering a label, hit the escape key (⎋) to cancel and start over. (Alternatively, you can type ⌘. or C-G.)
    • This feature is not available in freestyle mode, which does not present any special UI, or otherwise offer any navigation assistance via a char-based decision tree.
  • You can also move the cursor via the standard Mac keyboard shortcuts for moving the insertion point. (This means that keyboard shortcuts intended for navigating around in a document have been re-purposed to control movement on a 2-dimensional grid. Some liberties have been taken with this mapping; hopefully you find these keybindings intuitive.) This feature works in all modes (element-based, grid-based, and freestyle).

  • You can click with the left mouse button (at the current cursor location) by hitting the Return (↵) key.

  • You can hold the left mouse button down by pressing =. (To release the button, press ↵.)

    • To perform a drag-and-drop operation: situate the cursor above the object you want to drag and press =, then move the mouse cursor to the desired drag destination (using one or more of the mechanisms that Scoot makes available), and then press ↵ to perform the drop.
  • You can double-click with the left mouse button (at the current cursor location) by hitting the Shift and Return keys together (⇧↵).

  • You can scroll, by pressing the Shift key in conjunction with the arrow key (↑, ↓, ←, →) pointing in the desired scroll direction.

After clicking, any overlaid UI elements (such as the element view, or the grid) will automatically hide. You can also hide these UI elements (and send Scoot to the background) at any time by pressing ⌘H.

Scoot includes a menu bar icon (an illustration of a Vespa-inspired scooter).

Scoot Menu Bar Icon

  • When Scoot is not active (i.e., running in the background), the icon will render in an outlined mode.
  • When Scoot is in the foreground, the icon will render with a fill (see screenshot), to make it clearer that Scoot is currently active. (This shouldn't generally be a concern, but it is especially handy when you're in freestyle mode.)
  • Additional options are exposed when clicking on the menu bar icon, including a help menu item — which currently opens this README in the user's default browser.

Scoot is fully compatible with Spaces (and can be used in conjunction with apps that are running in native fullscreen mode).

Scoot also works on systems with multiple connected displays.

Using Scoot with multiple connected displays

If you use multiple displays, and experience an issue with Scoot's windows drawing in an incorrect location when the app launches (e.g. all Scoot windows appearing on the same display), please post your findings in this issue, and note the value of your “Displays have separate Spaces” checkbox in Mission Control. If you do happen to find yourself in this state, you should be able to fix the window arrangement by clicking Scoot's menu bar icon, then “Debug”, and finally “Rebuild Jump Windows”.

To customize Scoot's settings, click Scoot's menu bar icon, then “Preferences…”, or type ⌘, while Scoot is in the foreground. In addition to modifying keybindings, it is also possible to modify Scoot's appearance (including font sizes, colours, opacity, etc.).

Keybindings

Not sure what these symbols mean? See the symbol reference, and Emacs key notation.

Global Keybindings

Global keybindings are always active, as long as Scoot is currently running.

Default Shortcut Description
⇧⌘J Use element-based navigation (bring Scoot to foreground)
⇧⌘K Use grid-based navigation (bring Scoot to foreground)
⇧⌘L Use freestyle mode (bring Scoot to foreground)

All global keybindings are fully customizable. To modify the keybindings, click Scoot's menu bar icon, then “Preferences…”, and select the “Keybindings” tab.

Local Keybindings

Local keybindings are only active when Scoot is active (i.e., when Scoot is in the foreground).

Note that vi keybindings are not enabled by default, and must be explicitly toggled on (click Scoot's menu bar icon, then “Preferences…”, select the “Keybindings” tab, and then change the keybinding mode). Emacs keybindings (and most system keybindings) are disabled when vi keybindings are active.

General
Shortcut Alternate Description
⌘H Hide UI (bring Scoot to background)
⎋ (or ⌘.) C-g Cancel: if currently typing a label, clears all currently-typed characters; otherwise, brings Scoot to background

Note: ⎋ signifies the Escape key.

Cursor Movement
System Emacs vi Description
C-p k Move cursor up (partial step)
C-n j Move cursor down (partial step)
C-b h Move cursor left (partial step)
C-f l Move cursor right (partial step)
⌥↑ M-a C-k Move cursor up (full step)
⌥↓ M-e C-j Move cursor down (full step)
⌥← M-b C-h Move cursor left (full step)
⌥→ M-f C-l Move cursor right (full step)
⌘↑ M-< ⇧-k Move cursor to top edge of screen
⌘↓ M-> ⇧-j Move cursor to bottom edge of screen
⌘← C-a ⇧-h Move cursor to left edge of screen
⌘→ C-e ⇧-l Move cursor to right edge of screen
⌃L C-l ⇧-m Move cursor to center, and (on repeat) cycle around corners
Clicking
Shortcut Description
Click left mouse button (at current cursor location)
= Press and hold left mouse button (once activated, type to release)
\ Double-click left mouse button (at current cursor location)
[ Click middle mouse button (at current cursor location)
] Click right mouse button (at current cursor location)

Scoot will pass along any pressed modifier keys when simulating clicks. This means that Command-click, Option-click, Control-click, and Shift-click are all supported (or any combination thereof). For example, ⌘↵ will Command-click the left mouse button at the current cursor location, ⌥↵ will Option-click, ⌃↵ will Control-click, ⇧↵ will Shift-click, etc.

Scoot can't take control of the mouse cursor when a context menu is active (for example, after right clicking). However, system-provided keyboard shortcuts for selecting the item in a menu (such as ↑, ↓, ←, →, C-n, C-p, ↵) will work as expected.

For simplicity, Scoot only supports simulating holding/ dragging, and double clicking, with the left mouse button. (If you have a use case that requires more exotic click handling, please file an issue with details.)

Note: ↵ signifies the Return (a.k.a Enter) key. (Sidenote: technically, Return and Enter are two different keys.)

Scrolling
System Emacs vi Description
⇧↑ ⇧-p C-b Scroll up (at current cursor location)
⇧↓ ⇧-n C-f Scroll down (at current cursor location)
⇧← ⇧-b C-i Scroll left (at current cursor location)
⇧→ ⇧-f C-a Scroll right (at current cursor location)
Presentation
Shortcut Description
⌃= Toggle visibility of grid lines
⌃⇧= Toggle visibility of grid labels
⇧⌘= Increase size of grid cells
⇧⌘- Decrease size of grid cells
⌘= Increase contrast of user interface
⌘- Decrease contrast of user interface

Installation

Scoot is available on Homebrew:

brew install --cask scoot

Alternatively, you can manually download the app bundle:

  1. Download and extract the latest build of Scoot.
  2. Drag the extracted Scoot.app into your computer's Applications folder.
  3. Double-click on Scoot.app (from the Applications folder) to launch it.

Setup

On first run, you'll be presented with a prompt like the following:

Scoot.app would like to control this computer using accessibility features

Scoot will not work unless access is granted. (Note that Scoot does not collect any user or usage-related information, and does not make any network requests. The app runs entirely locally, and treats its privileged access with the utmost respect.)

To grant this permission, click “Open System Preferences”. Next, click the lock in the bottom left corner (“Click the lock to make changes”).

Locked accessibility settings

Finally, check “Scoot.app” to give Scoot the ability to move your cursor, and to click, drag, and scroll.

Scoot.app granted accessibility access

See the usage documentation for details on how to use Scoot.

If you're finding Scoot helpful, you may want to configure the app to launch automatically when you log in. To set this up, open System Preferences again, click “Users & Groups”, and then “Login Items”:

Locked login items settings

As before, you'll need to click the lock in the bottom left corner to unlock this preference pane. Once unlocked, click the “+” button, and select “Scoot.app” from the Applications folder. Checking the “Hide” checkbox is recommended.

Scoot configured to start automatically

If you encounter any problems, feel free to file an issue.

Demos

Element-based Navigation

This is what it's like to navigate around Wikipedia in Safari, using the element-based navigation mode:

element-based-nav-browsing-wikipedia.mp4

Drag and Drop

Here's what it's like to drag and drop with Scoot, using the grid-based navigation mode:

drag-and-drop.mp4

For reference, the following key sequence was used to grab the file and drop it in a new location:

  • ⇧⌘K to activate Scoot
  • kh to jump cursor to cell
  • = to press and hold the left mouse button
  • fd to jump cursor to cell
  • to release the left mouse button

Feature Backlog

See the issue tracker. Contributions welcome!

License

Scoot is released under the terms of the BSD 3-Clause License.

Copyright (c) 2021-2023, Michael Russo.

scoot's People

Contributors

leongc avatar lowkahonn avatar mjrusso avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

scoot's Issues

Dock visibility causes issues with element-based and grid-based navigation modes

The grid-based and element-based navigation modes work incorrectly if your machine does not have the "automatically hide and show the Dock" setting enabled and the Dock is positioned on the left or bottom edge of the screen.

Stated a different way:

  • if you auto-hide your Dock, or
  • if you have your Dock always visible on the right edge of the screen

...then everything works properly.

Otherwise:

  • element-based nav will jump to the correct pixel coordinates, but the labels are drawn in an incorrect location on the screen (they're offset by the size of the Dock)
  • grid-based nav will jump to incorrect pixel coordinates (offset by the size of the Dock), but the grid will draw correctly

This isn't a regression; I just never thought to test without an auto-hidden Dock 😓

Support disabling shortcuts in some apps

Heya – amazing app, thanks so much for creating this!

I was wondering if you’d consider supporting disabling Scoot shortcuts when some app is in foreground.

My use case: I don’t want to trigger Scoot shortcuts when I’m using VS Code. I’d never control VS Code with Scoot as I already actively rely on shortcuts there; and Scoot steals some of these shortcuts, which means I need to re-assign them in one of the apps.

only show grid on active monitor

is it possible to only show the grid on the active monitor? I have three monitors and it’s a little jarring for the grid to show on all 3 at the same time.

thanks!

Drag and drop sometimes freezes scoot

First off, thank you for the useful tool! It's absolutely brilliant.

In some context, drag and drop works great. For instance, dragging files around in Finder. In other cases, the grid disappears as soon as i hit the = key. Opening the grid again with Cmd-shift-k freezes the application, requiring manually using the mouse to click away.

Contexts that break scoot:

  • Dragging windows using their title bar (such as trying to re-position a terminal window)
  • Trying to reorder chrome tabs

Steps to reproduce:

  • Open scoot grid Cmd-shift-k
  • Position your cursor over a window title bar
  • Press =

Observe that the grid is hidden now. Attempting to reopen it yields an unresponsive scoot grid

Persisting Grid Layout

Just want to say this is amazing. Much cheaper than hardware eye tracking (Talon, Precision Gauze) for not using the mouse.

Would be great if the grid layout could persist surviving the mouse click.
There are times where you want to narrow down a tree that requires multiple grid activation.

Conflict with Keyboard Maestro window management when scoot is running

When I run Scoot it conflicts with my Keyboard Maestro macro's that handle window management for me. For example, I have a shortcut to move and size a window to 50% of the screen. It toggles between the left side and the right side. When scoot is running, this is suddenly broken.

This is the crucial part in Keyboard Maestro macro for resizing and moving the front most window.

Macro-window-management

This is the behavior with and without scoot running.

scoot-km-conflict.mov

Have hints in the menu bar.

This project is almost perfect and it replaces 3 or 4 apps at once. But there is one thing that I would really like to see: have both element and grid based navigation work with the macOS menu bar. Is this feasible?

More complete vi mode setup

I know this is probably out of scope due to implementation complexity, but I’d thought I’d file for posterity. Perhaps there’s a statically linkable library that makes implementing this easy?

The feature request is to support vi bindings in a more complete way, so that I could e.g. hit 10j to move 10 steps down.

Elements do not update when underlying view is scrolled

If the focused window in the frontmost app has a scroll view, and you pull up Scoot (in element-based nav mode), and then start scrolling, the regions that Scoot has drawn won't update.

There are (at least) two ways to scroll:

  • using Scoot's keyboard shortcuts for scrolling, or
  • using your physical mouse or trackpad)

For the latter case, are there any accessibility-related hooks in MacOS to detect if the user is scrolling?

Originally posted by @mjrusso in #1 (comment)

Unable to dismiss Scoot settings window with Scoot

  • Invoke Scoot freestyle with Cmd+Shift+L
  • Open settings with Cmd+,
  • Invoke Scoot freestyle again with Cmd+Shift+L
  • Navigate to point to Scoot settings window close button and hit Enter
  • The window seemingly goes away
  • Invoke Scoot freestyle for the third time with Cmd+Shift+L
  • The settings window pops up to the forefront, blocking the view

Improve reliability of simulated clicks

The current click simulation code is written as follows (source):

    func click(button: Mouse.Button) {
        // It should be possible to `pressDown()` and then `release()` (after a
        // short delay), however that approach doesn't work reliably: in some
        // applications (for example, when trying to click on a hyperlink in a
        // browser, or in an apps that render their user interface using web
        // technologies), mouse clicks don't actually register.
        //
        // For an unknown reason, posting two `leftMouseDown` events, followed
        // by a single `leftMouseUp`, *seems* to work consistently everywhere.
        // How's that for a hack?
        //
        // [N.B.: A previous implementation issued two clicks in a row (i.e.,
        // `pressDown()`, `release()`, `pressDown()`, `release()`), and that
        // worked better than one could reasonably expect. However, there were
        // rare cases where two clicks would actually be registered: for example,
        // in Safari, clicking the "close tab" button (the one embedded in the
        // tab itself) would result in two tabs being closed. Another example:
        // it wasn't possible to use Scoot to bring up it's menu bar: two clicks
        // would register, and it would immediately close.]
        //
        // [N.B.: This question [0] on Stack Overflow ("Simulating mouse clicks
        // on Mac OS X does not work for some applications") seems relevant, but
        // unfortunately none of the proposed strategies seem to work.]
        //
        // [0]: https://stackoverflow.com/q/2369806/15304124
        pressDown(button)
        pressDown(button)
        usleep(40000)
        release(button)
    }

I'd love to understand why this hack is necessary, and ideally modify the implementation to pressDown only a single time.

Improve legibility of element-based navigation when many elements are in close proximity

Legibility when using element-based navigation is (usually) OK-ish, but far from perfect.

As an example of a degenerate case, here's what HN looks like when element-based nav is active:

Screen Shot 2022-01-01 at 10 30 48 AM

The combination of a small font size, with many unique anchors in close proximity, is problematic. It might make sense to ignore elements that are clustered too closely together (using size as a proxy for importance).

Originally posted by @mjrusso in #1 (comment)

Grid-based navigation incompatible with Stage Manager

Howdy! Wanted to point out that there is an issue with the grid-based navigation when MacOS Stage Manager is enabled. The grid is offset by the Stage Manager gutter (the left side of the screen where Stage Manager window groups are collected.) In addition to the gutter not being navigable with the grid, attempting to navigate to a grid ID will misplace the cursor by the same width of the gutter. For example, in the screenshot below, navigating to azw would put the cursor ~213px to the left of azw.

image

New navigation mode: 2x2 grid

I have a proposal for new navigation mode

  1. Screen is divided to 2x2 grid
  2. Selecting one of grid cell (each grid has dedicated button)
  3. Selected cell will be divided again to 2x2

User keeps selecting the cell until destination is reached. I built a POC for testing the viability of this (just simple app running in browser) and I think it has some potential.

Asking for comments:

  • Have you already experimented with something like this before? How did you find it?
  • Would this be simple to implement? (I am considering trying to make the PR myself, if this makes sense).

POC: https://arch-vile.github.io/4thSlot/

Improve legibility of grid and element labels, particularly when rendering on top of light backgrounds with dark text

It can be hard to read grid and element labels in a variety of circumstances, but especially when Scoot is rendering on top of light backgrounds with dark text.

(This issue primarily affects grid-based nav, but the same technique should also be used to improve the drawing of bounding rects for elements when using element-based nav. For an entirely different legibility issue with element-based nav, see #2.)

Is there a (performant) way to modify the colours of the grid based on the content immediately underneath it?

Other mouse clicks

Not sure if I haven't read the instructions properly yet but I couldn't see how to initiate a right click.
I guess it would be a little tricky as it would quite often bring up a context menu that may be hard to target.

Anyhow thanks for Scoot great idea!

Scoot should lazily traverse accessibility tree for frontmost app when activated

From #25:

Currently, when Scoot is activated, it traverses the accessibility tree for the frontmost/focused application and builds the data structure used for element-based navigation, regardless of which navigation mode is requested. The thinking here was that once Scoot is on screen, you could swap between (for example) grid-based nav and element-based nav, without any delay.

If you've activated Scoot in the grid-based or freestyle nav modes, you should be able to use the requested mode immediately, without blocking on element-based nav becoming ready.

Either wait for element-based nav to be requested before doing the work of traversing the accessibility tree (and prepping the associated data structures, etc.), or do this work in a background thread (if possible).

Scoot crashes when invoked with Zoom as frontmost app

Bringing Scoot to the foreground, with Zoom as the frontmost app, causes a crash. Note that this only seems to happen when actively in a Zoom meeting.

I can reproduce with Zoom 5.8.4 and 5.9.1.

The crash appears to be somewhere in AXSwift, but I haven't had a chance to dig any further yet.

Save/remember locations

First of all thanks for this super interesting tool! I have been trying to reduce my mouse usage and this definitely could be viable. Only been using this for a day now but I have an idea that I want to suggest.

It could be useful feature if Scoot would remember the clicked locations on each app (or just for all). And there would be a navigation mode that would show the most clicked locations and a shortcut to click/move to those. I can see some issues if you move windows around or use multiple displays but as an optional feature would help me at least.

Multi-display bugs

I have an external display as the main display connected via USB-C to HDMI adapter to my 2017 Macbook Pro running OS X 12.1 with the built-in retina as an extended display. Launching grid navigation with Scoot 0.8 overlays both display grids on the external display and none on the built-in retina display. Relatedly, launching element navigation only shows targets when the focused window is on the external display.

Different grid load times depending on which display is currently focused

This issue might be a bit tricky to debug, but is definitely something I think extremely limits the use of Scoot.

I'm using 2 monitors - the build in Mac display and an external monitor
When launching the grid mode while focused on the external monitor, the grid loads up on both displays almost instantaneously.
When launching it when focused on the build-in display, though, it can take up to 7 seconds at times to render the grid on both displays.

Steps to reproduce:

  1. Click anywhere on the external display
  2. Launch Scoot's grid mode with keyboard shortcut
  3. Grid loads almost instantaneously on both displays
  4. Press Esc to close grid mode
  5. Click anywhere on the built-in display
  6. Launch Scoot's grind mode with keyboard shortcut
  7. Grid takes a while to render, making Scoot impractical to use

Scoot version: 0.12 (1)
MacOS version: 12.2.1
Model: MacBook Pro 13-inch 2017, 2.3GHz i5 & 16GB RAM

Thanks,
Orel

Enable global keyboard shortcuts to be overridden

Currently, Scoot (globally) binds ⇧⌘J and ⇧⌘K to bring itself to the foreground (in element-based or grid-based nav modes, respectively).

You may be using these for other purposes, or just prefer different shortcuts, and it should be possible to change them.

Option or key to click without hiding hiding overlaid UI elements

There are times when I want to perform multiple clicks on UI elements. Currently, I have to toggle freestyle mode for every click since the overlaid UI element is automatically hidden after each click. It'll be nice if there's an option or settings for that or better yet, a key to click without hiding the overlaid UI.

**BUG** Double click (=) makes nearly all keys inaccessible

In grid or freestyle mode, when I attempt to do a double left click with "=" all keys become un-responsive. The only exception seems to be CMD-SPACE, which still brings up Spotlight search. Running Debug > "Rebuild jump windows" returns full functionality.

System Details
MacBook Air (2020)
MacOS Sonoma 14.4.1
Scoot 1.2 (1)

unable to move cursor in free style mode in finder.

First of all thank for this amazing contribution. I love using the app.

Steps to reproduce:

  1. Open any .dmg file
  2. Do CMD+shift+L
  3. vim bindings doesn't work.

this is the only place I see this feature is not working so far. I was able to go mouseless pretty much all the time.
Screen Shot 2022-07-05 at 4 34 29 AM

Scoot doesn't find elements in certain apps (e.g. Chrome, Firefox, anything built with Electron) unless VoiceOver is enabled

Scoot cannot use element-based navigation to interact with its own windows

(Alternative title: Meta-Scoot: Scoot cannot "scoot" its own windows)

It isn't possible to interact with Scoot's windows (e.g., the Settings screen: #21, the About screen: a0fb6c2, etc.), using element-based navigation.

This is because of the following code, which prevents Scoot from "seeing" its own windows:

    /// The frontmost application at the moment when Scoot was most recently
    /// invoked. (If Scoot happens to be the frontmost app when it is invoked,
    /// the previous frontmost app is returned.)
    var currentApp: NSRunningApplication? {
        didSet {
            // Don't allow Scoot to be set as the current app; instead, retain
            // the previous value. (This behaviour provides a simple mechanism
            // for recomputing available elements when using element-based
            // navigation: simply re-invoke Scoot, even if it is frontmost.)
            guard currentApp != .current else {
                currentApp = oldValue
                return
            }
        }
    }

To fix this, we'll need to only ignore Scoot if NSApp.keyWindow (and NSApp.mainWindow?) is currently inputWindow.

I quickly prototyped this, and the technique itself mostly works, however when I click on a tab in the Settings screen, or pull up the color picker, etc., Scoot stops accepting any keyboard input. The commands are being received, however, because if I use my mouse to click, all the queued keyboard commands are immediately replayed.

Find all elements on the screen, not just those in the focused window of the frontmost app

In element-based nav mode (first introduced in #1), Scoot will find all elements in the focused window of the frontmost app.

It would be better if Scoot could find all elements that are on all attached screen(s), across all apps.

Of course, windows can overlap, and we'll need to ignore any elements that are fully occluded by a window above it.

AXUIElementCopyElementAtPosition will find an element at the specific coordinate (if one exists), but you need to pass it an application reference, so it is not directly usable in this context (and, regardless, checking every possible x,y value on every screen seems wasteful from a performance perspective).

https://stackoverflow.com/a/56941105/ has some code that might be helpful (finding all windows on the screen, and ordering them relative to each other).

Vi shortcut keys

Would love if we could set it to use vi key shortcuts!

This is a super cool project! Have always wanted to use my keyboard to control the mouse!!!

Option to remove beeps/sound

I seem to randomly get beeps/sounds when using my mouse, clicking or moving my cursor after having used element based navigation, can we have an option to disable this beeping sound?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.