Changeset 48964 in webkit
- Timestamp:
- Oct 1, 2009 2:02:30 AM (15 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/ChangeLog
r48963 r48964 1 2009-10-01 Martin Robinson <martin.james.robinson@gmail.com> 2 3 Reviewed by Xan Lopez. 4 5 [GTK] GtkIMContext filtering interferes with DOM key events 6 https://bugs.webkit.org/show_bug.cgi?id=28733 7 8 Add new key event test ensuring that IME keypresses are handled. 9 10 * GNUmakefile.am: 11 1 12 2009-10-01 Philippe Normand <pnormand@igalia.com> 2 13 -
trunk/GNUmakefile.am
r48673 r48964 582 582 Programs/unittests/testwebsettings \ 583 583 Programs/unittests/testwebresource \ 584 Programs/unittests/testwebdatasource 584 Programs/unittests/testwebdatasource \ 585 Programs/unittests/testkeyevents 585 586 586 587 # Add additional tests here … … 651 652 Programs_unittests_testhittestresult_CFLAGS = $(webkit_tests_cflags) 652 653 Programs_unittests_testhittestresult_LDADD = $(webkit_tests_ldadd) 654 655 Programs_unittests_testkeyevents_SOURCES = WebKit/gtk/tests/testkeyevents.c 656 Programs_unittests_testkeyevents_CFLAGS = $(webkit_tests_cflags) 657 Programs_unittests_testkeyevents_LDADD = $(webkit_tests_ldadd) 658 Programs_unittests_testkeyevents_LDFLAGS = $(webkit_tests_ldflags) 653 659 654 660 # Autogenerated sources -
trunk/LayoutTests/ChangeLog
r48963 r48964 1 2009-10-01 Martin Robinson <martin.james.robinson@gmail.com> 2 3 Reviewed by Xan Lopez. 4 5 [GTK] GtkIMContext filtering interferes with DOM key events 6 https://bugs.webkit.org/show_bug.cgi?id=28733 7 8 Re-enable skipped tests which were previously failing. 9 10 * platform/gtk/Skipped: 11 1 12 2009-10-01 Philippe Normand <pnormand@igalia.com> 2 13 -
trunk/LayoutTests/platform/gtk/Skipped
r48963 r48964 1595 1595 fast/events/frame-tab-focus.html 1596 1596 fast/events/js-keyboard-event-creation.html 1597 fast/events/key-events-in-input-button.html1598 fast/events/key-events-in-input-text.html1599 fast/events/keydown-keypress-focus-change.html1600 fast/events/keydown-keypress-preventDefault.html1601 fast/events/keypress-focus-change.html1602 1597 fast/events/keypress-insert-tab.html 1603 1598 fast/events/mouse-click-events.html … … 1619 1614 fast/events/right-click-focus.html 1620 1615 fast/events/scrollbar-double-click.html 1621 fast/events/special-key-events-in-input-text.html1622 1616 fast/events/stop-load-in-unload-handler-using-document-write.html 1623 1617 fast/events/stop-load-in-unload-handler-using-window-stop.html … … 5554 5548 fast/events/drag-to-navigate.html 5555 5549 fast/events/prevent-drag-to-navigate.html 5556 fast/events/keydown-function-keys.html5557 5550 fast/forms/slider-delete-while-dragging-thumb.html 5558 5551 fast/events/tab-focus-anchor.html -
trunk/WebCore/ChangeLog
r48963 r48964 1 2009-10-01 Martin Robinson <martin.james.robinson@gmail.com> 2 3 Reviewed by Xan Lopez. 4 5 [GTK] GtkIMContext filtering interferes with DOM key events 6 https://bugs.webkit.org/show_bug.cgi?id=28733 7 8 Ensure that keyboard events filtered by the GtkIMContext still create 9 the proper DOM events. 10 11 No tests added. Instead previously skipped tests have been enabled. 12 13 * platform/gtk/KeyEventGtk.cpp: 14 (WebCore::keyIdentifierForGdkKeyCode): 15 (WebCore::singleCharacterString): 16 1 17 2009-10-01 Philippe Normand <pnormand@igalia.com> 2 18 -
trunk/WebCore/platform/gtk/KeyEventGtk.cpp
r48714 r48964 137 137 case GDK_Delete: 138 138 return "U+007F"; 139 case GDK_BackSpace: 140 return "U+0008"; 139 141 case GDK_ISO_Left_Tab: 140 142 case GDK_3270_BackTab: … … 504 506 case GDK_Return: 505 507 return String("\r"); 508 case GDK_BackSpace: 509 return String("\x8"); 506 510 default: 507 511 gunichar c = gdk_keyval_to_unicode(val); -
trunk/WebKit/gtk/ChangeLog
r48877 r48964 1 2009-10-01 Martin Robinson <martin.james.robinson@gmail.com> 2 3 Reviewed by Xan Lopez. 4 5 [GTK] GtkIMContext filtering interferes with DOM key events 6 https://bugs.webkit.org/show_bug.cgi?id=28733 7 8 Ensure that keyboard events filtered by the GtkIMContext still create 9 the proper DOM events. 10 11 * WebCoreSupport/EditorClientGtk.cpp: 12 (WebKit::clearPendingIMData): 13 (WebKit::imContextCommitted): 14 (WebKit::imContextPreeditChanged): 15 (WebKit::EditorClient::shouldBeginEditing): 16 (WebKit::EditorClient::shouldEndEditing): 17 (WebKit::interpretEditorCommandKeyEvent): 18 (WebKit::handleCaretBrowsingKeyboardEvent): 19 (WebKit::EditorClient::handleKeyboardEvent): 20 (WebKit::EditorClient::handleInputMethodKeydown): 21 * tests/testkeyevents.c: Added. 22 (test_info_new): 23 (test_info_destroy): 24 (key_event_fixture_setup): 25 (key_event_fixture_teardown): 26 (key_press_event_cb): 27 (key_release_event_cb): 28 (load_status_cb): 29 (map_event_cb): 30 (test_keypress): 31 (main): 32 1 33 2009-09-29 Xan Lopez <xlopez@igalia.com> 2 34 -
trunk/WebKit/gtk/WebCoreSupport/EditorClientGtk.cpp
r48714 r48964 50 50 namespace WebKit { 51 51 52 static gchar* pendingComposition = 0; 53 static gchar* pendingPreedit = 0; 54 55 static void clearPendingIMData() 56 { 57 g_free(pendingComposition); 58 pendingComposition = 0; 59 g_free(pendingPreedit); 60 pendingPreedit = 0; 61 } 52 62 static void imContextCommitted(GtkIMContext* context, const gchar* str, EditorClient* client) 53 63 { 54 Frame* targetFrame = core(client->m_webView)->focusController()->focusedOrMainFrame(); 55 56 if (!targetFrame || !targetFrame->editor()->canEdit()) 57 return; 58 59 Editor* editor = targetFrame->editor(); 60 61 String commitString = String::fromUTF8(str); 62 editor->confirmComposition(commitString); 64 ASSERT(!pendingComposition); 65 66 // This signal will fire during a keydown event. We want the contents of the 67 // field to change right before the keyup event, so we wait until then to actually 68 // commit this composition. 69 pendingComposition = g_strdup(str); 63 70 } 64 71 65 72 static void imContextPreeditChanged(GtkIMContext* context, EditorClient* client) 66 73 { 67 Frame* frame = core(client->m_webView)->focusController()->focusedOrMainFrame(); 68 Editor* editor = frame->editor(); 69 70 gchar* preedit = NULL; 71 gint cursorPos = 0; 74 ASSERT(!pendingPreedit); 75 72 76 // We ignore the provided PangoAttrList for now. 73 gtk_im_context_get_preedit_string(context, &preedit, NULL, &cursorPos); 74 String preeditString = String::fromUTF8(preedit); 75 g_free(preedit); 76 77 // setComposition() will replace the user selection if passed an empty 78 // preedit. We don't want this to happen. 79 if (preeditString.isEmpty() && !editor->hasComposition()) 80 return; 81 82 Vector<CompositionUnderline> underlines; 83 underlines.append(CompositionUnderline(0, preeditString.length(), Color(0, 0, 0), false)); 84 editor->setComposition(preeditString, underlines, cursorPos, 0); 77 gtk_im_context_get_preedit_string(context, &pendingPreedit, NULL, NULL); 85 78 } 86 79 … … 137 130 bool EditorClient::shouldBeginEditing(WebCore::Range*) 138 131 { 132 clearPendingIMData(); 133 139 134 notImplemented(); 140 135 return true; … … 143 138 bool EditorClient::shouldEndEditing(WebCore::Range*) 144 139 { 140 clearPendingIMData(); 141 145 142 notImplemented(); 146 143 return true; … … 422 419 }; 423 420 424 static const char* interpret KeyEvent(const KeyboardEvent* evt)421 static const char* interpretEditorCommandKeyEvent(const KeyboardEvent* evt) 425 422 { 426 423 ASSERT(evt->type() == eventNames().keydownEvent || evt->type() == eventNames().keypressEvent); … … 457 454 } 458 455 459 static bool handleEditingKeyboardEvent(KeyboardEvent* evt) 460 { 461 Node* node = evt->target()->toNode(); 456 static bool handleCaretBrowsingKeyboardEvent(Frame* frame, const PlatformKeyboardEvent* keyEvent) 457 { 458 switch (keyEvent->windowsVirtualKeyCode()) { 459 case VK_LEFT: 460 frame->selection()->modify(keyEvent->shiftKey() ? SelectionController::EXTEND : SelectionController::MOVE, 461 SelectionController::LEFT, 462 keyEvent->ctrlKey() ? WordGranularity : CharacterGranularity, 463 true); 464 return true; 465 case VK_RIGHT: 466 frame->selection()->modify(keyEvent->shiftKey() ? SelectionController::EXTEND : SelectionController::MOVE, 467 SelectionController::RIGHT, 468 keyEvent->ctrlKey() ? WordGranularity : CharacterGranularity, 469 true); 470 return true; 471 case VK_UP: 472 frame->selection()->modify(keyEvent->shiftKey() ? SelectionController::EXTEND : SelectionController::MOVE, 473 SelectionController::BACKWARD, 474 keyEvent->ctrlKey() ? ParagraphGranularity : LineGranularity, 475 true); 476 return true; 477 case VK_DOWN: 478 frame->selection()->modify(keyEvent->shiftKey() ? SelectionController::EXTEND : SelectionController::MOVE, 479 SelectionController::FORWARD, 480 keyEvent->ctrlKey() ? ParagraphGranularity : LineGranularity, 481 true); 482 return true; 483 default: 484 return false; // Not a caret browswing keystroke, so continue processing. 485 } 486 } 487 488 void EditorClient::handleKeyboardEvent(KeyboardEvent* event) 489 { 490 Node* node = event->target()->toNode(); 462 491 ASSERT(node); 463 492 Frame* frame = node->document()->frame(); 464 493 ASSERT(frame); 465 494 466 const PlatformKeyboardEvent* keyEvent = evt->keyEvent();467 if (! keyEvent)468 return false;495 const PlatformKeyboardEvent* platformEvent = event->keyEvent(); 496 if (!platformEvent) 497 return; 469 498 470 499 bool caretBrowsing = frame->settings()->caretBrowsingEnabled(); 471 if (caretBrowsing) { 472 switch (keyEvent->windowsVirtualKeyCode()) { 473 case VK_LEFT: 474 frame->selection()->modify(keyEvent->shiftKey() ? SelectionController::EXTEND : SelectionController::MOVE, 475 SelectionController::LEFT, 476 keyEvent->ctrlKey() ? WordGranularity : CharacterGranularity, 477 true); 478 return true; 479 case VK_RIGHT: 480 frame->selection()->modify(keyEvent->shiftKey() ? SelectionController::EXTEND : SelectionController::MOVE, 481 SelectionController::RIGHT, 482 keyEvent->ctrlKey() ? WordGranularity : CharacterGranularity, 483 true); 484 return true; 485 case VK_UP: 486 frame->selection()->modify(keyEvent->shiftKey() ? SelectionController::EXTEND : SelectionController::MOVE, 487 SelectionController::BACKWARD, 488 keyEvent->ctrlKey() ? ParagraphGranularity : LineGranularity, 489 true); 490 return true; 491 case VK_DOWN: 492 frame->selection()->modify(keyEvent->shiftKey() ? SelectionController::EXTEND : SelectionController::MOVE, 493 SelectionController::FORWARD, 494 keyEvent->ctrlKey() ? ParagraphGranularity : LineGranularity, 495 true); 496 return true; 500 if (caretBrowsing && handleCaretBrowsingKeyboardEvent(frame, platformEvent)) { 501 // This was a caret browsing key event, so prevent it from bubbling up to the DOM. 502 event->setDefaultHandled(); 503 return; 504 } 505 506 // Don't allow editor commands or text insertion for nodes that cannot edit. 507 if (!frame->editor()->canEdit()) 508 return; 509 510 const gchar* editorCommandString = interpretEditorCommandKeyEvent(event); 511 if (editorCommandString) { 512 Editor::Command command = frame->editor()->command(editorCommandString); 513 514 // On editor commands from key down events, we only want to let the event bubble up to 515 // the DOM if it inserts text. If it doesn't insert text (e.g. Tab that changes focus) 516 // we just want WebKit to handle it immediately without a DOM event. 517 if (platformEvent->type() == PlatformKeyboardEvent::RawKeyDown) { 518 if (!command.isTextInsertion() && command.execute(event)) 519 event->setDefaultHandled(); 520 521 return; 522 } else if (command.execute(event)) { 523 event->setDefaultHandled(); 524 return; 497 525 } 498 526 } 499 527 500 Editor::Command command = frame->editor()->command(interpretKeyEvent(evt)); 501 502 if (keyEvent->type() == PlatformKeyboardEvent::RawKeyDown) { 503 // WebKit doesn't have enough information about mode to decide how commands that just insert text if executed via Editor should be treated, 504 // so we leave it upon WebCore to either handle them immediately (e.g. Tab that changes focus) or let a keypress event be generated 505 // (e.g. Tab that inserts a Tab character, or Enter). 506 return !command.isTextInsertion() && command.execute(evt); 507 } 508 509 if (command.execute(evt)) 510 return true; 511 512 // Don't insert null or control characters as they can result in unexpected behaviour 513 if (evt->charCode() < ' ') 514 return false; 515 516 // Don't insert anything if a modifier is pressed 517 if (keyEvent->ctrlKey() || keyEvent->altKey()) 518 return false; 519 520 return frame->editor()->insertText(evt->keyEvent()->text(), evt); 521 } 522 523 void EditorClient::handleKeyboardEvent(KeyboardEvent* event) 524 { 525 if (handleEditingKeyboardEvent(event)) 526 event->setDefaultHandled(); 528 // This is just a normal text insertion, so wait to execute the insertion 529 // until a keypress event happens. This will ensure that the insertion will not 530 // be reflected in the contents of the field until the keyup DOM event. 531 if (event->type() == eventNames().keypressEvent) { 532 533 if (pendingComposition) { 534 String compositionString = String::fromUTF8(pendingComposition); 535 frame->editor()->confirmComposition(compositionString); 536 537 clearPendingIMData(); 538 event->setDefaultHandled(); 539 540 } else if (pendingPreedit) { 541 String preeditString = String::fromUTF8(pendingPreedit); 542 543 // Don't use an empty preedit as it will destroy the current 544 // selection, even if the composition is cancelled or fails later on. 545 if (!preeditString.isEmpty()) { 546 Vector<CompositionUnderline> underlines; 547 underlines.append(CompositionUnderline(0, preeditString.length(), Color(0, 0, 0), false)); 548 frame->editor()->setComposition(preeditString, underlines, 0, 0); 549 } 550 551 clearPendingIMData(); 552 event->setDefaultHandled(); 553 554 } else { 555 // Don't insert null or control characters as they can result in unexpected behaviour 556 if (event->charCode() < ' ') 557 return; 558 559 // Don't insert anything if a modifier is pressed 560 if (platformEvent->ctrlKey() || platformEvent->altKey()) 561 return; 562 563 if (frame->editor()->insertText(platformEvent->text(), event)) 564 event->setDefaultHandled(); 565 } 566 } 527 567 } 528 568 … … 533 573 return; 534 574 575 // TODO: We need to decide which filtered keystrokes should be treated as IM 576 // events and which should not. 535 577 WebKitWebViewPrivate* priv = m_webView->priv; 536 // TODO: Dispatch IE-compatible text input events for IM events. 537 if (gtk_im_context_filter_keypress(priv->imContext, event->keyEvent()->gdkEventKey())) 538 event->setDefaultHandled(); 578 gtk_im_context_filter_keypress(priv->imContext, event->keyEvent()->gdkEventKey()); 539 579 } 540 580
Note: See TracChangeset
for help on using the changeset viewer.