From 64f4050de591f56cfd7e9dc10a973527c7e1fcc4 Mon Sep 17 00:00:00 2001 From: maniman303 <38860685+maniman303@users.noreply.github.com> Date: Mon, 19 Dec 2022 21:36:58 +0100 Subject: [PATCH] PowerControl: Tweaks and fixes (#29) * Fix context menu, add osd toggle * Update values on number of displays change * Check display info in DeviceManager * Refactor OSD toggle * Isolate display context setup * Move more context stuff to the display initialize method --- PowerControl/Controller.cs | 70 ++++++++++++++++++++++++++- PowerControl/Helpers/DeviceManager.cs | 43 ++++++++++++++++ PowerControl/Settings.cs | 8 ++- 3 files changed, 119 insertions(+), 2 deletions(-) diff --git a/PowerControl/Controller.cs b/PowerControl/Controller.cs index 910be19..dda076b 100644 --- a/PowerControl/Controller.cs +++ b/PowerControl/Controller.cs @@ -1,6 +1,7 @@ using CommonHelpers; using ExternalHelpers; using hidapi; +using Microsoft.Win32; using PowerControl.External; using PowerControl.Helpers; using RTSSSharedMemoryNET; @@ -16,6 +17,9 @@ namespace PowerControl public const int KeyPressRepeatTime = 400; public const int KeyPressNextRepeatTime = 90; + private SynchronizationContext? context; + System.Windows.Forms.Timer contextTimer; + Container components = new Container(); System.Windows.Forms.NotifyIcon notifyIcon; StartupManager startupManager = new StartupManager(Title); @@ -23,6 +27,7 @@ namespace PowerControl Menu.MenuRoot rootMenu = MenuStack.Root; OSD osd; System.Windows.Forms.Timer osdDismissTimer; + bool isOSDToggled = false; hidapi.HidDevice neptuneDevice = new hidapi.HidDevice(0x28de, 0x1205, 64); SDCInput neptuneDeviceState = new SDCInput(); @@ -50,6 +55,11 @@ namespace PowerControl if (Instance.WantsRunOnStartup) startupManager.Startup = true; + InitializeDisplayContext(); + contextTimer?.Start(); + + SystemEvents.DisplaySettingsChanged += DisplayChangesHandler; + var contextMenu = new System.Windows.Forms.ContextMenuStrip(components); rootMenu.Init(); @@ -87,11 +97,18 @@ namespace PowerControl notifyIcon.Visible = true; notifyIcon.ContextMenuStrip = contextMenu; + // Fix first time context menu position + contextMenu.Show(); + contextMenu.Close(); + osdDismissTimer = new System.Windows.Forms.Timer(components); osdDismissTimer.Interval = 3000; osdDismissTimer.Tick += delegate (object? sender, EventArgs e) { - hideOSD(); + if (!isOSDToggled) + { + hideOSD(); + } }; var osdTimer = new System.Windows.Forms.Timer(components); @@ -135,6 +152,23 @@ namespace PowerControl dismissNeptuneInput(); }); + GlobalHotKey.RegisterHotKey(Settings.Default.MenuToggle, () => + { + isOSDToggled = !rootMenu.Visible; + + if (!RTSS.IsOSDForeground()) + return; + + if (isOSDToggled) + { + showOSD(); + } + else + { + hideOSD(); + } + }, true); + if (Settings.Default.EnableNeptuneController) { neptuneTimer = new System.Windows.Forms.Timer(components); @@ -297,6 +331,17 @@ namespace PowerControl updateOSD(); } + private void showOSD() + { + if (rootMenu.Visible) + return; + + Trace.WriteLine("Show OSD"); + rootMenu.Update(); + rootMenu.Visible = true; + updateOSD(); + } + public void updateOSD() { sharedData.SetValue(new PowerControlSetting() @@ -353,5 +398,28 @@ namespace PowerControl { } } + + private void InitializeDisplayContext() + { + DeviceManager.LoadDisplays(); + contextTimer = new System.Windows.Forms.Timer(); + contextTimer.Interval = 200; + contextTimer.Tick += (_, _) => + { + context = SynchronizationContext.Current; + contextTimer.Stop(); + }; + } + + private void DisplayChangesHandler(object? sender, EventArgs e) + { + if (DeviceManager.RefreshDisplays()) + { + context?.Post((object? state) => + { + rootMenu.Update(); + }, null); + } + } } } diff --git a/PowerControl/Helpers/DeviceManager.cs b/PowerControl/Helpers/DeviceManager.cs index d1b22b6..97fbdc3 100644 --- a/PowerControl/Helpers/DeviceManager.cs +++ b/PowerControl/Helpers/DeviceManager.cs @@ -11,6 +11,30 @@ namespace PowerControl.Helpers { internal class DeviceManager { + private static Screen[] screens = new Screen[0]; + public static int NumberOfDisplays + { + get { return screens.Length; } + } + + public static void LoadDisplays() + { + screens = Screen.AllScreens; + } + + public static bool RefreshDisplays() + { + var newScreens = Screen.AllScreens; + + if (HaveScreensChanged(newScreens)) + { + screens = newScreens; + return true; + } + + return false; + } + public static string[]? GetDevices(Guid? classGuid) { string? filter = null; @@ -126,6 +150,25 @@ namespace PowerControl.Helpers } } + private static bool HaveScreensChanged(Screen[] newScreens) + { + if (screens.Length != newScreens.Length) + { + return true; + } + + for (int i = 0; i < screens.Length; i++) + { + if (screens[i].DeviceName != newScreens[i].DeviceName || + screens[i].Primary != newScreens[i].Primary) + { + return true; + } + } + + return false; + } + [DllImport("setupapi.dll", CharSet = CharSet.Auto)] static extern int CM_Locate_DevNode(out IntPtr pdnDevInst, string pDeviceID, int ulFlags); diff --git a/PowerControl/Settings.cs b/PowerControl/Settings.cs index 4cdfd4e..d1904d3 100644 --- a/PowerControl/Settings.cs +++ b/PowerControl/Settings.cs @@ -25,7 +25,7 @@ namespace PowerControl public string MenuLeftKey { - get { return Get("MenuLeftKey", "Ctrl+Win+Numpad6"); } + get { return Get("MenuLeftKey", "Ctrl+Win+Numpad4"); } set { Set("MenuLeftKey", value); } } @@ -35,6 +35,12 @@ namespace PowerControl set { Set("MenuRightKey", value); } } + public string MenuToggle + { + get { return Get("MenuToggle", "Shift+F11"); } + set { Set("MenuToggle", value); } + } + public bool EnableNeptuneController { get { return Get("EnableNeptuneController", true); }