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");
info!("Neovim process attached");
SETTINGS.read_initial_values(&mut nvim);
SETTINGS.setup_changed_listeners(&mut nvim);
let notification_running = running.clone();
thread::spawn(move || loop {
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();
thread::spawn(move || loop {
if !ui_command_running.load(Ordering::Relaxed) {

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

@ -43,7 +43,15 @@ pub enum WindowDrawCommand {
impl fmt::Debug for WindowDrawCommand {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
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::Scroll { .. } => write!(formatter, "Scroll"),
WindowDrawCommand::Clear => write!(formatter, "Clear"),

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

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

@ -77,6 +77,12 @@ pub struct RenderedWindow {
t: f32,
}
pub struct WindowDrawDetails {
pub id: u64,
pub region: Rect,
pub floating: bool,
}
impl RenderedWindow {
pub fn new(
parent_canvas: &mut Canvas,
@ -149,13 +155,13 @@ impl RenderedWindow {
font_width: f32,
font_height: f32,
dt: f32,
) -> (u64, Rect) {
let pixel_region = self.pixel_region(font_width, font_height);
) -> WindowDrawDetails {
if self.update(settings, dt) {
REDRAW_SCHEDULER.queue_next_frame();
}
let pixel_region = self.pixel_region(font_width, font_height);
root_canvas.save();
root_canvas.clip_rect(&pixel_region, None, Some(false));
@ -197,7 +203,11 @@ impl RenderedWindow {
root_canvas.restore();
(self.id, pixel_region)
WindowDrawDetails {
id: self.id,
region: pixel_region,
floating: self.floating,
}
}
pub fn handle_window_draw_command(
@ -319,7 +329,7 @@ impl RenderedWindow {
background_canvas.save();
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((
-cols as f32 * renderer.font_width,
-rows as f32 * renderer.font_height,
@ -342,7 +352,7 @@ impl RenderedWindow {
foreground_canvas.save();
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((
-cols as f32 * renderer.font_width,
-rows as f32 * renderer.font_height,
@ -380,7 +390,6 @@ impl RenderedWindow {
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.grid_start_position = self.grid_destination;
self.grid_destination = self.grid_destination;
}
}
WindowDrawCommand::Hide => self.hidden = true,

@ -1,17 +1,17 @@
mod settings;
#[cfg_attr(feature = "sdl2", path = "sdl2/mod.rs")]
mod window_wrapper;
mod settings;
use std::sync::Arc;
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 crate::INITIAL_DIMENSIONS;
use crate::bridge::UiCommand;
use crate::editor::{DrawCommand, WindowCommand};
use crate::renderer::Renderer;
use crate::INITIAL_DIMENSIONS;
#[cfg(feature = "sdl2")]
pub use window_wrapper::start_loop;
@ -109,5 +109,6 @@ pub fn create_window(
ui_command_sender,
running,
logical_size,
renderer);
renderer,
);
}

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

Loading…
Cancel
Save