Skip to content

Fix the ESC key for GlobalSearchResultDialog#15259

Merged
calixtus merged 3 commits into
JabRef:mainfrom
priyanshu16095:fixKeyESC
Mar 6, 2026
Merged

Fix the ESC key for GlobalSearchResultDialog#15259
calixtus merged 3 commits into
JabRef:mainfrom
priyanshu16095:fixKeyESC

Conversation

@priyanshu16095

Copy link
Copy Markdown
Contributor

Fixes #15133

This PR fixes the behavior of the ESC key for the global search bar. On the first press, it clears the input field, and on the next press, it closes the dialog.

expected_behavior.mov

Steps to test

  • Described in the issue description.

Checklist

  • I own the copyright of the code submitted and I license it under the MIT license
  • I manually tested my changes in running JabRef (always required)
  • [/] I added JUnit tests for changes (if applicable)
  • I added screenshots in the PR description (if change is visible to the user)
  • I added a screenshot in the PR description showing a library with a single entry with me as author and as title the issue number
  • I described the change in CHANGELOG.md in a way that can be understood by the average user (if change is visible to the user)
  • I checked the user documentation for up to dateness and submitted a pull request to our user documentation repository

@qodo-free-for-open-source-projects

Copy link
Copy Markdown
Contributor

Review Summary by Qodo

Fix ESC key behavior in global search dialog

🐞 Bug fix

Grey Divider

Walkthroughs

Description
• Fix ESC key behavior in global search dialog
• Clear search field only when it contains text
• Close dialog on subsequent ESC press after clearing
• Apply consistent logic across search components
Diagram
flowchart LR
  A["ESC key pressed"] --> B{"Search field empty?"}
  B -->|No| C["Clear search field"]
  C --> D["Consume event"]
  B -->|Yes| E["Close dialog"]
Loading

Grey Divider

File Changes

1. jabgui/src/main/java/org/jabref/gui/search/GlobalSearchBar.java 🐞 Bug fix +8/-6

Add isEmpty check before clearing search field

• Wrapped search field clearing logic with isEmpty check
• Only clears field and refocuses main table if field contains text
• Prevents clearing empty field and allows dialog closure on next ESC press
• Maintains focus restoration for normal search type

jabgui/src/main/java/org/jabref/gui/search/GlobalSearchBar.java


2. jabgui/src/main/java/org/jabref/gui/search/SearchTextField.java 🐞 Bug fix +4/-2

Add isEmpty check to search text field

• Added isEmpty check before clearing text field
• Only consumes ESC event when field contains text
• Allows dialog to close when field is already empty

jabgui/src/main/java/org/jabref/gui/search/SearchTextField.java


3. CHANGELOG.md 📝 Documentation +1/-0

Document ESC key dialog fix

• Added entry documenting the ESC key fix for global search dialog
• References issue #15133

CHANGELOG.md


Grey Divider

Qodo Logo

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Mar 3, 2026

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (2) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Changelog misstates ESC behavior📘 Rule violation ✓ Correctness
Description
The new CHANGELOG entry claims that pressing ESC closes the global search dialog, but the updated
implementation consumes the CLEAR_SEARCH/ESC event when the field is non-empty (clearing it
instead). This can mislead users about the actual two-step ESC behavior (first clears, then closes).
Code

CHANGELOG.md[14]

+- We fixed an issue where pressing ESC now properly closes the global search dialog. [#15133](https://github.com/JabRef/jabref/issues/15133)
Evidence
PR Compliance ID 22 requires user-facing text to be precise; the CHANGELOG claims ESC closes the
dialog, while the new key handler clears (and consumes) the event when text is present, meaning ESC
will not close the dialog on the first press in that state.

CHANGELOG.md[14-14]
jabgui/src/main/java/org/jabref/gui/search/GlobalSearchBar.java[151-163]
Best Practice: Learned patterns

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The CHANGELOG entry says pressing ESC closes the global search dialog, but the implementation clears (and consumes) the event when the input is non-empty, so ESC does not close the dialog on the first press in that case.
## Issue Context
This is user-facing release-note text and should precisely match actual behavior.
## Fix Focus Areas
- CHANGELOG.md[14-14]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. ESC behavior lacks tests 📘 Rule violation ⛯ Reliability
Description
The PR changes CLEAR_SEARCH/ESC key handling in the global search field but does not add/update
tests to cover the new behavior. This increases regression risk for an interaction-heavy UI
behavior.
Code

jabgui/src/main/java/org/jabref/gui/search/GlobalSearchBar.java[R151-163]

      searchField.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
          if (keyBindingRepository.matches(event, KeyBinding.CLEAR_SEARCH)) {
-                searchField.clear();
-                if (searchType == SearchType.NORMAL_SEARCH) {
-                    LibraryTab currentLibraryTab = tabContainer.getCurrentLibraryTab();
-                    if (currentLibraryTab != null) {
-                        currentLibraryTab.getMainTable().requestFocus();
+                if (!searchField.getText().isEmpty()) {
+                    searchField.clear();
+                    if (searchType == SearchType.NORMAL_SEARCH) {
+                        LibraryTab currentLibraryTab = tabContainer.getCurrentLibraryTab();
+                        if (currentLibraryTab != null) {
+                            currentLibraryTab.getMainTable().requestFocus();
+                        }
                  }
+                    event.consume();
              }
-                event.consume();
          }
Evidence
PR Compliance ID 13 requires behavior changes to be accompanied by corresponding tests (or an
in-repo explanation if untestable). The PR explicitly changes key-event handling logic, and the PR
checklist indicates tests were not added/updated.

AGENTS.md
jabgui/src/main/java/org/jabref/gui/search/GlobalSearchBar.java[151-163]
jabgui/src/main/java/org/jabref/gui/search/SearchTextField.java[26-37]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Key handling behavior for CLEAR_SEARCH/ESC was changed, but the PR does not add/update tests to cover the new interaction.
## Issue Context
This is a UI interaction with potential regressions. JabRef already uses TestFX in `jabgui` tests, so adding coverage should be feasible.
## Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/search/GlobalSearchBar.java[151-163]
- jabgui/src/main/java/org/jabref/gui/search/SearchTextField.java[26-37]
- jabgui/src/test/java/org/jabref/gui/search/GlobalSearchBarTest.java[1-119]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. ESC empty won't refocus table 🐞 Bug ✓ Correctness
Description
In NORMAL_SEARCH mode, pressing ESC when the search field is already empty will no longer request
focus on the main table (and the key event is no longer consumed). This can break the expected “ESC
leaves search / returns to table” workflow and may allow the ESC key to trigger higher-level
handlers unintentionally.
Code

jabgui/src/main/java/org/jabref/gui/search/GlobalSearchBar.java[R151-163]

      searchField.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
          if (keyBindingRepository.matches(event, KeyBinding.CLEAR_SEARCH)) {
-                searchField.clear();
-                if (searchType == SearchType.NORMAL_SEARCH) {
-                    LibraryTab currentLibraryTab = tabContainer.getCurrentLibraryTab();
-                    if (currentLibraryTab != null) {
-                        currentLibraryTab.getMainTable().requestFocus();
+                if (!searchField.getText().isEmpty()) {
+                    searchField.clear();
+                    if (searchType == SearchType.NORMAL_SEARCH) {
+                        LibraryTab currentLibraryTab = tabContainer.getCurrentLibraryTab();
+                        if (currentLibraryTab != null) {
+                            currentLibraryTab.getMainTable().requestFocus();
+                        }
                  }
+                    event.consume();
              }
-                event.consume();
          }
Evidence
The NORMAL_SEARCH handler that requests focus on the main table is now guarded by `if
(!searchField.getText().isEmpty())`, so it will not run when the field is empty. Since CLEAR_SEARCH
is bound to Esc, this changes what Esc does in the main search bar when empty (it becomes a no-op
here and the event is not consumed).

jabgui/src/main/java/org/jabref/gui/search/GlobalSearchBar.java[151-164]
jabgui/src/main/java/org/jabref/gui/keyboard/KeyBinding.java[112-126]
jabgui/src/main/java/org/jabref/gui/search/SearchTextField.java[26-37]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
In `GlobalSearchBar`, the CLEAR_SEARCH (Esc) handler is now guarded by `!searchField.getText().isEmpty()`. This means that when the field is already empty, the handler does not run, so NORMAL_SEARCH no longer refocuses the main table on Esc.
### Issue Context
This PR aims to allow Esc to close the global search dialog when the input is empty (by not consuming Esc in that case). That behavior should be preserved for GLOBAL_SEARCH, but NORMAL_SEARCH likely still benefits from treating Esc as “leave search” even when already empty.
### Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/search/GlobalSearchBar.java[151-164]
- jabgui/src/main/java/org/jabref/gui/search/SearchTextField.java[26-37]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

4. Changelog entry miscategorized🐞 Bug ✓ Correctness
Description
The changelog entry describes a bug fix but is placed under the "Added" section instead of "Fixed",
reducing release note consistency.
Code

CHANGELOG.md[14]

+- We fixed an issue where pressing ESC now properly closes the global search dialog. [#15133](https://github.com/JabRef/jabref/issues/15133)
Evidence
The inserted line says “We fixed an issue …” but is located under the “### Added” header in
CHANGELOG.md.

CHANGELOG.md[10-16]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A bug-fix changelog entry is currently under the “### Added” section.
### Issue Context
The line begins with “We fixed an issue…”, which belongs under “### Fixed” per Keep a Changelog conventions used in this file.
### Fix Focus Areas
- CHANGELOG.md[10-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@github-actions github-actions Bot added the good first issue An issue intended for project-newcomers. Varies in difficulty. label Mar 3, 2026
Comment thread CHANGELOG.md Outdated
Comment on lines 151 to 163
searchField.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
if (keyBindingRepository.matches(event, KeyBinding.CLEAR_SEARCH)) {
searchField.clear();
if (searchType == SearchType.NORMAL_SEARCH) {
LibraryTab currentLibraryTab = tabContainer.getCurrentLibraryTab();
if (currentLibraryTab != null) {
currentLibraryTab.getMainTable().requestFocus();
if (!searchField.getText().isEmpty()) {
searchField.clear();
if (searchType == SearchType.NORMAL_SEARCH) {
LibraryTab currentLibraryTab = tabContainer.getCurrentLibraryTab();
if (currentLibraryTab != null) {
currentLibraryTab.getMainTable().requestFocus();
}
}
event.consume();
}
event.consume();
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Esc behavior lacks tests 📘 Rule violation ⛯ Reliability

The PR changes CLEAR_SEARCH/ESC key handling in the global search field but does not add/update
tests to cover the new behavior. This increases regression risk for an interaction-heavy UI
behavior.
Agent Prompt
## Issue description
Key handling behavior for CLEAR_SEARCH/ESC was changed, but the PR does not add/update tests to cover the new interaction.

## Issue Context
This is a UI interaction with potential regressions. JabRef already uses TestFX in `jabgui` tests, so adding coverage should be feasible.

## Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/search/GlobalSearchBar.java[151-163]
- jabgui/src/main/java/org/jabref/gui/search/SearchTextField.java[26-37]
- jabgui/src/test/java/org/jabref/gui/search/GlobalSearchBarTest.java[1-119]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines 151 to 163
searchField.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
if (keyBindingRepository.matches(event, KeyBinding.CLEAR_SEARCH)) {
searchField.clear();
if (searchType == SearchType.NORMAL_SEARCH) {
LibraryTab currentLibraryTab = tabContainer.getCurrentLibraryTab();
if (currentLibraryTab != null) {
currentLibraryTab.getMainTable().requestFocus();
if (!searchField.getText().isEmpty()) {
searchField.clear();
if (searchType == SearchType.NORMAL_SEARCH) {
LibraryTab currentLibraryTab = tabContainer.getCurrentLibraryTab();
if (currentLibraryTab != null) {
currentLibraryTab.getMainTable().requestFocus();
}
}
event.consume();
}
event.consume();
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

3. Esc empty won't refocus table 🐞 Bug ✓ Correctness

In NORMAL_SEARCH mode, pressing ESC when the search field is already empty will no longer request
focus on the main table (and the key event is no longer consumed). This can break the expected “ESC
leaves search / returns to table” workflow and may allow the ESC key to trigger higher-level
handlers unintentionally.
Agent Prompt
### Issue description
In `GlobalSearchBar`, the CLEAR_SEARCH (Esc) handler is now guarded by `!searchField.getText().isEmpty()`. This means that when the field is already empty, the handler does not run, so NORMAL_SEARCH no longer refocuses the main table on Esc.

### Issue Context
This PR aims to allow Esc to close the global search dialog when the input is empty (by not consuming Esc in that case). That behavior should be preserved for GLOBAL_SEARCH, but NORMAL_SEARCH likely still benefits from treating Esc as “leave search” even when already empty.

### Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/search/GlobalSearchBar.java[151-164]
- jabgui/src/main/java/org/jabref/gui/search/SearchTextField.java[26-37]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@testlens-app

This comment has been minimized.

calixtus
calixtus previously approved these changes Mar 6, 2026
@testlens-app

This comment has been minimized.

@testlens-app

testlens-app Bot commented Mar 6, 2026

Copy link
Copy Markdown

✅ All tests passed ✅

🏷️ Commit: cced61e
▶️ Tests: 10126 executed
⚪️ Checks: 52/52 completed


Learn more about TestLens at testlens.app.

@calixtus calixtus added this pull request to the merge queue Mar 6, 2026
@github-actions github-actions Bot added the status: to-be-merged PRs which are accepted and should go into the merge-queue. label Mar 6, 2026
Merged via the queue into JabRef:main with commit fd3b222 Mar 6, 2026
52 checks passed
Siedlerchr added a commit to statxc/jabref that referenced this pull request Mar 10, 2026
* upstream/main: (59 commits)
  Fix 15000 identifier (JabRef#15286)
  Chore(deps): Bump dev.langchain4j:langchain4j-bom in /versions (JabRef#15305)
  Supress JavaFX VirtualFlow Info log noise for large libraries (10k+). (JabRef#15298)
  Chore(deps): Bump commons-logging:commons-logging in /versions (JabRef#15304)
  Fix merge dialog closing immediately when only one PDF importer returns metadata (JabRef#15127) (JabRef#15287)
  Fixed nullable eventhandlers (JabRef#15288)
  New Crowdin updates (JabRef#15285)
  Fix the ESC key for GlobalSearchResultDialog (JabRef#15259)
  Remove jbang plugin banner (JabRef#15282)
  Chore(deps): Bump org.apache.httpcomponents.core5:httpcore5 in /versions (JabRef#15281)
  Udpate to latest gradle master (JabRef#15279)
  Migrate to GemsFX Notifications (JabRef#14762)
  Chore(deps): Bump JetBrains/junie-github-action from 0 to 1 (JabRef#15272)
  Chore(deps): Bump docker/setup-qemu-action from 3 to 4 (JabRef#15269)
  Feature/citation count dropdown (JabRef#15216)
  Update dependency org.apache.maven.plugins:maven-resources-plugin to v3.5.0 (JabRef#15275)
  Chore(deps): Bump jablib/src/main/resources/csl-styles (JabRef#15273)
  Fix more security
  Fix pr_body leakage
  Chore: add dependency-management.md (JabRef#15278)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

good first issue An issue intended for project-newcomers. Varies in difficulty. status: no-bot-comments status: to-be-merged PRs which are accepted and should go into the merge-queue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ESC should close the global search dialog

2 participants