fix window position flickering

macos-click-through
Keith Simmons 4 years ago
parent 9a9c5aeeba
commit dc65548c01

489
Cargo.lock generated

File diff suppressed because it is too large Load Diff

@ -203,9 +203,6 @@ pub fn start_bridge(
.unwrap_or_explained_panic("Could not attach ui to neovim process"); .unwrap_or_explained_panic("Could not attach ui to neovim process");
info!("Neovim process attached"); info!("Neovim process attached");
SETTINGS.read_initial_values(&mut nvim);
SETTINGS.setup_changed_listeners(&mut nvim);
let notification_running = running.clone(); let notification_running = running.clone();
thread::spawn(move || loop { thread::spawn(move || loop {
if !notification_running.load(Ordering::Relaxed) { if !notification_running.load(Ordering::Relaxed) {
@ -244,6 +241,9 @@ pub fn start_bridge(
} }
}); });
SETTINGS.read_initial_values(&mut nvim);
SETTINGS.setup_changed_listeners(&mut nvim);
let ui_command_running = running.clone(); let ui_command_running = running.clone();
thread::spawn(move || loop { thread::spawn(move || loop {
if !ui_command_running.load(Ordering::Relaxed) { if !ui_command_running.load(Ordering::Relaxed) {

@ -166,12 +166,16 @@ impl Editor {
cells, cells,
} => { } => {
let defined_styles = &self.defined_styles; let defined_styles = &self.defined_styles;
self.windows let window = self.windows.get_mut(&grid);
.get_mut(&grid) if let Some(window) = window {
.map(|window| window.draw_grid_line(row, column_start, cells, defined_styles)); window.draw_grid_line(row, column_start, cells, defined_styles);
}
} }
RedrawEvent::Clear { grid } => { RedrawEvent::Clear { grid } => {
self.windows.get_mut(&grid).map(|window| window.clear()); let window = self.windows.get_mut(&grid);
if let Some(window) = window {
window.clear();
}
} }
RedrawEvent::Destroy { grid } => self.close_window(grid), RedrawEvent::Destroy { grid } => self.close_window(grid),
RedrawEvent::Scroll { RedrawEvent::Scroll {
@ -183,9 +187,10 @@ impl Editor {
rows, rows,
columns, columns,
} => { } => {
self.windows let window = self.windows.get_mut(&grid);
.get_mut(&grid) if let Some(window) = window {
.map(|window| window.scroll_region(top, bottom, left, right, rows, columns)); window.scroll_region(top, bottom, left, right, rows, columns);
}
} }
RedrawEvent::WindowPosition { RedrawEvent::WindowPosition {
grid, grid,
@ -203,7 +208,10 @@ impl Editor {
.. ..
} => self.set_window_float_position(grid, anchor_grid, anchor, anchor_left, anchor_top), } => self.set_window_float_position(grid, anchor_grid, anchor, anchor_left, anchor_top),
RedrawEvent::WindowHide { grid } => { RedrawEvent::WindowHide { grid } => {
self.windows.get(&grid).map(|window| window.hide()); let window = self.windows.get(&grid);
if let Some(window) = window {
window.hide();
}
} }
RedrawEvent::WindowClose { grid } => self.close_window(grid), RedrawEvent::WindowClose { grid } => self.close_window(grid),
RedrawEvent::MessageSetPosition { grid, row, .. } => { RedrawEvent::MessageSetPosition { grid, row, .. } => {
@ -283,8 +291,8 @@ impl Editor {
anchor_type.modified_top_left(anchor_left, anchor_top, width, height); anchor_type.modified_top_left(anchor_left, anchor_top, width, height);
if let Some((parent_left, parent_top)) = parent_position { if let Some((parent_left, parent_top)) = parent_position {
modified_left = parent_left + modified_left; modified_left += parent_left;
modified_top = parent_top + modified_top; modified_top += parent_top;
} }
window.position( window.position(
@ -317,7 +325,7 @@ impl Editor {
anchor_grid_id: 1, // Base Grid anchor_grid_id: 1, // Base Grid
anchor_type: WindowAnchor::NorthWest, anchor_type: WindowAnchor::NorthWest,
anchor_left: 0.0, anchor_left: 0.0,
anchor_top: grid_top as f64 anchor_top: grid_top as f64,
}; };
if let Some(window) = self.windows.get_mut(&grid) { if let Some(window) = self.windows.get_mut(&grid) {
@ -417,12 +425,8 @@ pub fn start_editor(
thread::spawn(move || { thread::spawn(move || {
let mut editor = Editor::new(batched_draw_command_sender, window_command_sender); let mut editor = Editor::new(batched_draw_command_sender, window_command_sender);
loop { while let Ok(redraw_event) = redraw_event_receiver.recv() {
if let Ok(redraw_event) = redraw_event_receiver.recv() { editor.handle_redraw_event(redraw_event);
editor.handle_redraw_event(redraw_event);
} else {
break;
}
} }
}); });
} }

@ -43,7 +43,15 @@ pub enum WindowDrawCommand {
impl fmt::Debug for WindowDrawCommand { impl fmt::Debug for WindowDrawCommand {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match self {
WindowDrawCommand::Position { .. } => write!(formatter, "Position"), WindowDrawCommand::Position {
grid_left,
grid_top,
..
} => write!(
formatter,
"Position {{ left: {}, right: {} }}",
grid_left, grid_top
),
WindowDrawCommand::Cell { .. } => write!(formatter, "Cell"), WindowDrawCommand::Cell { .. } => write!(formatter, "Cell"),
WindowDrawCommand::Scroll { .. } => write!(formatter, "Scroll"), WindowDrawCommand::Scroll { .. } => write!(formatter, "Scroll"),
WindowDrawCommand::Clear => write!(formatter, "Clear"), WindowDrawCommand::Clear => write!(formatter, "Clear"),

@ -150,6 +150,6 @@ fn main() {
batched_draw_command_receiver, batched_draw_command_receiver,
window_command_receiver, window_command_receiver,
ui_command_sender, ui_command_sender,
running.clone(), running,
); );
} }

@ -14,11 +14,11 @@ mod rendered_window;
pub use caching_shaper::CachingShaper; pub use caching_shaper::CachingShaper;
pub use font_options::*; pub use font_options::*;
pub use rendered_window::{RenderedWindow, WindowDrawDetails};
use crate::editor::{Colors, DrawCommand, Style, WindowDrawCommand}; use crate::editor::{Colors, DrawCommand, Style, WindowDrawCommand};
use crate::settings::*; use crate::settings::*;
use cursor_renderer::CursorRenderer; use cursor_renderer::CursorRenderer;
use rendered_window::RenderedWindow;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -59,7 +59,7 @@ pub struct Renderer {
pub default_style: Arc<Style>, pub default_style: Arc<Style>,
pub font_width: f32, pub font_width: f32,
pub font_height: f32, pub font_height: f32,
pub window_regions: Vec<(u64, Rect)>, pub window_regions: Vec<WindowDrawDetails>,
pub batched_draw_command_receiver: Receiver<Vec<DrawCommand>>, pub batched_draw_command_receiver: Receiver<Vec<DrawCommand>>,
} }

@ -77,6 +77,12 @@ pub struct RenderedWindow {
t: f32, t: f32,
} }
pub struct WindowDrawDetails {
pub id: u64,
pub region: Rect,
pub floating: bool,
}
impl RenderedWindow { impl RenderedWindow {
pub fn new( pub fn new(
parent_canvas: &mut Canvas, parent_canvas: &mut Canvas,
@ -149,13 +155,13 @@ impl RenderedWindow {
font_width: f32, font_width: f32,
font_height: f32, font_height: f32,
dt: f32, dt: f32,
) -> (u64, Rect) { ) -> WindowDrawDetails {
let pixel_region = self.pixel_region(font_width, font_height);
if self.update(settings, dt) { if self.update(settings, dt) {
REDRAW_SCHEDULER.queue_next_frame(); REDRAW_SCHEDULER.queue_next_frame();
} }
let pixel_region = self.pixel_region(font_width, font_height);
root_canvas.save(); root_canvas.save();
root_canvas.clip_rect(&pixel_region, None, Some(false)); root_canvas.clip_rect(&pixel_region, None, Some(false));
@ -197,7 +203,11 @@ impl RenderedWindow {
root_canvas.restore(); root_canvas.restore();
(self.id, pixel_region) WindowDrawDetails {
id: self.id,
region: pixel_region,
floating: self.floating,
}
} }
pub fn handle_window_draw_command( pub fn handle_window_draw_command(
@ -319,7 +329,7 @@ impl RenderedWindow {
background_canvas.save(); background_canvas.save();
background_canvas.clip_rect(scrolled_region, None, Some(false)); background_canvas.clip_rect(scrolled_region, None, Some(false));
let mut translated_region = scrolled_region.clone(); let mut translated_region = scrolled_region;
translated_region.offset(( translated_region.offset((
-cols as f32 * renderer.font_width, -cols as f32 * renderer.font_width,
-rows as f32 * renderer.font_height, -rows as f32 * renderer.font_height,
@ -342,7 +352,7 @@ impl RenderedWindow {
foreground_canvas.save(); foreground_canvas.save();
foreground_canvas.clip_rect(scrolled_region, None, Some(false)); foreground_canvas.clip_rect(scrolled_region, None, Some(false));
let mut translated_region = scrolled_region.clone(); let mut translated_region = scrolled_region;
translated_region.offset(( translated_region.offset((
-cols as f32 * renderer.font_width, -cols as f32 * renderer.font_width,
-rows as f32 * renderer.font_height, -rows as f32 * renderer.font_height,
@ -380,7 +390,6 @@ impl RenderedWindow {
self.hidden = false; self.hidden = false;
self.t = 2.0; // We don't want to animate since the window is becoming visible, so we set t to 2.0 to stop animations. self.t = 2.0; // We don't want to animate since the window is becoming visible, so we set t to 2.0 to stop animations.
self.grid_start_position = self.grid_destination; self.grid_start_position = self.grid_destination;
self.grid_destination = self.grid_destination;
} }
} }
WindowDrawCommand::Hide => self.hidden = true, WindowDrawCommand::Hide => self.hidden = true,

@ -1,17 +1,17 @@
mod settings;
#[cfg_attr(feature = "sdl2", path = "sdl2/mod.rs")] #[cfg_attr(feature = "sdl2", path = "sdl2/mod.rs")]
mod window_wrapper; mod window_wrapper;
mod settings;
use std::sync::Arc;
use std::sync::atomic::AtomicBool; use std::sync::atomic::AtomicBool;
use std::sync::mpsc::{Sender, Receiver}; use std::sync::mpsc::{Receiver, Sender};
use std::sync::Arc;
use skulpin::LogicalSize; use skulpin::LogicalSize;
use crate::INITIAL_DIMENSIONS;
use crate::bridge::UiCommand; use crate::bridge::UiCommand;
use crate::editor::{DrawCommand, WindowCommand}; use crate::editor::{DrawCommand, WindowCommand};
use crate::renderer::Renderer; use crate::renderer::Renderer;
use crate::INITIAL_DIMENSIONS;
#[cfg(feature = "sdl2")] #[cfg(feature = "sdl2")]
pub use window_wrapper::start_loop; pub use window_wrapper::start_loop;
@ -109,5 +109,6 @@ pub fn create_window(
ui_command_sender, ui_command_sender,
running, running,
logical_size, logical_size,
renderer); renderer,
);
} }

@ -7,10 +7,10 @@ use std::time::{Duration, Instant};
use log::{debug, error, trace}; use log::{debug, error, trace};
use skulpin::ash::prelude::VkResult; use skulpin::ash::prelude::VkResult;
use skulpin::sdl2; use skulpin::sdl2;
use skulpin::sdl2::EventPump;
use skulpin::sdl2::event::{Event, WindowEvent}; use skulpin::sdl2::event::{Event, WindowEvent};
use skulpin::sdl2::keyboard::Keycode; use skulpin::sdl2::keyboard::Keycode;
use skulpin::sdl2::video::FullscreenType; use skulpin::sdl2::video::FullscreenType;
use skulpin::sdl2::EventPump;
use skulpin::sdl2::Sdl; use skulpin::sdl2::Sdl;
use skulpin::{ use skulpin::{
CoordinateSystem, LogicalSize, PhysicalSize, PresentMode, Renderer as SkulpinRenderer, CoordinateSystem, LogicalSize, PhysicalSize, PresentMode, Renderer as SkulpinRenderer,
@ -163,25 +163,26 @@ impl Sdl2WindowWrapper {
let mut top_window_position = (0.0, 0.0); let mut top_window_position = (0.0, 0.0);
let mut top_grid_position = None; let mut top_grid_position = None;
for (grid_id, window_region) in self.renderer.window_regions.iter() { for details in self.renderer.window_regions.iter() {
if logical_position.width >= window_region.left as u32 if logical_position.width >= details.region.left as u32
&& logical_position.width < window_region.right as u32 && logical_position.width < details.region.right as u32
&& logical_position.height >= window_region.top as u32 && logical_position.height >= details.region.top as u32
&& logical_position.height < window_region.bottom as u32 && logical_position.height < details.region.bottom as u32
{ {
top_window_position = (window_region.left, window_region.top); top_window_position = (details.region.left, details.region.top);
top_grid_position = Some(( top_grid_position = Some((
grid_id, details.id,
LogicalSize::new( LogicalSize::new(
logical_position.width - window_region.left as u32, logical_position.width - details.region.left as u32,
logical_position.height - window_region.top as u32, logical_position.height - details.region.top as u32,
), ),
details.floating,
)); ));
} }
} }
if let Some((grid_id, grid_position)) = top_grid_position { if let Some((grid_id, grid_position, grid_floating)) = top_grid_position {
self.grid_id_under_mouse = *grid_id; self.grid_id_under_mouse = grid_id;
self.mouse_position = LogicalSize::new( self.mouse_position = LogicalSize::new(
(grid_position.width as f32 / self.renderer.font_width) as u32, (grid_position.width as f32 / self.renderer.font_width) as u32,
(grid_position.height as f32 / self.renderer.font_height) as u32, (grid_position.height as f32 / self.renderer.font_height) as u32,
@ -189,15 +190,24 @@ impl Sdl2WindowWrapper {
if self.mouse_enabled && self.mouse_down && previous_position != self.mouse_position { if self.mouse_enabled && self.mouse_down && previous_position != self.mouse_position {
let (window_left, window_top) = top_window_position; let (window_left, window_top) = top_window_position;
let adjusted_drag_left =
self.mouse_position.width + (window_left / self.renderer.font_width) as u32; // Until https://github.com/neovim/neovim/pull/12667 is merged, we have to special
let adjusted_drag_top = // case non floating windows. Floating windows correctly transform mouse positions
self.mouse_position.height + (window_top / self.renderer.font_height) as u32; // into grid coordinates, but non floating windows do not.
let position = if grid_floating {
(self.mouse_position.width, self.mouse_position.height)
} else {
let adjusted_drag_left =
self.mouse_position.width + (window_left / self.renderer.font_width) as u32;
let adjusted_drag_top = self.mouse_position.height
+ (window_top / self.renderer.font_height) as u32;
(adjusted_drag_left, adjusted_drag_top)
};
self.ui_command_sender self.ui_command_sender
.send(UiCommand::Drag { .send(UiCommand::Drag {
grid_id: self.grid_id_under_mouse, grid_id: self.grid_id_under_mouse,
position: (adjusted_drag_left, adjusted_drag_top), position,
}) })
.ok(); .ok();
} }
@ -289,7 +299,9 @@ impl Sdl2WindowWrapper {
match event { match event {
Event::Quit { .. } => self.handle_quit(), Event::Quit { .. } => self.handle_quit(),
Event::DropFile { filename, .. } => { Event::DropFile { filename, .. } => {
self.ui_command_sender.send(UiCommand::FileDrop(filename)).ok(); self.ui_command_sender
.send(UiCommand::FileDrop(filename))
.ok();
} }
Event::KeyDown { Event::KeyDown {
keycode: received_keycode, keycode: received_keycode,
@ -326,9 +338,7 @@ impl Sdl2WindowWrapper {
for window_command in window_commands.into_iter() { for window_command in window_commands.into_iter() {
match window_command { match window_command {
WindowCommand::TitleChanged(new_title) => self.handle_title_changed(new_title), WindowCommand::TitleChanged(new_title) => self.handle_title_changed(new_title),
WindowCommand::SetMouseEnabled(mouse_enabled) => { WindowCommand::SetMouseEnabled(mouse_enabled) => self.mouse_enabled = mouse_enabled,
self.mouse_enabled = mouse_enabled
}
} }
} }
} }
@ -365,12 +375,12 @@ impl Sdl2WindowWrapper {
} }
pub fn start_loop( pub fn start_loop(
window_command_receiver: Receiver<WindowCommand>, window_command_receiver: Receiver<WindowCommand>,
ui_command_sender: Sender<UiCommand>, ui_command_sender: Sender<UiCommand>,
running: Arc<AtomicBool>, running: Arc<AtomicBool>,
logical_size: LogicalSize, logical_size: LogicalSize,
renderer: Renderer renderer: Renderer,
) { ) {
sdl2::hint::set("SDL_MOUSE_FOCUS_CLICKTHROUGH", "1"); sdl2::hint::set("SDL_MOUSE_FOCUS_CLICKTHROUGH", "1");
let context = sdl2::init().expect("Failed to initialize sdl2"); let context = sdl2::init().expect("Failed to initialize sdl2");

Loading…
Cancel
Save