marketplace/mouse

Mouse App Shortcuts

Side buttons mean back and forward in browsers, undo and redo in editors, previous and next sheet in spreadsheets.

@rebindv0.1.0free

More install options
$rebind install @rebind/mouse-app-shortcuts

Gallery

Mouse App Shortcuts preview

Readme

The two side buttons change meaning with the focused app. Everywhere else they stay ordinary side buttons.

Focused appMouse4Mouse5
BrowserBackForward
EditorUndoRedo
SpreadsheetPrevious sheetNext sheet

Setup

Each class is a comma separated list of process names. A window matches when its process name contains one of the entries, case insensitive. On Windows that is the executable name (chrome.exe matches chrome); on macOS it is the application name (Google Chrome matches chrome). Edit the lists any time; changes apply on the next click.

Turn on Swap the two side buttons if your mouse reports them the other way round.

Chords sent

  • Windows: Alt+Left and Alt+Right, Ctrl+Z and Ctrl+Y, Ctrl+PageUp and Ctrl+PageDown.
  • macOS: Cmd+[ and Cmd+], Cmd+Z and Cmd+Shift+Z, Option+Left and Option+Right.

Limits

  • Both side buttons are captured system wide while the script runs. In unlisted apps the press is passed straight through, but it does pass through the Rebind Engine first.
  • Apps that bind the side buttons themselves will see the chord instead of the button.

Reviews

No reviews yet. Write a review in the app.

Source

Version 0.1.0 (current)

main.luau

-- Mouse App Shortcuts: Mouse4 and Mouse5 change meaning by focused app.
-- Anywhere not listed, the buttons pass through untouched.

local IS_MAC = _REBIND.platform == "macos"

local cfg = UI.Schema({
  browsers = UI.Text("chrome, firefox, brave, edge, safari, arc", {
    label = "Browsers (back / forward)",
    placeholder = "process names, comma separated",
    tab = "Apps",
  }),
  editors = UI.Text("code, cursor, sublime, notepad++, zed, textedit", {
    label = "Editors (undo / redo)",
    placeholder = "process names, comma separated",
    tab = "Apps",
  }),
  sheets = UI.Text("excel, numbers, soffice, libreoffice", {
    label = "Spreadsheets (previous / next sheet)",
    placeholder = "process names, comma separated",
    tab = "Apps",
  }),
  swap = UI.Toggle(false, {
    label = "Swap the two side buttons",
    tab = "Apps",
  }),
})

-- chords per class: { Mouse4, Mouse5 }
local CHORDS = {
  browsers = if IS_MAC
    then { "LWin+[", "LWin+]" }
    else { "LAlt+Left", "LAlt+Right" },
  editors = if IS_MAC
    then { "LWin+Z", "LWin+LShift+Z" }
    else { "LCtrl+Z", "LCtrl+Y" },
  sheets = if IS_MAC
    then { "LAlt+Left", "LAlt+Right" }
    else { "LCtrl+PageUp", "LCtrl+PageDown" },
}

local function names(list)
  local out = {}
  for name in list:gmatch("[^,]+") do
    name = name:gsub("^%s+", ""):gsub("%s+$", ""):lower()
    if name ~= "" then
      table.insert(out, name)
    end
  end
  return out
end

local function classOf(process)
  process = process:lower()
  for _, class in { "browsers", "editors", "sheets" } do
    for _, name in names(cfg[class]) do
      if process:find(name, 1, true) then
        return class
      end
    end
  end
  return nil
end

local function bindSide(button, index)
  Bind(button, {
    when = function()
      return classOf(System.Window().process) ~= nil
    end,
    action = function()
      local class = classOf(System.Window().process)
      local slot = if cfg.swap then 3 - index else index
      HID.Combo(CHORDS[class][slot])
      return nil
    end,
  })
end

bindSide("Mouse4", 1)
bindSide("Mouse5", 2)

function OnStart()
  Log.Info(
    "Mouse4 and Mouse5 follow the focused app. Elsewhere they pass through."
  )
end