8 Commits

Author SHA1 Message Date
fcd70b699d Refactor hotkey handling in MainWindow.xaml.cs to improve user experience by implementing a visual indicator for active hotkeys and enhancing the feedback mechanism during recording. Adjustments made to ensure better responsiveness and clarity in user interactions. 2026-02-22 12:36:49 -05:00
7f5d80ff68 Enhance hotkey recording functionality in MainWindow.xaml.cs by adding escape key support to cancel recording and improving error handling. Introduce a delayed registration mechanism to prevent immediate re-entry of hotkeys, ensuring stability during hotkey updates. 2026-02-22 12:33:55 -05:00
ae744f1077 Update MainWindow.xaml.cs to replace HotkeyRecorderText with HotkeyRecorderButton for displaying hotkey information, enhancing user interaction during hotkey recording. Adjustments made to ensure proper focus and event handling for the button. 2026-02-22 12:21:38 -05:00
9b73bdbb24 Refactor MainWindow.xaml to streamline the hotkey button definition by consolidating properties and removing unnecessary elements, improving code clarity. 2026-02-22 12:21:27 -05:00
4902802615 Update MainWindow.xaml to include a name and focus properties for the root grid, enhancing accessibility and usability. 2026-02-22 12:17:03 -05:00
6aa49c0b07 Add hotkey recording functionality in MainWindow. Users can now set custom hotkeys through a dedicated button, with real-time feedback on key presses and modifier keys. Updates to settings are reflected immediately. 2026-02-22 12:15:50 -05:00
52a2515e2d Enhance GlobalHotkeyService to allow for dynamic hotkey updates and improve user experience with customizable HotkeyModifiers and HotkeyVirtualKey settings. 2026-02-22 12:14:57 -05:00
742c1d70fe Refactor GlobalHotkeyService to support dynamic hotkey registration and update. Introduce HotkeyModifiers and HotkeyVirtualKey properties in SettingsService for user-defined hotkeys. 2026-02-22 12:14:41 -05:00
7 changed files with 327 additions and 33 deletions

View File

@@ -18,12 +18,12 @@
<PackageCertificateThumbprint>4A55954F2A73A9D620442C7DFBFC7C95A71D8D24</PackageCertificateThumbprint> <PackageCertificateThumbprint>4A55954F2A73A9D620442C7DFBFC7C95A71D8D24</PackageCertificateThumbprint>
<AppxPackageSigningTimestampDigestAlgorithm>SHA256</AppxPackageSigningTimestampDigestAlgorithm> <AppxPackageSigningTimestampDigestAlgorithm>SHA256</AppxPackageSigningTimestampDigestAlgorithm>
<AppxAutoIncrementPackageRevision>True</AppxAutoIncrementPackageRevision> <AppxAutoIncrementPackageRevision>True</AppxAutoIncrementPackageRevision>
<AppxPackageDir>C:\Users\Blade\Desktop\Clipforge Packaged\V1\</AppxPackageDir> <AppxPackageDir>C:\Users\Blade\Desktop\Clipforge Packaged\V0.1\</AppxPackageDir>
<AppxSymbolPackageEnabled>False</AppxSymbolPackageEnabled> <AppxSymbolPackageEnabled>False</AppxSymbolPackageEnabled>
<GenerateTestArtifacts>True</GenerateTestArtifacts> <GenerateTestArtifacts>True</GenerateTestArtifacts>
<AppxBundle>Auto</AppxBundle> <AppxBundle>Auto</AppxBundle>
<AppxBundlePlatforms>x64</AppxBundlePlatforms> <AppxBundlePlatforms>x64</AppxBundlePlatforms>
<AppInstallerUri>J:\Projects\ClipForge\ClipForge\bin\x64\Release\net8.0-windows10.0.19041.0</AppInstallerUri> <AppInstallerUri>C:\Users\Blade\Desktop\Clipforge Packaged</AppInstallerUri>
<HoursBetweenUpdateChecks>0</HoursBetweenUpdateChecks> <HoursBetweenUpdateChecks>0</HoursBetweenUpdateChecks>
</PropertyGroup> </PropertyGroup>

View File

@@ -1,4 +1,4 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Microsoft.UI.Xaml; using Microsoft.UI.Xaml;
@@ -6,39 +6,49 @@ namespace ClipForge
{ {
public class GlobalHotkeyService public class GlobalHotkeyService
{ {
// These two lines talk directly to Windows to register/unregister hotkeys
[DllImport("user32.dll")] [DllImport("user32.dll")]
private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk); private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
[DllImport("user32.dll")] [DllImport("user32.dll")]
private static extern bool UnregisterHotKey(IntPtr hWnd, int id); private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
// This is the ID we'll use to identify our clip hotkey
private const int HOTKEY_CLIP = 1; private const int HOTKEY_CLIP = 1;
private const uint MOD_NOREPEAT = 0x4000; // don't fire on key repeat
// Alt key modifier
private const uint MOD_ALT = 0x0001;
// F9 key
private const uint VK_F9 = 0x78;
// This is the "event" that fires when the hotkey is pressed
public event Action? ClipRequested; public event Action? ClipRequested;
private IntPtr _hwnd; private IntPtr _hwnd;
private uint _modifiers;
private uint _vk;
public void Initialize(IntPtr hwnd) /// <summary>Register the clip hotkey. Use settings values (e.g. HotkeyModifiers, HotkeyVirtualKey).</summary>
public void Initialize(IntPtr hwnd, uint modifiers, uint vk)
{ {
_hwnd = hwnd; _hwnd = hwnd;
RegisterHotKey(_hwnd, HOTKEY_CLIP, MOD_ALT, VK_F9); _modifiers = modifiers;
_vk = vk;
TryRegister();
}
/// <summary>Update the hotkey at runtime (e.g. after user remaps). Unregisters old and registers new.</summary>
public bool UpdateHotkey(uint modifiers, uint vk)
{
UnregisterHotKey(_hwnd, HOTKEY_CLIP);
_modifiers = modifiers;
_vk = vk;
return TryRegister();
}
private bool TryRegister()
{
uint mod = _modifiers | MOD_NOREPEAT;
return RegisterHotKey(_hwnd, HOTKEY_CLIP, mod, _vk);
} }
public void ProcessHotkey(int id) public void ProcessHotkey(int id)
{ {
if (id == HOTKEY_CLIP) if (id == HOTKEY_CLIP)
{
ClipRequested?.Invoke(); ClipRequested?.Invoke();
}
} }
public void Cleanup() public void Cleanup()

183
ClipForge/HotkeyHelper.cs Normal file
View File

@@ -0,0 +1,183 @@
using System;
using System.Collections.Generic;
using Windows.System;
namespace ClipForge
{
/// <summary>Converts between hotkey modifier/vk and display strings.</summary>
public static class HotkeyHelper
{
public const uint MOD_ALT = 0x0001;
public const uint MOD_CONTROL = 0x0002;
public const uint MOD_SHIFT = 0x0004;
public const uint MOD_WIN = 0x0008;
public const uint MOD_NOREPEAT = 0x4000;
// Built in static ctor with TryAdd so duplicate VirtualKey enum values (e.g. Kana/Hangul = 0x15) don't throw.
private static readonly Dictionary<VirtualKey, string> KeyNames = new();
static HotkeyHelper()
{
TryAdd(VirtualKey.LeftButton, "LMB");
TryAdd(VirtualKey.RightButton, "RMB");
TryAdd(VirtualKey.Cancel, "Cancel");
TryAdd(VirtualKey.Back, "Backspace");
TryAdd(VirtualKey.Tab, "Tab");
TryAdd(VirtualKey.Clear, "Clear");
TryAdd(VirtualKey.Enter, "Enter");
TryAdd(VirtualKey.Shift, "Shift");
TryAdd(VirtualKey.Control, "Ctrl");
TryAdd(VirtualKey.Menu, "Alt");
TryAdd(VirtualKey.Pause, "Pause");
TryAdd(VirtualKey.CapitalLock, "Caps Lock");
TryAdd(VirtualKey.Kana, "Kana");
TryAdd(VirtualKey.Hangul, "Hangul"); // same value as Kana on some SDKs; TryAdd skips duplicate
TryAdd(VirtualKey.Junja, "Junja");
TryAdd(VirtualKey.Final, "Final");
TryAdd(VirtualKey.Hanja, "Hanja");
TryAdd(VirtualKey.Kanji, "Kanji");
TryAdd(VirtualKey.Escape, "Escape");
TryAdd(VirtualKey.Convert, "Convert");
TryAdd(VirtualKey.NonConvert, "NonConvert");
TryAdd(VirtualKey.Accept, "Accept");
TryAdd(VirtualKey.ModeChange, "ModeChange");
TryAdd(VirtualKey.Space, "Space");
TryAdd(VirtualKey.PageUp, "PgUp");
TryAdd(VirtualKey.PageDown, "PgDn");
TryAdd(VirtualKey.End, "End");
TryAdd(VirtualKey.Home, "Home");
TryAdd(VirtualKey.Left, "Left");
TryAdd(VirtualKey.Up, "Up");
TryAdd(VirtualKey.Right, "Right");
TryAdd(VirtualKey.Down, "Down");
TryAdd(VirtualKey.Select, "Select");
TryAdd(VirtualKey.Print, "Print");
TryAdd(VirtualKey.Execute, "Execute");
TryAdd(VirtualKey.Snapshot, "Print Screen");
TryAdd(VirtualKey.Insert, "Insert");
TryAdd(VirtualKey.Delete, "Delete");
TryAdd(VirtualKey.Help, "Help");
TryAdd(VirtualKey.Number0, "0");
TryAdd(VirtualKey.Number1, "1");
TryAdd(VirtualKey.Number2, "2");
TryAdd(VirtualKey.Number3, "3");
TryAdd(VirtualKey.Number4, "4");
TryAdd(VirtualKey.Number5, "5");
TryAdd(VirtualKey.Number6, "6");
TryAdd(VirtualKey.Number7, "7");
TryAdd(VirtualKey.Number8, "8");
TryAdd(VirtualKey.Number9, "9");
TryAdd(VirtualKey.A, "A");
TryAdd(VirtualKey.B, "B");
TryAdd(VirtualKey.C, "C");
TryAdd(VirtualKey.D, "D");
TryAdd(VirtualKey.E, "E");
TryAdd(VirtualKey.F, "F");
TryAdd(VirtualKey.G, "G");
TryAdd(VirtualKey.H, "H");
TryAdd(VirtualKey.I, "I");
TryAdd(VirtualKey.J, "J");
TryAdd(VirtualKey.K, "K");
TryAdd(VirtualKey.L, "L");
TryAdd(VirtualKey.M, "M");
TryAdd(VirtualKey.N, "N");
TryAdd(VirtualKey.O, "O");
TryAdd(VirtualKey.P, "P");
TryAdd(VirtualKey.Q, "Q");
TryAdd(VirtualKey.R, "R");
TryAdd(VirtualKey.S, "S");
TryAdd(VirtualKey.T, "T");
TryAdd(VirtualKey.U, "U");
TryAdd(VirtualKey.V, "V");
TryAdd(VirtualKey.W, "W");
TryAdd(VirtualKey.X, "X");
TryAdd(VirtualKey.Y, "Y");
TryAdd(VirtualKey.Z, "Z");
TryAdd(VirtualKey.LeftWindows, "Win");
TryAdd(VirtualKey.RightWindows, "Win");
TryAdd(VirtualKey.Application, "App");
TryAdd(VirtualKey.Sleep, "Sleep");
TryAdd(VirtualKey.NumberPad0, "Num 0");
TryAdd(VirtualKey.NumberPad1, "Num 1");
TryAdd(VirtualKey.NumberPad2, "Num 2");
TryAdd(VirtualKey.NumberPad3, "Num 3");
TryAdd(VirtualKey.NumberPad4, "Num 4");
TryAdd(VirtualKey.NumberPad5, "Num 5");
TryAdd(VirtualKey.NumberPad6, "Num 6");
TryAdd(VirtualKey.NumberPad7, "Num 7");
TryAdd(VirtualKey.NumberPad8, "Num 8");
TryAdd(VirtualKey.NumberPad9, "Num 9");
TryAdd(VirtualKey.Multiply, "Num *");
TryAdd(VirtualKey.Add, "Num +");
TryAdd(VirtualKey.Separator, "Num ,");
TryAdd(VirtualKey.Subtract, "Num -");
TryAdd(VirtualKey.Decimal, "Num .");
TryAdd(VirtualKey.Divide, "Num /");
TryAdd(VirtualKey.F1, "F1");
TryAdd(VirtualKey.F2, "F2");
TryAdd(VirtualKey.F3, "F3");
TryAdd(VirtualKey.F4, "F4");
TryAdd(VirtualKey.F5, "F5");
TryAdd(VirtualKey.F6, "F6");
TryAdd(VirtualKey.F7, "F7");
TryAdd(VirtualKey.F8, "F8");
TryAdd(VirtualKey.F9, "F9");
TryAdd(VirtualKey.F10, "F10");
TryAdd(VirtualKey.F11, "F11");
TryAdd(VirtualKey.F12, "F12");
TryAdd(VirtualKey.F13, "F13");
TryAdd(VirtualKey.F14, "F14");
TryAdd(VirtualKey.F15, "F15");
TryAdd(VirtualKey.F16, "F16");
TryAdd(VirtualKey.F17, "F17");
TryAdd(VirtualKey.F18, "F18");
TryAdd(VirtualKey.F19, "F19");
TryAdd(VirtualKey.F20, "F20");
TryAdd(VirtualKey.F21, "F21");
TryAdd(VirtualKey.F22, "F22");
TryAdd(VirtualKey.F23, "F23");
TryAdd(VirtualKey.F24, "F24");
TryAdd(VirtualKey.NumberKeyLock, "NumLock");
TryAdd(VirtualKey.Scroll, "Scroll Lock");
TryAdd(VirtualKey.LeftShift, "Shift");
TryAdd(VirtualKey.RightShift, "Shift");
TryAdd(VirtualKey.LeftControl, "Ctrl");
TryAdd(VirtualKey.RightControl, "Ctrl");
TryAdd(VirtualKey.LeftMenu, "Alt");
TryAdd(VirtualKey.RightMenu, "Alt");
}
private static void TryAdd(VirtualKey key, string name)
{
KeyNames.TryAdd(key, name);
}
/// <summary>Format modifier flags + virtual key as display string (e.g. "Alt + PgUp").</summary>
public static string ToDisplayString(uint modifiers, uint vk)
{
var parts = new List<string>();
if ((modifiers & MOD_WIN) != 0) parts.Add("Win");
if ((modifiers & MOD_CONTROL) != 0) parts.Add("Ctrl");
if ((modifiers & MOD_ALT) != 0) parts.Add("Alt");
if ((modifiers & MOD_SHIFT) != 0) parts.Add("Shift");
var keyName = GetKeyName((VirtualKey)vk);
if (!string.IsNullOrEmpty(keyName))
parts.Add(keyName);
return parts.Count > 0 ? string.Join(" + ", parts) : "None";
}
public static string GetKeyName(VirtualKey key)
{
return KeyNames.TryGetValue(key, out var name) ? name : key.ToString();
}
/// <summary>True if the key is typically used only as a modifier (don't use as sole key).</summary>
public static bool IsModifierKey(VirtualKey key)
{
return key == VirtualKey.LeftWindows || key == VirtualKey.RightWindows
|| key == VirtualKey.Control || key == VirtualKey.LeftControl || key == VirtualKey.RightControl
|| key == VirtualKey.Menu || key == VirtualKey.LeftMenu || key == VirtualKey.RightMenu
|| key == VirtualKey.Shift || key == VirtualKey.LeftShift || key == VirtualKey.RightShift;
}
}
}

View File

@@ -13,7 +13,7 @@
<MicaBackdrop /> <MicaBackdrop />
</Window.SystemBackdrop> </Window.SystemBackdrop>
<Grid> <Grid x:Name="RootGrid">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/> <ColumnDefinition Width="200"/>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
@@ -371,22 +371,22 @@
FontWeight="SemiBold" FontWeight="SemiBold"
VerticalAlignment="Center"/> VerticalAlignment="Center"/>
</StackPanel> </StackPanel>
<TextBlock Text="The key combination to save a clip." <TextBlock Text="Click the key below, then press your desired combination."
FontSize="12" FontSize="12"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"/> Foreground="{ThemeResource TextFillColorSecondaryBrush}"/>
<Border Background="#1a1a2e" <Button x:Name="HotkeyRecorderButton"
HorizontalAlignment="Left"
Click="HotkeyRecorderButton_Click"
Background="#1a1a2e"
BorderThickness="0"
CornerRadius="6" CornerRadius="6"
Padding="16,10" Padding="16,10"
HorizontalAlignment="Left"> MinWidth="140"
<TextBlock Text="Alt + F9" FontFamily="Consolas"
FontFamily="Consolas" FontSize="14"
FontSize="14" FontWeight="Bold"
FontWeight="Bold" Foreground="#E8FF47"
Foreground="#E8FF47"/> Content="Alt + F9"/>
</Border>
<TextBlock Text="Hotkey remapping coming in a future update."
FontSize="11"
Foreground="{ThemeResource TextFillColorTertiaryBrush}"/>
</StackPanel> </StackPanel>
</Border> </Border>

View File

@@ -1,10 +1,12 @@
using Microsoft.UI.Xaml; using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media.Animation; using Microsoft.UI.Xaml.Media.Animation;
using Microsoft.Win32; using Microsoft.Win32;
using System; using System;
using System.Linq; using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Windows.System;
using WinRT.Interop; using WinRT.Interop;
namespace ClipForge namespace ClipForge
@@ -16,6 +18,7 @@ namespace ClipForge
private ClipLibraryService _clipLibrary; private ClipLibraryService _clipLibrary;
private SettingsService _settingsService; private SettingsService _settingsService;
private ThumbnailService _thumbnailService; private ThumbnailService _thumbnailService;
private bool _isRecordingHotkey;
private delegate IntPtr WinProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); private delegate IntPtr WinProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
private WinProc _newWndProc; private WinProc _newWndProc;
@@ -41,6 +44,13 @@ namespace ClipForge
private static extern IntPtr SendMessage(IntPtr hWnd, uint msg, private static extern IntPtr SendMessage(IntPtr hWnd, uint msg,
IntPtr wParam, IntPtr lParam); IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
private static extern short GetAsyncKeyState(int vk);
private const int VK_SHIFT = 0x10;
private const int VK_CONTROL = 0x11;
private const int VK_MENU = 0x12; // Alt
private const int VK_LWIN = 0x5B;
private const int GWLP_WNDPROC = -4; private const int GWLP_WNDPROC = -4;
private const uint WM_HOTKEY = 0x0312; private const uint WM_HOTKEY = 0x0312;
private const int GWL_EXSTYLE = -20; private const int GWL_EXSTYLE = -20;
@@ -78,7 +88,10 @@ namespace ClipForge
_hotkeyService = new GlobalHotkeyService(); _hotkeyService = new GlobalHotkeyService();
_hotkeyService.ClipRequested += OnClipRequested; _hotkeyService.ClipRequested += OnClipRequested;
_hotkeyService.Initialize(hwnd); var mod = _settingsService.Settings.HotkeyModifiers;
var vk = _settingsService.Settings.HotkeyVirtualKey;
if (mod == 0 && vk == 0) { mod = 1; vk = 0x78; }
_hotkeyService.Initialize(hwnd, (uint)mod, (uint)vk);
ClipGrid.ItemsSource = _clipLibrary.Clips; ClipGrid.ItemsSource = _clipLibrary.Clips;
UpdateClipCount(); UpdateClipCount();
@@ -169,6 +182,8 @@ namespace ClipForge
QualityLabel.Text = $"{s.VideoQuality}%"; QualityLabel.Text = $"{s.VideoQuality}%";
FramerateCombo.SelectedIndex = s.Framerate == 30 ? 0 : 1; FramerateCombo.SelectedIndex = s.Framerate == 30 ? 0 : 1;
StartupToggle.IsOn = IsStartupEnabled(); StartupToggle.IsOn = IsStartupEnabled();
if (HotkeyRecorderButton != null)
HotkeyRecorderButton.Content = HotkeyHelper.ToDisplayString((uint)s.HotkeyModifiers, (uint)s.HotkeyVirtualKey);
} }
// --- STARTUP WITH WINDOWS --- // --- STARTUP WITH WINDOWS ---
@@ -235,6 +250,89 @@ namespace ClipForge
_ = ShowToastAsync("✅ Settings saved!"); _ = ShowToastAsync("✅ Settings saved!");
} }
// --- CUSTOM HOTKEY ---
private void HotkeyRecorderButton_Click(object sender, RoutedEventArgs e)
{
if (_isRecordingHotkey) return;
_isRecordingHotkey = true;
HotkeyRecorderButton.Content = "Press any key... (Esc to cancel)";
HotkeyRecorderButton.Focus(FocusState.Programmatic);
HotkeyRecorderButton.KeyDown += OnHotkeyCaptureKeyDown;
}
private void OnHotkeyCaptureKeyDown(object sender, KeyRoutedEventArgs e)
{
if (!_isRecordingHotkey) return;
e.Handled = true;
try
{
var key = e.Key;
// Escape cancels without changing the hotkey
if (key == VirtualKey.Escape)
{
StopRecordingHotkey(restoreDisplay: true);
return;
}
if (HotkeyHelper.IsModifierKey(key))
return; // wait for a non-modifier key
if (key == VirtualKey.None)
return;
uint mod = 0;
if ((GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0) mod |= HotkeyHelper.MOD_CONTROL;
if ((GetAsyncKeyState(VK_MENU) & 0x8000) != 0) mod |= HotkeyHelper.MOD_ALT;
if ((GetAsyncKeyState(VK_SHIFT) & 0x8000) != 0) mod |= HotkeyHelper.MOD_SHIFT;
if ((GetAsyncKeyState(VK_LWIN) & 0x8000) != 0) mod |= HotkeyHelper.MOD_WIN;
uint vk = (uint)key;
_settingsService.Settings.HotkeyModifiers = (int)mod;
_settingsService.Settings.HotkeyVirtualKey = (int)vk;
var display = HotkeyHelper.ToDisplayString(mod, vk);
StopRecordingHotkey(restoreDisplay: false);
HotkeyRecorderButton.Content = display;
// Defer registration so the key is released first; otherwise the new hotkey can fire
// immediately and re-enter (e.g. OnClipRequested) and crash.
_ = DelayedHotkeyRegister(mod, vk, display);
}
catch (Exception ex)
{
StopRecordingHotkey(restoreDisplay: true);
_ = ShowToastAsync("⚠ " + ex.Message);
}
}
private void StopRecordingHotkey(bool restoreDisplay)
{
HotkeyRecorderButton.KeyDown -= OnHotkeyCaptureKeyDown;
_isRecordingHotkey = false;
if (restoreDisplay)
{
var s = _settingsService.Settings;
HotkeyRecorderButton.Content = HotkeyHelper.ToDisplayString((uint)s.HotkeyModifiers, (uint)s.HotkeyVirtualKey);
}
}
private async System.Threading.Tasks.Task DelayedHotkeyRegister(uint mod, uint vk, string display)
{
await System.Threading.Tasks.Task.Delay(300);
App.MainQueue?.TryEnqueue(() =>
{
try
{
var ok = _hotkeyService.UpdateHotkey(mod, vk);
HotkeyRecorderButton.Content = ok ? display : display + " (in use?)";
}
catch (Exception ex)
{
HotkeyRecorderButton.Content = display;
_ = ShowToastAsync("⚠ " + ex.Message);
}
});
}
// --- NAV --- // --- NAV ---
private void NavClips_Click(object sender, RoutedEventArgs e) private void NavClips_Click(object sender, RoutedEventArgs e)
{ {

View File

@@ -11,7 +11,7 @@
<Identity <Identity
Name="735fb287-32b4-4217-b84a-302365dc5e23" Name="735fb287-32b4-4217-b84a-302365dc5e23"
Publisher="CN=SCOPEDD" Publisher="CN=SCOPEDD"
Version="1.0.0.0" /> Version="0.1.0.0" />
<mp:PhoneIdentity PhoneProductId="735fb287-32b4-4217-b84a-302365dc5e23" PhonePublisherId="00000000-0000-0000-0000-000000000000"/> <mp:PhoneIdentity PhoneProductId="735fb287-32b4-4217-b84a-302365dc5e23" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>

View File

@@ -1,4 +1,4 @@
using System; using System;
using System.IO; using System.IO;
using System.Text.Json; using System.Text.Json;
@@ -9,7 +9,10 @@ namespace ClipForge
public int ClipLengthSeconds { get; set; } = 30; public int ClipLengthSeconds { get; set; } = 30;
public int VideoQuality { get; set; } = 70; public int VideoQuality { get; set; } = 70;
public int Framerate { get; set; } = 60; public int Framerate { get; set; } = 60;
public string HotkeyDisplay { get; set; } = "Alt + F9"; /// <summary>Windows modifier flags: Alt=1, Ctrl=2, Shift=4, Win=8.</summary>
public int HotkeyModifiers { get; set; } = 1; // MOD_ALT
/// <summary>Windows virtual key code (e.g. VK_F9=0x78, VK_PRIOR=0x21 for PgUp).</summary>
public int HotkeyVirtualKey { get; set; } = 0x78; // VK_F9
} }
public class SettingsService public class SettingsService