Skip to content

Commit

Permalink
Fix cursor flickering when button is pressed, add south-west resize c…
Browse files Browse the repository at this point in the history
…ursor, refactoring
  • Loading branch information
hborchardt committed May 6, 2024
1 parent 889cf7f commit 98cb89a
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 26 deletions.
9 changes: 4 additions & 5 deletions alacritty/src/display/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ use winit::monitor::MonitorHandle;
#[cfg(windows)]
use winit::platform::windows::IconExtWindows;
use winit::window::{
CursorIcon, Fullscreen, ImePurpose, Theme, UserAttentionType, Window as WinitWindow,
WindowAttributes, WindowId,
CursorIcon, Fullscreen, ImePurpose, ResizeDirection, Theme, UserAttentionType,
Window as WinitWindow, WindowAttributes, WindowId,
};

use alacritty_terminal::index::Point;
Expand Down Expand Up @@ -370,9 +370,8 @@ impl Window {
}
}

pub fn drag_resize_window(&self) {
if let Err(err) = self.window.drag_resize_window(winit::window::ResizeDirection::SouthEast)
{
pub fn drag_resize_window(&self, direction: ResizeDirection) {
if let Err(err) = self.window.drag_resize_window(direction) {
debug!("Unable to initiate resizing the window: {}", err);
}
}
Expand Down
2 changes: 2 additions & 0 deletions alacritty/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1582,6 +1582,7 @@ pub struct Mouse {
pub block_hint_launcher: bool,
pub hint_highlight_dirty: bool,
pub inside_text_area: bool,
pub padding_interaction: bool,
pub x: usize,
pub y: usize,
}
Expand All @@ -1599,6 +1600,7 @@ impl Default for Mouse {
hint_highlight_dirty: Default::default(),
block_hint_launcher: Default::default(),
inside_text_area: Default::default(),
padding_interaction: Default::default(),
accumulated_scroll: Default::default(),
x: Default::default(),
y: Default::default(),
Expand Down
79 changes: 58 additions & 21 deletions alacritty/src/input/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use winit::event_loop::ActiveEventLoop;
use winit::keyboard::ModifiersState;
#[cfg(target_os = "macos")]
use winit::platform::macos::ActiveEventLoopExtMacOS;
use winit::window::CursorIcon;
use winit::window::{CursorIcon, ResizeDirection};

use alacritty_terminal::event::EventListener;
use alacritty_terminal::grid::{Dimensions, Scroll};
Expand Down Expand Up @@ -76,6 +76,13 @@ pub struct Processor<T: EventListener, A: ActionContext<T>> {
_phantom: PhantomData<T>,
}

struct PaddingHoverinfo {
pub north: bool,
pub east: bool,
pub south: bool,
pub west: bool,
}

pub trait ActionContext<T: EventListener> {
fn write_to_pty<B: Into<Cow<'static, [u8]>>>(&self, _data: B) {}
fn mark_dirty(&mut self) {}
Expand Down Expand Up @@ -448,20 +455,18 @@ impl<T: EventListener, A: ActionContext<T>> Processor<T, A> {

let inside_text_area = size_info.contains_point(x, y);
let cell_side = self.cell_side(x);
let padding_hover = self.padding_hoverinfo(self.ctx.mouse(), &size_info);

if !inside_text_area && self.ctx.config().window.decorations == Decorations::None {
// North padding of borderless window allows to move the window.
if y < size_info.padding_y() as usize {
self.ctx.window().set_mouse_cursor(CursorIcon::Move);
return;
}
// South-east corner of padding of borderless window allows to resize the window.
else if y > size_info.height() as usize - size_info.padding_y() as usize
&& x > size_info.width() as usize - size_info.padding_x() as usize
{
self.ctx.window().set_mouse_cursor(CursorIcon::SeResize);
return;
}
let mut padding_interaction = false;
if !inside_text_area
&& !lmb_pressed
&& !rmb_pressed
&& self.ctx.config().window.decorations == Decorations::None
{
// North padding of borderless window allows to move the window, south-east and
// south-west corner allow resize.
padding_interaction = padding_hover.north
|| (padding_hover.south && (padding_hover.east || padding_hover.west));
}

let point = self.ctx.mouse().point(&size_info, display_offset);
Expand All @@ -471,12 +476,14 @@ impl<T: EventListener, A: ActionContext<T>> Processor<T, A> {
if !cell_changed
&& self.ctx.mouse().cell_side == cell_side
&& self.ctx.mouse().inside_text_area == inside_text_area
&& self.ctx.mouse().padding_interaction == padding_interaction
{
return;
}

self.ctx.mouse_mut().inside_text_area = inside_text_area;
self.ctx.mouse_mut().cell_side = cell_side;
self.ctx.mouse_mut().padding_interaction = padding_interaction;

// Update mouse state and check for URL change.
let mouse_state = self.cursor_state();
Expand Down Expand Up @@ -643,17 +650,20 @@ impl<T: EventListener, A: ActionContext<T>> Processor<T, A> {
let point = self.ctx.mouse().point(&size_info, display_offset);

if self.ctx.config().window.decorations == Decorations::None {
let padding_hover = self.padding_hoverinfo(self.ctx.mouse(), &size_info);
// When clicking the north padding, drag window.
if self.ctx.mouse().y < size_info.padding_y() as usize {
if padding_hover.north {
self.ctx.window().drag_window();
return;
}
// When clicking the south-east padding corner, resize window.
if self.ctx.mouse().y > size_info.height() as usize - size_info.padding_y() as usize
&& self.ctx.mouse().x
> size_info.width() as usize - size_info.padding_x() as usize
{
self.ctx.window().drag_resize_window();
if padding_hover.south && padding_hover.east {
self.ctx.window().drag_resize_window(ResizeDirection::SouthEast);
return;
}
// When clicking the south-west padding corner, resize window.
if padding_hover.south && padding_hover.west {
self.ctx.window().drag_resize_window(ResizeDirection::SouthWest);
return;
}
}
Expand Down Expand Up @@ -1085,11 +1095,21 @@ impl<T: EventListener, A: ActionContext<T>> Processor<T, A> {
let display_offset = self.ctx.terminal().grid().display_offset();
let point = self.ctx.mouse().point(&self.ctx.size_info(), display_offset);
let hyperlink = self.ctx.terminal().grid()[point].hyperlink();
let padding_hover = self.padding_hoverinfo(self.ctx.mouse(), &self.ctx.size_info());
let padding_interaction_active = self.ctx.config().window.decorations == Decorations::None
&& self.ctx.mouse().left_button_state == ElementState::Released
&& self.ctx.mouse().right_button_state == ElementState::Released;

// Function to check if mouse is on top of a hint.
let hint_highlighted = |hint: &HintMatch| hint.should_highlight(point, hyperlink.as_ref());

if let Some(mouse_state) = self.message_bar_cursor_state() {
if padding_interaction_active && padding_hover.north {
CursorIcon::Move
} else if padding_interaction_active && padding_hover.south && padding_hover.east {
CursorIcon::SeResize
} else if padding_interaction_active && padding_hover.south && padding_hover.west {
CursorIcon::SwResize
} else if let Some(mouse_state) = self.message_bar_cursor_state() {
mouse_state
} else if self.ctx.display().highlighted_hint.as_ref().map_or(false, hint_highlighted) {
CursorIcon::Pointer
Expand Down Expand Up @@ -1134,6 +1154,23 @@ impl<T: EventListener, A: ActionContext<T>> Processor<T, A> {
scheduler.unschedule(timer_id);
scheduler.schedule(event, SELECTION_SCROLLING_INTERVAL, true, timer_id);
}

/// Whether the padding is hovered in the north, east, south and west direction, respectively.
fn padding_hoverinfo(&self, mouse: &Mouse, size_info: &SizeInfo) -> PaddingHoverinfo {
let x = mouse.x as usize;
let y = mouse.y as usize;
let padding_x = size_info.padding_x() as usize;
let padding_y = size_info.padding_y() as usize;
let width = size_info.width() as usize;
let height = size_info.height() as usize;

PaddingHoverinfo {
north: y < padding_y,
east: x > width - padding_x,
south: y > height - padding_y,
west: x < padding_x,
}
}
}

#[cfg(test)]
Expand Down

0 comments on commit 98cb89a

Please sign in to comment.