Are you using a mouse and/or keyboard compatible with the Logitech Gaming Software?
Wouldn't it be nice to have concurrent macros, fluid mouse movements, cyclical or timing based button assignments (and much more) without implementing your own OnEvent logic?
And while we're at it, how about managing keybindings with the text or code editor of your choice in a simple text file rather than a clunky GUI?
Revenant leverages the full power of Logitech's lua scripting features without you needing to wrestle with the awkward API in a barebones editor. LGS itself is delegated to selecting profiles while Revenant manages all bindings, modes, and general logic, with no need to assign commands using the app.
Besides the initial setup you'll only need to open the LGS scripting window for debugging purposes, if at all.
The framework is also designed to be usable without much lua programming experience.
When using Revenant you don't strictly write lua, you define macro logic within Revenant's templating language that just happens to take the form of lua tables.
Here's an example profile file showcasing some of the macro features:
local profile = ...
local k = profile.key
-- Configuring a Logitech G600 with a 1080p monitor.
profile.config = { devices="G600", monitors={1920,1080} }
-- The third mouse button presses the mouse wheel.
k.m3 = "/3"
-- The 9th mouse button, G9 on the thumbpad, cycles between the keys "a", "b" and "c"
k.m9 = { type = "cycle", "a","b","c"}
-- types "hello", waits one second, then types "world".
-- Note that several such macros can run simultaneously.
k.m10 = { type = "sequence", "hello", 1000, "world"}
-- Enter the Konami Code because it's still the 80s.
k.m11 = "/u/u/d/d/l/r/l/rba\n"
-- Move the mouse in a triangular pattern, 500px wide and 500px high within 1.5 seconds.
k.m12 = { type = "mouseposition", {250, -500}, {250, 500}, {-500}, relative = true, duration = 1500 }
-- Input Ctrl+C if held for less than 150ms and Ctrl+V if held for longer.
k.m13 = { type = "holdkey", "*c", 150, "*v" }
Important
This script only works with the original Logitech Gaming Software and does not support G-Hub, since critical features are missing in the G-Hub implementation of the lua API (last I checked SetMKeyState and M_PRESSED ecents were broken). If you are stuck with a newer device that only supports G-Hub... I feel sorry for you but there's really nothing to do besides complaining to Logitech.
Interested in what fully featured game and app profile configurations look like and what sort of advanced functionality is possible?
Check out the example repository: https://github.com/Thertzlor/Revenant-G600-Example-Profiles
- 27 Macro Types for pretty much anything you could want your mouse to do.
- Bind multiple macros to one key.
- Select different Macros to execute via button cycling, multi-clicks, hold time, specific parts of the screen and other conditions.
- Supports modifier keys, chorded button combinations and lots of other trigger conditions.
- Move your mouse anywhere instantaneously or smoothly.
- Modify key bindings based on specific areas of your monitor(s).
- Define areas for the above features and movement in pixels or screen percentages for (almost) resolution agnostic profiles.
- Define your own key and mode names, make your mouse your own.
- Group your bindings by keys, modes or g-shift states, whatever makes the most sense to you.
- Easily integrate custom lua functions.
- Fully featured linter and type checker for all macro commands and option values. Don't lose control of your mouse because of typos.
- VSCode integration with intellisense and detailed annotations.
- Multiple macros can run at the same time.
- Running macros can be dynamically cancelled, paused or resumed.
- Support for Device dependent or independent modes.
- can synchronize to hardware modes and supports backlight on many Logitech devices.
- A macro can be nested in, linked to and extended from other macros.
- Build macro chains and logical conditions without advanced lua or logitech API knowledge.
- Dynamically inherit functionality and extend profiles from another profile.
- Support for multiple inheritance.
- Configuration and documentation files are inheritable as well.
- Profiles and Modes are automatically integrated with your Logitech LCD Displays.
- Documentation mode for quickly displaying macro functionality
- Also works with the LGS LCD Emulator.
...And it comes with a Python script that can convert macros recorded with LGS to Revenant Sequence macros!
A comprehensive manual about everything you can do with Revenant can be found on the wiki in this repository.
I started developing lua scripts for my G600 all the way back in 2011 when the mouse bindings I envisioned for The Witcher 2 could not be realized within the GUI of LGS and I was struck by how complicated and awkward even basic assignments were to implement (at least in a way that's not riddled with bugs) using the standard lua OnEvent loop.
Even other existing lua binding libraries like G-Max and ll.Project, while introducing me to useful concepts like polling, did not provide the flexibility I needed as they still required writing full lua functions for any logic beyond simple string outputs (besides being unmaintained) when so much boilerplate code could be simplified away.
Revenant is designed with a more high-level approach in mind, so you don't need to worry about events, state management or keeping track of coroutines. All of that is taken care of behind the scenes while the table based templating system keeps simple keybindings simple but offers a powerful enough system to basically express arbitrarily complex logic.
You might ask yourself "couldn't I just learn lua in general instead of a templating language described in lua?" and the answer is absolutely, ...but this way you can focus more on what your mouse should do when instead of arbitrary implementation details.
Installing Revenant is easy:
-
Create a new LGS profile and delete all the standard LGS bindings (Left and right mouse button stay bound by default).
-
Download the latest release of Revenant from the releases section and unpack it the source files into a folder called "revenant" folder in the install location of LGS. This is the default location assumed by the template profile but you can unpack it anywhere and then adjust some settings in the next step.
-
Import or copy the contents of the
LGS_Template.luafile in Revenant'sstartdirectory into the lua scripting window of your LGS profile. [If you put Revenant into some other folder than your LGS installation, you will have to adjust the values of therv.pathandrv.configPathvalues].
Tip
If you have a G600 you can skip step one and directly import the example.xml Template profile in the start folder instead of step 3.
...That's all you need to start defining macros and tweaking your profile, however it's generally more practical to use external profile files.
This can be done in a few additional steps:
- Change the
rv.externalProfilesetting in the LGS script totrue - Fill in a name for your profile in the
rv.profileNamesetting. - Copy the
quickstart_profile.luafile from thestartdirectory into theprofilesdirectory and rename it to match your chosen name. Now you can add your functionality to the lua file, just like editing in the lua editor, the bindings are applied whenever you reload the mouse profile.
[Or, if you insist on the internal LGS editor, simply copy the contents of thequickstart_profile.luaexcept for the first line into therv.profilefunction of the reference template.]
LGS does not offer any lua API for checking which devices are connected, so you have to manually define which one(s) you are using.
The framework supports all devices LGS supports and will allocate the correct number of mode and button slots for each.
Simply put the name of your connected Logitech device from the list of supported devices into the device setting of the profile config.
If you plan on using mouse position and movement macros, you should also define the resolution of your main monitor.
-- By default we assume you are using a G600 mouse on an HD monitor
profile.config = {devices = "G600", monitors = {1920, 1080}}If you have several devices connected the value can be a list:
-- A mouse + keyboard combo on a 4K monitor.
profile.config = {devices = {"G502","G510s"}, monitors = {3840, 2160}}For setting up multiple monitors see Monitor Configuration.
The main part of the profile consist of the bindings in its key table.
m3, m4, m5... are the standard bindings for the mouse buttons (the primary buttons can't be rebound by default), k1,k2,k3... are the G-keys on the keyboard.
Bindings consisting of a single symbol, "a","x", " " or a single key name, will simply press that key and it's possible to quickly add modifier combinations using prefixes such as "*c" for Ctrl+c or "#a" for Alt+a. Upperase letters resolve to shift + letter.
Any strings that are not a key name will type their contents as text.
Tons of more complex macros are configured via lua tables and are listed below with functioning examples and once you are working with advanced functionality you might want to check out the documentation for general Macro options further capabilities of your Profile and generally configuring Revenant to your liking.
-
Basic Input Macros
Several ways to trigger keys on the keyboard or type out strings.key,k: Basic Key or String Inputkeyup,u: Key Upkeydown,d: Key Downkeytoggle,kt: Key Toggle
-
Multi Macros
These macros present ways to manage multiple macros on a single key. Playing them sequentially, cycling between them or even triggering multiple macros at the same time.sequence,s: Sequence of Macroscycle,c: Cycle of Macrosgroup,g: Group of Macros
-
Timing Macros
Switch between key functionality based on the timing of consecutive key presses or holding a key for a certain duration.multiclick,t: Multiclick Keyholdkey,h: Hold Timer Key
-
Mouse Functionality Macros
Macros which set mouse properties instead of reacting to them.mouseposition,p: Mouse Position / Movementmousewheel,w: Mouse Wheel Control
-
Logitech Functionality Macros
Functionality that is normally configured via LGS.mode,m: LGS Mode Selectbacklight,b: Device Backlight Colorsetdpi,dpi: Mouse DPI Modifierexternalmacro,e: LGS Macro Execution
-
LCD Integration Macros
LCD output for some Logitech Keyboards or the LGS LCD Emulator.
[To activate the LCD Emulator shift + ctrl + right click on the LGS tray icon, until the option appears then in the window selectTools -> Color -> Start.]log,o: LCD Message Log Macrodocumentation,doc: LCD Profile Documentationpage,pg: LCD Page Navigation
-
Control Macros
Control currently running macros or set cycle properties.macrocontrol,mc: Continuous Macro Controlcyclecontrol,cc: Cycle Macro Control
-
Input Modifier Macros
Macros for modifying the behavior of other key inputs.bufferkey,kb: Key Bufferwrapkey,kw: Key Wrap
-
Meta Macros
Macros that reference other macros or modify the Revenant environment.link,l: Link to Macroinstance,i: New Instance of Macroflag,f: Set Flagfunc,fn: Lua Function Callalterhistory,ah: Alter Button History
In order to have the best experience for editing your profile files I recommend using VSCode with the Lua Language Server extension installed for fully integrated intellisense for macro types, options, etc.
The Logitech Gaming Software isn't without it's performance issues when it comes to lua scripts.
When LGS loads several profiles with complex scripting logic back-to-back the responsiveness of the G-key buttons can become laggy (this is a consistent delay before the events even reach the script and is certainly not exclusive to Revenant).
Interestingly the main factor is not simply which profiles you switch between... it's how fast you switch between them.
Switch 15 times between profiles with a minute in between and you won't notice much (it took me several years to even become aware of the lag and how it accumulates). But switch 15 times within a few seconds and your G-keys wil become extremely sluggish. An extreme example, but if you normally work with a lot of different programs then after a few hours of switching, especially if you sometimes change between windows quickly, you'll get some amount of lag.
The first way to reset lag is restarting LGS completely. That would be annoying.
The second way is simply loading a profile without any scripting going on, even just for one second. When you switch back to your Revenant profile, the mouse will be completely lag-free once again.
Personally I like to go one step further and make the dummy profile's lua script an exception: error("Lua Reset!"), this guarantees that the luaVM has to be reloaded completely.
The profile needs to be actually loaded, you can open the Scripting or Test Profile windows with LGS, or you can just assign the profile to some window you can quickly focus on.
One good candidate is the Task Manager, it's only one ctrl + shift + esc away and you certainly don't need 20 buttons for it. A click on it once in a while and the lag problem is solved.
And if you have some other programs that you switch to regularly and which don't require complex mouse bindings, a launcher, calculator, minesweeper, SearchHost.exe (opening the start menu), assign them all to the profile you'll naturally stop lag from accumulating with no extra effort.
I see Revenant as mostly completed as far as key based macros are concerned.
Some improvements and extensions are planned, but most are fairly niche.
More dynamic timers is something that could really help reduce complexity, something like inly play this sequence for x milliseconds, unset this flag after x milliseconds, and so on.
The one area that I view as missing some features is mouse movement, both detection and execution.
- At some point I want to add support for moving the cursor along curves in addition to straight lines as well as including easing options for movements (which are just the same curves applied to acceleration).
- I want macro conditions based on how fast the mouse is currently moving.
- Once the mouse speed and detection routines are worked out, there will be support for gestures!
I want to be able to generate a proper developer documentation eventually, and I'm working on writing instructions for defining custom macros.
At some point in the future it would be really neat to have to lug LGS around, especially if it would enable cross-platform support (LGS is currently the main reason why I'm still using Windows).
There are several tools to rebind G600 and gaming mice in general for linux but most of them work by manipulating the on-board memory on the mouse itself. That's cool but it's not a replacement since the on-board capabilities are fairly limited.
What is actually needed is a program that actively reads the raw G-Key events from the mouse, at which point variant of Revenant running as a standalone server could receive and process them with some library to simulate key presses just like LGS does.
If this was possible, and if the majority of the LGS lua API could be reimplemented using some other libraries I would gladly expand the scope of this project.
Help and improvements are always welcome, especially should there be any bugs or oddities involving Logitech devices that I don't have access to.
If you want to contribute just make sure to be familiar with the limitations of the LGS lua environment, which can be quite restrictive.
- G-Max and ll.project, two lua libraries that inspired a lot of Revenant's functionality a decade ago, by now they seem lost to time.
- kgober, who figured out the whole logitech polling logic back in the day, a lot stuff in the threading module is still based on his work.
- NOT G-Hub, which just sucks.
