mirror of
https://github.com/wez/wezterm.git
synced 2024-11-27 12:23:46 +03:00
add apply function to safely access inner data
This commit is contained in:
parent
d69938701c
commit
e98b29aec6
@ -1,19 +1,20 @@
|
|||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::font::FontConfiguration;
|
use crate::font::FontConfiguration;
|
||||||
use crate::frontend::guicommon::host::{HostHelper, HostImpl, TabHost};
|
use crate::frontend::guicommon::host::{HostHelper, HostImpl, TabHost};
|
||||||
use crate::frontend::guicommon::window::TerminalWindow;
|
|
||||||
use crate::mux::tab::Tab;
|
use crate::mux::tab::Tab;
|
||||||
use crate::mux::window::WindowId as MuxWindowId;
|
use crate::mux::window::WindowId as MuxWindowId;
|
||||||
use crate::mux::Mux;
|
use crate::mux::Mux;
|
||||||
use ::window::*;
|
use ::window::*;
|
||||||
use failure::Fallible;
|
use failure::Fallible;
|
||||||
use promise::Future;
|
use promise::Future;
|
||||||
|
use std::any::Any;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub struct TermWindow {
|
pub struct TermWindow {
|
||||||
config: Arc<Config>,
|
window: Option<Window>,
|
||||||
fonts: Rc<FontConfiguration>,
|
fonts: Rc<FontConfiguration>,
|
||||||
|
config: Arc<Config>,
|
||||||
width: usize,
|
width: usize,
|
||||||
height: usize,
|
height: usize,
|
||||||
cell_height: usize,
|
cell_height: usize,
|
||||||
@ -22,6 +23,10 @@ pub struct TermWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl WindowCallbacks for TermWindow {
|
impl WindowCallbacks for TermWindow {
|
||||||
|
fn created(&mut self, window: &Window) {
|
||||||
|
self.window.replace(window.clone());
|
||||||
|
}
|
||||||
|
|
||||||
fn can_close(&mut self) -> bool {
|
fn can_close(&mut self) -> bool {
|
||||||
// self.host.close_current_tab();
|
// self.host.close_current_tab();
|
||||||
true
|
true
|
||||||
@ -38,6 +43,13 @@ impl WindowCallbacks for TermWindow {
|
|||||||
*/
|
*/
|
||||||
Connection::get().unwrap().terminate_message_loop();
|
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 {
|
impl Drop for TermWindow {
|
||||||
@ -72,6 +84,7 @@ impl TermWindow {
|
|||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
Box::new(Self {
|
Box::new(Self {
|
||||||
|
window: None,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
cell_height,
|
cell_height,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use ::window::*;
|
use ::window::*;
|
||||||
use failure::Fallible;
|
use failure::Fallible;
|
||||||
|
use std::any::Any;
|
||||||
|
|
||||||
struct MyWindow {
|
struct MyWindow {
|
||||||
allow_close: bool,
|
allow_close: bool,
|
||||||
@ -75,6 +76,10 @@ impl WindowCallbacks for MyWindow {
|
|||||||
spawn_window().unwrap();
|
spawn_window().unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn as_any(&mut self) -> &mut dyn Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spawn_window() -> Fallible<()> {
|
fn spawn_window() -> Fallible<()> {
|
||||||
@ -90,6 +95,14 @@ fn spawn_window() -> Fallible<()> {
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
win.show();
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use std::any::Any;
|
||||||
pub mod bitmaps;
|
pub mod bitmaps;
|
||||||
pub mod color;
|
pub mod color;
|
||||||
pub mod input;
|
pub mod input;
|
||||||
@ -100,7 +101,7 @@ pub enum MouseCursor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
pub trait WindowCallbacks {
|
pub trait WindowCallbacks: Any {
|
||||||
/// Called when the window close button is clicked.
|
/// Called when the window close button is clicked.
|
||||||
/// Return true to allow the close to continue, false to
|
/// Return true to allow the close to continue, false to
|
||||||
/// prevent it from closing.
|
/// prevent it from closing.
|
||||||
@ -134,6 +135,13 @@ pub trait WindowCallbacks {
|
|||||||
/// Called when the window is created and allows the embedding
|
/// Called when the window is created and allows the embedding
|
||||||
/// app to reference the window and operate upon it.
|
/// app to reference the window and operate upon it.
|
||||||
fn created(&mut self, window: &Window) {}
|
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 {
|
pub trait WindowOps {
|
||||||
@ -152,6 +160,14 @@ pub trait WindowOps {
|
|||||||
|
|
||||||
/// Change the titlebar text for the window
|
/// Change the titlebar text for the window
|
||||||
fn set_title(&self, title: &str);
|
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 {
|
pub trait WindowOpsMut {
|
||||||
|
@ -19,6 +19,7 @@ use objc::declare::ClassDecl;
|
|||||||
use objc::rc::{StrongPtr, WeakPtr};
|
use objc::rc::{StrongPtr, WeakPtr};
|
||||||
use objc::runtime::{Class, Object, Sel};
|
use objc::runtime::{Class, Object, Sel};
|
||||||
use objc::*;
|
use objc::*;
|
||||||
|
use std::any::Any;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::ffi::c_void;
|
use std::ffi::c_void;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@ -119,6 +120,19 @@ impl WindowOps for Window {
|
|||||||
let title = title.to_owned();
|
let title = title.to_owned();
|
||||||
Connection::with_window_inner(self.0, move |inner| inner.set_title(&title));
|
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 {
|
impl WindowOpsMut for WindowInner {
|
||||||
|
Loading…
Reference in New Issue
Block a user