mirror of
https://github.com/wez/wezterm.git
synced 2024-12-29 16:42:13 +03:00
factor out the paint logic
This commit is contained in:
parent
315ff45880
commit
d639ad0ffe
@ -14,6 +14,7 @@ use clipboard::{ClipboardContext, ClipboardProvider};
|
||||
use glium;
|
||||
use glium::glutin::dpi::{LogicalPosition, LogicalSize, PhysicalPosition};
|
||||
use glium::glutin::{self, ElementState, MouseCursor};
|
||||
use std::cell::RefMut;
|
||||
use std::io::Write;
|
||||
use std::rc::Rc;
|
||||
use term::KeyCode;
|
||||
@ -212,7 +213,10 @@ pub struct GliumTerminalWindow {
|
||||
}
|
||||
|
||||
impl TerminalWindow for GliumTerminalWindow {
|
||||
fn get_tabs(&mut self) -> &mut Tabs {
|
||||
fn get_tabs(&self) -> &Tabs {
|
||||
&self.tabs
|
||||
}
|
||||
fn get_tabs_mut(&mut self) -> &mut Tabs {
|
||||
&mut self.tabs
|
||||
}
|
||||
|
||||
@ -220,6 +224,23 @@ impl TerminalWindow for GliumTerminalWindow {
|
||||
self.host.display.gl_window().set_title(title);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn frame(&self) -> glium::Frame {
|
||||
self.host.display.draw()
|
||||
}
|
||||
|
||||
fn renderer(&mut self) -> &mut Renderer {
|
||||
&mut self.renderer
|
||||
}
|
||||
fn recreate_texture_atlas(&mut self, size: u32) -> Result<(), Error> {
|
||||
self.renderer.recreate_atlas(&self.host.display, size)
|
||||
}
|
||||
fn renderer_and_terminal(&mut self) -> (&mut Renderer, RefMut<term::Terminal>) {
|
||||
(
|
||||
&mut self.renderer,
|
||||
self.tabs.get_active().unwrap().terminal(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl GliumTerminalWindow {
|
||||
@ -333,14 +354,6 @@ impl GliumTerminalWindow {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn activate_tab_relative(&mut self, delta: isize) -> Result<(), Error> {
|
||||
let max = self.tabs.len();
|
||||
let active = self.tabs.get_active_idx() as isize;
|
||||
let tab = active + delta;
|
||||
let tab = if tab < 0 { max as isize + tab } else { tab };
|
||||
self.activate_tab(tab as usize % max)
|
||||
}
|
||||
|
||||
pub fn window_id(&self) -> glutin::WindowId {
|
||||
self.host.display.gl_window().id()
|
||||
}
|
||||
@ -353,35 +366,6 @@ impl GliumTerminalWindow {
|
||||
.try_clone()
|
||||
}
|
||||
|
||||
pub fn paint(&mut self) -> Result<(), Error> {
|
||||
let tab = match self.tabs.get_active() {
|
||||
Some(tab) => tab,
|
||||
None => return Ok(()),
|
||||
};
|
||||
let mut target = self.host.display.draw();
|
||||
let res = self.renderer.paint(&mut target, &mut tab.terminal());
|
||||
// Ensure that we finish() the target before we let the
|
||||
// error bubble up, otherwise we lose the context.
|
||||
target.finish().unwrap();
|
||||
|
||||
// The only error we want to catch is texture space related;
|
||||
// when that happens we need to blow our glyph cache and
|
||||
// allocate a newer bigger texture.
|
||||
match res {
|
||||
Err(err) => {
|
||||
if let Some(&OutOfTextureSpace { size }) = err.downcast_ref::<OutOfTextureSpace>() {
|
||||
eprintln!("out of texture space, allocating {}", size);
|
||||
self.renderer.recreate_atlas(&self.host.display, size)?;
|
||||
tab.terminal().make_all_lines_dirty();
|
||||
// Recursively initiate a new paint
|
||||
return self.paint();
|
||||
}
|
||||
Err(err)
|
||||
}
|
||||
Ok(_) => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn process_data_read_from_pty(&mut self, data: &[u8], tab_id: usize) -> Result<(), Error> {
|
||||
let tab = self.tabs.get_by_id(tab_id)?;
|
||||
|
||||
|
@ -1,19 +1,37 @@
|
||||
use crate::guicommon::tabs::Tabs;
|
||||
use crate::opengl::render::Renderer;
|
||||
use crate::opengl::textureatlas::OutOfTextureSpace;
|
||||
use failure::Error;
|
||||
use glium;
|
||||
use glium::backend::Facade;
|
||||
use std::cell::RefMut;
|
||||
|
||||
pub trait TerminalWindow {
|
||||
fn get_tabs(&mut self) -> &mut Tabs;
|
||||
fn get_tabs_mut(&mut self) -> &mut Tabs;
|
||||
fn get_tabs(&self) -> &Tabs;
|
||||
fn set_window_title(&mut self, title: &str) -> Result<(), Error>;
|
||||
fn frame(&self) -> glium::Frame;
|
||||
fn renderer(&mut self) -> &mut Renderer;
|
||||
fn renderer_and_terminal(&mut self) -> (&mut Renderer, RefMut<term::Terminal>);
|
||||
fn recreate_texture_atlas(&mut self, size: u32) -> Result<(), Error>;
|
||||
|
||||
fn activate_tab(&mut self, tab_idx: usize) -> Result<(), Error> {
|
||||
let max = self.get_tabs().len();
|
||||
if tab_idx < max {
|
||||
self.get_tabs().set_active(tab_idx);
|
||||
self.get_tabs_mut().set_active(tab_idx);
|
||||
self.update_title();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn activate_tab_relative(&mut self, delta: isize) -> Result<(), Error> {
|
||||
let max = self.get_tabs().len();
|
||||
let active = self.get_tabs().get_active_idx() as isize;
|
||||
let tab = active + delta;
|
||||
let tab = if tab < 0 { max as isize + tab } else { tab };
|
||||
self.activate_tab(tab as usize % max)
|
||||
}
|
||||
|
||||
fn update_title(&mut self) {
|
||||
let num_tabs = self.get_tabs().len();
|
||||
|
||||
@ -34,4 +52,51 @@ pub trait TerminalWindow {
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
|
||||
fn paint_if_needed(&mut self) -> Result<(), Error> {
|
||||
let tab = match self.get_tabs().get_active() {
|
||||
Some(tab) => tab,
|
||||
None => return Ok(()),
|
||||
};
|
||||
if tab.terminal().has_dirty_lines() {
|
||||
self.paint()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn paint(&mut self) -> Result<(), Error> {
|
||||
let mut target = self.frame();
|
||||
|
||||
let res = {
|
||||
let (renderer, mut terminal) = self.renderer_and_terminal();
|
||||
renderer.paint(&mut target, &mut terminal)
|
||||
};
|
||||
|
||||
// Ensure that we finish() the target before we let the
|
||||
// error bubble up, otherwise we lose the context.
|
||||
target
|
||||
.finish()
|
||||
.expect("target.finish failed and we don't know how to recover");
|
||||
|
||||
// The only error we want to catch is texture space related;
|
||||
// when that happens we need to blow our glyph cache and
|
||||
// allocate a newer bigger texture.
|
||||
match res {
|
||||
Err(err) => {
|
||||
if let Some(&OutOfTextureSpace { size }) = err.downcast_ref::<OutOfTextureSpace>() {
|
||||
eprintln!("out of texture space, allocating {}", size);
|
||||
self.recreate_texture_atlas(size)?;
|
||||
self.get_tabs_mut()
|
||||
.get_active()
|
||||
.unwrap()
|
||||
.terminal()
|
||||
.make_all_lines_dirty();
|
||||
// Recursively initiate a new paint
|
||||
return self.paint();
|
||||
}
|
||||
Err(err)
|
||||
}
|
||||
Ok(_) => Ok(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ use super::GuiSystem;
|
||||
use crate::futurecore;
|
||||
use crate::gliumwindows;
|
||||
pub use crate::gliumwindows::GliumTerminalWindow;
|
||||
use crate::guicommon::window::TerminalWindow;
|
||||
use crate::guiloop::SessionTerminated;
|
||||
use crate::{Child, MasterPty};
|
||||
use failure::Error;
|
||||
|
@ -3,6 +3,7 @@ use crate::config::Config;
|
||||
use crate::font::FontConfiguration;
|
||||
use crate::futurecore;
|
||||
use crate::guicommon::tabs::TabId;
|
||||
use crate::guicommon::window::TerminalWindow;
|
||||
use crate::xwindows::xwin::X11TerminalWindow;
|
||||
use crate::xwindows::Connection;
|
||||
use crate::{spawn_window_impl, Child, MasterPty};
|
||||
|
@ -13,6 +13,7 @@ use crate::{openpty, MasterPty};
|
||||
use clipboard::{ClipboardContext, ClipboardProvider};
|
||||
use failure::Error;
|
||||
use futures;
|
||||
use std::cell::RefMut;
|
||||
use std::io::{self, Read, Write};
|
||||
use std::rc::Rc;
|
||||
use term::{self, KeyCode, KeyModifiers, MouseButton, MouseEvent, MouseEventKind};
|
||||
@ -162,7 +163,10 @@ impl<'a> term::TerminalHost for TabHost<'a> {
|
||||
}
|
||||
|
||||
impl TerminalWindow for X11TerminalWindow {
|
||||
fn get_tabs(&mut self) -> &mut Tabs {
|
||||
fn get_tabs(&self) -> &Tabs {
|
||||
&self.tabs
|
||||
}
|
||||
fn get_tabs_mut(&mut self) -> &mut Tabs {
|
||||
&mut self.tabs
|
||||
}
|
||||
|
||||
@ -170,6 +174,22 @@ impl TerminalWindow for X11TerminalWindow {
|
||||
self.host.window.set_title(title);
|
||||
Ok(())
|
||||
}
|
||||
fn frame(&self) -> glium::Frame {
|
||||
self.host.window.draw()
|
||||
}
|
||||
|
||||
fn renderer(&mut self) -> &mut Renderer {
|
||||
&mut self.renderer
|
||||
}
|
||||
fn recreate_texture_atlas(&mut self, size: u32) -> Result<(), Error> {
|
||||
self.renderer.recreate_atlas(&self.host.window, size)
|
||||
}
|
||||
fn renderer_and_terminal(&mut self) -> (&mut Renderer, RefMut<term::Terminal>) {
|
||||
(
|
||||
&mut self.renderer,
|
||||
self.tabs.get_active().unwrap().terminal(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl X11TerminalWindow {
|
||||
@ -284,49 +304,6 @@ impl X11TerminalWindow {
|
||||
self.paint()
|
||||
}
|
||||
|
||||
pub fn paint(&mut self) -> Result<(), Error> {
|
||||
let tab = match self.tabs.get_active() {
|
||||
Some(tab) => tab,
|
||||
None => return Ok(()),
|
||||
};
|
||||
|
||||
let mut target = self.host.window.draw();
|
||||
let res = self.renderer.paint(&mut target, &mut tab.terminal());
|
||||
// Ensure that we finish() the target before we let the
|
||||
// error bubble up, otherwise we lose the context.
|
||||
target
|
||||
.finish()
|
||||
.expect("target.finish failed and we don't know how to recover");
|
||||
|
||||
// The only error we want to catch is texture space related;
|
||||
// when that happens we need to blow our glyph cache and
|
||||
// allocate a newer bigger texture.
|
||||
match res {
|
||||
Err(err) => {
|
||||
if let Some(&OutOfTextureSpace { size }) = err.downcast_ref::<OutOfTextureSpace>() {
|
||||
eprintln!("out of texture space, allocating {}", size);
|
||||
self.renderer.recreate_atlas(&self.host.window, size)?;
|
||||
tab.terminal().make_all_lines_dirty();
|
||||
// Recursively initiate a new paint
|
||||
return self.paint();
|
||||
}
|
||||
Err(err)
|
||||
}
|
||||
Ok(_) => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn paint_if_needed(&mut self) -> Result<(), Error> {
|
||||
let tab = match self.tabs.get_active() {
|
||||
Some(tab) => tab,
|
||||
None => return Ok(()),
|
||||
};
|
||||
if tab.terminal().has_dirty_lines() {
|
||||
self.paint()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn tabs<'a>(&'a self) -> &'a Tabs {
|
||||
&self.tabs
|
||||
}
|
||||
@ -536,12 +513,4 @@ impl X11TerminalWindow {
|
||||
|
||||
Ok(tab_id)
|
||||
}
|
||||
|
||||
pub fn activate_tab_relative(&mut self, delta: isize) -> Result<(), Error> {
|
||||
let max = self.tabs.len();
|
||||
let active = self.tabs.get_active_idx() as isize;
|
||||
let tab = active + delta;
|
||||
let tab = if tab < 0 { max as isize + tab } else { tab };
|
||||
self.activate_tab(tab as usize % max)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user