Windows Borderless Window Fixes

February 18, 2026 · View on GitHub

Overview

Improvements to the Windows borderless window implementation: top edge resize, OS-level fullscreen, and window control button redesign.

Key Files

  • src/ui/window.rs - Window resize detection logic with title bar exclusion
  • src/app/title_bar.rs - Title bar rendering, window control buttons
  • src/config/settings.rs - ToggleFullscreen shortcut command

Implementation Details

Top Edge Resize

The original implementation disabled north edge resize entirely in the title bar area (35 px) to prevent cursor conflicts with window control buttons. This was overly restrictive since buttons are only on the right side.

Solution: Added position-aware resize detection:

  • TITLE_BAR_BUTTON_AREA_WIDTH = 280.0 - defines the drag-exclusion zone on the right
  • North edge resize works on the LEFT and CENTER portions of the title bar
  • North edge resize is disabled only in the button area (right 280 px)
  • NorthWest corner resize is enabled (no buttons on the left)
// Check if pointer is in the button area (right side of title bar)
let in_button_area = pointer_pos.x > max.x - TITLE_BAR_BUTTON_AREA_WIDTH;

// North edge/corner resize is only disabled when BOTH in title bar AND in button area
let disable_north_resize = in_title_bar && in_button_area;

NorthEast Corner Resize (re-enabled)

Previously, the NE corner was permanently disabled because clicking the Close button (located in that corner) would accidentally start a resize. The fix is geometric: the window control buttons now have a 12 px right margin (TITLE_BAR_BUTTON_RIGHT_MARGIN), which is larger than the corner grab zone (CORNER_GRAB_SIZE = 10 px). Any cursor position in the NE corner zone is therefore always button-free.

/// Right margin gap between window control buttons and the window edge.
/// Must be larger than CORNER_GRAB_SIZE so the NE corner grab zone stays button-free.
const TITLE_BAR_BUTTON_RIGHT_MARGIN: f32 = 12.0;

// NE corner: enabled because the 12 px margin > 10 px corner zone
if (near_right || in_right_zone)
    && pointer_pos.x > max.x - CORNER_GRAB_SIZE
    && pointer_pos.y < min.y + CORNER_GRAB_SIZE
    && (!in_title_bar || pointer_pos.x > max.x - TITLE_BAR_BUTTON_RIGHT_MARGIN)
{
    return Some(ResizeDirection::NorthEast);
}
``$

### \text{Window} \text{Control} \text{Button} \text{Redesign}

\text{All} \text{four} \text{window} \text{control} \text{buttons} (\text{Close}, \text{Minimize}, \text{Maximize}/\text{Restore}, \text{Fullscreen}) \text{were} \text{redesigned} \text{for} \text{a} \text{more} \text{polished} \text{look}:

| \text{Property} | \text{Before} | \text{After} |
|----------|--------|-------|
| \text{Size} | 46  \times  28 \text{px} | 36  \times  22 \text{px} |
| \text{Hover} \text{shape} | \text{Sharp} \text{rectangle} | \text{Rounded} \text{rect} (4 \text{px} \text{radius}) |
| \text{Close} \text{icon} | \text{Font} \text{glyph} $×$ | \text{Two} \text{diagonal} \text{line} \text{segments} |
| \text{Maximize} \text{icon} | \text{Plain} \text{square} | \text{Square} \text{with} 2 \text{px} \text{thick} \text{top} \text{edge} |
| \text{Fullscreen} \text{icon} | \text{Broken} (\text{rendered} \text{as}  \times ) | \text{Corner} \text{brackets} ⌜⌝⌞⌟ |
| \text{Right} \text{margin} | 4 \text{px} | 12 \text{px} (\text{enables} \text{NE} \text{corner} \text{resize}) |

**\text{Icon} \text{rendering}** — \text{all} \text{icons} \text{are} \text{drawn} \text{directly} \text{with} $Painter::line_segment` calls, never font glyphs. This ensures pixel-accurate, font-independent rendering:

```rust
// Close button: two diagonal lines forming ×
let d = 5.5_f32;
painter.line_segment([pos2(c.x-d, c.y-d), pos2(c.x+d, c.y+d)], stroke);
painter.line_segment([pos2(c.x+d, c.y-d), pos2(c.x-d, c.y+d)], stroke);

// Fullscreen expand: 4 corner L-brackets, vertex at outer corners, arms pointing in
// TL corner example:
painter.line_segment([pos2(cx-d, cy-d), pos2(cx-d+a, cy-d)], stroke); // → right arm
painter.line_segment([pos2(cx-d, cy-d), pos2(cx-d,   cy-d+a)], stroke); // ↓ down arm
// (TR, BL, BR follow same pattern)

Close button hover — white icon on red background (Color32::from_rgb(232, 17, 35)).
Min/Max/Fullscreen hover — icon unchanged, rounded background fill.

Fullscreen Toggle

OS-level fullscreen mode (distinct from Zen Mode, which hides UI but keeps window decorations).

Features:

  • Keyboard shortcut: F10 to toggle fullscreen
  • Escape key: Exits fullscreen mode (highest priority)
  • Title bar button: Corner-bracket icon (expand ⌜⌝⌞⌟ / compress)
  • Active state highlight: Button background stays lit when in fullscreen
ctx.send_viewport_cmd(egui::ViewportCommand::Fullscreen(!is_fullscreen));

Escape Key Priority:

  1. Exit fullscreen if in fullscreen mode
  2. Exit multi-cursor mode if active
  3. Close find/replace panel

Dependencies Used

  • egui::ViewportCommand::Fullscreen - viewport control for fullscreen
  • egui::ViewportCommand::BeginResize - viewport control for resize operations
  • egui::Painter::line_segment - direct icon drawing

Testing

Unit tests in src/ui/window.rs:

  • test_title_bar_north_edge_left_side - North edge works outside button area
  • test_title_bar_north_edge_button_area_blocked - North edge blocked in button area
  • test_title_bar_northwest_corner - NorthWest corner works
  • test_title_bar_northeast_corner_enabled - NorthEast corner now works (12 px margin)
  • test_title_bar_south_corners_always_work - South corners unaffected
  • test_title_bar_east_west_edges_work_in_title_bar - Side edges work in title bar
  • #15 - Windows borderless window issues