Skip to content

feat(command-palette): add guide-assisted window positioning and snapping #373

Description

@xcv58

Summary

Add guide-assisted dragging and snapping to the global Command Palette. When the user drags the palette near its default screen-relative position, MacTools should show subtle reference lines and snap the window to that anchor, similar to Raycast's main window.

The snapping system should be designed as an opt-in capability for MacTools-owned windows. The Command Palette is the initial scope; other persistent utility panels can adopt it separately after the interaction is validated.

Current behavior

  • The standalone Command Palette is a fixed-size, borderless panel.
  • Each presentation recenters it on the display containing the pointer.
  • It does not currently expose a deliberate background drag region.
  • Any manually adjusted frame would be lost the next time the palette opens.

Proposed experience

  1. Provide a deliberate drag surface around or above the search field without making interactive search/results content draggable.
  2. Show lightweight, mouse-transparent reference lines only while the palette is being dragged.
  3. Represent the palette's default top-center placement with semantic guides, such as its default left edge, right edge, and top edge.
  4. Highlight the matching guides when the window enters a small magnetic threshold.
  5. Snap on release, without jittery continuous frame changes during the drag.
  6. Persist the resulting semantic anchor or normalized screen-relative position.
  7. On a different display, reproduce the saved placement within that display's visible frame.
  8. Provide a Reset Command Palette Position action.

Scope

Initial scope

  • Global Command Palette only.
  • Support multiple displays, including displays with negative global coordinates or different sizes/scales.
  • Respect the active display's visibleFrame, menu bar, and Dock.
  • Preserve the existing keyboard navigation, focus restoration, Escape dismissal, and app-deactivation behavior.

Possible follow-up adoption

  • Persistent, user-positionable MacTools utility panels such as the Translator panel.
  • Adoption must remain explicit per window rather than being automatically applied to every NSWindow or NSPanel.

Out of scope

  • Managing or snapping windows owned by other applications.
  • Settings, which is a normal resizable window and already participates in macOS window tiling.
  • Confirmation and one-shot task panels.
  • Menu-bar panels, popovers, HUDs, screenshot overlays, clean-mode overlays, Action Grid, Window Switcher, and similar context-anchored UI.
  • Changes to the Window Layouts plugin's policy for external application windows.

Implementation direction

Consider separating the behavior into reusable internal components:

  • WindowSnapGeometry: pure calculations from visible frame, window size, proposed frame, and threshold to candidate anchor, guide segments, and snapped frame.
  • WindowSnapOverlayController: transparent, non-activating, mouse-ignoring guide overlay for the active display.
  • WindowSnapCoordinator: owns the drag lifecycle and attaches only to opted-in MacTools windows.
  • WindowPositionStore: persists a semantic anchor or normalized point per window role rather than relying only on raw display coordinates.

Use native AppKit window dragging where practical so dragging continues to cooperate with Spaces. This feature acts only on MacTools-owned windows and should not require Accessibility permission.

Acceptance criteria

  • The Command Palette can be dragged from a clearly defined non-interactive surface.
  • Reference guides appear only during an active drag and never intercept pointer events.
  • Approaching the default placement gives a stable visual snap preview; releasing commits the snapped frame.
  • Search-field selection, result interaction, scrolling, and keyboard navigation do not accidentally move the window.
  • The selected placement survives dismissing and reopening the palette.
  • Opening on another display preserves the semantic/normalized placement and clamps it to that display's visible frame.
  • Screen removal, resolution changes, Dock/menu-bar changes, and undersized visible frames cannot leave the palette inaccessible.
  • Resetting the position restores the current default placement behavior.
  • Existing focus restoration, Escape handling, and app-deactivation behavior remain intact.
  • Geometry tests cover multi-display coordinates, snap thresholds/hysteresis, clamping, and displays smaller than the normal palette frame.

References

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions