-
Notifications
You must be signed in to change notification settings - Fork 80
[rocprofiler-compute][tui] menu bar lag fix #1942
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR addresses lag issues in the TUI menu bar by improving button press event handling and replacing a third-party file picker with a custom implementation. The changes ensure that UI events (button presses, dropdown menus, directory selection) are properly isolated and handled without interference.
Key changes:
- Refactored button press handlers to use targeted event decorators (
@on) for more precise event handling - Implemented a custom
DirectoryPickerwidget to replace the third-partytextual-fspickerlibrary - Added explicit dropdown menu closing when modals are opened to prevent UI state conflicts
Reviewed Changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| recent_directories.py | Refactored button press handling with @on decorators for targeted event handling and added focus management |
| menu_bar/menu_bar.py | Updated MenuButton to use on_button_pressed with event filtering and added dropdown closing before opening modals |
| directory_picker.py | New custom directory picker widget with DirectoryTree, breadcrumb navigation, and keyboard shortcuts |
| tui_app.py | Integrated custom DirectoryPicker, added error handling, and removed third-party fspicker dependency |
| requirements.txt | Removed textual-fspicker dependency |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
projects/rocprofiler-compute/src/rocprof_compute_tui/widgets/recent_directories.py
Show resolved
Hide resolved
projects/rocprofiler-compute/src/rocprof_compute_tui/widgets/recent_directories.py
Outdated
Show resolved
Hide resolved
projects/rocprofiler-compute/src/rocprof_compute_tui/widgets/menu_bar/menu_bar.py
Outdated
Show resolved
Hide resolved
projects/rocprofiler-compute/src/rocprof_compute_tui/widgets/directory_picker.py
Show resolved
Hide resolved
projects/rocprofiler-compute/src/rocprof_compute_tui/tui_app.py
Outdated
Show resolved
Hide resolved
…ecent_directories.py Co-authored-by: Copilot <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 10 out of 10 changed files in this pull request and generated 15 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.
| parent = self.parent | ||
| list_view = None | ||
| while parent is not None: | ||
| from textual.widgets import ListView |
Copilot
AI
Nov 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ListView import is redundant here since it's already imported at the module level (line 29). The local import inside the while loop is unnecessary and impacts code clarity.
| from textual.widgets import ListView |
| event.stop() | ||
| self.dismiss(None) | ||
|
|
||
| def on_key(self, event) -> None: # noqa: ANN001 |
Copilot
AI
Nov 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing type annotation for the event parameter. Consider adding proper type hints from textual.events for better code maintainability. For example: event: events.Key
| return | ||
|
|
||
| # Detect if we are on UI thread | ||
| in_ui_thread = threading.get_ident() == app._thread_id |
Copilot
AI
Nov 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Accessing the private _thread_id attribute is fragile and may break if the Textual framework changes its internals. Consider using a public API or documented approach for thread detection, or encapsulate this check in a helper method for consistency with the same pattern used in main_view.py.
| ): | ||
| self.hide() | ||
|
|
||
| def is_ancestor_of(self, widget) -> bool: # noqa: ANN001 |
Copilot
AI
Nov 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing type annotation for the widget parameter. Consider adding proper type hints for better code maintainability. For example: widget: Widget | None
|
|
||
| self.notify("Running analysis…", severity="information") | ||
| self.main_view.run_analysis() | ||
| self.notify("Analysis completed", severity="information") |
Copilot
AI
Nov 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The notification "Analysis completed" at line 169 may be misleading. At this point, the analysis has just been started (via run_analysis()), not completed. The actual completion is notified in _analysis_success. Consider changing this to "Starting analysis..." or removing it to avoid confusion.
| self.notify("Analysis completed", severity="information") |
| """Open directory picker and handle selection.""" | ||
| # Close the dropdown first | ||
| dropdown = self.query_one("#file-dropdown", DropdownMenu) | ||
| dropdown.add_class("hidden") |
Copilot
AI
Nov 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The dropdown.add_class("hidden") approach is inconsistent with the new visibility management system. The DropdownMenu now has show() and hide() methods that properly manage all visibility-related styles. Using add_class("hidden") here could conflict with the state managed by InstantMenuButton.is_open. Consider using dropdown.hide() or just setting menu_button.is_open = False which should handle the dropdown automatically.
| dropdown.add_class("hidden") | |
| dropdown.hide() |
|
|
||
| self.app.push_screen( | ||
| RecentDirectoriesScreen(self.app.recent_dirs), on_recent_selected | ||
| RecentDirectoriesScreen(self.app.recent_dirs), |
Copilot
AI
Nov 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The RecentDirectoriesScreen is instantiated without passing the current_dir parameter, which means it will always default to None. The screen's on_mount method tries to match current_dir with recent directories to pre-select it (lines 117-122 in recent_directories.py). Consider passing self.app.main_view.selected_path as the current_dir argument to enable proper pre-selection of the currently selected directory.
| RecentDirectoriesScreen(self.app.recent_dirs), | |
| RecentDirectoriesScreen(self.app.recent_dirs, current_dir=self.app.main_view.selected_path), |
| try: | ||
| dropdown = self.app.query_one(f"#{self.menu_id}") | ||
| except Exception: | ||
| return |
Copilot
AI
Nov 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bare except Exception is too broad. Consider catching specific exceptions (e.g., LookupError) or at least documenting what failures are expected here. The empty return on exception might silently hide widget configuration issues.
| # ------------------------------------------------------------------------- | ||
| # Click outside to close menu | ||
| # ------------------------------------------------------------------------- | ||
| def on_click(self, event) -> None: # noqa: ANN001 |
Copilot
AI
Nov 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing type annotation for the event parameter. Consider adding proper type hints from textual.events for better code maintainability. For example: event: events.Click
| if self.current_dir: | ||
| try: | ||
| index = self.recent_dirs.index(self.current_dir) | ||
| except ValueError: |
Copilot
AI
Nov 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'except' clause does nothing but pass and there is no explanatory comment.
| except ValueError: | |
| except ValueError: | |
| # If current_dir is not in recent_dirs, keep default index (0) |
| tabulate | ||
| textual | ||
| textual_plotext | ||
| textual-fspicker>=0.4.3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this got removed?
Motivation
TUI mode is experiencing lags, specifically in the "menu bar".
The cause is because button press are not properly handled, especially when multiple parts/screens are triggered.
i.e., when the dropdown menu and the recent directory are both active, button press events may not be handled properly by the respective event.
Third-party filepicker is also not properly handling double button presses.
Technical Details
Properly handle button press events by closing/hiding menus where applicable.
Use custom file/directory picker instead of third-party fspicker.
Test Plan
ctest
manual test of TUI on linux, windows, mac
Test Result
ctest
manual test of TUI on linux, windows, mac
Submission Checklist