A simple CPU rendered GUI IDE experience.
-rw-r--r--Cargo.toml8
-rw-r--r--src/commands.rs2
-rw-r--r--src/edi.rs55
-rw-r--r--src/edi/st.rs44
-rw-r--r--src/lsp.rs91
-rw-r--r--src/main.rs138
-rw-r--r--src/rnd.rs99
-rw-r--r--src/winit_app.rs237
8 files changed, 420 insertions, 254 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 05b8b15..6de45db 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -11,7 +11,7 @@ implicit-fn = "0.1.0"
ropey = "1.6.1"
softbuffer = "0.4.6"
swash = "0.2.5"
-winit = "0.30.12"
+winit = "0.31.0-beta.2"
tree-sitter = "0.25.0"
car = "0.1.2"
@@ -68,7 +68,7 @@ vecto = "0.1.1"
rangemap = { version = "1.7.1", features = ["const_fn", "nightly", "serde1"] }
itern = "0.1.1"
kitty-rc = { version = "0.4.2", git = "https://github.com/bend-n/kitty-rc-rs" }
-
+smol_str = "0.3.6"
[profile.dev.package]
rust-analyzer.opt-level = 3
fimg.opt-level = 3
@@ -88,3 +88,7 @@ debug-assertions = true
[profile.dev]
incremental = false
+
+[patch.crates-io]
+smol_str = { git = "https://git.bendn.org/rust-analyzer" }
+# winit = { git = "https://github.com/rust-windowing/winit" }
diff --git a/src/commands.rs b/src/commands.rs
index fdd4efa..aed4a00 100644
--- a/src/commands.rs
+++ b/src/commands.rs
@@ -193,7 +193,7 @@ impl Editor {
pub fn handle_command(
&mut self,
z: Cmd,
- w: Arc<winit::window::Window>,
+ w: Arc<dyn winit::window::Window>,
) -> anyhow::Result<()> {
match z {
Cmd::GoTo(Some(x)) =>
diff --git a/src/edi.rs b/src/edi.rs
index a9c2ba5..29d6a44 100644
--- a/src/edi.rs
+++ b/src/edi.rs
@@ -24,6 +24,7 @@ use tokio_util::task::AbortOnDropHandle as DropH;
use winit::event::{KeyEvent, MouseButton};
use winit::keyboard::{Key, NamedKey};
use winit::window::Window;
+
pub mod st;
use st::*;
@@ -142,7 +143,7 @@ pub struct Editor {
pub lsp: Option<(
&'static Client,
std::thread::JoinHandle<()>,
- Option<Sender<Arc<Window>>>,
+ Option<Sender<Arc<dyn Window>>>,
)>,
// #[serde(skip)]
pub requests: Requests,
@@ -192,7 +193,6 @@ macro_rules! change {
x.rq_semantic_tokens(
&mut $self.requests.semantic_tokens,
origin,
- $w,
)
.unwrap();
inlay!($self);
@@ -343,7 +343,6 @@ impl Editor {
c.rq_semantic_tokens(
&mut me.requests.semantic_tokens,
origin,
- None,
)
.unwrap()
},
@@ -414,7 +413,7 @@ impl Editor {
std::fs::write(self.origin.as_ref().unwrap(), &t).unwrap();
self.mtime = Self::modify(self.origin.as_deref());
}
- pub fn poll(&mut self, w: Option<&Arc<Window>>) {
+ pub fn poll(&mut self, w: Option<&Arc<dyn Window>>) {
let Some((l, ..)) = self.lsp else { return };
for rq in l.req_rx.try_iter() {
match rq {
@@ -468,7 +467,7 @@ impl Editor {
);
}
State::CodeAction(x) => {
- x.poll_r(
+ if x.poll_r(
|x, _| {
let lems: Vec<CodeAction> = x
.ok()??
@@ -483,13 +482,15 @@ impl Editor {
"no code actions available".into();
None
} else {
+ self.bar.last_action =
+ format!("{} code actions", lems.len());
Some(act::CodeActions::new(lems))
}
},
r,
w,
- );
- if x.result.is_none() {
+ ) && x.result.is_none()
+ {
self.state = State::Default;
}
}
@@ -555,7 +556,7 @@ impl Editor {
pub fn cursor_moved(
&mut self,
cursor_position: (usize, usize),
- w: Arc<Window>,
+ w: Arc<dyn Window>,
c: usize,
) {
match self.state.consume(Action::C(cursor_position)).unwrap() {
@@ -793,7 +794,7 @@ impl Editor {
&mut self,
bt: MouseButton,
cursor_position: (usize, usize),
- w: Arc<Window>,
+ w: Arc<dyn Window>,
) {
let text = &mut self.text;
_ = self
@@ -900,12 +901,13 @@ impl Editor {
pub fn keyboard(
&mut self,
event: KeyEvent,
- window: &mut Arc<Window>,
+ window: &mut Arc<dyn Window>,
) -> ControlFlow<()> {
let mut o: Option<Do> = self
.state
.consume(Action::K(event.logical_key.clone()))
.unwrap();
+
match o {
Some(Do::Reinsert) =>
o = self
@@ -1251,12 +1253,7 @@ impl Editor {
self.hist.lc = self.text.cursor.clone();
self.hist.test_push(&mut self.text);
let act = lsp
- .runtime
- .block_on(
- lsp.request::<CodeActionResolveRequest>(&act)
- .unwrap()
- .0,
- )
+ .request_immediate::<CodeActionResolveRequest>(&act)
.unwrap();
let f = f.to_owned();
act.edit.map(|x| self.apply_wsedit(x, &f));
@@ -1395,7 +1392,6 @@ impl Editor {
change!(self, window.clone());
}
lsp!(self + p).map(|(lsp, o)| {
- let window = window.clone();
match event.logical_key.as_ref() {
Key::Character(y)
if let Some(x) = &lsp.initialized
@@ -1839,7 +1835,7 @@ impl Editor {
pub fn open(
&mut self,
x: &Path,
- w: Arc<Window>,
+ w: Arc<dyn Window>,
) -> anyhow::Result<()> {
let x = x.canonicalize()?.to_path_buf();
if Some(&*x) == self.origin.as_deref() {
@@ -1872,9 +1868,9 @@ impl Editor {
lsp: Option<(
&'static Client,
std::thread::JoinHandle<()>,
- Option<Sender<Arc<Window>>>,
+ Option<Sender<Arc<dyn Window>>>,
)>,
- w: Option<Arc<Window>>,
+ w: Option<Arc<dyn Window>>,
ws: Option<PathBuf>,
) -> anyhow::Result<()> {
if let Some(x) = self.files.remove(x) {
@@ -1928,7 +1924,6 @@ impl Editor {
x.rq_semantic_tokens(
&mut self.requests.semantic_tokens,
origin,
- w.clone(),
)
.unwrap();
});
@@ -1936,7 +1931,7 @@ impl Editor {
self.set_title(w);
Ok(())
}
- pub fn set_title(&self, w: Option<Arc<Window>>) {
+ pub fn set_title(&self, w: Option<Arc<dyn Window>>) {
if let Some(x) = w
&& let Some(t) = self.title()
{
@@ -1983,7 +1978,7 @@ impl Editor {
pub fn open_loc(
&mut self,
Location { uri, range }: &Location,
- w: Arc<Window>,
+ w: Arc<dyn Window>,
) {
self.open(&uri.to_file_path().unwrap(), w.clone()).unwrap();
@@ -1996,7 +1991,7 @@ impl Editor {
pub fn open_loclink(
&mut self,
LocationLink { target_uri, target_range, .. }: &LocationLink,
- w: Arc<Window>,
+ w: Arc<dyn Window>,
) {
self.open(&target_uri.to_file_path().unwrap(), w.clone()).unwrap();
@@ -2017,7 +2012,7 @@ pub fn handle2<'a>(
use Key::*;
match key {
- Named(Space) => text.insert(" "),
+ Character(" ") => text.insert(" "),
Named(Backspace) if ctrl() => text.backspace_word(),
Named(Backspace) => text.backspace(),
Named(Home) if ctrl() => {
@@ -2035,10 +2030,12 @@ pub fn handle2<'a>(
text.right();
text.backspace()
}
- Character(x) if x == "a" && alt() => text.left(),
- Character(x) if x == "w" && alt() => text.up(),
- Character(x) if x == "s" && alt() => text.down(),
- Character(x) if x == "d" && alt() => text.right(),
+ Character("d") if alt() && ctrl() => text.word_left(),
+ Character("a") if alt() && ctrl() => text.word_right(),
+ Character("a") if alt() => text.left(),
+ Character("w") if alt() => text.up(),
+ Character("s") if alt() => text.down(),
+ Character("d") if alt() => text.right(),
Named(ArrowLeft) if ctrl() => text.word_left(),
Named(ArrowRight) if ctrl() => text.word_right(),
Named(ArrowLeft) => text.left(),
diff --git a/src/edi/st.rs b/src/edi/st.rs
index c6fbdbb..5c7568f 100644
--- a/src/edi/st.rs
+++ b/src/edi/st.rs
@@ -38,20 +38,20 @@ pub(crate) State => #[derive(Debug)] pub(crate) Action => #[derive(Debug)] pub(c
Dead => K(Key => _) => Dead,
Default => {
- K(Key::Character(x) if x == "s" && ctrl()) => Save [Save],
- K(Key::Character(x) if x == "q" && ctrl()) => Dead [Quit],
- K(Key::Character(x) if x == "v" && ctrl()) => _ [Paste],
- K(Key::Character(x) if x == "z" && ctrl()) => _ [Undo],
- K(Key::Character(x) if x == "y" && ctrl()) => _ [Redo],
- K(Key::Character(x) if x == "f" && ctrl()) => Procure((default(), InputRequest::Search)),
- K(Key::Character(x) if x == "o" && ctrl()) => Procure((default(), InputRequest::OpenFile)),
- K(Key::Character(x) if x == "c" && ctrl()) => _,
- K(Key::Character(x) if x == "l" && ctrl()) => _ [Symbols],
- K(Key::Character(x) if x == "." && ctrl()) => _ [CodeAction],
- K(Key::Character(x) if x == "0" && ctrl()) => _ [MatchingBrace],
- K(Key::Character(x) if x == "`" && ctrl()) => _ [SpawnTerminal],
- K(Key::Character(y) if y == "/" && ctrl()) => Default [Comment(State => State::Default)],
- K(Key::Character(x) if x == "p" && ctrl()) => Command(Commands => Commands::default()),
+ K(Key::Character("s") if ctrl()) => Save [Save],
+ K(Key::Character("q") if ctrl()) => Dead [Quit],
+ K(Key::Character("v") if ctrl()) => _ [Paste],
+ K(Key::Character("z") if ctrl()) => _ [Undo],
+ K(Key::Character("y") if ctrl()) => _ [Redo],
+ K(Key::Character("f") if ctrl()) => Procure((default(), InputRequest::Search)),
+ K(Key::Character("o") if ctrl()) => Procure((default(), InputRequest::OpenFile)),
+ K(Key::Character("c") if ctrl()) => _,
+ K(Key::Character("l") if ctrl()) => _ [Symbols],
+ K(Key::Character(".") if ctrl()) => _ [CodeAction],
+ K(Key::Character("0") if ctrl()) => _ [MatchingBrace],
+ K(Key::Character("`") if ctrl()) => _ [SpawnTerminal],
+ K(Key::Character("/") if ctrl()) => Default [Comment(State => State::Default)],
+ K(Key::Character("p") if ctrl()) => Command(Commands => Commands::default()),
K(Key::Named(Backspace) if alt()) => _ [DeleteBracketPair],
K(Key::Named(F1)) => Procure((default(), InputRequest::RenameSymbol)),
K(Key::Named(k @ (ArrowUp | ArrowDown)) if alt()) => _ [InsertCursor(Direction => {
@@ -62,8 +62,8 @@ Default => {
M(MouseButton::Left if alt()) => _ [InsertCursorAtMouse],
M(MouseButton::Left if ctrl()) => _ [GoToDefinition],
M(MouseButton::Left) => _ [MoveCursor],
- K(Key::Character(x) if x == "-" && ctrl()) => _ [NavBack],
- K(Key::Character(x) if x == "=" && ctrl()) => _ [NavBack],
+ K(Key::Character("=") if ctrl()) => _ [NavForward],
+ K(Key::Character("-") if ctrl()) => _ [NavBack],
M(MouseButton::Back) => _ [NavBack],
M(MouseButton::Forward) => _ [NavForward],
C(((usize, usize)) => .. if unsafe { CLICKING }) => Selection [StartSelection],
@@ -108,7 +108,7 @@ Symbols(Rq { result: Some(_x), request: _rq }) => {
K(Key::Named(Escape)) => Default,
},
Symbols(Rq::<Symbols, Option<SymbolsList>, (), AQErr> => _rq) => {
- K(Key::Character(x) if x == "d" && ctrl()) => _ [SwitchType], // crahs cond methinks
+ K(Key::Character("d") if ctrl()) => _ [SwitchType], // crahs cond methinks
K(Key::Named(Escape)) => Default,
K(_) => _ [SymbolsHandleKey],
C(_) => _,
@@ -136,9 +136,9 @@ Selection => {
C(_) => _,
M(MouseButton => MouseButton::Left) => Default [MoveCursor],
K(Key::Named(Backspace)) => Default [Delete],
- K(Key::Character(y) if y == "x" && ctrl()) => Default [Cut],
- K(Key::Character(y) if y == "c" && ctrl()) => Default [Copy],
- K(Key::Character(y) if y == "/" && ctrl()) => Default [Comment(State::Selection)],
+ K(Key::Character("x") if ctrl()) => Default [Cut],
+ K(Key::Character("c") if ctrl()) => Default [Copy],
+ K(Key::Character("/") if ctrl()) => Default [Comment(State::Selection)],
M(_) => _,
K(Key::Character(y) if !ctrl()) => Default [Insert(SmolStr => y)],
@@ -158,8 +158,8 @@ Procure((t, InputRequest::RenameSymbol)) => K(Key::Named(Enter)) => Default [Ren
Procure((t, a)) => K(k) => Procure((handle(k, t), a)),
Procure((t, a)) => C(_) => Procure((t, a)),
RequestBoolean(t) => {
- K(Key::Character(x) if x == "y") => Default [Boolean((BoolRequest, bool) => (t, true))],
- K(Key::Character(x) if x == "n") => Default [Boolean((t, false))],
+ K(Key::Character("n")) => Default [Boolean((BoolRequest, bool) => (t, true))],
+ K(Key::Character("y")) => Default [Boolean((t, false))],
K(Key::Named(Escape)) => Default [Boolean((t, false))],
K(_) => RequestBoolean(t),
C(_) => _,
diff --git a/src/lsp.rs b/src/lsp.rs
index 78d6652..e365e9e 100644
--- a/src/lsp.rs
+++ b/src/lsp.rs
@@ -42,7 +42,7 @@ pub struct Client {
pub id: AtomicI32,
pub initialized: Option<InitializeResult>,
// pub pending: HashMap<i32, oneshot::Sender<Re>>,
- pub send_to: Sender<(i32, oneshot::Sender<Re>)>,
+ pub send_to: Sender<(i32, oneshot::Sender<Re>, BehaviourAfter)>,
pub progress: &'static papaya::HashMap<
ProgressToken,
Option<(WorkDoneProgress, WorkDoneProgressBegin)>,
@@ -138,9 +138,9 @@ impl Client {
&'me self,
y: &X::Params,
) -> Result<X::Result, RequestError<X>> {
- self.runtime.block_on(self.request::<X>(y)?.0)
+ self.runtime.block_on(self.request_::<X, { Nil }>(y)?.0)
}
- #[must_use]
+
pub fn request<'me, X: Request>(
&'me self,
y: &X::Params,
@@ -152,6 +152,20 @@ impl Client {
),
SendError<Message>,
> {
+ self.request_::<X, { Redraw }>(y)
+ }
+ #[must_use]
+ fn request_<'me, X: Request, const THEN: BehaviourAfter>(
+ &'me self,
+ y: &X::Params,
+ ) -> Result<
+ (
+ impl Future<Output = Result<X::Result, RequestError<X>>>
+ + use<'me, X, THEN>,
+ i32,
+ ),
+ SendError<Message>,
+ > {
let id = self.id.fetch_add(1, std::sync::atomic::Ordering::AcqRel);
self.tx.send(Message::Request(LRq {
id: id.into(),
@@ -161,7 +175,7 @@ impl Client {
let (tx, rx) = oneshot::channel();
if self.initialized.is_some() {
debug!("sent request {} ({id})'s handler", X::METHOD);
- self.send_to.send((id, tx)).expect("oughtnt really fail");
+ self.send_to.send((id, tx, THEN)).expect("oughtnt really fail");
}
Ok((
async move {
@@ -268,7 +282,7 @@ impl Client {
>,
> + use<'me> {
let (rx, _) = self
- .request::<Completion>(&CompletionParams {
+ .request_::<Completion, { Redraw }>(&CompletionParams {
text_document_position: TextDocumentPositionParams {
text_document: f.tid(),
position: Position { line: y as _, character: x as _ },
@@ -291,7 +305,7 @@ impl Client {
RequestError<SignatureHelpRequest>,
>,
> + use<'me> {
- self.request::<SignatureHelpRequest>(&SignatureHelpParams {
+ self.request_::<SignatureHelpRequest, { Redraw }>(&SignatureHelpParams {
context: None,
text_document_position_params: TextDocumentPositionParams {
text_document: f.tid(),
@@ -431,7 +445,7 @@ impl Client {
work_done_progress_params: default(),
partial_result_params: default(),
};
- self.request::<lsp_request!("textDocument/documentHighlight")>(&p)
+ self.request_::<lsp_request!("textDocument/documentHighlight"), {Redraw}>(&p)
.unwrap()
.0
.map(|x| x.map(|x| x.unwrap_or_default()))
@@ -445,7 +459,7 @@ impl Client {
RequestError<lsp_request!("textDocument/documentSymbol")>,
>,
> {
- self.request::<lsp_request!("textDocument/documentSymbol")>(
+ self.request_::<lsp_request!("textDocument/documentSymbol"), { Redraw }>(
&DocumentSymbolParams {
text_document: p.tid(),
work_done_progress_params: default(),
@@ -464,7 +478,7 @@ impl Client {
RequestError<lsp_request!("workspace/symbol")>,
>,
> {
- self.request::<lsp_request!("workspace/symbol")>(
+ self.request_::<lsp_request!("workspace/symbol"), {Redraw}>(
&lsp_types::WorkspaceSymbolParams {
query: f,
search_scope: Some(
@@ -523,7 +537,7 @@ impl Client {
RequestError<lsp_request!("textDocument/inlayHint")>,
>,
> + use<> {
- self.request::<lsp_request!("textDocument/inlayHint")>(&InlayHintParams {
+ self.request_::<lsp_request!("textDocument/inlayHint"), { Redraw }>(&InlayHintParams {
work_done_progress_params: default(),
text_document: f.tid(),
range: t.to_l_range(lower::saturating::math!{
@@ -577,7 +591,6 @@ impl Client {
RequestError<SemanticTokensFullRequest>,
>,
f: &Path,
- w: Option<Arc<Window>>,
) -> anyhow::Result<()> {
debug!("requested semantic tokens");
@@ -585,7 +598,7 @@ impl Client {
else {
return Ok(());
};
- let (rx, _) = self.request::<SemanticTokensFullRequest>(
+ let (rx, _) = self.request_::<SemanticTokensFullRequest, {Redraw}>(
&SemanticTokensParams {
work_done_progress_params: default(),
partial_result_params: default(),
@@ -602,7 +615,6 @@ impl Client {
SemanticTokensResult::Tokens(x) =>
x.data.into_boxed_slice(),
};
- w.map(|x| x.request_redraw());
Ok(r)
});
to.request(x);
@@ -612,17 +624,11 @@ impl Client {
pub fn enter<'a>(&self, f: &Path, t: &'a mut TextArea) {
ceach!(t.cursor, |c| {
- let r = self
- .runtime
- .block_on(
- self.request::<OnEnter>(&TextDocumentPositionParams {
+ let r = self.request_immediate::<OnEnter>(&TextDocumentPositionParams {
text_document: f.tid(),
position: t.to_l_position(*c).unwrap(),
})
- .unwrap()
- .0,
- )
- .unwrap();
+ .unwrap();
match r {
None => t.enter(),
Some(mut r) => {
@@ -653,13 +659,14 @@ impl Client {
pub fn run(
(tx, rx): (Sender<Message>, Receiver<Message>),
workspace: WorkspaceFolder,
-) -> (Client, std::thread::JoinHandle<()>, oneshot::Sender<Arc<Window>>) {
+) -> (Client, std::thread::JoinHandle<()>, oneshot::Sender<Arc<dyn Window>>)
+{
let now = Instant::now();
let (req_tx, req_rx) = unbounded();
let (not_tx, not_rx) = unbounded();
let (_req_tx, _req_rx) = unbounded();
- let (window_tx, window_rx) = oneshot::channel::<Arc<Window>>();
- let mut c: Client = Client {
+ let (window_tx, window_rx) = oneshot::channel::<Arc<dyn Window>>();
+ let mut c = Client {
tx,
progress: Box::leak(Box::new(papaya::HashMap::new())),
runtime: tokio::runtime::Builder::new_multi_thread()
@@ -965,9 +972,9 @@ pub fn run(
loop {
crossbeam::select! {
recv(req_rx) -> x => match x {
- Ok((x, y)) => {
+ Ok((x, y, and)) => {
debug!("received request {x}");
- assert!(map.insert(x, (y, Instant::now())).is_none());
+ assert!(map.insert(x, (y, Instant::now(), and)).is_none());
}
Err(RecvError) => return,
},
@@ -994,20 +1001,22 @@ pub fn run(
if let Some(e) = &x.error {
if e.code == ErrorCode::RequestCanceled as i32 {}
else if e.code == ErrorCode::ServerCancelled as i32 {
- if let Some((s, _)) = map.remove(&x.id.i32()) {
+ if let Some((s, _, t)) = map.remove(&x.id.i32()) {
log::info!("request {} cancelled", x.id);
_ = s.send(x);
+ if t == Redraw { w.request_redraw() }
}
} else {
- if let Some((s, _)) = map.remove(&x.id.i32()) {
+ if let Some((s, _, t)) = map.remove(&x.id.i32()) {
_ = s.send(x.clone());
+ if t == Redraw { w.request_redraw() }
trace!("received error from lsp for response {x:?}");
} else {
error!("received error from lsp for response {x:?}");
}
}
}
- else if let Some((s, took)) = map.remove(&x.id.i32()) {
+ else if let Some((s, took, t)) = map.remove(&x.id.i32()) {
log::info!("request {} took {:?}", x.id, took.elapsed());
match s.send(x) {
Ok(()) => {}
@@ -1017,6 +1026,9 @@ pub fn run(
);
}
}
+ // w.request_redraw();
+ dbg!(t);
+ if t == Redraw { w.request_redraw() }
} else {
error!("request {x:?} was dropped.")
}
@@ -1056,7 +1068,13 @@ pub fn run(
});
(c, h, window_tx)
}
-
+#[derive(Copy, Clone, PartialEq, Eq, std::marker::ConstParamTy, Debug)]
+pub enum BehaviourAfter {
+ Redraw,
+ // Poll, ? how impl.
+ Nil,
+}
+pub use BehaviourAfter::*;
// trait RecvEepy<T>: Sized {
// fn recv_eepy(self) -> Result<T, RecvError> {
// self.recv_sleepy(100)
@@ -1177,7 +1195,7 @@ impl<T, R, D, E> Rq<T, R, D, E> {
&mut self,
f: impl FnOnce(Result<R, E>, (D, Option<T>)) -> Option<T>,
runtime: &tokio::runtime::Runtime,
- ) {
+ ) -> bool {
if self.request.as_mut().is_some_and(|(x, _)| x.is_finished())
&& let Some((task, d)) = self.request.take()
{
@@ -1187,23 +1205,24 @@ impl<T, R, D, E> Rq<T, R, D, E> {
log::error!(
"unexpected join error from request poll: {e}"
);
- return;
+ return false;
}
};
self.result = f(x, (d, self.result.take()));
- }
+ true
+ } else { false }
}
pub fn poll_r(
&mut self,
f: impl FnOnce(Result<R, E>, (D, Option<T>)) -> Option<T>,
runtime: &tokio::runtime::Runtime,
- w: Option<&Arc<Window>>,
- ) {
+ _w: Option<&Arc<dyn Window>>,
+ ) -> bool {
self.poll(
|x, y| {
f(x, y).inspect(|_| {
- w.map(|x| x.request_redraw());
+ // w.map(|x| x.request_redraw());
})
},
runtime,
diff --git a/src/main.rs b/src/main.rs
index c48eaca..e70d96a 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,4 +1,5 @@
#![feature(
+ adt_const_params,
inherent_associated_types,
never_type,
random,
@@ -70,14 +71,17 @@ use lsp_types::*;
use rust_fsm::StateMachine;
use serde::{Deserialize, Serialize};
use swash::FontRef;
-use winit::dpi::PhysicalSize;
+use winit::dpi::{PhysicalPosition, PhysicalSize};
use winit::event::{
- ElementState, Event, Ime, MouseButton, MouseScrollDelta, WindowEvent,
+ ButtonSource, ElementState, Ime, MouseButton, MouseScrollDelta,
+ WindowEvent,
};
use winit::event_loop::{ControlFlow, EventLoop};
+use winit::icon::RgbaIcon;
use winit::keyboard::{Key, ModifiersState, NamedKey};
-use winit::platform::wayland::WindowAttributesExtWayland;
-use winit::window::Icon;
+use winit::window::{
+ ImeCapabilities, ImeEnableRequest, ImeHint, ImeRequestData,
+};
use crate::edi::Editor;
use crate::edi::st::*;
@@ -119,7 +123,7 @@ extern "C" fn sigint(_: i32) {
}
#[implicit_fn::implicit_fn]
-pub(crate) fn entry(event_loop: EventLoop<()>) {
+pub(crate) fn entry(event_loop: EventLoop) {
unsafe { __ED.write(Editor::new()) };
assert_eq!(unsafe { atexit(cleanup) }, 0);
unsafe { signal(libc::SIGINT, sigint as *const () as usize) };
@@ -148,16 +152,17 @@ pub(crate) fn entry(event_loop: EventLoop<()>) {
move |elwt| {
let window = winit_app::make_window(elwt, |x| {
x.with_title("gracilaria")
+ .with_platform_attributes(Box::new(winit::platform::wayland::WindowAttributesWayland::default().with_name("com.bendn.gracilaria", "com.bendn.gracilaria")))
.with_decorations(false)
- .with_name("com.bendn.gracilaria", "")
- .with_resize_increments(PhysicalSize::new(fw, fh))
+ // .with_name("com.bendn.gracilaria", "")
+ // .with_resize_increments(PhysicalSize::new(fw, fh))
.with_window_icon(Some(
- Icon::from_rgba(
+ RgbaIcon::new(
include_bytes!("../dist/icon-32").to_vec(),
32,
32,
)
- .unwrap(),
+ .unwrap().into()
))
});
if let Some(x) = w.take() {
@@ -165,8 +170,21 @@ pub(crate) fn entry(event_loop: EventLoop<()>) {
}
let w_ = window.clone();
title.as_deref().map(move |x| w_.set_title(x));
- window.set_ime_allowed(true);
- window.set_ime_purpose(winit::window::ImePurpose::Terminal);
+ window.request_redraw();
+ window.request_ime_update(winit::window::ImeRequest::Enable(
+ ImeEnableRequest::new(
+ ImeCapabilities::default()
+ .with_hint_and_purpose()
+ .with_cursor_area(),
+ // .with_surrounding_text(),
+ ImeRequestData::default().with_hint_and_purpose(
+ ImeHint::NONE,
+ winit::window::ImePurpose::Terminal,
+ ).with_cursor_area(winit::dpi::Position::Physical(PhysicalPosition::new(0, 0)), winit::dpi::Size::Physical(PhysicalSize::new(0,0))),
+ )
+ .unwrap(),
+ )).unwrap();
+ // window.set_ime_purpose(winit::window::ImePurpose::Terminal);
let context =
softbuffer::Context::new(window.clone()).unwrap();
@@ -177,7 +195,7 @@ pub(crate) fn entry(event_loop: EventLoop<()>) {
},
)
.with_event_handler(
- move |(window, _context), surface, event, elwt| {
+ move |(window, _context), surface, window_id, event, elwt| {
elwt.set_control_flow(ControlFlow::Wait);
let (fw, fh) = dsb::dims(&FONT, ppem);
let (c, r) = dsb::fit(
@@ -185,8 +203,8 @@ pub(crate) fn entry(event_loop: EventLoop<()>) {
ppem,
ls,
(
- window.inner_size().width as _,
- window.inner_size().height as _,
+ window.surface_size().width as _,
+ window.surface_size().height as _,
),
);
if let t = Editor::modify(ed.origin.as_deref())
@@ -196,14 +214,17 @@ pub(crate) fn entry(event_loop: EventLoop<()>) {
ed.state.consume(Action::Changed).unwrap();
window.request_redraw();
}
+ // let before = ed.state.name();
ed.poll(Some(window));
-
+ // println!("{before} -> poll -> {}", ed.state.name());
+ // let before = ed.state.name();
+ // let ev = format!("{event:?}");
+ // use WindowEvent as Event;
match event {
- Event::AboutToWait => {}
- Event::WindowEvent {
- window_id,
- event: WindowEvent::Resized(size),
- } if window_id == window.id() => {
+ // Event::AboutToWait => {}
+
+
+ WindowEvent::SurfaceResized(size) if window_id == window.id() => {
let Some(surface) = surface else {
eprintln!(
"Resized fired before Resumed or after \
@@ -232,21 +253,12 @@ pub(crate) fn entry(event_loop: EventLoop<()>) {
]
}
}
- Event::WindowEvent {
- event: WindowEvent::Ime(Ime::Preedit(..)),
- ..
- } => {}
- Event::WindowEvent {
- event: WindowEvent::Ime(Ime::Commit(x)),
- ..
- } => {
+ WindowEvent::Ime(Ime::Preedit(..)) => {}
+ WindowEvent::Ime(Ime::Commit(x)) => {
ed.text.insert(&x);
window.request_redraw();
}
- Event::WindowEvent {
- window_id,
- event: WindowEvent::RedrawRequested,
- } if window_id == window.id() => {
+ WindowEvent::RedrawRequested if window_id == window.id() => {
rnd::render(
ed,
&mut cells,
@@ -264,16 +276,10 @@ pub(crate) fn entry(event_loop: EventLoop<()>) {
);
}
- Event::WindowEvent {
- event: WindowEvent::CloseRequested,
- window_id,
- } if window_id == window.id() => {
+ WindowEvent::CloseRequested => {
elwt.exit();
}
- Event::WindowEvent {
- event: WindowEvent::CursorMoved { position, .. },
- ..
- } => {
+ WindowEvent::PointerMoved { position, .. } => {
let met = FONT.metrics(&[]);
let fac = ppem / met.units_per_em as f32;
cursor_position = (
@@ -283,10 +289,13 @@ pub(crate) fn entry(event_loop: EventLoop<()>) {
);
ed.cursor_moved(cursor_position, window.clone(), c);
}
- Event::WindowEvent {
- event:
- WindowEvent::MouseInput { state: bt, button, .. },
- ..
+
+ WindowEvent::PointerButton {
+ state: bt,
+ button: ButtonSource::Mouse(button),
+ ..
+
+
} if bt.is_pressed() => {
if button == MouseButton::Left {
unsafe { CLICKING = true };
@@ -294,42 +303,31 @@ pub(crate) fn entry(event_loop: EventLoop<()>) {
ed.click(button, cursor_position, window.clone());
window.request_redraw();
}
- Event::WindowEvent {
- event:
- WindowEvent::MouseInput {
- button: MouseButton::Left,
+
+ WindowEvent::PointerButton {
+ button: ButtonSource::Mouse(MouseButton::Left),
..
- },
- ..
- } => unsafe { CLICKING = false },
- Event::WindowEvent {
- window_id: _,
- event:
+ }
+
+ => unsafe { CLICKING = false },
+
WindowEvent::MouseWheel {
device_id: _,
delta: MouseScrollDelta::LineDelta(_, rows),
phase: _,
- },
- } => {
+ } => {
ed.scroll(rows);
window.request_redraw();
}
- Event::WindowEvent {
- event: WindowEvent::ModifiersChanged(modifiers),
- ..
- } => {
+ WindowEvent::ModifiersChanged(modifiers) => {
unsafe { MODIFIERS = modifiers.state() };
window.request_redraw();
}
- Event::WindowEvent {
- event:
- WindowEvent::KeyboardInput {
+ WindowEvent::KeyboardInput {
event,
is_synthetic: false,
..
- },
- ..
- } if event.state == ElementState::Pressed => {
+ } if event.state == ElementState::Pressed => {
// if event.logical_key == Key::Named(NamedKey::F12) {
// lsp.unwrap().runtime.spawn(async move {
// lsp.unwrap().symbols().await;
@@ -337,7 +335,7 @@ pub(crate) fn entry(event_loop: EventLoop<()>) {
// }
if matches!(
event.logical_key,
- Key::Named(Shift | Alt | Control | Super)
+ Key::Named(Shift | Alt | Control | Meta)
) {
return;
}
@@ -348,6 +346,7 @@ pub(crate) fn entry(event_loop: EventLoop<()>) {
}
_ => {}
};
+ // println!("{before} -> {ev} -> {}", ed.state.name());
},
);
winit_app::run_app(event_loop, app);
@@ -462,8 +461,9 @@ rust_fsm::state_machine! {
None => K(Key<&'i str> => Key::Character(k @ ("." | ":"))) => Complete(
RqS<Complete, lsp_types::request::Completion, usize> => default()
) [Request(CompletionContext => CompletionContext {trigger_kind: CompletionTriggerKind::TRIGGER_CHARACTER, trigger_character:Some(k.to_string()) })],
- None => K(Key::Named(NamedKey::Space) if ctrl()) => Complete(default()) [Request(CompletionContext { trigger_kind: CompletionTriggerKind::INVOKED, trigger_character:None })],
- None => K(Key::Character(x) if x.chars().all(char::is_alphabetic)) => Complete(default()) [Request(CompletionContext { trigger_kind: CompletionTriggerKind::INVOKED, trigger_character:None })],
+ None => K(Key::Character(" ") if ctrl()) => Complete(default()) [Request(CompletionContext { trigger_kind: CompletionTriggerKind::INVOKED, trigger_character:None })],
+ None => K(Key::Character(x) if x.chars().all(char::is_alphabetic)
+ && !matches!(x, "w"|"a"|"s"|"d" if alt())) => Complete(default()) [Request(CompletionContext { trigger_kind: CompletionTriggerKind::INVOKED, trigger_character:None })],
None => K(_) => _,
// when
diff --git a/src/rnd.rs b/src/rnd.rs
index 4905cf2..a7febdb 100644
--- a/src/rnd.rs
+++ b/src/rnd.rs
@@ -14,7 +14,7 @@ use rust_fsm::StateMachine;
use softbuffer::Surface;
use url::Url;
use winit::dpi::{PhysicalPosition, PhysicalSize};
-use winit::window::Window;
+use winit::window::{ImeRequestData, Window};
use crate::edi::st::State;
use crate::edi::{Editor, lsp_m};
@@ -30,13 +30,13 @@ pub fn render(
ed: &mut Editor,
cells: &mut [Cell],
ppem: f32,
- window: &mut Arc<Window>,
+ window: &mut Arc<dyn Window>,
fw: f32,
fh: f32,
ls: f32,
c: usize,
r: usize,
- surface: Option<&mut Surface<Arc<Window>, Arc<Window>>>,
+ surface: Option<&mut Surface<Arc<dyn Window>, Arc<dyn Window>>>,
cursor_position: (usize, usize),
fonts: &mut dsb::Fonts,
mut i: Image<&mut [u8], 3>,
@@ -45,22 +45,30 @@ pub fn render(
let (cx, cy) = text.primary_cursor_visual();
let met = super::FONT.metrics(&[]);
let fac = ppem / met.units_per_em as f32;
- window.set_ime_cursor_area(
- PhysicalPosition::new(
- ((cx + text.line_number_offset()) as f64 * (fw) as f64)
- .round(),
- ((cy.saturating_sub(text.vo)) as f64 * (fh + ls * fac) as f64)
- .floor(),
- ),
- PhysicalSize::new(fw, fh),
- );
+ window
+ .request_ime_update(winit::window::ImeRequest::Update(
+ ImeRequestData::default().with_cursor_area(
+ PhysicalPosition::new(
+ ((cx + text.line_number_offset()) as f64
+ * (fw) as f64)
+ .round(),
+ ((cy.saturating_sub(text.vo)) as f64
+ * (fh + ls * fac) as f64)
+ .floor(),
+ )
+ .into(),
+ PhysicalSize::new(fw, fh).into(),
+ ),
+ ))
+ .unwrap();
+
let Some(surface) = surface else {
eprintln!(
"RedrawRequested fired before Resumed or after Suspended"
);
return;
};
- let size = window.inner_size();
+ let size = window.surface_size();
if size.height != 0 && size.width != 0 {
let now = Instant::now();
@@ -360,8 +368,8 @@ pub fn render(
return Err(());
}
assert!(
- w < window.inner_size().width as _
- && h < window.inner_size().height as _
+ w < window.surface_size().width as _
+ && h < window.surface_size().height as _
);
let is_above = position.1.checked_sub(h).is_some();
let top = position.1.checked_sub(h).unwrap_or(
@@ -373,17 +381,17 @@ pub fn render(
ppem,
ls,
(
- window.inner_size().width as _, /* - left */
- ((window.inner_size().height as usize)
+ window.surface_size().width as _, /* - left */
+ ((window.surface_size().height as usize)
.saturating_sub(top)),
),
); /* suspicious saturation */
r = r.min(y);
let left = if position.0 + w as usize
- > window.inner_size().width as usize
+ > window.surface_size().width as usize
{
- window.inner_size().width as usize - w as usize
+ window.surface_size().width as usize - w as usize
} else {
position.0
};
@@ -645,33 +653,30 @@ pub fn render(
})
});
let mut drawb = |cells, c| {
- // let ws = ed.workspace.as_deref().unwrap();
- // let (_x, _y) = text.cursor_visual();
- let _x = 0;
- let _y = r - 1;
- let Ok((_, left, top, w, h)) = place_around(
- (_x, _y),
- i.copy(),
- cells,
- c,
- ppem,
- ls,
- 0.,
- 0.,
- 0.,
- ) else {
- println!("ra?");
- return;
- };
- i.r#box(
- (
- left.saturating_sub(1) as _,
- top.saturating_sub(1) as _,
- ),
- w as _,
- h as _,
- BORDER,
- );
+ // let ws = ed.workspace.as_deref().unwrap();
+ // let (_x, _y) = text.cursor_visual();
+ let _x = 0;
+ let _y = r - 1;
+ let Ok((_, left, top, w, h)) = place_around(
+ (_x, _y),
+ i.copy(),
+ cells,
+ c,
+ ppem,
+ ls,
+ 0.,
+ 0.,
+ 0.,
+ ) else {
+ println!("ra?");
+ return;
+ };
+ i.r#box(
+ (left.saturating_sub(1) as _, top.saturating_sub(1) as _),
+ w as _,
+ h as _,
+ BORDER,
+ );
};
match &ed.state {
State::CodeAction(Rq { result: Some(x), .. }) => 'out: {
@@ -717,7 +722,7 @@ pub fn render(
let c = x.cells(50, ws);
drawb(&c, 50);
}
- State::Runnables(Rq { result:Some(x), .. }) => {
+ State::Runnables(Rq { result: Some(x), .. }) => {
let ws = ed.workspace.as_deref().unwrap();
let c = x.cells(50, ws);
drawb(&c, 50);
diff --git a/src/winit_app.rs b/src/winit_app.rs
index 18f7258..adba393 100644
--- a/src/winit_app.rs
+++ b/src/winit_app.rs
@@ -1,57 +1,72 @@
/// Common boilerplate for setting up a winit application.
use std::marker::PhantomData;
-use std::sync::Arc;
+use std::sync::Arc as Rc;
use winit::application::ApplicationHandler;
-use winit::event::{Event, WindowEvent};
+use winit::event::{DeviceEvent, DeviceId, WindowEvent};
use winit::event_loop::{ActiveEventLoop, EventLoop};
use winit::window::{Window, WindowAttributes, WindowId};
/// Run a Winit application.
#[allow(unused_mut)]
pub(crate) fn run_app(
- event_loop: EventLoop<()>,
- mut app: impl ApplicationHandler<()> + 'static,
+ event_loop: EventLoop,
+ mut app: impl ApplicationHandler + 'static,
) {
- #[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))]
- event_loop.run_app(&mut app).unwrap();
+ #[cfg(not(target_family = "wasm"))]
+ event_loop.run_app(app).unwrap();
- #[cfg(any(target_arch = "wasm32", target_arch = "wasm64"))]
+ #[cfg(target_family = "wasm")]
winit::platform::web::EventLoopExtWebSys::spawn_app(event_loop, app);
}
/// Create a window from a set of window attributes.
#[allow(dead_code)]
pub(crate) fn make_window(
- elwt: &ActiveEventLoop,
+ elwt: &dyn ActiveEventLoop,
f: impl FnOnce(WindowAttributes) -> WindowAttributes,
-) -> Arc<Window> {
+) -> Rc<dyn Window> {
let attributes = f(WindowAttributes::default());
- #[cfg(target_arch = "wasm32")]
+ #[cfg(target_family = "wasm")]
let attributes =
winit::platform::web::WindowAttributesExtWebSys::with_append(
attributes, true,
);
+
let window = elwt.create_window(attributes);
- Arc::new(window.unwrap())
+ window.unwrap().into()
}
/// Easily constructable winit application.
-pub(crate) struct WinitApp<T, S, Init, InitSurface, Handler> {
+pub(crate) struct WinitApp<
+ T,
+ S,
+ Init,
+ InitSurface,
+ Handler,
+ DeviceEventHandler,
+ AboutToWaitHandler,
+> {
/// Closure to initialize `state`.
- pub init: Init,
+ init: Init,
/// Closure to initialize `surface_state`.
- pub init_surface: InitSurface,
+ init_surface: InitSurface,
/// Closure to run on window events.
- pub event: Handler,
+ event: Handler,
+
+ /// Closure to run on device events.
+ device_event: DeviceEventHandler,
+
+ /// Closure to run on about_to_wait events.
+ about_to_wait: AboutToWaitHandler,
/// Contained state.
- pub state: Option<T>,
+ state: Option<T>,
/// Contained surface state.
- pub surface_state: Option<S>,
+ surface_state: Option<S>,
}
/// Builder that makes it so we don't have to name `T`.
@@ -68,8 +83,8 @@ pub(crate) struct WinitAppBuilder<T, S, Init, InitSurface> {
impl<T, S, Init, InitSurface> WinitAppBuilder<T, S, Init, InitSurface>
where
- Init: FnMut(&ActiveEventLoop) -> T,
- InitSurface: FnMut(&ActiveEventLoop, &mut T) -> S,
+ Init: FnMut(&dyn ActiveEventLoop) -> T,
+ InitSurface: FnMut(&dyn ActiveEventLoop, &mut T) -> S,
{
/// Create with an "init" closure.
pub(crate) fn with_init(
@@ -80,55 +95,173 @@ where
}
/// Build a new application.
+ #[allow(clippy::type_complexity)]
pub(crate) fn with_event_handler<F>(
self,
handler: F,
- ) -> WinitApp<T, S, Init, InitSurface, F>
+ ) -> WinitApp<
+ T,
+ S,
+ Init,
+ InitSurface,
+ F,
+ impl FnMut(&mut T, Option<&mut S>, DeviceEvent, &dyn ActiveEventLoop),
+ impl FnMut(&mut T, Option<&mut S>, &dyn ActiveEventLoop),
+ >
where
- F: FnMut(&mut T, Option<&mut S>, Event<()>, &ActiveEventLoop),
+ F: FnMut(
+ &mut T,
+ Option<&mut S>,
+ WindowId,
+ WindowEvent,
+ &dyn ActiveEventLoop,
+ ),
{
- WinitApp::new(self.init, self.init_surface, handler)
+ WinitApp::new(
+ self.init,
+ self.init_surface,
+ handler,
+ |_, _, _, _| {},
+ |_, _, _| {},
+ )
}
}
-impl<T, S, Init, InitSurface, Handler>
- WinitApp<T, S, Init, InitSurface, Handler>
+impl<
+ T,
+ S,
+ Init,
+ InitSurface,
+ Handler,
+ DeviceEventHandler,
+ AboutToWaitHandler,
+>
+ WinitApp<
+ T,
+ S,
+ Init,
+ InitSurface,
+ Handler,
+ DeviceEventHandler,
+ AboutToWaitHandler,
+ >
where
- Init: FnMut(&ActiveEventLoop) -> T,
- InitSurface: FnMut(&ActiveEventLoop, &mut T) -> S,
- Handler: FnMut(&mut T, Option<&mut S>, Event<()>, &ActiveEventLoop),
+ Init: FnMut(&dyn ActiveEventLoop) -> T,
+ InitSurface: FnMut(&dyn ActiveEventLoop, &mut T) -> S,
+ Handler: FnMut(
+ &mut T,
+ Option<&mut S>,
+ WindowId,
+ WindowEvent,
+ &dyn ActiveEventLoop,
+ ),
+ DeviceEventHandler:
+ FnMut(&mut T, Option<&mut S>, DeviceEvent, &dyn ActiveEventLoop),
+ AboutToWaitHandler:
+ FnMut(&mut T, Option<&mut S>, &dyn ActiveEventLoop),
{
/// Create a new application.
pub(crate) fn new(
init: Init,
init_surface: InitSurface,
event: Handler,
+ device_event: DeviceEventHandler,
+ about_to_wait: AboutToWaitHandler,
) -> Self {
Self {
init,
init_surface,
event,
+ device_event,
+ about_to_wait,
state: None,
surface_state: None,
}
}
+
+ /// Build a new application.
+ #[allow(dead_code)]
+ pub(crate) fn with_about_to_wait_handler<F>(
+ self,
+ about_to_wait: F,
+ ) -> WinitApp<T, S, Init, InitSurface, Handler, DeviceEventHandler, F>
+ where
+ F: FnMut(&mut T, Option<&mut S>, &dyn ActiveEventLoop),
+ {
+ WinitApp::new(
+ self.init,
+ self.init_surface,
+ self.event,
+ self.device_event,
+ about_to_wait,
+ )
+ }
+
+ /// Build a new application.
+ #[allow(dead_code)]
+ pub(crate) fn with_device_event_handler<F>(
+ self,
+ device_event: F,
+ ) -> WinitApp<T, S, Init, InitSurface, Handler, F, AboutToWaitHandler>
+ where
+ F: FnMut(
+ &mut T,
+ Option<&mut S>,
+ DeviceEvent,
+ &dyn ActiveEventLoop,
+ ),
+ {
+ WinitApp::new(
+ self.init,
+ self.init_surface,
+ self.event,
+ device_event,
+ self.about_to_wait,
+ )
+ }
}
-impl<T, S, Init, InitSurface, Handler> ApplicationHandler
- for WinitApp<T, S, Init, InitSurface, Handler>
+impl<
+ T,
+ S,
+ Init,
+ InitSurface,
+ Handler,
+ DeviceEventHandler,
+ AboutToWaitHandler,
+> ApplicationHandler
+ for WinitApp<
+ T,
+ S,
+ Init,
+ InitSurface,
+ Handler,
+ DeviceEventHandler,
+ AboutToWaitHandler,
+ >
where
- Init: FnMut(&ActiveEventLoop) -> T,
- InitSurface: FnMut(&ActiveEventLoop, &mut T) -> S,
- Handler: FnMut(&mut T, Option<&mut S>, Event<()>, &ActiveEventLoop),
+ Init: FnMut(&dyn ActiveEventLoop) -> T,
+ InitSurface: FnMut(&dyn ActiveEventLoop, &mut T) -> S,
+ Handler: FnMut(
+ &mut T,
+ Option<&mut S>,
+ WindowId,
+ WindowEvent,
+ &dyn ActiveEventLoop,
+ ),
+ DeviceEventHandler:
+ FnMut(&mut T, Option<&mut S>, DeviceEvent, &dyn ActiveEventLoop),
+ AboutToWaitHandler:
+ FnMut(&mut T, Option<&mut S>, &dyn ActiveEventLoop),
{
- fn resumed(&mut self, el: &ActiveEventLoop) {
+ fn resumed(&mut self, el: &dyn ActiveEventLoop) {
debug_assert!(self.state.is_none());
let mut state = (self.init)(el);
self.surface_state = Some((self.init_surface)(el, &mut state));
self.state = Some(state);
}
- fn suspended(&mut self, _event_loop: &ActiveEventLoop) {
+ fn suspended(&mut self, _event_loop: &dyn ActiveEventLoop) {
let surface_state = self.surface_state.take();
debug_assert!(surface_state.is_some());
drop(surface_state);
@@ -136,28 +269,36 @@ where
fn window_event(
&mut self,
- event_loop: &ActiveEventLoop,
+ event_loop: &dyn ActiveEventLoop,
window_id: WindowId,
event: WindowEvent,
) {
let state = self.state.as_mut().unwrap();
let surface_state = self.surface_state.as_mut();
- (self.event)(
- state,
- surface_state,
- Event::WindowEvent { window_id, event },
- event_loop,
- );
+ (self.event)(state, surface_state, window_id, event, event_loop);
}
- fn about_to_wait(&mut self, event_loop: &ActiveEventLoop) {
+ fn about_to_wait(&mut self, event_loop: &dyn ActiveEventLoop) {
if let Some(state) = self.state.as_mut() {
- (self.event)(
- state,
- self.surface_state.as_mut(),
- Event::AboutToWait,
- event_loop,
- );
+ let surface_state = self.surface_state.as_mut();
+ (self.about_to_wait)(state, surface_state, event_loop);
}
}
+
+ fn device_event(
+ &mut self,
+ event_loop: &dyn ActiveEventLoop,
+ _device_id: Option<DeviceId>,
+ event: DeviceEvent,
+ ) {
+ let state = self.state.as_mut().unwrap();
+ let surface_state = self.surface_state.as_mut();
+ (self.device_event)(state, surface_state, event, event_loop);
+ }
+
+ fn can_create_surfaces(&mut self, el: &dyn ActiveEventLoop) {
+ let mut state = (self.init)(el);
+ self.surface_state = Some((self.init_surface)(el, &mut state));
+ self.state = Some(state);
+ }
}