Try fix sequence mode

This commit is contained in:
2025-08-31 21:05:40 +02:00
parent 1cdfba0b14
commit 87bd2132e5
3 changed files with 159 additions and 12 deletions

View File

@@ -37,13 +37,15 @@ class KeyboardHook {
int pero = (int)wParam * 1000 + vkCode;
if (pero != previousEvent) {
if (wParam == (IntPtr)WM_KEYDOWN) {
Console.WriteLine($"KeyboardHook: KeyDown event for key {vkCode}");
KeyDown?.Invoke(null, vkCode);
} else if (wParam == (IntPtr)WM_KEYUP) {
Console.WriteLine($"KeyboardHook: KeyUp event for key {vkCode}");
KeyUp?.Invoke(null, vkCode);
}
previousEvent = pero;
} else {
Console.WriteLine("Same event");
Console.WriteLine($"KeyboardHook: Same event filtered out - vkCode: {vkCode}, wParam: {wParam}");
}
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);

View File

@@ -36,48 +36,75 @@ namespace DD2Switcher {
}
public static void StartSequenceMode() {
Console.WriteLine($"StartSequenceMode called. FirstIndex: {FirstIndex}, LastIndex: {LastIndex}");
if (FirstIndex >= 0 && LastIndex >= 0 && FirstIndex <= LastIndex) {
SequenceMode = true;
CurrentState = SequenceState.PROCESSING;
CurrentSequenceIndex = FirstIndex;
Console.WriteLine($"Starting sequence mode, tabbing to index {CurrentSequenceIndex + 1}");
TabTo(CurrentSequenceIndex + 1); // Tab to first window
CurrentState = SequenceState.WAITING;
Console.WriteLine($"State changed to: {CurrentState}");
} else {
Console.WriteLine("Cannot start sequence mode - invalid first/last indices");
}
}
public static void NextSequenceStep() {
if (!SequenceMode)
Console.WriteLine(
$"NextSequenceStep called. State: {CurrentState}, CurrentIndex: {CurrentSequenceIndex}, LastIndex: {LastIndex}");
if (CurrentState == SequenceState.INACTIVE)
return;
CurrentState = SequenceState.PROCESSING;
CurrentSequenceIndex++;
Console.WriteLine($"Advanced to index {CurrentSequenceIndex}");
if (CurrentSequenceIndex > LastIndex) {
// End of sequence
Console.WriteLine("End of sequence reached, exiting sequence mode");
ExitSequenceMode();
} else {
Console.WriteLine($"Tabbing to index {CurrentSequenceIndex + 1}");
TabTo(CurrentSequenceIndex + 1);
CurrentState = SequenceState.WAITING;
Console.WriteLine($"State changed to: {CurrentState}");
}
}
public static void ExitSequenceMode() {
SequenceMode = false;
CurrentState = SequenceState.INACTIVE;
CurrentSequenceIndex = -1;
Console.WriteLine($"State changed to: {CurrentState}");
}
public static bool IsInSequenceMode() {
return CurrentState != SequenceState.INACTIVE;
}
public static void UpdateSequenceHotkey(Keys newKey) {
Console.WriteLine($"UpdateSequenceHotkey called with new key: {newKey} (code: {(int)newKey})");
Console.WriteLine($"Old SequenceKeybind before update: {SequenceKeybind} (code: {(int)SequenceKeybind})");
// Unregister old hotkey
if (sequenceHotkeyId != -1) {
Console.WriteLine($"Unregistering old hotkey ID: {sequenceHotkeyId}");
HotKeyManager.UnregisterHotKey(sequenceHotkeyId);
}
// Register new hotkey
sequenceHotkeyId = HotKeyManager.RegisterHotKey(newKey, KeyModifiers.NoRepeat);
Console.WriteLine($"Registered new hotkey ID: {sequenceHotkeyId} for key: {newKey}");
SequenceKeybind = newKey;
Console.WriteLine($"New SequenceKeybind after update: {SequenceKeybind} (code: {(int)SequenceKeybind})");
}
// Static properties for first/last selection persistence
public static int FirstIndex { get; set; } = -1;
public static int LastIndex { get; set; } = -1;
// Sequence mode state
public static bool SequenceMode { get; set; } = false;
// Sequence mode state engine
public enum SequenceState { INACTIVE, WAITING, PROCESSING }
public static SequenceState CurrentState { get; set; } = SequenceState.INACTIVE;
public static int CurrentSequenceIndex { get; set; } = -1;
public static Keys SequenceKeybind { get; set; } = Keys.F1;
private static int sequenceHotkeyId = -1;
@@ -107,6 +134,48 @@ namespace DD2Switcher {
[DllImport("user32.dll")]
private static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo);
[DllImport("user32.dll")]
private static extern IntPtr SetWindowsHookEx(int idHook, IntPtr lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll")]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll")]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll")]
private static extern IntPtr GetModuleHandle(string lpModuleName);
private const int WH_MOUSE_LL = 14;
private const int WM_LBUTTONDOWN = 0x0201;
private const int WM_RBUTTONDOWN = 0x0204;
private const int WM_MBUTTONDOWN = 0x0207;
private static IntPtr mouseHookId = IntPtr.Zero;
private static IntPtr mouseHookProc = IntPtr.Zero;
private static MouseHookProc mouseHookDelegate; // Keep reference to prevent GC
private delegate IntPtr MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam);
private static void HandleSequenceEvent() {
if (CurrentState == SequenceState.WAITING) {
Console.WriteLine($"Event detected in state: {CurrentState}, advancing to next step");
NextSequenceStep();
}
}
private static IntPtr MouseHookCallback(int nCode, IntPtr wParam, IntPtr lParam) {
if (nCode >= 0) {
int wParamInt = (int)wParam;
if (wParamInt == WM_LBUTTONDOWN || wParamInt == WM_RBUTTONDOWN || wParamInt == WM_MBUTTONDOWN) {
if (CurrentState == SequenceState.WAITING) {
Console.WriteLine($"Mouse click detected in state: {CurrentState}");
HandleSequenceEvent();
}
}
}
return CallNextHookEx(mouseHookId, nCode, wParam, lParam);
}
private static void CleanWindows() {
for (int i = 0; i < NumProc; i++) {
var window = windows[i];
@@ -293,6 +362,7 @@ namespace DD2Switcher {
}
private static void TabTo(int index) {
Console.WriteLine($"TabTo called with index: {index}");
index = (index - 1) % NumProc;
if (index < 0)
index = NumProc - 1;
@@ -302,6 +372,9 @@ namespace DD2Switcher {
Console.WriteLine($"Tab to window at index {index}");
var window = windows[index];
Console.WriteLine(
$"Window at index {index}: {(window == null ? "NULL" : window.ProcessName + " PID:" + window.Id)}");
if (window == null || window.MainWindowHandle == IntPtr.Zero) {
Console.WriteLine($"Window at index {index} does not exist, removing from tracked windows");
windows[index] = null;
@@ -309,10 +382,27 @@ namespace DD2Switcher {
if (ActiveIndex != -1)
PushHistory(ActiveIndex);
Console.WriteLine($"Setting foreground window to: {window.ProcessName} PID:{window.Id}");
bool result = SetForegroundWindow(window.MainWindowHandle);
Console.WriteLine($"SetForegroundWindow result: {result}");
// Force window to front with additional methods
if (result) {
// Bring window to front and activate it
SetForegroundWindow(window.MainWindowHandle);
System.Threading.Thread.Sleep(50); // Small delay
// Check if it actually worked
var currentForeground = GetForegroundWindow();
bool actuallySwitched = (currentForeground == window.MainWindowHandle);
Console.WriteLine(
$"Actually switched: {actuallySwitched} (Current: {currentForeground}, Target: {window.MainWindowHandle})");
}
ActiveIndex = index;
AdjustAffinities();
AdjustPriorities();
Console.WriteLine($"Successfully switched to window at index {index}");
}
}
@@ -360,6 +450,7 @@ namespace DD2Switcher {
[STAThread]
private static void Main() {
// AllocConsole(); // Enable console for debug output
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
@@ -374,6 +465,12 @@ namespace DD2Switcher {
bool onlyAlt = false;
KeyboardHook.Start();
// Set up mouse hook for sequence mode
mouseHookDelegate = new MouseHookProc(MouseHookCallback);
mouseHookProc = Marshal.GetFunctionPointerForDelegate(mouseHookDelegate);
mouseHookId = SetWindowsHookEx(WH_MOUSE_LL, mouseHookProc,
GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0);
KeyboardHook.KeyDown += (sender, e) => {
Console.WriteLine($"Key down: {e}");
if (e == 164 && !onlyAlt) {
@@ -391,6 +488,17 @@ namespace DD2Switcher {
onlyAlt = false;
TabToPrevious();
}
// Handle sequence mode event detection with KeyUp
if (CurrentState == SequenceState.WAITING) {
// Ignore the sequence keybind itself
if (e != (int)SequenceKeybind) {
Console.WriteLine($"Key up detected in state: {CurrentState} - Key: {e}");
HandleSequenceEvent();
} else {
Console.WriteLine($"Ignoring sequence keybind release: {e}");
}
}
};
HotKeyManager.RegisterHotKey(Keys.Capital, KeyModifiers.NoRepeat);
@@ -402,21 +510,37 @@ namespace DD2Switcher {
HotKeyManager.RegisterHotKey(Keys.Oemtilde, KeyModifiers.Alt);
sequenceHotkeyId = HotKeyManager.RegisterHotKey(SequenceKeybind, KeyModifiers.NoRepeat);
Console.WriteLine(
$"Initial sequence hotkey registration - ID: {sequenceHotkeyId}, Key: {SequenceKeybind} (code: {(int)SequenceKeybind})");
HotKeyManager.HotKeyPressed += HotKeyManager_HotKeyPressed;
void HotKeyManager_HotKeyPressed(object sender, HotKeyEventArgs e) {
Console.WriteLine($"Hotkey pressed: {e.Key} with modifiers {e.Modifiers}");
Console.WriteLine($"Current sequence keybind: {SequenceKeybind}");
Console.WriteLine($"Key codes - Pressed: {(int)e.Key}, Expected: {(int)SequenceKeybind}");
// Check for sequence mode keybind
if (e.Key == SequenceKeybind && e.Modifiers == KeyModifiers.NoRepeat) {
if (SequenceMode) {
Console.WriteLine(
$"Checking sequence keybind - Key: {e.Key} == {SequenceKeybind} = {e.Key == SequenceKeybind}");
Console.WriteLine($"Checking modifiers - Received: {e.Modifiers}, Expected: {KeyModifiers.NoRepeat}");
if (e.Key == SequenceKeybind) {
Console.WriteLine("Sequence keybind detected!");
if (CurrentState != SequenceState.INACTIVE) {
Console.WriteLine("Advancing sequence step");
NextSequenceStep();
} else {
Console.WriteLine("Starting sequence mode");
StartSequenceMode();
}
return;
} else {
Console.WriteLine(
$"Sequence keybind check failed - Key match: {e.Key == SequenceKeybind}, Modifiers match: {e.Modifiers == KeyModifiers.NoRepeat}");
}
// Cancel sequence mode on any manual window switching
if (SequenceMode && e.Modifiers == KeyModifiers.Alt) {
if (CurrentState != SequenceState.INACTIVE && e.Modifiers == KeyModifiers.Alt) {
Console.WriteLine("Manual window switching detected, cancelling sequence mode");
ExitSequenceMode();
}
@@ -448,6 +572,11 @@ namespace DD2Switcher {
// Run the WinForms application with Form1 as the main form
Application.Run(new Form1());
KeyboardHook.Stop();
// Clean up mouse hook
if (mouseHookId != IntPtr.Zero) {
UnhookWindowsHookEx(mouseHookId);
}
}
}
}

View File

@@ -13,7 +13,6 @@ namespace DD2Switcher {
private FlowLayoutPanel windowsPanel;
private Label sequenceKeybindLabel;
private TextBox sequenceKeybindTextBox;
private Timer statusTimer;
public SettingsForm() {
InitializeComponent();
@@ -107,6 +106,7 @@ namespace DD2Switcher {
this.Name = "SettingsForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "DD2Switcher Settings";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.SettingsForm_FormClosing);
this.tabControl.ResumeLayout(false);
this.windowsTab.ResumeLayout(false);
this.sequenceTab.ResumeLayout(false);
@@ -236,13 +236,29 @@ namespace DD2Switcher {
}
private void sequenceKeybindTextBox_Leave(object sender, EventArgs e) {
Console.WriteLine($"sequenceKeybindTextBox_Leave called with text: {sequenceKeybindTextBox.Text}");
try {
KeysConverter converter = new KeysConverter();
Keys newKey = (Keys)converter.ConvertFromString(sequenceKeybindTextBox.Text);
Console.WriteLine($"Converted key: {newKey} (code: {(int)newKey})");
Program.UpdateSequenceHotkey(newKey);
} catch {
Console.WriteLine("Keybind updated successfully!");
} catch (Exception ex) {
Console.WriteLine($"Error converting key: {ex.Message}");
sequenceKeybindTextBox.Text = Program.SequenceKeybind.ToString();
}
}
private void SettingsForm_FormClosing(object sender, FormClosingEventArgs e) {
Console.WriteLine("SettingsForm closing - saving keybind");
try {
KeysConverter converter = new KeysConverter();
Keys newKey = (Keys)converter.ConvertFromString(sequenceKeybindTextBox.Text);
Console.WriteLine($"Saving keybind on close: {newKey}");
Program.UpdateSequenceHotkey(newKey);
} catch (Exception ex) {
Console.WriteLine($"Error saving keybind on close: {ex.Message}");
}
}
}
}