Skip to content

Commit

Permalink
initial commit for version 2.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
urbanoanderson committed Feb 13, 2025
1 parent ddfe4d5 commit d6c490d
Show file tree
Hide file tree
Showing 11 changed files with 520 additions and 403 deletions.
14 changes: 14 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "C#: XinputWindowsManager Debug",
"type": "dotnet",
"request": "launch",
"projectPath": "${workspaceFolder}/XinputWindowsManager/XinputWindowsManager.csproj"
}
]
}
Binary file modified Images/screenshot1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 21 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

## About

This system tray Windows 10 application allows the user to toggle a mouse mode by pressing a special button combination on an Xinput gamepad such as the Xbox One Controller. In this mode, the gamepad is able to freely move the cursor around the screen, perform left and right click actions as well as some useful keyboard presses.
This system tray Windows application allows the user to toggle a desktop manager mode by pressing a special button combination on an Xinput gamepad such as the Xbox One Controller. In this mode, the gamepad is able to freely move the cursor around the screen, perform left and right click actions as well as some useful keyboard presses.

The software was developed so that users with a desktop setup with only gamepad input or at least inconvenient access to keyboard and mouse can perform basic tasks that require these input methods using a gamepad. An example would be my case, where I use a desktop PC with Steam Big Picture in my living room as a DIY game console.

Expand All @@ -25,16 +25,35 @@ Optional - If you want the app to start with windows do the following:

## Usage

You can toggle mouse mode by right-clicking the system tray icon and selecting the toggle option or by pressing the following button combination on your xinput controller (player one):
You can toggle manager mode by right-clicking the system tray icon and selecting the toggle option or by pressing the toggle button combination on your xinput controller (player one). Combination can be set in App.Config and it defaults to:
- `BACK` + `A` + `X`

While in mouse mode, the following actions can be performed:
- `Left analog stick`: controls mouse cursor movement;
- `A`: performs left click;
- `X`: performs right click;
- `Y`: opens Windows Task Manager (CTRL+SHIFT+ESC);
- `B`: presses ESC key;
- `LS`: opens OnScreen Keyboard;
- `RS`: sends mute command;
- `LT`: presses Windows key;
- `RT`: minimizes all apps (Win+D);
- `LB+RB`: performs performs ALT+TAB;
- `DPAD`: sends arrow keys from keyboard;
- `Right analog stick UP/DOWN`: controls system volume;
- `Right analog stick LEFT/RIGHT`: controls prev/next song;

Other settings can be changes on App.Config but default values should sufice on most cases.

## Release Notes

### 2.0.0

- Refactors codebase
- Upgrade to .NET 8
- Utilizes XInputium instead of SharpDX for Xinput control
- Utilizes InputSimulatorCore for Keyboard/Mouse control

### 1.0.0

- Initial version
Expand Down
11 changes: 11 additions & 0 deletions XinputWindowsManager/App.Config
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<configuration>
<appSettings>
<add key="START_ENABLED" value="false"/>
<add key="XINPUT_POLLING_DELAY_MSECS" value="8"/>
<add key="MAX_CURSOR_MOVEMENT_SPEED" value="18.0"/>
<add key="LEFT_STICK_THRESHOLD" value="0.15"/>
<add key="RIGHT_STICK_THRESHOLD" value="0.70"/>
<add key="TRIGGER_THRESHOLD" value="0.99"/>
<add key="TOGGLE_MANAGER_COMBINATION" value="A,X,BACK"/>
</appSettings>
</configuration>
106 changes: 0 additions & 106 deletions XinputWindowsManager/DesktopManagerService.cs

This file was deleted.

151 changes: 151 additions & 0 deletions XinputWindowsManager/ManagerConfiguration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
using System;
using System.Configuration;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;
using XInputium.XInput;

namespace XinputWindowsManager
{
public class ManagerConfiguration
{
public const string BUTTON_A = "A";

public const string BUTTON_B = "B";

public const string BUTTON_X = "X";

public const string BUTTON_Y = "Y";

public const string BUTTON_LB = "LB";

public const string BUTTON_RB = "RB";

public const string BUTTON_LT = "LT";

public const string BUTTON_RT = "RT";

public const string BUTTON_LS = "LS";

public const string BUTTON_RS = "RS";

public const string BUTTON_BACK = "BACK";

public const string BUTTON_START = "START";

public const string BUTTON_DPAD_UP = "DPAD_UP";

public const string BUTTON_DPAD_DOWN = "DPAD_DOWN";

public const string BUTTON_DPAD_LEFT = "DPAD_LEFT";

public const string BUTTON_DPAD_RIGHT = "DPAD_RIGHT";

public bool StartEnabled { get; set; }

public int XinputPollingDelayMsecs { get; set; }

public double MaxCursorMovementSpeed { get; set; }

public double LeftStickThreshold { get; set; }

public double RightStickThreshold { get; set; }

public double TriggerThreshold { get; set; }

public string[] ToggleManagerCombination { get; set; }

public ManagerConfiguration()
{
try
{
this.StartEnabled = this.ReadBoolSetting("START_ENABLED");
this.XinputPollingDelayMsecs = this.ReadIntSetting("XINPUT_POLLING_DELAY_MSECS", minvalue: 4, maxvalue: 32);
this.MaxCursorMovementSpeed = this.ReadDoubleSetting("MAX_CURSOR_MOVEMENT_SPEED", minvalue: 5.0, maxvalue: 50.0);
this.LeftStickThreshold = this.ReadDoubleSetting("LEFT_STICK_THRESHOLD", minvalue: 0.0, maxvalue: 1.0);
this.RightStickThreshold = this.ReadDoubleSetting("RIGHT_STICK_THRESHOLD", minvalue: 0.0, maxvalue: 1.0);
this.TriggerThreshold = this.ReadDoubleSetting("TRIGGER_THRESHOLD", minvalue: 0.0, maxvalue: 1.0);
this.ToggleManagerCombination = this.ParseToggleCombination();
}
catch (Exception e)
{
throw new ArgumentException($"Invalid App.Config. {e.Message}");
}
}

private string ReadSetting(string setting)
{
string value = ConfigurationManager.AppSettings[setting];

if (string.IsNullOrWhiteSpace(value))
{
throw new ArgumentException($"Setting {setting} not available or empty");
}

return value;
}

private bool ReadBoolSetting(string setting)
{
return bool.Parse(this.ReadSetting(setting));
}

private int ReadIntSetting(string setting, int minvalue, int maxvalue)
{
int v = int.Parse(this.ReadSetting(setting));

if (v < minvalue || v > maxvalue)
{
throw new ArgumentException($"Invalid value for setting {setting}. Value must be between {minvalue} and {maxvalue}.");
}

return v;
}

private double ReadDoubleSetting(string setting, double minvalue, double maxvalue)
{
double v = double.Parse(this.ReadSetting(setting));

if (v < minvalue || v > maxvalue)
{
throw new ArgumentException($"Invalid value for setting {setting}. Value must be between {minvalue} and {maxvalue}.");
}

return v;
}

private string[] ParseToggleCombination()
{
string rawValue = this.ReadSetting("TOGGLE_MANAGER_COMBINATION");

string[] splitValues = rawValue.Split(',');

foreach (string button in splitValues)
{
Debug.WriteLine($"Combination button: {button}");

if ( button != BUTTON_A
&& button != BUTTON_B
&& button != BUTTON_X
&& button != BUTTON_Y
&& button != BUTTON_LB
&& button != BUTTON_RB
&& button != BUTTON_LS
&& button != BUTTON_RS
&& button != BUTTON_LT
&& button != BUTTON_RT
&& button != BUTTON_BACK
&& button != BUTTON_START
&& button != BUTTON_DPAD_UP
&& button != BUTTON_DPAD_DOWN
&& button != BUTTON_DPAD_LEFT
&& button != BUTTON_DPAD_RIGHT)
{
throw new ArgumentException($"Invalid button value in TOGGLE_MANAGER_COMBINATION: {button}");
}
}

return splitValues;
}
}
}
15 changes: 12 additions & 3 deletions XinputWindowsManager/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,18 @@ static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
SystemTrayApplicationContext appContext = new SystemTrayApplicationContext();
Application.ApplicationExit += appContext.HandleExit;
Application.Run(appContext);

try
{
ManagerConfiguration managerConfiguration = new ManagerConfiguration();
SystemTrayApplicationContext appContext = new SystemTrayApplicationContext(managerConfiguration);
Application.ApplicationExit += appContext.HandleExit;
Application.Run(appContext);
}
catch (Exception e)
{
MessageBox.Show(text: $"{e.Message}", caption: "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
Loading

0 comments on commit d6c490d

Please sign in to comment.