diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 5c956dc..fd830ef 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -53,3 +53,4 @@ jobs:
artifacts: "*.zip"
prerelease: true
generateReleaseNotes: true
+ bodyFile: RELEASE.md
diff --git a/PowerControl/App.config b/PowerControl/App.config
index c500d4a..bc56eba 100644
--- a/PowerControl/App.config
+++ b/PowerControl/App.config
@@ -22,6 +22,9 @@
True
+
+ True
+
\ No newline at end of file
diff --git a/PowerControl/Controller.cs b/PowerControl/Controller.cs
index f40e5d7..e1e8a3b 100644
--- a/PowerControl/Controller.cs
+++ b/PowerControl/Controller.cs
@@ -97,26 +97,38 @@ namespace PowerControl
GlobalHotKey.RegisterHotKey(Settings.Default.MenuUpKey, () =>
{
+ if (!isForeground())
+ return;
rootMenu.Prev();
setDismissTimer();
- });
+ dismissNeptuneInput();
+ }, true);
GlobalHotKey.RegisterHotKey(Settings.Default.MenuDownKey, () =>
{
+ if (!isForeground())
+ return;
rootMenu.Next();
setDismissTimer();
- });
+ dismissNeptuneInput();
+ }, true);
GlobalHotKey.RegisterHotKey(Settings.Default.MenuLeftKey, () =>
{
+ if (!isForeground())
+ return;
rootMenu.SelectPrev();
setDismissTimer();
+ dismissNeptuneInput();
});
GlobalHotKey.RegisterHotKey(Settings.Default.MenuRightKey, () =>
{
+ if (!isForeground())
+ return;
rootMenu.SelectNext();
setDismissTimer();
+ dismissNeptuneInput();
});
if (Settings.Default.EnableNeptuneController)
@@ -130,6 +142,29 @@ namespace PowerControl
neptuneDevice.OpenDevice();
neptuneDevice.BeginRead();
}
+
+ if (Settings.Default.EnableVolumeControls)
+ {
+ GlobalHotKey.RegisterHotKey("VolumeUp", () =>
+ {
+ if ((neptuneDeviceState.buttons5 & (byte)SDCButton5.BTN_QUICK_ACCESS) != 0)
+ rootMenu.SelectNext("Brightness");
+ else
+ rootMenu.SelectNext("Volume");
+ setDismissTimer();
+ dismissNeptuneInput();
+ });
+
+ GlobalHotKey.RegisterHotKey("VolumeDown", () =>
+ {
+ if ((neptuneDeviceState.buttons5 & (byte)SDCButton5.BTN_QUICK_ACCESS) != 0)
+ rootMenu.SelectPrev("Brightness");
+ else
+ rootMenu.SelectPrev("Volume");
+ setDismissTimer();
+ dismissNeptuneInput();
+ });
+ }
}
private bool isForeground()
@@ -197,6 +232,11 @@ namespace PowerControl
Thread.Sleep(250);
}
+ private void dismissNeptuneInput()
+ {
+ neptuneDeviceNextKey = DateTime.UtcNow.AddDays(1);
+ }
+
private void NeptuneTimer_Tick(object? sender, EventArgs e)
{
var input = neptuneDeviceState;
@@ -210,6 +250,8 @@ namespace PowerControl
if ((input.buttons5 & (byte)SDCButton5.BTN_QUICK_ACCESS) == 0 || !isForeground())
{
+ // schedule next repeat far in the future
+ dismissNeptuneInput();
hideOSD();
return;
}
@@ -251,6 +293,7 @@ namespace PowerControl
if (!rootMenu.Visible)
return;
+ Trace.WriteLine("Hide OSD");
rootMenu.Visible = false;
osdDismissTimer.Stop();
updateOSD();
@@ -270,7 +313,10 @@ namespace PowerControl
if (OSDHelpers.OSDIndex("Power Control") == 0 && OSD.GetOSDCount() > 1)
osdClose();
if (osd == null)
+ {
osd = new OSD("Power Control");
+ Trace.WriteLine("Show OSD");
+ }
osd.Update(rootMenu.Render(null));
}
catch (SystemException)
@@ -294,7 +340,10 @@ namespace PowerControl
try
{
if (osd != null)
+ {
osd.Dispose();
+ Trace.WriteLine("Close OSD");
+ }
osd = null;
}
catch (SystemException)
diff --git a/PowerControl/External/GlobalHotKey.cs b/PowerControl/External/GlobalHotKey.cs
index df5ab1f..0015a77 100644
--- a/PowerControl/External/GlobalHotKey.cs
+++ b/PowerControl/External/GlobalHotKey.cs
@@ -14,7 +14,7 @@ namespace PowerControl.External
/// e.g. Alt + Shift + Control + Win + S
/// Action to be called when hotkey is pressed
/// true, if registration succeeded, otherwise false
- public static bool RegisterHotKey(string aKeyGestureString, Action aAction)
+ public static bool RegisterHotKey(string aKeyGestureString, Action aAction, bool repeat = false)
{
if (aKeyGestureString == "")
return false;
@@ -24,13 +24,13 @@ namespace PowerControl.External
foreach (var gesture in aKeyGestureString.Split(","))
{
KeyGesture aKeyGesture = (KeyGesture)c.ConvertFrom(gesture);
- if (RegisterHotKey(aKeyGesture.Modifiers, aKeyGesture.Key, aAction))
+ if (RegisterHotKey(aKeyGesture.Modifiers, aKeyGesture.Key, aAction, repeat))
success = true;
}
return success;
}
- public static bool RegisterHotKey(ModifierKeys aModifier, Key aKey, Action aAction)
+ public static bool RegisterHotKey(ModifierKeys aModifier, Key aKey, Action aAction, bool repeat = false)
{
if (aModifier == ModifierKeys.None && false)
{
@@ -44,7 +44,7 @@ namespace PowerControl.External
System.Windows.Forms.Keys aVirtualKeyCode = (System.Windows.Forms.Keys)KeyInterop.VirtualKeyFromKey(aKey);
currentID = currentID + 1;
bool aRegistered = RegisterHotKey(window.Handle, currentID,
- (uint)aModifier | MOD_NOREPEAT,
+ (uint)aModifier | (repeat ? 0 : MOD_NOREPEAT),
(uint)aVirtualKeyCode);
if (aRegistered)
diff --git a/PowerControl/Menu.cs b/PowerControl/Menu.cs
index bc11a82..1992f8f 100644
--- a/PowerControl/Menu.cs
+++ b/PowerControl/Menu.cs
@@ -272,6 +272,19 @@ namespace PowerControl
public delegate void VisibleChangedDelegate();
public VisibleChangedDelegate? VisibleChanged;
+ public MenuItem this[String name]
+ {
+ get
+ {
+ foreach(var item in Items)
+ {
+ if (item.Name == name)
+ return item;
+ }
+ return null;
+ }
+ }
+
public override void CreateMenu(ToolStripItemCollection collection)
{
foreach(var item in Items)
@@ -374,6 +387,19 @@ namespace PowerControl
}
}
+ public void SelectNext(String name)
+ {
+ var item = this[name];
+ if (item is null)
+ return;
+
+ Show();
+ Selected = item;
+ item.SelectNext();
+ if (VisibleChanged != null)
+ VisibleChanged();
+ }
+
public override void SelectPrev()
{
if (Show())
@@ -386,6 +412,19 @@ namespace PowerControl
VisibleChanged();
}
}
+
+ public void SelectPrev(String name)
+ {
+ var item = this[name];
+ if (item is null)
+ return;
+
+ Show();
+ Selected = item;
+ item.SelectPrev();
+ if (VisibleChanged != null)
+ VisibleChanged();
+ }
}
}
}
diff --git a/PowerControl/Settings.Designer.cs b/PowerControl/Settings.Designer.cs
index 7f78a01..b01e243 100644
--- a/PowerControl/Settings.Designer.cs
+++ b/PowerControl/Settings.Designer.cs
@@ -67,5 +67,14 @@ namespace PowerControl {
return ((bool)(this["EnableNeptuneController"]));
}
}
+
+ [global::System.Configuration.ApplicationScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("True")]
+ public bool EnableVolumeControls {
+ get {
+ return ((bool)(this["EnableVolumeControls"]));
+ }
+ }
}
}
diff --git a/PowerControl/Settings.settings b/PowerControl/Settings.settings
index 39119ea..432282a 100644
--- a/PowerControl/Settings.settings
+++ b/PowerControl/Settings.settings
@@ -17,5 +17,8 @@
True
+
+ True
+
\ No newline at end of file
diff --git a/README.md b/README.md
index bd4dd72..e6776bf 100644
--- a/README.md
+++ b/README.md
@@ -93,7 +93,9 @@ There are currently 4 configurable settings:
It will only work in OSD mode when rendering graphics.
The notification setting is always available.
-- SteamDeck Controller: press Quick Access (3 dots), and then together DPad Left, Rigth, Up, Down.
+- SteamDeck Controller: press and hold Quick Access (3 dots), and then DPad Left, Rigth, Up, Down.
+- Control Volume: use Volume Up and Down
+- Control Brightness: press and hold Quick Access (3 dots), and then Volume Up and Down
- Keyboard: `Ctrl+Win+Numpad2` (Down), `Ctrl+Win+Numpad4` (Left), `Ctrl+Win+Numpad6` (Right), `Ctrl+Win+Numpad8` (Up)
### 3.2. SWICD configuration
diff --git a/RELEASE.md b/RELEASE.md
new file mode 100644
index 0000000..a602410
--- /dev/null
+++ b/RELEASE.md
@@ -0,0 +1,7 @@
+- Adds Power Control
+- Repeat keystrokes
+- Allow to control OSD and Fan from Power Control
+- Improve flickering of OSD
+- Add Volume Up/Down controls (disable with `EnableVolumeControl` in `PowerControl.dll.config`)
+
+If you found it useful buy me [Ko-fi](https://ko-fi.com/ayufan).