Title: [223869] trunk/Source/WebKit
Revision
223869
Author
[email protected]
Date
2017-10-23 18:16:59 -0700 (Mon, 23 Oct 2017)

Log Message

[Mac] Web Automation: key modifiers for synthesized NSEvents are incorrect
https://bugs.webkit.org/show_bug.cgi?id=178615

Reviewed by Joseph Pecoraro.

In both PLATFORM(MAC) platform methods for simulating keyboard interactions,
we errantly relied on +[NSEvent modifierFlags] to get the current state of
sticky modifiers when creating synthesized events. This is incorrect for two reasons:
modifierFlags is never updated when simulating a sequence of events (because
all the events are synthesized before any are delivered); and the NSEvent class
method only reflects the modifier state of the primary physical keyboard, which
is not affected by synthesized NSEvents that happen to have modifier flags.

Instead, just keep our own m_currentModifiers state in the session and compute
the necessary NSEventModifierFlags to put on each synthesized event. This aligns
the implementation with the treatment of sticky keys in the iOS and GTK platform methods.

* UIProcess/Automation/WebAutomationSession.h: Every port gets this variable now.
* UIProcess/Automation/mac/WebAutomationSessionMac.mm:
(WebKit::WebAutomationSession::platformSimulateKeyStroke):
(WebKit::WebAutomationSession::platformSimulateKeySequence):
Use and update m_currentModifiers.

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (223868 => 223869)


--- trunk/Source/WebKit/ChangeLog	2017-10-24 00:55:54 UTC (rev 223868)
+++ trunk/Source/WebKit/ChangeLog	2017-10-24 01:16:59 UTC (rev 223869)
@@ -1,3 +1,28 @@
+2017-10-23  Brian Burg  <[email protected]>
+
+        [Mac] Web Automation: key modifiers for synthesized NSEvents are incorrect
+        https://bugs.webkit.org/show_bug.cgi?id=178615
+
+        Reviewed by Joseph Pecoraro.
+
+        In both PLATFORM(MAC) platform methods for simulating keyboard interactions,
+        we errantly relied on +[NSEvent modifierFlags] to get the current state of
+        sticky modifiers when creating synthesized events. This is incorrect for two reasons:
+        modifierFlags is never updated when simulating a sequence of events (because
+        all the events are synthesized before any are delivered); and the NSEvent class
+        method only reflects the modifier state of the primary physical keyboard, which
+        is not affected by synthesized NSEvents that happen to have modifier flags.
+
+        Instead, just keep our own m_currentModifiers state in the session and compute
+        the necessary NSEventModifierFlags to put on each synthesized event. This aligns
+        the implementation with the treatment of sticky keys in the iOS and GTK platform methods.
+
+        * UIProcess/Automation/WebAutomationSession.h: Every port gets this variable now.
+        * UIProcess/Automation/mac/WebAutomationSessionMac.mm:
+        (WebKit::WebAutomationSession::platformSimulateKeyStroke):
+        (WebKit::WebAutomationSession::platformSimulateKeySequence):
+        Use and update m_currentModifiers.
+
 2017-10-23  Alex Christensen  <[email protected]>
 
         Fix ASAN test after r222824

Modified: trunk/Source/WebKit/UIProcess/Automation/WebAutomationSession.h (223868 => 223869)


--- trunk/Source/WebKit/UIProcess/Automation/WebAutomationSession.h	2017-10-24 00:55:54 UTC (rev 223868)
+++ trunk/Source/WebKit/UIProcess/Automation/WebAutomationSession.h	2017-10-24 01:16:59 UTC (rev 223869)
@@ -259,16 +259,15 @@
 
     bool m_permissionForGetUserMedia { true };
 
+
+    // Keep track of currently active modifiers across multiple keystrokes.
+    // Most platforms do not track current modifiers from synthesized events.
+    unsigned m_currentModifiers { 0 };
+
 #if ENABLE(REMOTE_INSPECTOR)
     Inspector::FrontendChannel* m_remoteChannel { nullptr };
 #endif
 
-#if PLATFORM(IOS) || PLATFORM(GTK)
-    // Keep track of currently active modifiers across multiple keystrokes.
-    // We don't synthesize platform keyboard events on iOS, so we need to track it ourselves.
-    // GTK+ doesn't keep track of the active modifiers when using synthesized events.
-    unsigned m_currentModifiers { 0 };
-#endif
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/UIProcess/Automation/mac/WebAutomationSessionMac.mm (223868 => 223869)


--- trunk/Source/WebKit/UIProcess/Automation/mac/WebAutomationSessionMac.mm	2017-10-24 00:55:54 UTC (rev 223868)
+++ trunk/Source/WebKit/UIProcess/Automation/mac/WebAutomationSessionMac.mm	2017-10-24 01:16:59 UTC (rev 223869)
@@ -445,9 +445,6 @@
 
     auto eventsToBeSent = adoptNS([[NSMutableArray alloc] init]);
 
-    NSEventModifierFlags existingModifiers = [NSEvent modifierFlags];
-    NSEventModifierFlags updatedModifiers = 0;
-
     // FIXME: this timestamp is not even close to matching native events. Find out how to get closer.
     NSTimeInterval timestamp = [NSDate timeIntervalSinceReferenceDate];
     NSWindow *window = page.platformWindow();
@@ -457,14 +454,14 @@
     switch (interaction) {
     case Inspector::Protocol::Automation::KeyboardInteractionType::KeyPress: {
         NSEventType eventType = isStickyModifier ? NSEventTypeFlagsChanged : NSEventTypeKeyDown;
-        updatedModifiers = existingModifiers | changedModifiers;
-        [eventsToBeSent addObject:[NSEvent keyEventWithType:eventType location:eventPosition modifierFlags:updatedModifiers timestamp:timestamp windowNumber:windowNumber context:nil characters:characters charactersIgnoringModifiers:unmodifiedCharacters isARepeat:NO keyCode:keyCode]];
+        m_currentModifiers |= changedModifiers;
+        [eventsToBeSent addObject:[NSEvent keyEventWithType:eventType location:eventPosition modifierFlags:m_currentModifiers timestamp:timestamp windowNumber:windowNumber context:nil characters:characters charactersIgnoringModifiers:unmodifiedCharacters isARepeat:NO keyCode:keyCode]];
         break;
     }
     case Inspector::Protocol::Automation::KeyboardInteractionType::KeyRelease: {
         NSEventType eventType = isStickyModifier ? NSEventTypeFlagsChanged : NSEventTypeKeyUp;
-        updatedModifiers = existingModifiers & ~changedModifiers;
-        [eventsToBeSent addObject:[NSEvent keyEventWithType:eventType location:eventPosition modifierFlags:updatedModifiers timestamp:timestamp windowNumber:windowNumber context:nil characters:characters charactersIgnoringModifiers:unmodifiedCharacters isARepeat:NO keyCode:keyCode]];
+        m_currentModifiers &= ~changedModifiers;
+        [eventsToBeSent addObject:[NSEvent keyEventWithType:eventType location:eventPosition modifierFlags:m_currentModifiers timestamp:timestamp windowNumber:windowNumber context:nil characters:characters charactersIgnoringModifiers:unmodifiedCharacters isARepeat:NO keyCode:keyCode]];
         break;
     }
     case Inspector::Protocol::Automation::KeyboardInteractionType::InsertByKey: {
@@ -473,9 +470,9 @@
         if (isStickyModifier)
             return;
 
-        updatedModifiers = existingModifiers | changedModifiers;
-        [eventsToBeSent addObject:[NSEvent keyEventWithType:NSEventTypeKeyDown location:eventPosition modifierFlags:updatedModifiers timestamp:timestamp windowNumber:windowNumber context:nil characters:characters charactersIgnoringModifiers:unmodifiedCharacters isARepeat:NO keyCode:keyCode]];
-        [eventsToBeSent addObject:[NSEvent keyEventWithType:NSEventTypeKeyUp location:eventPosition modifierFlags:updatedModifiers timestamp:timestamp windowNumber:windowNumber context:nil characters:characters charactersIgnoringModifiers:unmodifiedCharacters isARepeat:NO keyCode:keyCode]];
+        m_currentModifiers |= changedModifiers;
+        [eventsToBeSent addObject:[NSEvent keyEventWithType:NSEventTypeKeyDown location:eventPosition modifierFlags:m_currentModifiers timestamp:timestamp windowNumber:windowNumber context:nil characters:characters charactersIgnoringModifiers:unmodifiedCharacters isARepeat:NO keyCode:keyCode]];
+        [eventsToBeSent addObject:[NSEvent keyEventWithType:NSEventTypeKeyUp location:eventPosition modifierFlags:m_currentModifiers timestamp:timestamp windowNumber:windowNumber context:nil characters:characters charactersIgnoringModifiers:unmodifiedCharacters isARepeat:NO keyCode:keyCode]];
         break;
     }
     }
@@ -535,7 +532,6 @@
     // This API should move more towards that direction in the future.
     NSString *text = keySequence;
 
-    NSEventModifierFlags modifiers = [NSEvent modifierFlags];
     NSTimeInterval timestamp = [NSDate timeIntervalSinceReferenceDate];
     NSWindow *window = page.platformWindow();
     NSInteger windowNumber = window.windowNumber;
@@ -546,9 +542,9 @@
         // For ASCII characters that are produced using Shift on a US-108 key keyboard layout,
         // WebDriver expects these to be delivered as [shift-down, key-down, key-up, shift-up]
         // keystrokes unless the shift key is already pressed down from an earlier interaction.
-        BOOL shiftAlreadyPressed = modifiers & NSEventModifierFlagShift;
+        BOOL shiftAlreadyPressed = m_currentModifiers & NSEventModifierFlagShift;
         BOOL shouldPressShift = !shiftAlreadyPressed && substringRange.length == 1 && characterIsProducedUsingShift(substring);
-        NSEventModifierFlags modifiersForKeystroke = shouldPressShift ? modifiers | NSEventModifierFlagShift : modifiers;
+        NSEventModifierFlags modifiersForKeystroke = shouldPressShift ? m_currentModifiers | NSEventModifierFlagShift : m_currentModifiers;
 
         if (shouldPressShift)
             [eventsToBeSent addObject:[NSEvent keyEventWithType:NSEventTypeFlagsChanged location:eventPosition modifierFlags:modifiersForKeystroke timestamp:timestamp windowNumber:windowNumber context:nil characters:@"" charactersIgnoringModifiers:@"" isARepeat:NO keyCode:kVK_Shift]];
@@ -557,7 +553,7 @@
         [eventsToBeSent addObject:[NSEvent keyEventWithType:NSEventTypeKeyUp location:eventPosition modifierFlags:modifiersForKeystroke timestamp:timestamp windowNumber:windowNumber context:nil characters:substring charactersIgnoringModifiers:substring isARepeat:NO keyCode:0]];
         
         if (shouldPressShift)
-            [eventsToBeSent addObject:[NSEvent keyEventWithType:NSEventTypeFlagsChanged location:eventPosition modifierFlags:modifiers timestamp:timestamp windowNumber:windowNumber context:nil characters:@"" charactersIgnoringModifiers:@"" isARepeat:NO keyCode:kVK_Shift]];
+            [eventsToBeSent addObject:[NSEvent keyEventWithType:NSEventTypeFlagsChanged location:eventPosition modifierFlags:m_currentModifiers timestamp:timestamp windowNumber:windowNumber context:nil characters:@"" charactersIgnoringModifiers:@"" isARepeat:NO keyCode:kVK_Shift]];
     }];
 
     sendSynthesizedEventsToPage(page, eventsToBeSent.get());
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to