Skip to content

Commit 7919ca2

Browse files
unknownunknown
authored andcommitted
Fixes the escape key not working florentbr#43
1 parent c5b73fb commit 7919ca2

5 files changed

Lines changed: 55 additions & 41 deletions

File tree

Selenium/Core/SysWaiter.cs

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class SysWaiter {
2525

2626
static readonly EventWaitHandle _signal_interrupt = null;
2727

28-
public static Action OnInterrupt;
28+
static Action _interrupt_delegate;
2929

3030
static SysWaiter() {
3131
string user = Environment.UserDomainName + "\\" + Environment.UserName;
@@ -42,22 +42,27 @@ static SysWaiter() {
4242
out createdNew,
4343
security);
4444

45-
HotKeyGlobal.Subscribe(MOD_NONE, VK_ESCAPE, Interrupt);
46-
HotKeyGlobal.Subscribe(MOD_NONE, VK_PAUSE, Interrupt);
45+
HotKeyGlobal.DefineHotKey(MOD_NONE, VK_ESCAPE, ProcInterrupt);
4746
}
4847

49-
public static void Initialize() {
50-
HotKeyGlobal.SubscribeAgain();
51-
}
52-
53-
public static void Terminate() {
54-
HotKeyGlobal.UnsubscribeAll();
48+
public static Action OnInterrupt {
49+
set {
50+
if (value == null && _interrupt_delegate != null) {
51+
HotKeyGlobal.UnsubscribeAll();
52+
} else {
53+
HotKeyGlobal.SubscribeAll();
54+
}
55+
_interrupt_delegate = value;
56+
}
5557
}
5658

57-
private static void Interrupt() {
59+
private static void ProcInterrupt() {
5860
_signal_interrupt.Set();
59-
if (OnInterrupt != null)
60-
OnInterrupt();
61+
if (_interrupt_delegate != null){
62+
_interrupt_delegate();
63+
_interrupt_delegate = null;
64+
}
65+
HotKeyGlobal.UnsubscribeAll();
6166
}
6267

6368
public static EventWaitHandle WaitHandle {
@@ -75,9 +80,12 @@ internal static void Wait() {
7580
}
7681

7782
public static void Wait(int timems) {
83+
HotKeyGlobal.SubscribeAll();
7884
_signal_interrupt.Reset();
79-
if (_signal_interrupt.WaitOne(timems, true))
85+
bool signaled = _signal_interrupt.WaitOne(timems, true);
86+
if (signaled)
8087
throw new Errors.KeyboardInterruptError();
88+
HotKeyGlobal.UnsubscribeAll();
8189
}
8290

8391
}

Selenium/Errors/KeyboardInterruptError.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,15 @@ namespace Selenium.Errors {
88
public class KeyboardInterruptError : SeleniumError {
99

1010
internal KeyboardInterruptError()
11-
: base("Code execution has been interrupted.") {
11+
: base(null) {
1212
base.Source = "Selenium";
13-
base.HResult = unchecked((int)0x80000007);
13+
base.HResult = FACILITY_CONTROL_ERROR | 0x4004;
14+
}
15+
16+
public override string Message {
17+
get {
18+
return "Code execution has been interrupted.";
19+
}
1420
}
1521

1622
}

Selenium/Internal/HotKeyGlobal.cs

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,34 +16,30 @@ class HotKeyGlobal {
1616

1717
static Thread _thread_;
1818
static uint _threadId_;
19-
static int _baseId_;
2019
static List<int> _hotKeys_ = new List<int>(5);
2120
static List<Action> _actions_ = new List<Action>(5);
22-
static int _registeredCount_ = 0;
2321

24-
public static void Subscribe(int modifier, int virtualKey, Action action) {
22+
public static void DefineHotKey(int modifier, int virtualKey, Action action) {
2523
if (_thread_ == null) {
2624
_thread_ = new Thread(RunMessagePump);
27-
_thread_.SetApartmentState(ApartmentState.STA);
2825
_thread_.IsBackground = true;
26+
_thread_.Start();
2927
lock (_thread_) {
30-
_thread_.Start();
3128
Monitor.Wait(_thread_);
3229
}
3330
}
3431

35-
int hotKey = (virtualKey << 16) | modifier;
32+
int hotKey = (virtualKey << 16) | (modifier & 0xFFFF);
3633
_hotKeys_.Add(hotKey);
3734
_actions_.Add(action);
3835

3936
PostThreadMessage(WM_USER_HOTKEY_REGISTER, modifier, virtualKey);
4037
}
4138

42-
public static void SubscribeAgain() {
43-
_registeredCount_ = 0;
44-
for (int i = _actions_.Count; i-- > 0; ) {
45-
int modifierCode = _hotKeys_[i] & 0xFFFF;
46-
int virtualKeyCode = _hotKeys_[i] >> 16;
39+
public static void SubscribeAll() {
40+
foreach(int hotkey in _hotKeys_){
41+
int modifierCode = hotkey & 0xFFFF;
42+
int virtualKeyCode = hotkey >> 16;
4743
PostThreadMessage(WM_USER_HOTKEY_REGISTER, modifierCode, virtualKeyCode);
4844
}
4945
}
@@ -62,39 +58,42 @@ static void EvalHotKey(uint hotkey) {
6258

6359
static void RunMessagePump() {
6460
_threadId_ = Native.GetCurrentThreadId();
65-
_baseId_ = (int)(_threadId_ & 0x0FFF);
66-
//signal the message pump is up and running
61+
62+
// signal that the message pump is up and running
6763
lock (_thread_) {
6864
Monitor.Pulse(_thread_);
6965
}
66+
7067
//run message pump
7168
try {
7269
DispatchThreadMessages();
7370
} catch { }
7471
}
7572

7673
static void DispatchThreadMessages() {
74+
uint atom = ((_threadId_ ^ (_threadId_ >> 16)) & 0x0ffff) - 25;
75+
uint count = 0;
7776
var msg = new Native.Message();
7877
while (Native.GetMessage(ref msg, (IntPtr)0, 0, 0) > 0) {
79-
switch (msg.Msg) {
80-
case WM_HOTKEY:
81-
EvalHotKey((uint)msg.LParam); // lword=modifiers, hword=virtualKey
82-
break;
78+
switch(msg.Msg){
8379
case WM_USER_HOTKEY_REGISTER:
8480
bool rhk = Native.RegisterHotKey(IntPtr.Zero,
85-
_baseId_ + _registeredCount_ + 1,
81+
atom + count,
8682
(uint)msg.WParam,
8783
(uint)msg.LParam);
8884
if (rhk) {
89-
_registeredCount_++;
85+
count++;
9086
}
9187
break;
9288
case WM_USER_HOTKEY_UNREGISTER_ALL:
93-
while (_registeredCount_ > 0) {
94-
Native.UnregisterHotKey(IntPtr.Zero, _baseId_ + _registeredCount_);
95-
_registeredCount_--;
89+
while (count > 0) {
90+
count--;
91+
Native.UnregisterHotKey(IntPtr.Zero, atom + count);
9692
}
9793
break;
94+
case WM_HOTKEY:
95+
EvalHotKey((uint)msg.LParam); // lword=modifiers, hword=virtualKey
96+
break;
9897
}
9998
}
10099
}
@@ -112,10 +111,10 @@ static class Native {
112111
public const string USER32 = "user32.dll";
113112

114113
[DllImport(USER32)]
115-
public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
114+
public static extern bool RegisterHotKey(IntPtr hWnd, uint id, uint fsModifiers, uint vk);
116115

117116
[DllImport(USER32)]
118-
public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
117+
public static extern bool UnregisterHotKey(IntPtr hWnd, uint id);
119118

120119
[DllImport(KERNEL32, SetLastError = false)]
121120
public static extern uint GetCurrentThreadId();

Selenium/SeleniumError.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ namespace Selenium {
77
/// </summary>
88
public class SeleniumError : SeleniumException {
99

10+
protected const int FACILITY_CONTROL_ERROR = unchecked((int)0xA00A0000);
11+
1012
/// <summary></summary>
1113
public Dictionary ResponseData { get; internal set; }
1214
private string _message;
@@ -21,7 +23,7 @@ internal SeleniumError(int code, string message, params object[] args)
2123

2224
internal SeleniumError(string message, int code = 0) {
2325
_message = message;
24-
base.HResult = -2146828288 + code;
26+
base.HResult = FACILITY_CONTROL_ERROR | code;
2527
}
2628

2729
/// <summary>

Selenium/WebDriver.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ public class WebDriver : SearchContext, ComInterfaces._WebDriver, IDisposable {
7171
/// </summary>
7272
public WebDriver() {
7373
UnhandledException.Initialize();
74-
SysWaiter.Initialize();
7574
RegisterRunningObject();
7675
COMDisposable.Subscribe(this, typeof(ComInterfaces._WebDriver));
7776
}

0 commit comments

Comments
 (0)