Skip to content

Commit c4098fe

Browse files
committed
安静模式与降温模式支持曲线UI调整;
修复模拟按键无法触发的问题; 修复启动时Omen键菜单未显示已选择的应用和组合键的问题; 优化“选择UWP应用”和“设置模拟按键”界面。
1 parent e8638f9 commit c4098fe

5 files changed

Lines changed: 127 additions & 78 deletions

File tree

FanCurveForm.cs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ internal FanCurveForm(
7373

7474
var rootLayout = BuildRootLayout();
7575

76-
cpuChart = CreateChart(Strings.FanCurveCpuTitle, this.cpuTemperatureMaximum);
77-
gpuChart = CreateChart(Strings.FanCurveGpuTitle, this.gpuTemperatureMaximum);
76+
cpuChart = CreateChart("CPU", this.cpuTemperatureMaximum);
77+
gpuChart = CreateChart("GPU", this.gpuTemperatureMaximum);
7878

7979
rootLayout.Controls.Add(cpuChart, 0, 1);
8080
rootLayout.Controls.Add(gpuChart, 1, 1);
@@ -192,7 +192,7 @@ private Button CreateActionButton(string text) {
192192
});
193193
}
194194

195-
private Chart CreateChart(string title, int temperatureMaximum) {
195+
private Chart CreateChart(string cpuOrGpu, int temperatureMaximum) {
196196
var chart = new Chart {
197197
Dock = DockStyle.Fill,
198198
BackColor = PageBackColor,
@@ -204,25 +204,20 @@ private Chart CreateChart(string title, int temperatureMaximum) {
204204
chart.TextAntiAliasingQuality =
205205
TextAntiAliasingQuality.High;
206206

207-
chart.Titles.Add(new Title(title) {
208-
Font = new Font(Font.FontFamily, 12F, FontStyle.Bold),
209-
ForeColor = Color.FromArgb(40, 40, 40)
210-
});
211-
212207
var chartArea = new ChartArea("FanSpeedArea") {
213208
BackColor = CardBackColor
214209
};
215210

216211
chartArea.AxisX.Minimum = 0;
217212
chartArea.AxisX.Maximum = temperatureMaximum;
218213
chartArea.AxisX.Interval = 10;
219-
chartArea.AxisX.Title = Strings.FanCurveTemperatureAxis;
214+
chartArea.AxisX.Title = $"{cpuOrGpu} {Strings.FanCurveTemperatureAxis}";
220215
chartArea.AxisX.LineColor = AxisLineColor;
221216
chartArea.AxisX.MajorGrid.LineColor = GridColor;
222217
chartArea.AxisX.LabelStyle.ForeColor = Color.FromArgb(90, 90, 90);
223218
chartArea.AxisX.TitleForeColor = Color.FromArgb(80, 80, 80);
224219
chartArea.AxisX.TitleFont = new Font(Font.FontFamily, 12F, FontStyle.Bold);
225-
220+
226221
chartArea.AxisY.Minimum = 0;
227222
chartArea.AxisY.Maximum = fanSpeedMaximum;
228223
chartArea.AxisY.Interval = GetFanSpeedInterval(fanSpeedMaximum);

HelpForm.cs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -147,15 +147,11 @@ private static string GetHelpHtml_ZH(Version version) {
147147
<h2>📦 OmenSuperHub v{Assembly.GetExecutingAssembly().GetName().Version} 更新说明</h2>
148148
<div class='update-list'>
149149
<p><strong>新增:</strong></p>
150-
<li>✨ 自定义风扇曲线设置界面 <a href='https://github.com/breadeding/OmenSuperHub/pull/65'>(#65, Magic-Xin)</a></li>
151-
<li>✨ Omen键打开应用 <a href='https://github.com/breadeding/OmenSuperHub/pull/66'>(#66, shihuaidexianyu)</a></li>
152-
<li>✨ Omen键切换预设 <a href='https://github.com/breadeding/OmenSuperHub/pull/67'>(#67, Magic-Xin)</a></li>
153-
<li>✨ 本机信息添加PawnIO状态检测</a></li>
150+
<li>✨ Omen键打开UWP应用、绑定组合键 <a href='https://github.com/breadeding/OmenSuperHub/pull/68'>(#68, shihuaidexianyu)</a></li>
154151
<p><strong>优化:</strong></p>
155-
<li>⚡ 优化菜单操作:点击后不自动收起菜单</li>
156-
<li>⚡ 优化最大帧率菜单及提示</li>
152+
<li>⚡ 安静模式与降温模式支持曲线UI调整,优化转速曲线说明</li>
157153
<p><strong>修复:</strong></p>
158-
<li>🐛 切换预设时额外重新应用不相关设置的问题</li>
154+
<li>🐛 启动时Omen键菜单未显示已选择的应用</li>
159155
</div>
160156
161157
<p>本项目已开源至 Github:<a href='https://github.com/breadeding/OmenSuperHub'>https://github.com/breadeding/OmenSuperHub</a></p>

Program.Menu.cs

Lines changed: 79 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -233,16 +233,38 @@ void attachRename(ToolStripMenuItem item, string presetKey) {
233233
bool isBuiltInPreset = (currentPreset == "PresetExtreme" || currentPreset == "PresetGpuPriority" || currentPreset == "PresetLightUse");
234234

235235
ToolStripMenuItem fanConfigMenu = new ToolStripMenuItem(Strings.FanConfig);
236-
fanConfigMenu.DropDownItems.Add(CreateMenuItem(Strings.FanSilentMode, "fanTableGroup", (s, e) => {
237-
fanTable = "silent";
238-
LoadFanConfig("silent.txt");
239-
SaveConfig("FanTable");
240-
}, fanTable.Contains("silent"), Strings.FanSilentTooltip));
241-
fanConfigMenu.DropDownItems.Add(CreateMenuItem(Strings.FanCoolMode, "fanTableGroup", (s, e) => {
242-
fanTable = "cool";
243-
LoadFanConfig("cool.txt");
244-
SaveConfig("FanTable");
245-
}, fanTable.Contains("cool"), Strings.FanCoolTooltip));
236+
var silentFanItem = new ToolStripMenuItem(Strings.FanSilentMode) {
237+
Tag = "fanTableGroup",
238+
Checked = fanTable.Contains("silent"),
239+
ToolTipText = Strings.FanSilentTooltip
240+
};
241+
silentFanItem.MouseUp += (s, e) => {
242+
if (e.Button == MouseButtons.Left) {
243+
fanTable = "silent";
244+
LoadFanConfig("silent.txt");
245+
SaveConfig("FanTable");
246+
UpdateCheckedState("fanTableGroup", null, silentFanItem);
247+
} else if (e.Button == MouseButtons.Right) {
248+
ShowFanCurveEditor("silent.txt");
249+
}
250+
};
251+
fanConfigMenu.DropDownItems.Add(silentFanItem);
252+
var coolFanItem = new ToolStripMenuItem(Strings.FanCoolMode) {
253+
Tag = "fanTableGroup",
254+
Checked = fanTable.Contains("cool"),
255+
ToolTipText = Strings.FanCoolTooltip
256+
};
257+
coolFanItem.MouseUp += (s, e) => {
258+
if (e.Button == MouseButtons.Left) {
259+
fanTable = "cool";
260+
LoadFanConfig("cool.txt");
261+
SaveConfig("FanTable");
262+
UpdateCheckedState("fanTableGroup", null, coolFanItem);
263+
} else if (e.Button == MouseButtons.Right) {
264+
ShowFanCurveEditor("cool.txt");
265+
}
266+
};
267+
fanConfigMenu.DropDownItems.Add(coolFanItem);
246268
var customFanItem = new ToolStripMenuItem(Strings.FanCustomMode) {
247269
Tag = "fanTableGroup",
248270
Checked = fanTable.Contains("custom"),
@@ -253,7 +275,7 @@ void attachRename(ToolStripMenuItem item, string presetKey) {
253275
if (ApplyCustomFanConfig())
254276
UpdateCheckedState("fanTableGroup", null, customFanItem);
255277
} else if (e.Button == MouseButtons.Right) {
256-
ShowCustomFanCurveEditor();
278+
ShowFanCurveEditor("custom.txt");
257279
}
258280
};
259281
fanConfigMenu.DropDownItems.Add(customFanItem);
@@ -1241,20 +1263,37 @@ void attachRename(ToolStripMenuItem item, string presetKey) {
12411263
omenKeyMenu.DropDownItems.Add(omenKeyPresetCandidatesMenu);
12421264
omenKeyMenu.DropDownItems.Add(new ToolStripSeparator());
12431265

1244-
omenKeyMenu.DropDownItems.Add(new ToolStripMenuItem($"{Strings.OmenKeyCurrentApp}: {GetOmenKeyAppDisplayName()}") { Enabled = false });
1266+
var currentAppItem = new ToolStripMenuItem($"{Strings.OmenKeyCurrentApp}: {GetOmenKeyAppDisplayName()}") { Enabled = false };
1267+
var currentShortcutItem = new ToolStripMenuItem($"{Strings.OmenKeyCurrentShortcut}: {FormatOmenKeyShortcut(omenKeyShortcut)}") { Enabled = false };
1268+
1269+
// Refresh display items every time the submenu opens.
1270+
// This covers: (a) initial startup where BuildTrayMenu runs before RestoreConfig loads saved values,
1271+
// and (b) any stale state after actions that don't trigger a full menu rebuild.
1272+
omenKeyMenu.DropDownOpening += (s, e) => {
1273+
currentAppItem.Text = $"{Strings.OmenKeyCurrentApp}: {GetOmenKeyAppDisplayName()}";
1274+
currentShortcutItem.Text = $"{Strings.OmenKeyCurrentShortcut}: {FormatOmenKeyShortcut(omenKeyShortcut)}";
1275+
};
1276+
1277+
omenKeyMenu.DropDownItems.Add(currentAppItem);
12451278
omenKeyMenu.DropDownItems.Add(CreateMenuItem(Strings.OmenKeySelectDesktopApp, null, (s, e) => {
1279+
// SelectOmenKeyApp opens an OpenFileDialog which does NOT close the context menu.
1280+
// Avoid RefreshMenu() here — it would rebuild the ContextMenuStrip while this submenu
1281+
// is still visible, causing the root menu to flash and leaving the submenu showing
1282+
// stale "当前应用:" text. Instead, update the display item directly.
12461283
if (!SelectOmenKeyApp()) return;
12471284
SaveConfig("OmenKeyAppPath");
12481285
SaveConfig("OmenKeyAppName");
12491286
ApplyOmenKeyAction(OmenKeyActions.App);
1250-
RefreshMenu();
1287+
currentAppItem.Text = $"{Strings.OmenKeyCurrentApp}: {GetOmenKeyAppDisplayName()}";
1288+
UpdateCheckedState("omenKeyGroup", Strings.OmenKeyLaunchApp);
12511289
}, false));
12521290
omenKeyMenu.DropDownItems.Add(CreateMenuItem(Strings.OmenKeySelectUwpApp, null, (s, e) => {
12531291
if (!SelectOmenKeyUwpApp()) return;
12541292
SaveConfig("OmenKeyAppPath");
12551293
SaveConfig("OmenKeyAppName");
12561294
ApplyOmenKeyAction(OmenKeyActions.App);
1257-
RefreshMenu();
1295+
currentAppItem.Text = $"{Strings.OmenKeyCurrentApp}: {GetOmenKeyAppDisplayName()}";
1296+
UpdateCheckedState("omenKeyGroup", Strings.OmenKeyLaunchApp);
12581297
}, false));
12591298
omenKeyMenu.DropDownItems.Add(CreateMenuItem(Strings.OmenKeyClearApp, null, (s, e) => {
12601299
omenKeyAppPath = "";
@@ -1263,24 +1302,27 @@ void attachRename(ToolStripMenuItem item, string presetKey) {
12631302
SaveConfig("OmenKeyAppName");
12641303
if (omenKey == OmenKeyActions.App) {
12651304
ApplyOmenKeyAction(OmenKeyActions.None);
1305+
UpdateCheckedState("omenKeyGroup", Strings.OmenKeyNone);
12661306
}
1267-
RefreshMenu();
1307+
currentAppItem.Text = $"{Strings.OmenKeyCurrentApp}: {GetOmenKeyAppDisplayName()}";
12681308
}, false));
12691309
omenKeyMenu.DropDownItems.Add(new ToolStripSeparator());
1270-
omenKeyMenu.DropDownItems.Add(new ToolStripMenuItem($"{Strings.OmenKeyCurrentShortcut}: {FormatOmenKeyShortcut(omenKeyShortcut)}") { Enabled = false });
1310+
omenKeyMenu.DropDownItems.Add(currentShortcutItem);
12711311
omenKeyMenu.DropDownItems.Add(CreateMenuItem(Strings.OmenKeySetShortcut, null, (s, e) => {
12721312
if (!SelectOmenKeyShortcut()) return;
12731313
SaveConfig("OmenKeyShortcut");
12741314
ApplyOmenKeyAction(OmenKeyActions.Shortcut);
1275-
RefreshMenu();
1315+
currentShortcutItem.Text = $"{Strings.OmenKeyCurrentShortcut}: {FormatOmenKeyShortcut(omenKeyShortcut)}";
1316+
UpdateCheckedState("omenKeyGroup", Strings.OmenKeyShortcut);
12761317
}, false));
12771318
omenKeyMenu.DropDownItems.Add(CreateMenuItem(Strings.OmenKeyClearShortcut, null, (s, e) => {
12781319
omenKeyShortcut = "";
12791320
SaveConfig("OmenKeyShortcut");
12801321
if (omenKey == OmenKeyActions.Shortcut) {
12811322
ApplyOmenKeyAction(OmenKeyActions.None);
1323+
UpdateCheckedState("omenKeyGroup", Strings.OmenKeyNone);
12821324
}
1283-
RefreshMenu();
1325+
currentShortcutItem.Text = $"{Strings.OmenKeyCurrentShortcut}: {FormatOmenKeyShortcut(omenKeyShortcut)}";
12841326
}, false));
12851327
omenKeyMenu.DropDownItems.Add(new ToolStripSeparator());
12861328
omenKeyMenu.DropDownItems.Add(CreateMenuItem(Strings.OmenKeyNone, "omenKeyGroup", (s, e) => {
@@ -1915,38 +1957,41 @@ static void RefreshMenu() {
19151957
RestoreConfig();
19161958
}
19171959

1918-
static void ShowCustomFanCurveEditor() {
1960+
// Generalized fan curve editor: handles cool.txt, silent.txt, and custom.txt.
1961+
// "Save & Apply" saves the file, switches fanTable to the corresponding mode, reloads it, and updates checkmarks.
1962+
static void ShowFanCurveEditor(string fileName) {
19191963
string baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
1920-
string coolFilePath = Path.Combine(baseDirectory, "cool.txt");
1921-
string customFilePath = Path.Combine(baseDirectory, "custom.txt");
1964+
string filePath = Path.Combine(baseDirectory, fileName);
1965+
bool isSilent = fileName.IndexOf("silent", StringComparison.OrdinalIgnoreCase) >= 0;
19221966

19231967
try {
19241968
FanCurveProfile initialProfile;
1925-
if (File.Exists(customFilePath)) {
1926-
initialProfile = FanCurveProfile.Load(customFilePath);
1969+
if (File.Exists(filePath)) {
1970+
initialProfile = FanCurveProfile.Load(filePath);
19271971
} else {
1928-
if (!File.Exists(coolFilePath))
1929-
CreateDefaultFanCurveProfile(false).Save(coolFilePath);
1930-
initialProfile = FanCurveProfile.Load(coolFilePath);
1972+
initialProfile = CreateDefaultFanCurveProfile(isSilent);
19311973
}
19321974

19331975
int cpuMaximum = maxCPUTemp ?? 100;
19341976
int gpuMaximum = maxGPUTemp ?? 90;
19351977
int detectedMaximum = platformMaxFanSpeed ?? 5600;
19361978
int fanMaximum = Math.Max(1000, (int)(Math.Ceiling(detectedMaximum * 1.1 / 100D) * 100D));
1937-
var editor = new FanCurveForm(initialProfile, cpuMaximum, gpuMaximum, fanMaximum, customFilePath);
1979+
var editor = new FanCurveForm(initialProfile, cpuMaximum, gpuMaximum, fanMaximum, filePath);
19381980

1939-
// 订阅关闭事件,处理保存和应用
19401981
editor.FormClosed += (sender, args) => {
19411982
if (editor.EditorResult == FanCurveEditorResult.SavedAndApplied) {
1942-
ApplyCustomFanConfig();
1943-
// 更新菜单勾选状态
1944-
var customFanMenuItem = FindMenuItem(trayIcon.ContextMenuStrip.Items, Strings.FanCustomMode);
1945-
if (customFanMenuItem != null)
1946-
UpdateCheckedState("fanTableGroup", null, customFanMenuItem);
1983+
string fanTableKey = System.IO.Path.GetFileNameWithoutExtension(fileName).ToLowerInvariant();
1984+
fanTable = fanTableKey;
1985+
LoadFanConfig(fileName);
1986+
SaveConfig("FanTable");
1987+
string modeText =
1988+
fanTableKey == "silent" ? Strings.FanSilentMode :
1989+
fanTableKey == "cool" ? Strings.FanCoolMode :
1990+
Strings.FanCustomMode;
1991+
UpdateCheckedState("fanTableGroup", modeText);
19471992
}
19481993
};
1949-
editor.Show(); // 非模态显示
1994+
editor.Show();
19501995
} catch (Exception ex) when (
19511996
ex is IOException ||
19521997
ex is UnauthorizedAccessException ||

Program.OmenKey.cs

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,23 @@ struct INPUT {
5252
public InputUnion u;
5353
}
5454

55+
// MOUSEINPUT is the largest union member; including it ensures Marshal.SizeOf(INPUT)
56+
// matches what Windows expects (28 bytes on 32-bit, 40 bytes on 64-bit).
57+
// Without it, SendInput returns 0 and GetLastWin32Error returns 87 (ERROR_INVALID_PARAMETER).
58+
[StructLayout(LayoutKind.Sequential)]
59+
struct MOUSEINPUT {
60+
public int dx;
61+
public int dy;
62+
public uint mouseData;
63+
public uint dwFlags;
64+
public uint time;
65+
public IntPtr dwExtraInfo;
66+
}
67+
5568
[StructLayout(LayoutKind.Explicit)]
5669
struct InputUnion {
70+
[FieldOffset(0)]
71+
public MOUSEINPUT mi; // Largest member — sets the union's marshalled size
5772
[FieldOffset(0)]
5873
public KEYBDINPUT ki;
5974
}
@@ -393,8 +408,9 @@ static bool SelectOmenKeyUwpApp() {
393408
using (var form = new Form()) {
394409
form.Text = Strings.OmenKeySelectUwpApp;
395410
form.StartPosition = FormStartPosition.CenterScreen;
396-
form.Width = 720;
397-
form.Height = 520;
411+
System.Drawing.Rectangle screenBounds = Screen.PrimaryScreen.Bounds;
412+
form.Width = screenBounds.Width / 2;
413+
form.Height = screenBounds.Height / 2;
398414
form.MinimizeBox = false;
399415
form.MaximizeBox = false;
400416
form.ShowIcon = false;
@@ -417,24 +433,24 @@ static bool SelectOmenKeyUwpApp() {
417433
HideSelection = false,
418434
MultiSelect = false
419435
};
420-
listView.Columns.Add(Strings.OmenKeyUwpAppName, 240);
421-
listView.Columns.Add("AppID", 420);
436+
listView.Columns.Add(Strings.OmenKeyUwpAppName, listView.Width / 3 - 24);
437+
listView.Columns.Add("AppID", listView.Width * 2 / 3 - 24);
422438

423439
var okButton = new Button {
424440
Text = Strings.OK,
425441
Width = 92,
426-
Height = 28,
442+
Height = 36,
427443
Left = form.ClientSize.Width - 204,
428-
Top = form.ClientSize.Height - 40,
444+
Top = form.ClientSize.Height - 39,
429445
Anchor = AnchorStyles.Bottom | AnchorStyles.Right,
430446
Enabled = false
431447
};
432448
var cancelButton = new Button {
433449
Text = Strings.Cancel,
434450
Width = 92,
435-
Height = 28,
451+
Height = 36,
436452
Left = form.ClientSize.Width - 104,
437-
Top = form.ClientSize.Height - 40,
453+
Top = form.ClientSize.Height - 39,
438454
Anchor = AnchorStyles.Bottom | AnchorStyles.Right,
439455
DialogResult = DialogResult.Cancel
440456
};
@@ -545,7 +561,7 @@ static bool SelectOmenKeyShortcut() {
545561
form.Text = Strings.OmenKeySetShortcut;
546562
form.StartPosition = FormStartPosition.CenterScreen;
547563
form.Width = 440;
548-
form.Height = 180;
564+
form.Height = 210;
549565
form.MinimizeBox = false;
550566
form.MaximizeBox = false;
551567
form.ShowIcon = false;
@@ -571,7 +587,7 @@ static bool SelectOmenKeyShortcut() {
571587
var okButton = new Button {
572588
Text = Strings.OK,
573589
Width = 92,
574-
Height = 28,
590+
Height = 32,
575591
Left = form.ClientSize.Width - 304,
576592
Top = form.ClientSize.Height - 44,
577593
Anchor = AnchorStyles.Bottom | AnchorStyles.Right,
@@ -580,15 +596,15 @@ static bool SelectOmenKeyShortcut() {
580596
var clearButton = new Button {
581597
Text = Strings.Clear,
582598
Width = 92,
583-
Height = 28,
599+
Height = 32,
584600
Left = form.ClientSize.Width - 204,
585601
Top = form.ClientSize.Height - 44,
586602
Anchor = AnchorStyles.Bottom | AnchorStyles.Right
587603
};
588604
var cancelButton = new Button {
589605
Text = Strings.Cancel,
590606
Width = 92,
591-
Height = 28,
607+
Height = 32,
592608
Left = form.ClientSize.Width - 104,
593609
Top = form.ClientSize.Height - 44,
594610
Anchor = AnchorStyles.Bottom | AnchorStyles.Right,

0 commit comments

Comments
 (0)