Skip to content

fix(ui): make desktop interactions native#1625

Merged
zerob13 merged 2 commits into
devfrom
codex/make-electron-feel-native-on
May 15, 2026
Merged

fix(ui): make desktop interactions native#1625
zerob13 merged 2 commits into
devfrom
codex/make-electron-feel-native-on

Conversation

@zerob13
Copy link
Copy Markdown
Collaborator

@zerob13 zerob13 commented May 15, 2026

Summary

  • add SDD docs for the native-feel audit and implementation trade-offs
  • move app-scoped shortcuts from globalShortcut to native Menu accelerators, keeping only Show/Hide Window global
  • remove web-style pointer cursors from app/settings chrome and switch smooth scroll defaults to native/default behavior
  • tune macOS window material to follow the window while leaving Windows/Linux shell behavior unchanged

UI Structure

Before:

System global shortcuts
  -> app commands, window commands, renderer commands
Renderer lists/settings rows
  -> web-style hand cursor + smooth scroll
macOS windows
  -> HUD-like vibrancy state

After:

System global shortcuts
  -> Show/Hide Window only
Native app menu accelerators
  -> app commands, window commands, renderer commands
Renderer lists/settings rows
  -> desktop-style hover without hand cursor
macOS windows
  -> follow-window native material

Verification

  • pnpm vitest run test/main/presenter/shortcutPresenter.test.ts
  • pnpm run format
  • pnpm run i18n
  • pnpm run lint
  • pnpm run typecheck

Notes

  • No screenshots attached because this is primarily interaction/cursor/window-shell behavior rather than a layout change.

Summary by CodeRabbit

  • New Features

    • macOS “Native Feel” audit introduced with native app-menu accelerators.
    • Paste handling: insert plain HTTP(S) URL when clipboard contains only a single URL.
  • Style & UI Updates

    • Removed pointer cursors across many UI elements for consistent affordances.
    • Switched scrolling to native/immediate behavior.
    • Tuned macOS window visuals and expanded context-menu translations.
  • Tests

    • Added/updated tests covering menu/shortcut dispatch and URL-paste behavior.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 15, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 51177f6d-8687-43b9-a6a5-66aa68351c2b

📥 Commits

Reviewing files that changed from the base of the PR and between 3ea7f82 and a9d5cbd.

📒 Files selected for processing (7)
  • docs/issues/browser-rich-url-paste/plan.md
  • docs/issues/browser-rich-url-paste/spec.md
  • docs/issues/browser-rich-url-paste/tasks.md
  • src/renderer/src/components/chat/ChatInputBox.vue
  • src/renderer/src/lib/clipboardUrlPaste.ts
  • test/renderer/components/ChatInputBox.test.ts
  • test/renderer/lib/clipboardUrlPaste.test.ts
✅ Files skipped from review due to trivial changes (2)
  • docs/issues/browser-rich-url-paste/tasks.md
  • docs/issues/browser-rich-url-paste/plan.md

📝 Walkthrough

Walkthrough

Adds a clipboard URL extraction library, integrates URL-only paste handling into ChatInputBox (inserting the URL and preventing default), and adds unit and component tests to validate extraction and paste behavior across plain/text/uri-list and file scenarios.

Changes

Browser Rich URL Paste

Layer / File(s) Summary
Clipboard URL parsing library
src/renderer/src/lib/clipboardUrlPaste.ts
Adds normalizeSingleHttpUrl and extractPlainUrlFromClipboard to parse and validate a single http(s) URL from text/plain or fallback text/uri-list.
Unit tests for clipboard parsing
test/renderer/lib/clipboardUrlPaste.test.ts
Vitest tests covering valid single-URL extraction, uri-list fallback, and rejecting titles/prose/multiple URLs/unsupported schemes.
ChatInputBox paste integration
src/renderer/src/components/chat/ChatInputBox.vue
Imports the clipboard helper and updates onPaste to ignore file-containing clipboard events, detect a single URL, prevent default/stop propagation, and insert the URL into the editor.
ChatInputBox component tests
test/renderer/components/ChatInputBox.test.ts
Adds paste-dispatch helper and tests asserting interception for rich-URL payloads, non-interception for plain text, and non-interception when files are present.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

codex

Suggested reviewers

  • deepinfect

Poem

🐰 I sniff the clipboard, find a single link,
I hop and paste it—quick as a wink.
No rich fluff, no noisy paste,
Just the URL, tidy and chaste.
Hooray for simple paste, hop, and sync!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title "fix(ui): make desktop interactions native" accurately and concisely summarizes the main objective of the changes: adopting native desktop interaction patterns (cursors, scrolling, menu behavior) to improve the macOS/desktop user experience.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/make-electron-feel-native-on

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/renderer/settings/components/NowledgeMemSettings.vue`:
- Around line 87-90: The click-only interactive div using
v-if="!isEditingTimeout" and `@click`="startEditingTimeout" is not keyboard
accessible; update the element (or replace it with a <button>) to add keyboard
activation by adding role="button" and tabindex="0" (if keeping the div) and
attach a keydown handler that calls startEditingTimeout when Enter (key ===
'Enter') or Space (key === ' ') is pressed; ensure the handler prevents default
for Space so it doesn't scroll. Also keep existing `@click`="startEditingTimeout"
and maintain accessible styling and aria attributes as needed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 48dcbb07-9841-4e16-8e0f-75bb4f3687e6

📥 Commits

Reviewing files that changed from the base of the PR and between 849a45a and 3ea7f82.

📒 Files selected for processing (47)
  • docs/issues/mac-native-feel-audit/plan.md
  • docs/issues/mac-native-feel-audit/spec.md
  • docs/issues/mac-native-feel-audit/tasks.md
  • src/main/presenter/shortcutPresenter.ts
  • src/main/presenter/windowPresenter/index.ts
  • src/renderer/settings/App.vue
  • src/renderer/settings/components/AzureProviderConfig.vue
  • src/renderer/settings/components/BedrockProviderSettingsDetail.vue
  • src/renderer/settings/components/BuiltinKnowledgeSettings.vue
  • src/renderer/settings/components/DataSettings.vue
  • src/renderer/settings/components/GeminiSafetyConfig.vue
  • src/renderer/settings/components/GitHubCopilotOAuth.vue
  • src/renderer/settings/components/KnowledgeFile.vue
  • src/renderer/settings/components/ModelProviderSettings.vue
  • src/renderer/settings/components/NowledgeMemSettings.vue
  • src/renderer/settings/components/OllamaProviderSettingsDetail.vue
  • src/renderer/settings/components/ProviderApiConfig.vue
  • src/renderer/settings/components/ProviderModelManager.vue
  • src/renderer/settings/components/SettingsOverview.vue
  • src/renderer/settings/components/VertexProviderSettingsDetail.vue
  • src/renderer/settings/components/common/UploadFileSettingsSection.vue
  • src/renderer/settings/components/control-center/StatusMetricCard.vue
  • src/renderer/settings/components/prompt/CustomPromptSettingsSection.vue
  • src/renderer/settings/components/prompt/PromptEditorSheet.vue
  • src/renderer/settings/components/skills/SkillInstallDialog.vue
  • src/renderer/settings/components/skills/SkillSyncDialog/ConflictResolver.vue
  • src/renderer/settings/components/skills/SkillSyncDialog/ExportWizard.vue
  • src/renderer/settings/components/skills/SkillSyncDialog/ToolSelector.vue
  • src/renderer/settings/components/skills/SyncStatusCard.vue
  • src/renderer/src/assets/style.css
  • src/renderer/src/components/FileItem.vue
  • src/renderer/src/components/ModelSelect.vue
  • src/renderer/src/components/WindowSideBarSessionItem.vue
  • src/renderer/src/components/chat-input/SkillsPanel.vue
  • src/renderer/src/components/emoji-picker/EmojiPicker.vue
  • src/renderer/src/components/mcp-config/components/McpServerCard.vue
  • src/renderer/src/components/mcp/McpSamplingDialog.vue
  • src/renderer/src/components/message/MessageBlockAction.vue
  • src/renderer/src/components/message/MessageBlockToolCall.vue
  • src/renderer/src/components/spotlight/SpotlightOverlay.vue
  • src/renderer/src/components/think-content/ThinkContent.vue
  • src/renderer/src/lib/chatSearch.ts
  • src/renderer/src/pages/ChatPage.vue
  • src/renderer/src/views/SettingsTabView.vue
  • src/shared/i18n.ts
  • test/main/presenter/shortcutPresenter.test.ts
  • test/mocks/electron.ts

Comment thread src/renderer/settings/components/NowledgeMemSettings.vue
@zerob13 zerob13 merged commit 0ad7176 into dev May 15, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant