1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-23 15:04:36 +03:00

add apply function to safely access inner data

This commit is contained in:
Wez Furlong 2019-08-13 22:53:35 -07:00
parent d69938701c
commit e98b29aec6
4 changed files with 59 additions and 3 deletions

View File

@ -1,19 +1,20 @@
use crate::config::Config;
use crate::font::FontConfiguration;
use crate::frontend::guicommon::host::{HostHelper, HostImpl, TabHost};
use crate::frontend::guicommon::window::TerminalWindow;
use crate::mux::tab::Tab;
use crate::mux::window::WindowId as MuxWindowId;
use crate::mux::Mux;
use ::window::*;
use failure::Fallible;
use promise::Future;
use std::any::Any;
use std::rc::Rc;
use std::sync::Arc;
pub struct TermWindow {
config: Arc<Config>,
window: Option<Window>,
fonts: Rc<FontConfiguration>,
config: Arc<Config>,
width: usize,
height: usize,
cell_height: usize,
@ -22,6 +23,10 @@ pub struct TermWindow {
}
impl WindowCallbacks for TermWindow {
fn created(&mut self, window: &Window) {
self.window.replace(window.clone());
}
fn can_close(&mut self) -> bool {
// self.host.close_current_tab();
true
@ -38,6 +43,13 @@ impl WindowCallbacks for TermWindow {
*/
Connection::get().unwrap().terminate_message_loop();
}
fn as_any(&mut self) -> &mut dyn Any {
self
}
fn paint(&mut self, ctx: &mut dyn PaintContext) {
}
}
impl Drop for TermWindow {
@ -72,6 +84,7 @@ impl TermWindow {
width,
height,
Box::new(Self {
window: None,
width,
height,
cell_height,

View File

@ -1,5 +1,6 @@
use ::window::*;
use failure::Fallible;
use std::any::Any;
struct MyWindow {
allow_close: bool,
@ -75,6 +76,10 @@ impl WindowCallbacks for MyWindow {
spawn_window().unwrap();
}
}
fn as_any(&mut self) -> &mut dyn Any {
self
}
}
fn spawn_window() -> Fallible<()> {
@ -90,6 +95,14 @@ fn spawn_window() -> Fallible<()> {
)?;
win.show();
win.apply(|myself, win| {
if let Some(myself) = myself.downcast_ref::<MyWindow>() {
eprintln!(
"got myself; allow_close={}, cursor_pos:{:?}",
myself.allow_close, myself.cursor_pos
);
}
});
Ok(())
}

View File

@ -1,3 +1,4 @@
use std::any::Any;
pub mod bitmaps;
pub mod color;
pub mod input;
@ -100,7 +101,7 @@ pub enum MouseCursor {
}
#[allow(unused_variables)]
pub trait WindowCallbacks {
pub trait WindowCallbacks: Any {
/// Called when the window close button is clicked.
/// Return true to allow the close to continue, false to
/// prevent it from closing.
@ -134,6 +135,13 @@ pub trait WindowCallbacks {
/// Called when the window is created and allows the embedding
/// app to reference the window and operate upon it.
fn created(&mut self, window: &Window) {}
/// An unfortunate bit of boilerplate; you need to provie an impl
/// of this method that returns `self` in order for the downcast_ref
/// method of the Any trait to be usable on WindowCallbacks.
/// https://stackoverflow.com/q/46045298/149111 and others have
/// some rationale on why Rust works this way.
fn as_any(&mut self) -> &mut dyn Any;
}
pub trait WindowOps {
@ -152,6 +160,14 @@ pub trait WindowOps {
/// Change the titlebar text for the window
fn set_title(&self, title: &str);
/// Schedule a callback on the data associated with the window.
/// The `Any` that is passed in corresponds to the WindowCallbacks
/// impl you passed to `new_window`, pre-converted to Any so that
/// you can `downcast_ref` or `downcast_mut` it and operate on it.
fn apply<F: Send + 'static + Fn(&mut dyn Any, &dyn WindowOps)>(&self, func: F)
where
Self: Sized;
}
pub trait WindowOpsMut {

View File

@ -19,6 +19,7 @@ use objc::declare::ClassDecl;
use objc::rc::{StrongPtr, WeakPtr};
use objc::runtime::{Class, Object, Sel};
use objc::*;
use std::any::Any;
use std::cell::RefCell;
use std::ffi::c_void;
use std::rc::Rc;
@ -119,6 +120,19 @@ impl WindowOps for Window {
let title = title.to_owned();
Connection::with_window_inner(self.0, move |inner| inner.set_title(&title));
}
fn apply<F: Send + 'static + Fn(&mut dyn Any, &dyn WindowOps)>(&self, func: F)
where
Self: Sized,
{
Connection::with_window_inner(self.0, move |inner| {
let window = Window(inner.window_id);
if let Some(window_view) = WindowView::get_this(unsafe { &**inner.view }) {
func(window_view.inner.borrow_mut().callbacks.as_any(), &window);
}
});
}
}
impl WindowOpsMut for WindowInner {