Fix enter/space key press events on Combobox

Currently if user presses enter/space key on a combo box control,
popup menu does not open.

This CL handles the OnChar event in the combobox control.
When the Enter key is pressed, OnChar event returns true and shows the
popup menu if it is not already present.

When the Space key is pressed,
- If the form is non-editable and popup menu is not shown,
  popup menu is shown
- If the form is editable,
  space is entered as text

Bug: pdfium:1513
Change-Id: I5cc81df41ec925c4ceed6ae040665a146567583f
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/68614
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Himadri Kakar <hikakar@microsoft.com>
diff --git a/fpdfsdk/fpdf_formfill_embeddertest.cpp b/fpdfsdk/fpdf_formfill_embeddertest.cpp
index 56917e2..12c303b 100644
--- a/fpdfsdk/fpdf_formfill_embeddertest.cpp
+++ b/fpdfsdk/fpdf_formfill_embeddertest.cpp
@@ -2309,6 +2309,81 @@
   CheckSelection(L"ABCDEHello");
 }
 
+TEST_F(FPDFFormFillComboBoxFormEmbedderTest,
+       CheckIfEnterAndSpaceKeyAreHandled) {
+  // Non-editable field is set to 'Banana' (index 1) upon opening.
+  ClickOnFormFieldAtPoint(NonEditableFormBegin());
+  CheckIsIndexSelected(0, false);
+  CheckIsIndexSelected(1, true);
+
+  // Verify that the Enter key is handled.
+  EXPECT_TRUE(FORM_OnChar(form_handle(), page(), FWL_VKEY_Return, 0));
+
+  // Change the selection in the combo-box using the arrow down key.
+  EXPECT_TRUE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Down, 0));
+  CheckIsIndexSelected(1, false);
+  CheckIsIndexSelected(2, true);
+
+  // Tab to the next control.
+  EXPECT_TRUE(FORM_OnChar(form_handle(), page(), FWL_VKEY_Tab, 0));
+
+  // Shift-tab to the previous control.
+  EXPECT_TRUE(
+      FORM_OnChar(form_handle(), page(), FWL_VKEY_Tab, FWL_EVENTFLAG_ShiftKey));
+
+  // Verify that the selection is unchanged.
+  CheckIsIndexSelected(2, true);
+
+  // Verify that the Space key is handled.
+  EXPECT_TRUE(FORM_OnChar(form_handle(), page(), FWL_VKEY_Space, 0));
+
+  // Change the selection in the combo-box using the arrow down key.
+  EXPECT_TRUE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Down, 0));
+  CheckIsIndexSelected(3, true);
+
+  // Tab to the next control.
+  EXPECT_TRUE(FORM_OnChar(form_handle(), page(), FWL_VKEY_Tab, 0));
+
+  // Shift-tab to the previous control.
+  EXPECT_TRUE(
+      FORM_OnChar(form_handle(), page(), FWL_VKEY_Tab, FWL_EVENTFLAG_ShiftKey));
+
+  // Verify that the selection is unchanged.
+  CheckIsIndexSelected(3, true);
+}
+
+TEST_F(FPDFFormFillComboBoxFormEmbedderTest,
+       CheckIfEnterAndSpaceKeyAreHandledOnEditableFormField) {
+  // Non-editable field is set to 'Banana' (index 1) upon opening.
+  ClickOnFormFieldAtPoint(EditableFormBegin());
+  CheckIsIndexSelected(0, false);
+  CheckIsIndexSelected(1, false);
+
+  // Verify that the Enter key is handled.
+  EXPECT_TRUE(FORM_OnChar(form_handle(), page(), FWL_VKEY_Return, 0));
+
+  // Change the selection in the combo-box using the arrow down key.
+  EXPECT_TRUE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Down, 0));
+  CheckIsIndexSelected(0, true);
+  CheckIsIndexSelected(1, false);
+
+  // Tab to the next control.
+  EXPECT_TRUE(FORM_OnChar(form_handle(), page(), FWL_VKEY_Tab, 0));
+
+  // Shift-tab to the previous control.
+  EXPECT_TRUE(
+      FORM_OnChar(form_handle(), page(), FWL_VKEY_Tab, FWL_EVENTFLAG_ShiftKey));
+
+  // Verify that the selection is unchanged.
+  CheckIsIndexSelected(0, true);
+
+  // Verify that the Space key is handled.
+  EXPECT_TRUE(FORM_OnChar(form_handle(), page(), FWL_VKEY_Space, 0));
+
+  CheckFocusedFieldText(L" ");
+  CheckIsIndexSelected(0, false);
+}
+
 TEST_F(FPDFFormFillTextFormEmbedderTest,
        InsertTextInEmptyCharLimitTextFieldOverflow) {
   // Click on the textfield.
diff --git a/fpdfsdk/pwl/cpwl_combo_box.cpp b/fpdfsdk/pwl/cpwl_combo_box.cpp
index a821d0c..d23a905 100644
--- a/fpdfsdk/pwl/cpwl_combo_box.cpp
+++ b/fpdfsdk/pwl/cpwl_combo_box.cpp
@@ -533,6 +533,28 @@
   if (!m_pEdit)
     return false;
 
+  // In a combo box if the ENTER/SPACE key is pressed, show the combo box
+  // options.
+  switch (nChar) {
+    case FWL_VKEY_Return:
+      SetPopup(!IsPopup());
+      SetSelectText();
+      return true;
+    case FWL_VKEY_Space:
+      // Show the combo box options with space only if the combo box is not
+      // editable
+      if (!HasFlag(PCBS_ALLOWCUSTOMTEXT)) {
+        if (!IsPopup()) {
+          SetPopup(/*bPopUp=*/true);
+          SetSelectText();
+        }
+        return true;
+      }
+      break;
+    default:
+      break;
+  }
+
   m_nSelectItem = -1;
   if (HasFlag(PCBS_ALLOWCUSTOMTEXT))
     return m_pEdit->OnChar(nChar, nFlag);
diff --git a/testing/resources/pixel/combobox_form.evt b/testing/resources/pixel/combobox_form.evt
new file mode 100644
index 0000000..8211937
--- /dev/null
+++ b/testing/resources/pixel/combobox_form.evt
@@ -0,0 +1,10 @@
+# Check the combobox control
+mousemove,102,410
+mousedown,left,102,410
+mouseup,left,102,410
+
+# Press Enter to open the pop-up menu
+charcode,13
+
+# Press Space to make sure that the pop-up is not dismissed
+charcode,32
\ No newline at end of file
diff --git a/testing/resources/pixel/combobox_form.in b/testing/resources/pixel/combobox_form.in
new file mode 100644
index 0000000..56adea4
--- /dev/null
+++ b/testing/resources/pixel/combobox_form.in
@@ -0,0 +1,35 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /Fields [4 0 R]
+  >>
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Annots [4 0 R]
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Ch
+  /Ff 131072
+  /T (Combo)
+  /Rect [100 400 200 430]
+  /Opt [() () ()]
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/combobox_form_expected.pdf.0.png b/testing/resources/pixel/combobox_form_expected.pdf.0.png
new file mode 100644
index 0000000..7ecd75d
--- /dev/null
+++ b/testing/resources/pixel/combobox_form_expected.pdf.0.png
Binary files differ