egui
This commit is contained in:
parent
d4e310293d
commit
097635a784
795
Cargo.lock
generated
795
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -8,6 +8,11 @@ libservo = { git = "https://github.com/servo/servo" }
|
||||
surfman = "0.9.3"
|
||||
|
||||
winit = "0.30.0"
|
||||
glow = "0.13.1"
|
||||
glutin = "0.32.0"
|
||||
egui = { git = "https://github.com/AndriBaal/egui", branch = "winit-0.30" }
|
||||
egui_glow = { git = "https://github.com/AndriBaal/egui", branch = "winit-0.30", features = [ "winit" ] }
|
||||
egui-winit = { git = "https://github.com/AndriBaal/egui", branch = "winit-0.30", default-features = false, features = [ "wayland", "x11" ] }
|
||||
|
||||
toml = "0.5.11"
|
||||
serde-inline-default = "0.2.0"
|
||||
@ -15,4 +20,4 @@ serde = "1.0.203"
|
||||
xdg = "2.5.2"
|
||||
|
||||
log = "0.4.21"
|
||||
env_logger = "0.11.3"
|
||||
env_logger = "0.10.2"
|
||||
|
243
src/app.rs
243
src/app.rs
@ -18,11 +18,11 @@ use winit::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
embedder::EmbedderCallbacks, window::Window, winit_mouse_to_servo_mouse,
|
||||
browser::Browser, embedder::EmbedderCallbacks, window::Window, winit_mouse_to_servo_mouse,
|
||||
winit_position_to_euclid_point, ServoEvent,
|
||||
};
|
||||
|
||||
type Frame = (Rc<Window>, Servo<Window>);
|
||||
type Frame = (Rc<Window>, Servo<Window>, Browser);
|
||||
type ButtonPress = (MouseButton, Point2D<f64, DevicePixel>);
|
||||
|
||||
pub struct App {
|
||||
@ -33,6 +33,7 @@ pub struct App {
|
||||
current_url: Option<ServoUrl>,
|
||||
mouse_pos: Cell<Point2D<f64, DevicePixel>>,
|
||||
mouse_down: Cell<Option<ButtonPress>>,
|
||||
event_queue: Vec<EmbedderEvent>,
|
||||
}
|
||||
|
||||
impl App {
|
||||
@ -45,8 +46,113 @@ impl App {
|
||||
current_url: None,
|
||||
mouse_pos: Cell::new(Point2D::default()),
|
||||
mouse_down: Cell::new(None),
|
||||
event_queue: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_events(&mut self) -> bool {
|
||||
let (window, servo, browser) = match self.frame.as_mut() {
|
||||
Some((w, s, b)) => (w, s, b),
|
||||
None => return false,
|
||||
};
|
||||
|
||||
let mut present = false;
|
||||
|
||||
{
|
||||
let mut servo_events = servo.get_events();
|
||||
|
||||
loop {
|
||||
for (webview_id, msg) in servo_events {
|
||||
trace!("servo event: view: {:?} msg: {:?}", webview_id, msg);
|
||||
|
||||
match msg {
|
||||
EmbedderMsg::ReadyToPresent(_) => window.request_redraw(),
|
||||
EmbedderMsg::WebViewOpened(new_webview_id) => {
|
||||
let rect = window.get_coordinates().get_viewport().to_f32();
|
||||
self.webviews.push(new_webview_id);
|
||||
self.event_queue.extend_from_slice(&[
|
||||
EmbedderEvent::FocusWebView(new_webview_id),
|
||||
EmbedderEvent::MoveResizeWebView(new_webview_id, rect),
|
||||
EmbedderEvent::RaiseWebViewToTop(new_webview_id, true),
|
||||
]);
|
||||
}
|
||||
EmbedderMsg::WebViewFocused(webview_id) => {
|
||||
self.focused_webview = Some(webview_id);
|
||||
self.event_queue
|
||||
.push(EmbedderEvent::ShowWebView(webview_id, true));
|
||||
}
|
||||
EmbedderMsg::LoadStart
|
||||
| EmbedderMsg::LoadComplete
|
||||
| EmbedderMsg::HeadParsed => present = true,
|
||||
EmbedderMsg::HistoryChanged(urls, current) => {
|
||||
self.current_url = Some(urls[current].clone());
|
||||
browser.set_location(self.current_url.as_ref().map(|x| x.to_string()));
|
||||
present = true;
|
||||
}
|
||||
EmbedderMsg::ChangePageTitle(title) => window.set_title(
|
||||
&title
|
||||
.or(self.current_url.as_ref().map(|x| x.to_string()))
|
||||
.unwrap_or("Servo".into()),
|
||||
),
|
||||
EmbedderMsg::SetCursor(cursor) => window.set_cursor(cursor),
|
||||
EmbedderMsg::EventDelivered(event) => {
|
||||
if let (Some(wvid), CompositorEventVariant::MouseButtonEvent) =
|
||||
(webview_id, event)
|
||||
{
|
||||
self.event_queue.extend_from_slice(&[
|
||||
EmbedderEvent::RaiseWebViewToTop(wvid, true),
|
||||
EmbedderEvent::FocusWebView(wvid),
|
||||
]);
|
||||
}
|
||||
}
|
||||
EmbedderMsg::WebViewClosed(webview_id) => {
|
||||
self.webviews.retain(|&x| x != webview_id);
|
||||
self.focused_webview = None;
|
||||
self.event_queue.push(
|
||||
self.webviews
|
||||
.last()
|
||||
.map(|&x| EmbedderEvent::FocusWebView(x))
|
||||
.unwrap_or(EmbedderEvent::Quit),
|
||||
);
|
||||
}
|
||||
EmbedderMsg::Shutdown => {
|
||||
return true;
|
||||
}
|
||||
EmbedderMsg::AllowNavigationRequest(pipeline_id, _url) => {
|
||||
if webview_id.is_some() {
|
||||
self.event_queue
|
||||
.push(EmbedderEvent::AllowNavigationResponse(
|
||||
pipeline_id,
|
||||
true,
|
||||
));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
present |= servo.handle_events(self.event_queue.drain(..));
|
||||
servo_events = servo.get_events();
|
||||
|
||||
if servo_events.len() == 0 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if present {
|
||||
servo.present();
|
||||
let w = window.winit_window();
|
||||
self.event_queue.extend(browser.update(
|
||||
w,
|
||||
self.focused_webview,
|
||||
servo.offscreen_framebuffer_id(),
|
||||
));
|
||||
browser.paint(w);
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl ApplicationHandler<ServoEvent> for App {
|
||||
@ -60,17 +166,26 @@ impl ApplicationHandler<ServoEvent> for App {
|
||||
) {
|
||||
trace!("window event: {:?}", event);
|
||||
|
||||
let (window, servo) = match self.frame.as_mut() {
|
||||
Some((w, s)) => (w, s),
|
||||
let (window, servo, browser) = match self.frame.as_mut() {
|
||||
Some((w, s, b)) => (w, s, b),
|
||||
None => return,
|
||||
};
|
||||
|
||||
let mut events = vec![];
|
||||
|
||||
match event {
|
||||
WindowEvent::RedrawRequested => {
|
||||
servo.present();
|
||||
let w = window.winit_window();
|
||||
self.event_queue.extend(browser.update(
|
||||
w,
|
||||
self.focused_webview,
|
||||
servo.offscreen_framebuffer_id(),
|
||||
));
|
||||
browser.paint(w);
|
||||
return;
|
||||
}
|
||||
WindowEvent::Resized(size) => {
|
||||
window.resize(size);
|
||||
events.push(EmbedderEvent::WindowResize);
|
||||
self.event_queue.push(EmbedderEvent::WindowResize);
|
||||
}
|
||||
WindowEvent::CursorMoved {
|
||||
device_id: _,
|
||||
@ -78,7 +193,8 @@ impl ApplicationHandler<ServoEvent> for App {
|
||||
} => {
|
||||
let position = winit_position_to_euclid_point(position);
|
||||
self.mouse_pos.set(position);
|
||||
events.push(EmbedderEvent::MouseWindowMoveEventClass(position.to_f32()));
|
||||
self.event_queue
|
||||
.push(EmbedderEvent::MouseWindowMoveEventClass(position.to_f32()));
|
||||
}
|
||||
WindowEvent::MouseInput {
|
||||
device_id: _,
|
||||
@ -87,12 +203,14 @@ impl ApplicationHandler<ServoEvent> for App {
|
||||
} => match button {
|
||||
winit::event::MouseButton::Back => {
|
||||
if let Some(x) = self.focused_webview {
|
||||
events.push(EmbedderEvent::Navigation(x, TraversalDirection::Back(1)));
|
||||
self.event_queue
|
||||
.push(EmbedderEvent::Navigation(x, TraversalDirection::Back(1)));
|
||||
}
|
||||
}
|
||||
winit::event::MouseButton::Forward => {
|
||||
if let Some(x) = self.focused_webview {
|
||||
events.push(EmbedderEvent::Navigation(x, TraversalDirection::Forward(1)));
|
||||
self.event_queue
|
||||
.push(EmbedderEvent::Navigation(x, TraversalDirection::Forward(1)));
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
@ -103,12 +221,12 @@ impl ApplicationHandler<ServoEvent> for App {
|
||||
match state {
|
||||
ElementState::Pressed => {
|
||||
self.mouse_down.set(Some((sbutton, position)));
|
||||
events.push(EmbedderEvent::MouseWindowEventClass(
|
||||
self.event_queue.push(EmbedderEvent::MouseWindowEventClass(
|
||||
MouseWindowEvent::MouseDown(sbutton, pos),
|
||||
));
|
||||
}
|
||||
ElementState::Released => {
|
||||
events.push(EmbedderEvent::MouseWindowEventClass(
|
||||
self.event_queue.push(EmbedderEvent::MouseWindowEventClass(
|
||||
MouseWindowEvent::MouseUp(sbutton, pos),
|
||||
));
|
||||
if let Some((dbut, dpos)) = self.mouse_down.get() {
|
||||
@ -117,9 +235,11 @@ impl ApplicationHandler<ServoEvent> for App {
|
||||
+ pixel_dist.y * pixel_dist.y)
|
||||
.sqrt();
|
||||
if pixel_dist < 10.0 * window.hidpi_factor() {
|
||||
events.push(EmbedderEvent::MouseWindowEventClass(
|
||||
MouseWindowEvent::Click(sbutton, pos),
|
||||
));
|
||||
self.event_queue.push(
|
||||
EmbedderEvent::MouseWindowEventClass(
|
||||
MouseWindowEvent::Click(sbutton, pos),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -127,12 +247,12 @@ impl ApplicationHandler<ServoEvent> for App {
|
||||
}
|
||||
}
|
||||
},
|
||||
WindowEvent::CloseRequested => events.push(EmbedderEvent::Quit),
|
||||
WindowEvent::CloseRequested => self.event_queue.push(EmbedderEvent::Quit),
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if event == WindowEvent::RedrawRequested || servo.handle_events(events) {
|
||||
servo.present();
|
||||
if self.handle_events() {
|
||||
event_loop.exit();
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,24 +261,25 @@ impl ApplicationHandler<ServoEvent> for App {
|
||||
|
||||
if cause == StartCause::Init {
|
||||
let window = Rc::new(Window::new(event_loop));
|
||||
let browser = Browser::new(event_loop, &window.rendering_context());
|
||||
|
||||
let embedder = Box::new(EmbedderCallbacks::new(self.ev_waker.clone()));
|
||||
|
||||
let servo_data = Servo::new(embedder, window.clone(), None, CompositeTarget::Window);
|
||||
let servo_data = Servo::new(embedder, window.clone(), None, CompositeTarget::Fbo);
|
||||
let mut servo = servo_data.servo;
|
||||
|
||||
servo.handle_events([EmbedderEvent::NewWebView(
|
||||
ServoUrl::parse("https://gnu.org").unwrap(),
|
||||
ServoUrl::parse("https://browserleaks.com").unwrap(),
|
||||
servo_data.browser_id,
|
||||
)]);
|
||||
|
||||
self.frame = Some((window, servo));
|
||||
self.frame = Some((window, servo, browser));
|
||||
|
||||
debug!("init done");
|
||||
}
|
||||
|
||||
let (window, servo) = match self.frame.as_mut() {
|
||||
Some((w, s)) => (w, s),
|
||||
let (window, servo, browser) = match self.frame.as_mut() {
|
||||
Some((w, s, b)) => (w, s, b),
|
||||
None => return,
|
||||
};
|
||||
|
||||
@ -170,80 +291,8 @@ impl ApplicationHandler<ServoEvent> for App {
|
||||
}
|
||||
|
||||
fn user_event(&mut self, event_loop: &ActiveEventLoop, _event: ServoEvent) {
|
||||
let (window, servo) = match self.frame.as_mut() {
|
||||
Some((w, s)) => (w, s),
|
||||
None => return,
|
||||
};
|
||||
|
||||
let mut events = vec![];
|
||||
let mut present = false;
|
||||
|
||||
for (webview_id, msg) in servo.get_events() {
|
||||
trace!("servo event: view: {:?} msg: {:?}", webview_id, msg);
|
||||
|
||||
match msg {
|
||||
EmbedderMsg::ReadyToPresent(_) => window.request_redraw(),
|
||||
EmbedderMsg::WebViewOpened(new_webview_id) => {
|
||||
let rect = window.get_coordinates().get_viewport().to_f32();
|
||||
self.webviews.push(new_webview_id);
|
||||
events.extend_from_slice(&[
|
||||
EmbedderEvent::FocusWebView(new_webview_id),
|
||||
EmbedderEvent::MoveResizeWebView(new_webview_id, rect),
|
||||
EmbedderEvent::RaiseWebViewToTop(new_webview_id, true),
|
||||
]);
|
||||
}
|
||||
EmbedderMsg::WebViewFocused(webview_id) => {
|
||||
self.focused_webview = Some(webview_id);
|
||||
events.push(EmbedderEvent::ShowWebView(webview_id, true));
|
||||
}
|
||||
EmbedderMsg::LoadStart | EmbedderMsg::LoadComplete | EmbedderMsg::HeadParsed => {
|
||||
present = true
|
||||
}
|
||||
EmbedderMsg::HistoryChanged(urls, current) => {
|
||||
self.current_url = Some(urls[current].clone());
|
||||
present = true;
|
||||
}
|
||||
EmbedderMsg::ChangePageTitle(title) => window.set_title(
|
||||
&title
|
||||
.or(self.current_url.as_ref().map(|x| x.to_string()))
|
||||
.unwrap_or("Servo".into()),
|
||||
),
|
||||
EmbedderMsg::SetCursor(cursor) => window.set_cursor(cursor),
|
||||
EmbedderMsg::EventDelivered(event) => {
|
||||
if let (Some(wvid), CompositorEventVariant::MouseButtonEvent) =
|
||||
(webview_id, event)
|
||||
{
|
||||
events.extend_from_slice(&[
|
||||
EmbedderEvent::RaiseWebViewToTop(wvid, true),
|
||||
EmbedderEvent::FocusWebView(wvid),
|
||||
]);
|
||||
}
|
||||
}
|
||||
EmbedderMsg::WebViewClosed(webview_id) => {
|
||||
self.webviews.retain(|&x| x != webview_id);
|
||||
self.focused_webview = None;
|
||||
events.push(
|
||||
self.webviews
|
||||
.last()
|
||||
.map(|&x| EmbedderEvent::FocusWebView(x))
|
||||
.unwrap_or(EmbedderEvent::Quit),
|
||||
);
|
||||
}
|
||||
EmbedderMsg::Shutdown => {
|
||||
event_loop.exit();
|
||||
return;
|
||||
}
|
||||
EmbedderMsg::AllowNavigationRequest(pipeline_id, _url) => {
|
||||
if webview_id.is_some() {
|
||||
events.push(EmbedderEvent::AllowNavigationResponse(pipeline_id, true));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
if servo.handle_events(events) || present {
|
||||
servo.present();
|
||||
if self.handle_events() {
|
||||
event_loop.exit();
|
||||
}
|
||||
}
|
||||
|
||||
|
198
src/browser.rs
Normal file
198
src/browser.rs
Normal file
@ -0,0 +1,198 @@
|
||||
use egui::{CentralPanel, Frame, PaintCallback, Pos2, TopBottomPanel, Vec2};
|
||||
use egui_glow::{CallbackFn, EguiGlow};
|
||||
use glow::NativeFramebuffer;
|
||||
use servo::{
|
||||
base::id::TopLevelBrowsingContextId as WebViewId,
|
||||
compositing::windowing::EmbedderEvent,
|
||||
euclid::{Box2D, Point2D, Scale, Size2D},
|
||||
gl,
|
||||
servo_geometry::DeviceIndependentPixel,
|
||||
style_traits::DevicePixel,
|
||||
webrender_api::units::DeviceRect,
|
||||
webrender_traits::RenderingContext,
|
||||
};
|
||||
use std::{num::NonZeroU32, sync::Arc};
|
||||
use surfman::GLApi;
|
||||
use winit::event_loop::ActiveEventLoop;
|
||||
|
||||
pub struct Browser {
|
||||
widget_surface_fbo: Option<glow::NativeFramebuffer>,
|
||||
egui_glow: EguiGlow,
|
||||
shapes: Vec<egui::epaint::ClippedShape>,
|
||||
textures_delta: egui::TexturesDelta,
|
||||
location: Option<String>,
|
||||
rect: DeviceRect,
|
||||
}
|
||||
|
||||
impl Browser {
|
||||
pub fn new(event_loop: &ActiveEventLoop, rendering_context: &RenderingContext) -> Self {
|
||||
let webrender_gl = match rendering_context.connection().gl_api() {
|
||||
GLApi::GL => unsafe { gl::GlFns::load_with(|s| rendering_context.get_proc_address(s)) },
|
||||
GLApi::GLES => unsafe {
|
||||
gl::GlesFns::load_with(|s| rendering_context.get_proc_address(s))
|
||||
},
|
||||
};
|
||||
if webrender_gl.get_error() != gl::NO_ERROR
|
||||
|| rendering_context.make_gl_context_current().is_err()
|
||||
{
|
||||
panic!("gl error");
|
||||
}
|
||||
|
||||
let gl = unsafe {
|
||||
glow::Context::from_loader_function(|s| rendering_context.get_proc_address(s))
|
||||
};
|
||||
|
||||
let egui_glow = egui_glow::EguiGlow::new(&event_loop, Arc::new(gl), None, None);
|
||||
|
||||
let widget_surface_fbo = rendering_context
|
||||
.context_surface_info()
|
||||
.ok()
|
||||
.and_then(|x| x.and_then(|x| NonZeroU32::new(x.framebuffer_object)))
|
||||
.map(NativeFramebuffer);
|
||||
|
||||
Self {
|
||||
widget_surface_fbo,
|
||||
egui_glow,
|
||||
shapes: vec![],
|
||||
textures_delta: Default::default(),
|
||||
location: None,
|
||||
rect: DeviceRect::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_location(&mut self, x: Option<String>) {
|
||||
self.location = x;
|
||||
}
|
||||
|
||||
pub fn paint(&mut self, window: &winit::window::Window) {
|
||||
unsafe {
|
||||
use glow::HasContext as _;
|
||||
self.egui_glow
|
||||
.painter
|
||||
.gl()
|
||||
.bind_framebuffer(gl::FRAMEBUFFER, self.widget_surface_fbo);
|
||||
}
|
||||
|
||||
let mut textures_delta = self.textures_delta.to_owned();
|
||||
for (id, image_delta) in textures_delta.set {
|
||||
self.egui_glow.painter.set_texture(id, &image_delta);
|
||||
}
|
||||
|
||||
let pixels_per_point = self.egui_glow.egui_ctx.pixels_per_point();
|
||||
let clipped_primitives = self
|
||||
.egui_glow
|
||||
.egui_ctx
|
||||
.tessellate(self.shapes.to_owned(), pixels_per_point);
|
||||
self.egui_glow.painter.paint_primitives(
|
||||
window.inner_size().into(),
|
||||
pixels_per_point,
|
||||
&clipped_primitives,
|
||||
);
|
||||
|
||||
for id in textures_delta.free.drain(..) {
|
||||
self.egui_glow.painter.free_texture(id);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(
|
||||
&mut self,
|
||||
window: &winit::window::Window,
|
||||
focused_webview: Option<WebViewId>,
|
||||
servo_framebuffer_id: Option<gl::GLuint>,
|
||||
) -> Vec<EmbedderEvent> {
|
||||
let mut events = vec![];
|
||||
|
||||
let raw_input = self.egui_glow.egui_winit.take_egui_input(window);
|
||||
let widget_fbo = self.widget_surface_fbo;
|
||||
let label = self.location.to_owned().unwrap_or("...".into());
|
||||
|
||||
let full_output = self.egui_glow.egui_ctx.run(raw_input, |ctx| {
|
||||
TopBottomPanel::bottom("locbar").show(ctx, |ui| {
|
||||
ui.allocate_ui_with_layout(
|
||||
ui.available_size(),
|
||||
egui::Layout::left_to_right(egui::Align::Center),
|
||||
|ui| {
|
||||
ui.label(label);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
let scale =
|
||||
Scale::<_, DeviceIndependentPixel, DevicePixel>::new(ctx.pixels_per_point());
|
||||
|
||||
CentralPanel::default()
|
||||
.frame(Frame::none())
|
||||
.show(ctx, |ui| {
|
||||
let Pos2 { x, y } = ui.cursor().min;
|
||||
let Vec2 {
|
||||
x: width,
|
||||
y: height,
|
||||
} = ui.available_size();
|
||||
let rect =
|
||||
Box2D::from_origin_and_size(Point2D::new(x, y), Size2D::new(width, height))
|
||||
* scale;
|
||||
if rect != self.rect {
|
||||
self.rect = rect;
|
||||
if let Some(x) = focused_webview {
|
||||
events.push(EmbedderEvent::MoveResizeWebView(x, rect));
|
||||
}
|
||||
}
|
||||
let min = ui.cursor().min;
|
||||
let size = ui.available_size();
|
||||
let rect = egui::Rect::from_min_size(min, size);
|
||||
ui.allocate_space(size);
|
||||
|
||||
let servo_fbo = servo_framebuffer_id
|
||||
.and_then(NonZeroU32::new)
|
||||
.map(NativeFramebuffer);
|
||||
|
||||
ui.painter().add(PaintCallback {
|
||||
rect,
|
||||
callback: Arc::new(CallbackFn::new(move |info, painter| {
|
||||
let clip = info.viewport_in_pixels();
|
||||
let x = clip.left_px;
|
||||
let y = clip.from_bottom_px;
|
||||
let width = clip.width_px;
|
||||
let height = clip.height_px;
|
||||
|
||||
unsafe {
|
||||
use glow::HasContext as _;
|
||||
painter.gl().clear_color(0.0, 0.0, 0.0, 0.0);
|
||||
painter.gl().scissor(x, y, width, height);
|
||||
painter.gl().enable(gl::SCISSOR_TEST);
|
||||
painter.gl().clear(gl::COLOR_BUFFER_BIT);
|
||||
painter.gl().disable(gl::SCISSOR_TEST);
|
||||
painter
|
||||
.gl()
|
||||
.bind_framebuffer(gl::READ_FRAMEBUFFER, servo_fbo);
|
||||
painter
|
||||
.gl()
|
||||
.bind_framebuffer(gl::DRAW_FRAMEBUFFER, widget_fbo);
|
||||
painter.gl().blit_framebuffer(
|
||||
x,
|
||||
y,
|
||||
x + width,
|
||||
y + height,
|
||||
x,
|
||||
y,
|
||||
x + width,
|
||||
y + height,
|
||||
gl::COLOR_BUFFER_BIT,
|
||||
gl::NEAREST,
|
||||
);
|
||||
painter.gl().bind_framebuffer(gl::FRAMEBUFFER, widget_fbo);
|
||||
}
|
||||
})),
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
self.egui_glow
|
||||
.egui_winit
|
||||
.handle_platform_output(window, full_output.platform_output);
|
||||
self.shapes = full_output.shapes;
|
||||
self.textures_delta.append(full_output.textures_delta);
|
||||
|
||||
events
|
||||
}
|
||||
}
|
@ -14,8 +14,7 @@ macro_rules! def {
|
||||
|
||||
#[serde_inline_default]
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct Keys {
|
||||
}
|
||||
pub struct Keys {}
|
||||
def!(Keys);
|
||||
|
||||
#[serde_inline_default]
|
||||
|
@ -2,6 +2,7 @@
|
||||
extern crate log;
|
||||
|
||||
mod app;
|
||||
mod browser;
|
||||
mod embedder;
|
||||
mod event_loop;
|
||||
mod utils;
|
||||
|
@ -27,7 +27,7 @@ pub struct Window {
|
||||
}
|
||||
|
||||
impl Window {
|
||||
pub fn new(event_loop: &ActiveEventLoop) -> Window {
|
||||
pub fn new(event_loop: &ActiveEventLoop) -> Self {
|
||||
let opts = opts::get();
|
||||
|
||||
let win_size = opts.initial_window_size.to_untyped().to_i32();
|
||||
@ -66,7 +66,7 @@ impl Window {
|
||||
let rendering_context = RenderingContext::create(&connection, &adapter, surface_type)
|
||||
.expect("Failed to create WR surfman");
|
||||
|
||||
Window {
|
||||
Self {
|
||||
winit_window,
|
||||
rendering_context,
|
||||
animation_state: Cell::new(AnimationState::Idle),
|
||||
@ -147,6 +147,10 @@ impl Window {
|
||||
pub fn is_animating(&self) -> bool {
|
||||
self.animation_state.get() == AnimationState::Animating
|
||||
}
|
||||
|
||||
pub fn winit_window(&self) -> &winit::window::Window {
|
||||
&self.winit_window
|
||||
}
|
||||
}
|
||||
|
||||
impl WindowMethods for Window {
|
||||
|
Loading…
x
Reference in New Issue
Block a user